Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0d17628

Browse filesBrowse files
committed
BracesFixer - Add allow_single_line_closure configuration
1 parent 189ad4a commit 0d17628
Copy full SHA for 0d17628

File tree

Expand file treeCollapse file tree

9 files changed

+161
-5
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+161
-5
lines changed

‎README.rst

Copy file name to clipboardExpand all lines: README.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ Choose from the list of available rules:
196196
* **braces** [@PSR2, @Symfony]
197197
| The body of each structure MUST be enclosed by braces. Braces should be
198198
| properly placed. Body of braces should be properly indented.
199+
| *Rule is: configurable.*
199200
200201
* **cast_spaces** [@Symfony]
201202
| A single space should be between cast and variable.

‎src/Fixer/Basic/BracesFixer.php

Copy file name to clipboardExpand all lines: src/Fixer/Basic/BracesFixer.php
+87-3Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
namespace PhpCsFixer\Fixer\Basic;
1414

1515
use PhpCsFixer\AbstractFixer;
16+
use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException;
17+
use PhpCsFixer\Fixer\ConfigurableFixerInterface;
1618
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
1719
use PhpCsFixer\FixerDefinition\CodeSample;
1820
use PhpCsFixer\FixerDefinition\FixerDefinition;
@@ -26,8 +28,41 @@
2628
*
2729
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
2830
*/
29-
final class BracesFixer extends AbstractFixer implements WhitespacesAwareFixerInterface
31+
final class BracesFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface
3032
{
33+
/**
34+
* @var array
35+
*/
36+
private $configuration;
37+
38+
private static $defaultConfiguration = array(
39+
'allow_single_line_closure' => false,
40+
);
41+
42+
/**
43+
* @param array<string, bool>|null $configuration
44+
*/
45+
public function configure(array $configuration = null)
46+
{
47+
if (null === $configuration) {
48+
$this->configuration = self::$defaultConfiguration;
49+
50+
return;
51+
}
52+
53+
foreach ($configuration as $functionName => $replacement) {
54+
if (!array_key_exists($functionName, self::$defaultConfiguration)) {
55+
throw new InvalidFixerConfigurationException($this->getName(), sprintf('"%s" is not handled by the fixer.', $functionName));
56+
}
57+
58+
if (!is_bool($replacement)) {
59+
throw new InvalidFixerConfigurationException($this->getName(), sprintf('Expected bool got "%s".', is_object($replacement) ? get_class($replacement) : gettype($replacement)));
60+
}
61+
}
62+
63+
$this->configuration = $configuration;
64+
}
65+
3166
/**
3267
* {@inheritdoc}
3368
*/
@@ -48,7 +83,8 @@ public function getDefinition()
4883
{
4984
return new FixerDefinition(
5085
'The body of each structure MUST be enclosed by braces. Braces should be properly placed. Body of braces should be properly indented.',
51-
array(new CodeSample(
86+
array(
87+
new CodeSample(
5288
'<?php
5389
5490
class Foo {
@@ -75,7 +111,19 @@ public function bar($baz) {
75111
}
76112
}
77113
'
78-
))
114+
),
115+
new CodeSample(
116+
'<?php
117+
$positive = function ($item) { return $item >= 0; };
118+
$negative = function ($item) {
119+
return $item < 0; };
120+
',
121+
array('allow_single_line_closure' => true)
122+
),
123+
),
124+
null,
125+
'The `allow_single_line_closure` key could be set to `true` to allow for single line lambda notation.',
126+
self::$defaultConfiguration
79127
);
80128
}
81129

@@ -220,6 +268,23 @@ function ($item) {
220268
continue;
221269
}
222270

271+
if (
272+
$this->configuration['allow_single_line_closure']
273+
&& $token->isGivenKind(T_FUNCTION)
274+
&& $tokensAnalyzer->isLambda($index)
275+
) {
276+
$braceEndIndex = $tokens->findBlockEnd(
277+
Tokens::BLOCK_TYPE_CURLY_BRACE,
278+
$tokens->getNextTokenOfKind($index, array('{'))
279+
);
280+
281+
if (!$this->isMultilined($tokens, $index, $braceEndIndex)) {
282+
$index = $braceEndIndex;
283+
284+
continue;
285+
}
286+
}
287+
223288
if ($token->isGivenKind($classyAndFunctionTokens)) {
224289
$startBraceIndex = $tokens->getNextTokenOfKind($index, array(';', '{'));
225290
$startBraceToken = $tokens[$startBraceIndex];
@@ -374,6 +439,7 @@ private function fixMissingControlBraces(Tokens $tokens)
374439
// if Token after parenthesis is { then we do not need to insert brace, but to fix whitespace before it
375440
if ($tokenAfterParenthesis->equals('{')) {
376441
$tokens->ensureWhitespaceAtIndex($parenthesisEndIndex + 1, 0, ' ');
442+
377443
continue;
378444
}
379445

@@ -674,4 +740,22 @@ private function removeWhitespaceInParenthesis(Tokens $tokens, $startParenthesis
674740
}
675741
}
676742
}
743+
744+
/**
745+
* @param Tokens $tokens
746+
* @param int $startParenthesisIndex
747+
* @param int $endParenthesisIndex
748+
*
749+
* @return bool
750+
*/
751+
private function isMultilined(Tokens $tokens, $startParenthesisIndex, $endParenthesisIndex)
752+
{
753+
for ($i = $startParenthesisIndex; $i < $endParenthesisIndex; ++$i) {
754+
if (false !== strpos($tokens[$i]->getContent(), "\n")) {
755+
return true;
756+
}
757+
}
758+
759+
return false;
760+
}
677761
}

