diff --git a/CHANGELOG.md b/CHANGELOG.md index 10da718..36eab49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Fixed +- Bug #9: `ErickSkrauch/align_multiline_parameters` now correctly aligns variadic arguments. ## [1.2.3] - 2024-01-09 ### Fixed diff --git a/README.md b/README.md index 4697dd3..adacadf 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,10 @@ Forces aligned or not aligned multiline function parameters: string $string, - int $index = 0, - $arg = 'no type', +- ...$variadic, + int $index = 0, + $arg = 'no type', ++ ...$variadic ): void {} ``` diff --git a/src/FunctionNotation/AlignMultilineParametersFixer.php b/src/FunctionNotation/AlignMultilineParametersFixer.php index 96c1b9e..4f3e598 100644 --- a/src/FunctionNotation/AlignMultilineParametersFixer.php +++ b/src/FunctionNotation/AlignMultilineParametersFixer.php @@ -30,6 +30,7 @@ * typeLength: non-negative-int, * nameLength: positive-int, * nameIndex: int, + * isVariadic: bool, * } */ final class AlignMultilineParametersFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { @@ -83,7 +84,8 @@ public function isCandidate(Tokens $tokens): bool { /** * Must run after StatementIndentationFixer, MethodArgumentSpaceFixer, CompactNullableTypehintFixer, - * SingleSpaceAroundConstructFixer, TypesSpacesFixer + * SingleSpaceAroundConstructFixer, TypesSpacesFixer, UnaryOperatorSpacesFixer, + * FunctionTypehintSpaceFixer, TypeDeclarationSpacesFixer */ public function getPriority(): int { return -10; @@ -131,6 +133,8 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void { $longestType = 0; $longestVariableName = 0; $hasAtLeastOneTypedArgument = false; + /** @var bool|null $isVariadicArgTypeLong */ + $isVariadicArgTypeLong = null; /** @var list $analysedArguments */ $analysedArguments = []; foreach ($arguments as $argument) { @@ -148,6 +152,10 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void { $longestVariableName = $declarationAnalysis['nameLength']; } + if ($declarationAnalysis['isVariadic']) { + $isVariadicArgTypeLong = $longestType === $declarationAnalysis['typeLength']; + } + $analysedArguments[] = $declarationAnalysis; } @@ -170,9 +178,27 @@ protected function applyFix(SplFileInfo $file, Tokens $tokens): void { } if ($this->configuration[self::C_VARIABLES] !== null) { - $whitespaceIndex = $argument['nameIndex'] - 1; + if ($argument['isVariadic']) { + $whitespaceIndex = $tokens->getPrevMeaningfulToken($argument['nameIndex']) - 1; + } else { + $whitespaceIndex = $argument['nameIndex'] - 1; + } + if ($this->configuration[self::C_VARIABLES] === true) { - $appendix = str_repeat(' ', $longestType - $argument['typeLength'] + (int)$hasAtLeastOneTypedArgument); + $alignLength = $longestType - $argument['typeLength'] + (int)$hasAtLeastOneTypedArgument; + if ($isVariadicArgTypeLong !== null) { + if ($isVariadicArgTypeLong) { + if (!$argument['isVariadic']) { + $alignLength += 3; + } + } else { + if ($argument['isVariadic']) { + $alignLength -= 3; + } + } + } + + $appendix = str_repeat(' ', $alignLength); if ($argument['typeLength'] > 0) { $whitespaceToken = $appendix; } else { @@ -197,6 +223,15 @@ private function getDeclarationAnalysis(Tokens $tokens, int $nameIndex, ?TypeAna $searchIndex = $nameIndex; $includeNextWhitespace = false; $typeLength = 0; + + $isVariadic = false; + $variadicTokenIndex = $tokens->getPrevMeaningfulToken($searchIndex); + $variadicToken = $tokens[$variadicTokenIndex]; + if ($variadicToken->isGivenKind(T_ELLIPSIS)) { + $isVariadic = true; + $searchIndex = $variadicTokenIndex; + } + if ($typeAnalysis !== null) { $searchIndex = $typeAnalysis->getStartIndex(); $includeNextWhitespace = true; @@ -237,6 +272,7 @@ private function getDeclarationAnalysis(Tokens $tokens, int $nameIndex, ?TypeAna 'typeLength' => $typeLength, 'nameLength' => $nameLength, 'nameIndex' => $nameIndex, + 'isVariadic' => $isVariadic, ]; } diff --git a/tests/FunctionNotation/AlignMultilineParametersFixerTest.php b/tests/FunctionNotation/AlignMultilineParametersFixerTest.php index b36cf9d..cfd7ce3 100644 --- a/tests/FunctionNotation/AlignMultilineParametersFixerTest.php +++ b/tests/FunctionNotation/AlignMultilineParametersFixerTest.php @@ -216,6 +216,51 @@ function test( ): void {} ', ]; + + yield 'variadic parameter (short)' => [ + ' [ + ' [ + '