Skip to content

Commit 28a9559

Browse files
authored
Merge pull request #36 from kubawerlos/fix/implode-call-fixer-with-comments
ImplodeCallFixer: fix for case with comments
2 parents 56b1ee1 + 143cc97 commit 28a9559

File tree

3 files changed

+80
-53
lines changed

3 files changed

+80
-53
lines changed

src/Fixer/ImplodeCallFixer.php

Lines changed: 33 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
use PhpCsFixer\FixerDefinition\CodeSample;
88
use PhpCsFixer\FixerDefinition\FixerDefinition;
9+
use PhpCsFixer\Tokenizer\Analyzer\ArgumentsAnalyzer;
910
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
10-
use PhpCsFixer\Tokenizer\CT;
1111
use PhpCsFixer\Tokenizer\Token;
1212
use PhpCsFixer\Tokenizer\Tokens;
1313

@@ -52,40 +52,42 @@ public function fix(\SplFileInfo $file, Tokens $tokens) : void
5252
$argumentsIndices = $this->getArgumentIndices($tokens, $index);
5353

5454
if (\count($argumentsIndices) === 1) {
55-
$firstArgumentIndex = \reset($argumentsIndices);
56-
$tokens->insertAt($firstArgumentIndex, new Token([T_WHITESPACE, ' ']));
57-
$tokens->insertAt($firstArgumentIndex, new Token(','));
58-
$tokens->insertAt($firstArgumentIndex, new Token([T_CONSTANT_ENCAPSED_STRING, "''"]));
55+
$firstArgumentIndex = \key($argumentsIndices);
56+
$tokens->insertAt($firstArgumentIndex, [
57+
new Token([T_CONSTANT_ENCAPSED_STRING, "''"]),
58+
new Token(','),
59+
new Token([T_WHITESPACE, ' ']),
60+
]);
61+
5962
continue;
6063
}
6164

6265
if (\count($argumentsIndices) === 2) {
63-
list($firstArgumentIndex, $secondArgumentIndex) = $argumentsIndices;
66+
list($firstArgumentIndex, $secondArgumentIndex) = \array_keys($argumentsIndices);
67+
68+
// If the first argument is string we have nothing to do
6469
if ($tokens[$firstArgumentIndex]->isGivenKind(T_CONSTANT_ENCAPSED_STRING)) {
6570
continue;
6671
}
72+
// If the second argument is not string we cannot make a swap
6773
if (!$tokens[$secondArgumentIndex]->isGivenKind(T_CONSTANT_ENCAPSED_STRING)) {
6874
continue;
6975
}
7076

71-
$insideCommaIndex = $tokens->getPrevTokenOfKind($secondArgumentIndex, [',']);
72-
73-
$indicesToMove = [$secondArgumentIndex, $insideCommaIndex];
74-
75-
$insideWhitespaceIndex = $tokens->getPrevTokenOfKind($secondArgumentIndex, [[T_WHITESPACE]]);
76-
if ($insideWhitespaceIndex > $insideCommaIndex) {
77-
$indicesToMove[] = $insideWhitespaceIndex;
77+
// collect tokens from first argument
78+
$firstArgumenteEndIndex = $argumentsIndices[\key($argumentsIndices)];
79+
$newSecondArgumentTokens = [];
80+
for ($i = \key($argumentsIndices); $i <= $firstArgumenteEndIndex; $i++) {
81+
$newSecondArgumentTokens[] = clone $tokens[$i];
82+
$tokens->clearAt($i);
7883
}
7984

80-
$tokensToInsert = [];
81-
foreach ($indicesToMove as $indexToRemove) {
82-
$tokensToInsert[] = clone $tokens[$indexToRemove];
83-
$tokens->clearAt($indexToRemove);
84-
}
85+
$tokens->insertAt($firstArgumentIndex, clone $tokens[$secondArgumentIndex]);
8586

86-
foreach (\array_reverse($tokensToInsert) as $tokenToInsert) {
87-
$tokens->insertAt($firstArgumentIndex, $tokenToInsert);
88-
}
87+
// insert above increased the second argument index
88+
$secondArgumentIndex++;
89+
$tokens->clearAt($secondArgumentIndex);
90+
$tokens->insertAt($secondArgumentIndex, $newSecondArgumentTokens);
8991
}
9092
}
9193
}
@@ -95,40 +97,22 @@ public function getPriority() : int
9597
return 0;
9698
}
9799