‎src/RuleSet.php

Copy file name to clipboardExpand all lines: src/RuleSet.php
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ final class RuleSet implements RuleSetInterface
5959
),
6060
'blank_line_after_opening_tag' => true,
6161
'blank_line_before_return' => true,
62+
'braces' => array(
63+
'allow_single_line_closure' => true,
64+
),
6265
'cast_spaces' => true,
6366
'class_definition' => array('singleLine' => true),
6467
'concat_space' => array('spacing' => 'none'),

‎tests/Fixer/Basic/BracesFixerTest.php

Copy file name to clipboardExpand all lines: tests/Fixer/Basic/BracesFixerTest.php
+49Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,6 +1710,55 @@ public function providePreserveLineAfterControlBrace()
17101710
);
17111711
}
17121712

1713+
/**
1714+
* @param string $expected
1715+
* @param null|string $input
1716+
*
1717+
* @dataProvider provideFixWithAllowOnelineLambdaCases
1718+
*/
1719+
public function testFixWithAllowSingleLineClosure($expected, $input = null)
1720+
{
1721+
$this->fixer->configure(array(
1722+
'allow_single_line_closure' => true,
1723+
));
1724+
1725+
$this->doTest($expected, $input);
1726+
}
1727+
1728+
public function provideFixWithAllowOnelineLambdaCases()
1729+
{
1730+
return array(
1731+
array(
1732+
'<?php
1733+
$callback = function () { return true; };',
1734+
),
1735+
array(
1736+
'<?php
1737+
$callback = function () { if ($a) { return true; } return false; };',
1738+
'<?php
1739+
$callback = function () { if($a){ return true; } return false; };',
1740+
),
1741+
array(
1742+
'<?php
1743+
$callback = function () { if ($a) { return true; } return false; };',
1744+
'<?php
1745+
$callback = function () { if($a) return true; return false; };',
1746+
),
1747+
array(
1748+
'<?php
1749+
$callback = function () {
1750+
if ($a) {
1751+
return true;
1752+
}
1753+
return false;
1754+
};',
1755+
'<?php
1756+
$callback = function () { if($a) return true;
1757+
return false; };',
1758+
),
1759+
);
1760+
}
1761+
17131762
/**
17141763
* @param string $expected
17151764
* @param null|string $input

‎tests/Fixtures/Integration/misc/PHP7.test

Copy file name to clipboardExpand all lines: tests/Fixtures/Integration/misc/PHP7.test
+13-2Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,18 @@ class Foo implements FooInterface
8080
{
8181
}
8282

83-
public function getFnc()
83+
public function getFnc1()
8484
{
8585
return function () {
8686
echo 1;
8787
};
8888
}
8989

90+
public function getFnc2()
91+
{
92+
return function () { echo 1; };
93+
}
94+
9095
public function gen1()
9196
{
9297
yield 1;
@@ -180,7 +185,13 @@ class Foo implements FooInterface
180185
// scalar typehinting
181186
public function bar2(int $a) : string{}
182187

183-
public function getFnc()
188+
public function getFnc1()
189+
{
190+
return function () {
191+
echo 1; };
192+
}
193+
194+
public function getFnc2()
184195
{
185196
return function () { echo 1; };
186197
}

‎tests/Fixtures/Integration/set/@Symfony.test-in.php

Copy file name to clipboardExpand all lines: tests/Fixtures/Integration/set/@Symfony.test-in.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public function __construct($dummy)
4444
*/
4545
private function transformText($dummy, array $options = array(),$data=null)
4646
{
47+
$fnc = function () { return true; };
48+
4749
$mergedOptions = array_merge(
4850
array(
4951
'some_default' => 'values',

‎tests/Fixtures/Integration/set/@Symfony.test-out.php

Copy file name to clipboardExpand all lines: tests/Fixtures/Integration/set/@Symfony.test-out.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public function __construct($dummy)
4343
*/
4444
private function transformText($dummy, array $options = array(), $data = null)
4545
{
46+
$fnc = function () { return true; };
47+
4648
$mergedOptions = array_merge(
4749
array(
4850
'some_default' => 'values',

‎tests/Fixtures/Integration/set/@Symfony_whitespaces.test-in.php

Copy file name to clipboardExpand all lines: tests/Fixtures/Integration/set/@Symfony_whitespaces.test-in.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public function __construct($dummy)
4444
*/
4545
private function transformText($dummy, array $options = array(),$data=null)
4646
{
47+
$fnc = function () { return true; };
48+
4749
$mergedOptions = array_merge(
4850
array(
4951
'some_default' => 'values',

‎tests/Fixtures/Integration/set/@Symfony_whitespaces.test-out.php

Copy file name to clipboardExpand all lines: tests/Fixtures/Integration/set/@Symfony_whitespaces.test-out.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public function __construct($dummy)
4343
*/
4444
private function transformText($dummy, array $options = array(), $data = null)
4545
{
46+
$fnc = function () { return true; };
47+
4648
$mergedOptions = array_merge(
4749
array(
4850
'some_default' => 'values',

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.