Skip to content

Commit fff5c5e

Browse files
committed
bug #4421 FunctionTypehintSpaceFixer - Ensure single space between type declaration and parameter (localheinz)
This PR was squashed before being merged into the 2.12 branch (closes #4421). Discussion ---------- FunctionTypehintSpaceFixer - Ensure single space between type declaration and parameter This PR * [x] adjusts the `FunctionTypehintSpaceFixer` to ensure a single (!) space between a type declaration and a parameter 💁‍♂ Not sure, should this be a separate fixer, or can this go into this fixer? Is it a bug? Is it a feature? Commits ------- 19f4ef0 FunctionTypehintSpaceFixer - Ensure single space between type declaration and parameter
2 parents 5830589 + 19f4ef0 commit fff5c5e

File tree

3 files changed

+90
-24
lines changed

3 files changed

+90
-24
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ Choose from the list of available rules:
679679

680680
* **function_typehint_space** [@Symfony, @PhpCsFixer]
681681

682-
Add missing space between function's argument and its typehint.
682+
Ensure single space between function's argument and its typehint.
683683

684684
* **general_phpdoc_annotation_remove**
685685

src/Fixer/FunctionNotation/FunctionTypehintSpaceFixer.php

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use PhpCsFixer\AbstractFixer;
1616
use PhpCsFixer\FixerDefinition\CodeSample;
1717
use PhpCsFixer\FixerDefinition\FixerDefinition;
18+
use PhpCsFixer\Tokenizer\Analyzer\Analysis\TypeAnalysis;
19+
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
1820
use PhpCsFixer\Tokenizer\Token;
1921
use PhpCsFixer\Tokenizer\Tokens;
2022

@@ -29,8 +31,11 @@ final class FunctionTypehintSpaceFixer extends AbstractFixer
2931
public function getDefinition()
3032
{
3133
return new FixerDefinition(
32-
'Add missing space between function\'s argument and its typehint.',
33-
[new CodeSample("<?php\nfunction sample(array\$a)\n{}\n")]
34+
'Ensure single space between function\'s argument and its typehint.',
35+
[
36+
new CodeSample("<?php\nfunction sample(array\$a)\n{}\n"),
37+
new CodeSample("<?php\nfunction sample(array \$a)\n{}\n"),
38+
]
3439
);
3540
}
3641

@@ -47,40 +52,35 @@ public function isCandidate(Tokens $tokens)
4752
*/
4853
protected function applyFix(\SplFileInfo $file, Tokens $tokens)
4954
{
55+
$functionsAnalyzer = new FunctionsAnalyzer();
56+
5057
for ($index = $tokens->count() - 1; $index >= 0; --$index) {
5158
$token = $tokens[$index];
5259

5360
if (!$token->isGivenKind(T_FUNCTION)) {
5461
continue;
5562
}
5663

57-
$startParenthesisIndex = $tokens->getNextTokenOfKind($index, ['(', ';', [T_CLOSE_TAG]]);
58-
if (!$tokens[$startParenthesisIndex]->equals('(')) {
59-
continue;
60-
}
64+
$arguments = $functionsAnalyzer->getFunctionArguments($tokens, $index);
6165

62-
$endParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startParenthesisIndex);
66+
foreach (array_reverse($arguments) as $argument) {
67+
$type = $argument->getTypeAnalysis();
6368

64-
for ($iter = $endParenthesisIndex - 1; $iter > $startParenthesisIndex; --$iter) {
65-
if (!$tokens[$iter]->isGivenKind(T_VARIABLE)) {
69+
if (!$type instanceof TypeAnalysis) {
6670
continue;
6771
}
6872

69-
// skip ... before $variable for variadic parameter
70-
$prevNonWhitespaceIndex = $tokens->getPrevNonWhitespace($iter);
71-
if ($tokens[$prevNonWhitespaceIndex]->isGivenKind(T_ELLIPSIS)) {
72-
$iter = $prevNonWhitespaceIndex;
73-
}
73+
$whitespaceTokenIndex = $type->getEndIndex() + 1;
7474

75-
// skip & before $variable for parameter passed by reference
76-
$prevNonWhitespaceIndex = $tokens->getPrevNonWhitespace($iter);
77-
if ($tokens[$prevNonWhitespaceIndex]->equals('&')) {
78-
$iter = $prevNonWhitespaceIndex;
79-
}
75+
if ($tokens[$whitespaceTokenIndex]->equals([T_WHITESPACE])) {
76+
if (' ' === $tokens[$whitespaceTokenIndex]->getContent()) {
77+
continue;
78+
}
8079

81-
if (!$tokens[$iter - 1]->equalsAny([[T_WHITESPACE], [T_COMMENT], [T_DOC_COMMENT], '(', ','])) {
82-
$tokens->insertAt($iter, new Token([T_WHITESPACE, ' ']));
80+
$tokens->clearAt($whitespaceTokenIndex);
8381
}
82+
83+
$tokens->insertAt($whitespaceTokenIndex, new Token([T_WHITESPACE, ' ']));
8484
}
8585
}
8686
}

tests/Fixer/FunctionNotation/FunctionTypehintSpaceFixerTest.php

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,58 +52,124 @@ public function provideFixCases()
5252
[
5353
'<?php function foo(/**int*/$param) {}',
5454
],
55+
[
56+
'<?php function foo(bool /**bla bla*/ $param) {}',
57+
],
58+
[
59+
'<?php function foo(bool /**bla bla*/$param) {}',
60+
'<?php function foo(bool/**bla bla*/$param) {}',
61+
],
62+
[
63+
'<?php function foo(bool /**bla bla*/$param) {}',
64+
'<?php function foo(bool /**bla bla*/$param) {}',
65+
],
5566
[
5667
'<?php function foo(callable $param) {}',
5768
'<?php function foo(callable$param) {}',
5869
],
70+
[
71+
'<?php function foo(callable $param) {}',
72+
'<?php function foo(callable $param) {}',
73+
],
5974
[
6075
'<?php function foo(array &$param) {}',
6176
'<?php function foo(array&$param) {}',
6277
],
78+
[
79+
'<?php function foo(array &$param) {}',
80+
'<?php function foo(array &$param) {}',
81+
],
6382
[
6483
'<?php function foo(array & $param) {}',
6584
'<?php function foo(array& $param) {}',
6685
],
86+
[
87+
'<?php function foo(array & $param) {}',
88+
'<?php function foo(array & $param) {}',
89+
],
6790
[
6891
'<?php function foo(Bar $param) {}',
6992
'<?php function foo(Bar$param) {}',
7093
],
94+
[
95+
'<?php function foo(Bar $param) {}',
96+
'<?php function foo(Bar $param) {}',
97+
],
7198
[
7299
'<?php function foo(Bar\Baz $param) {}',
73100
'<?php function foo(Bar\Baz$param) {}',
74101
],
102+
[
103+
'<?php function foo(Bar\Baz $param) {}',
104+
'<?php function foo(Bar\Baz $param) {}',
105+
],
75106
[
76107
'<?php function foo(Bar\Baz &$param) {}',
77108
'<?php function foo(Bar\Baz&$param) {}',
78109
],
110+
[
111+
'<?php function foo(Bar\Baz &$param) {}',
112+
'<?php function foo(Bar\Baz &$param) {}',
113+
],
79114
[
80115
'<?php function foo(Bar\Baz & $param) {}',
81116
'<?php function foo(Bar\Baz& $param) {}',
82117
],
118+
[
119+
'<?php function foo(Bar\Baz & $param) {}',
120+
'<?php function foo(Bar\Baz & $param) {}',
121+
],
83122
[
84123
'<?php $foo = function(Bar\Baz $param) {};',
85124
'<?php $foo = function(Bar\Baz$param) {};',
86125
],
126+
[
127+
'<?php $foo = function(Bar\Baz $param) {};',
128+
'<?php $foo = function(Bar\Baz $param) {};',
129+
],
87130
[
88131
'<?php $foo = function(Bar\Baz &$param) {};',
89132
'<?php $foo = function(Bar\Baz&$param) {};',
90133
],
134+
[
135+
'<?php $foo = function(Bar\Baz &$param) {};',
136+
'<?php $foo = function(Bar\Baz &$param) {};',
137+
],
91138
[
92139
'<?php $foo = function(Bar\Baz & $param) {};',
93140
'<?php $foo = function(Bar\Baz& $param) {};',
94141
],
142+
[
143+
'<?php $foo = function(Bar\Baz & $param) {};',
144+
'<?php $foo = function(Bar\Baz & $param) {};',
145+
],
95146
[
96147
'<?php class Test { public function foo(Bar\Baz $param) {} }',
97148
'<?php class Test { public function foo(Bar\Baz$param) {} }',
98149
],
150+
[
151+
'<?php class Test { public function foo(Bar\Baz $param) {} }',
152+
'<?php class Test { public function foo(Bar\Baz $param) {} }',
153+
],
99154
[
100155
'<?php $foo = function(array $a,
101-
array $b, array $c, array
102-
$d) {};',
156+
array $b, array $c, array $d) {};',
103157
'<?php $foo = function(array $a,
104158
array$b, array $c, array
105159
$d) {};',
106160
],
161+
[
162+
'<?php $foo = function(
163+
array $a,
164+
$b
165+
) {};',
166+
],
167+
[
168+
'<?php $foo = function(
169+
$a,
170+
array $b
171+
) {};',
172+
],
107173
[
108174
'<?php function foo(...$param) {}',
109175
],

0 commit comments

Comments
 (0)