Skip to content

Commit 0601ddc

Browse files
committed
ErickSkrauch/align_multiline_parameters inserted a space between the type and the param name in the wrong position
1 parent e4f93c2 commit 0601ddc

File tree

3 files changed

+52
-29
lines changed

3 files changed

+52
-29
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010

1111
### Fixed
1212
- Bug #6: `ErickSkrauch/align_multiline_parameters` not working correctly with unions and intersections.
13+
- `ErickSkrauch/align_multiline_parameters` inserted a space between the type and the param name in the wrong position when there were no whitespace between them.
1314

1415
## [1.2.1] - 2023-11-16
1516
### Fixed

src/FunctionNotation/AlignMultilineParametersFixer.php

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PhpCsFixer\FixerDefinition\CodeSample;
1313
use PhpCsFixer\FixerDefinition\FixerDefinition;
1414
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
15+
use PhpCsFixer\Tokenizer\Analyzer\Analysis\TypeAnalysis;
1516
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
1617
use PhpCsFixer\Tokenizer\Analyzer\WhitespacesAnalyzer;
1718
use PhpCsFixer\Tokenizer\CT;
@@ -127,7 +128,7 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void {
127128
$typeAnalysis = $argument->getTypeAnalysis();
128129
if ($typeAnalysis) {
129130
$hasAtLeastOneTypedArgument = true;
130-
$typeLength = $this->getFullTypeLength($tokens, $typeAnalysis->getStartIndex());
131+
$typeLength = $this->getFullTypeLength($tokens, $typeAnalysis);
131132
if ($typeLength > $longestType) {
132133
$longestType = $typeLength;
133134
}
@@ -140,13 +141,31 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void {
140141
}
141142

142143
$argsIndent = WhitespacesAnalyzer::detectIndent($tokens, $i) . $this->whitespacesConfig->getIndent();
143-
foreach ($arguments as $argument) {
144+
// Since we perform insertion of new tokens in this loop, if we go sequentially,
145+
// at each new iteration the token indices will shift due to the addition of new whitespaces.
146+
// If we go from the end, this problem will not occur.
147+
foreach (array_reverse($arguments) as $argument) {
148+
if ($this->configuration[self::C_DEFAULTS] !== null) {
149+
// Can't use $argument->hasDefault() because it's null when it's default for a type (e.g. 0 for int)
150+
$equalToken = $tokens[$tokens->getNextMeaningfulToken($argument->getNameIndex())];
151+
if ($equalToken->getContent() === '=') {
152+
$nameLen = mb_strlen($argument->getName());
153+
$whitespaceIndex = $argument->getNameIndex() + 1;
154+
if ($this->configuration[self::C_DEFAULTS] === true) {
155+
$tokens->ensureWhitespaceAtIndex($whitespaceIndex, 0, str_repeat(' ', $longestVariableName - $nameLen + 1));
156+
} else {
157+
$tokens->ensureWhitespaceAtIndex($whitespaceIndex, 0, ' ');
158+
}
159+
}
160+
}
161+
144162
if ($this->configuration[self::C_VARIABLES] !== null) {
145163
$whitespaceIndex = $argument->getNameIndex() - 1;
146164
if ($this->configuration[self::C_VARIABLES] === true) {
147165
$typeLen = 0;
148-
if ($argument->getTypeAnalysis() !== null) {
149-
$typeLen = $this->getFullTypeLength($tokens, $argument->getTypeAnalysis()->getStartIndex());
166+
$typeAnalysis = $argument->getTypeAnalysis();
167+
if ($typeAnalysis !== null) {
168+
$typeLen = $this->getFullTypeLength($tokens, $typeAnalysis);
150169
}
151170

152171
$appendix = str_repeat(' ', $longestType - $typeLen + (int)$hasAtLeastOneTypedArgument);
@@ -163,22 +182,7 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void {
163182
}
164183
}
165184

166-
$tokens->ensureWhitespaceAtIndex($whitespaceIndex, 0, $whitespaceToken);
167-
}
168-
169-
if ($this->configuration[self::C_DEFAULTS] !== null) {
170-
// Can't use $argument->hasDefault() because it's null when it's default for a type (e.g. 0 for int)
171-
/** @var \PhpCsFixer\Tokenizer\Token $equalToken */
172-
$equalToken = $tokens[$tokens->getNextMeaningfulToken($argument->getNameIndex())];
173-
if ($equalToken->getContent() === '=') {
174-
$nameLen = mb_strlen($argument->getName());
175-
$whitespaceIndex = $argument->getNameIndex() + 1;
176-
if ($this->configuration[self::C_DEFAULTS] === true) {
177-
$tokens->ensureWhitespaceAtIndex($whitespaceIndex, 0, str_repeat(' ', $longestVariableName - $nameLen + 1));
178-
} else {
179-
$tokens->ensureWhitespaceAtIndex($whitespaceIndex, 0, ' ');
180-
}
181-
}
185+
$tokens->ensureWhitespaceAtIndex($whitespaceIndex, 1, $whitespaceToken);
182186
}
183187
}
184188
}
@@ -187,25 +191,22 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void {
187191
/**
188192
* TODO: The declaration might be split across multiple lines.
189193
* In such case we need to find the longest line and return it as the full type length
190-
*
191-
* @param int $typeIndex points to the beginning of the type
192194
*/
193-
private function getFullTypeLength(Tokens $tokens, int $typeIndex): int {
195+
private function getFullTypeLength(Tokens $tokens, TypeAnalysis $typeAnalysis): int {
194196
$typeLength = 0;
195-
$varNameTokenIndex = $tokens->getNextTokenOfKind($typeIndex, [[T_VARIABLE]]);
196-
for ($i = $typeIndex; $i < $varNameTokenIndex - 1; $i++) { // -1 to avoid whitespace between param name and type
197+
for ($i = $typeAnalysis->getStartIndex(); $i <= $typeAnalysis->getEndIndex(); $i++) {
197198
$typeLength += mb_strlen($tokens[$i]->getContent());
198199
}
199200

200-
$possiblyReadonlyToken = $tokens[$typeIndex - 2];
201+
$possiblyReadonlyToken = $tokens[$typeAnalysis->getStartIndex() - 2];
201202
if ($possiblyReadonlyToken->isGivenKind($this->parameterModifiers)) {
202-
$whitespaceToken = $tokens[$typeIndex - 1];
203+
$whitespaceToken = $tokens[$typeAnalysis->getStartIndex() - 1];
203204
$typeLength += strlen($possiblyReadonlyToken->getContent() . $whitespaceToken->getContent());
204205
}
205206

206-
$possiblyPromotionToken = $tokens[$typeIndex - 4];
207+
$possiblyPromotionToken = $tokens[$typeAnalysis->getStartIndex() - 4];
207208
if ($possiblyPromotionToken->isGivenKind($this->parameterModifiers)) {
208-
$whitespaceToken = $tokens[$typeIndex - 3];
209+
$whitespaceToken = $tokens[$typeAnalysis->getStartIndex() - 3];
209210
$typeLength += strlen($possiblyPromotionToken->getContent() . $whitespaceToken->getContent());
210211
}
211212

tests/FunctionNotation/AlignMultilineParametersFixerTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,27 @@ public function provideNullCases(): iterable {
253253
}
254254
}
255255

256+
public function testNoWhitespace(): void {
257+
$this->fixer->configure([
258+
AlignMultilineParametersFixer::C_VARIABLES => true,
259+
AlignMultilineParametersFixer::C_DEFAULTS => true,
260+
]);
261+
$this->doTest(
262+
'<?php
263+
function test(
264+
string $string = "string",
265+
int $int = 0
266+
): void {}
267+
',
268+
'<?php
269+
function test(
270+
string$string = "string",
271+
int$int = 0
272+
): void {}
273+
',
274+
);
275+
}
276+
256277
/**
257278
* @dataProvider provide80TrueCases
258279
* @requires PHP 8.0

0 commit comments

Comments
 (0)