100+
/**
101+
* @return array<int, int> In the format: startIndex => endIndex
102+
*/
98103
private function getArgumentIndices(Tokens $tokens, int $functionNameIndex) : array
99104
{
100-
$startBracketIndex = $tokens->getNextTokenOfKind($functionNameIndex, ['(']);
101-
$endBracketIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startBracketIndex);
102-
$argumentsIndices = [];
103-
$parameterRecorded = false;
104-
105-
$index = $startBracketIndex;
106-
while ($index < $endBracketIndex) {
107-
$index++;
108-
$token = $tokens[$index];
109-
110-
if (!$parameterRecorded && !$token->isWhitespace() && !$token->isComment()) {
111-
$argumentsIndices[] = $index;
112-
$parameterRecorded = true;
113-
}
105+
$argumentsAnalyzer = new ArgumentsAnalyzer();
114106

115-
if ($token->equals('(')) {
116-
$index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index);
107+
$openParenthesis = $tokens->getNextTokenOfKind($functionNameIndex, ['(']);
108+
$closeParenthesis = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openParenthesis);
117109

118-
continue;
119-
}
110+
$indices = [];
120111

121-
if ($token->isGivenKind(CT::T_ARRAY_SQUARE_BRACE_OPEN)) {
122-
$index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $index);
123-
124-
continue;
125-
}
126-
127-
if ($token->equals(',')) {
128-
$parameterRecorded = false;
129-
}
112+
foreach ($argumentsAnalyzer->getArguments($tokens, $openParenthesis, $closeParenthesis) as $startIndexCandidate => $endIndex) {
113+
$indices[$tokens->getNextMeaningfulToken($startIndexCandidate - 1)] = $tokens->getPrevMeaningfulToken($endIndex + 1);
130114
}
131115

132-
return $argumentsIndices;
116+
return $indices;
133117
}
134118
}

tests/Fixer/ImplodeCallFixerTest.php

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ public function provideFixCases() : \Iterator
6464
];
6565

6666
yield [
67-
'<?php implode("", $weirdStuff[mt_rand($min, getMac()) + 200]);',
68-
'<?php implode($weirdStuff[mt_rand($min, getMac()) + 200], "");',
67+
'<?php implode("",$foo);',
68+
'<?php implode($foo,"");',
6969
];
7070

7171
yield [
72-
'<?php implode("",$foo);',
73-
'<?php implode($foo,"");',
72+
'<?php implode("", $weirdStuff[mt_rand($min, getMax()) + 200]);',
73+
'<?php implode($weirdStuff[mt_rand($min, getMax()) + 200], "");',
7474
];
7575

7676
yield [
@@ -85,5 +85,46 @@ public function provideFixCases() : \Iterator
8585
""
8686
);',
8787
];
88+
89+
yield [
90+
'<?php
91+
implode(
92+
\'\', $foo
93+
);',
94+
'<?php
95+
implode(
96+
$foo
97+
);',
98+
];
99+
100+
yield [
101+
'<?php
102+
implode(# 1
103+
""/* 2.1 */,# 2.2
104+
$foo# 3
105+
);',
106+
'<?php
107+
implode(# 1
108+
$foo/* 2.1 */,# 2.2
109+
""# 3
110+
);',
111+
];
112+
113+
yield [
114+
'<?php
115+
implode(# 1
116+
# 2
117+
\'\', $foo# 3
118+
# 4
119+
)# 5
120+
;',
121+
'<?php
122+
implode(# 1
123+
# 2
124+
$foo# 3
125+
# 4
126+
)# 5
127+
;',
128+
];
88129
}
89130
}

tests/psalm.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
</projectFiles>
1010

1111
<issueHandlers>
12+
<InvalidReturnStatement errorLevel='suppress' />
13+
<InvalidReturnType errorLevel='suppress' />
1214
<PossiblyNullArgument errorLevel='suppress' />
1315
<PossiblyNullArrayOffset errorLevel='suppress' />
1416
<PossiblyNullOperand errorLevel='suppress' />

0 commit comments

Comments
 (0)