diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fc683b3..41faf193 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG for PHP CS Fixer: custom fixers +## v3.31.0 +- Update minimum PHP CS Fixer version to 3.84.0 + ## v3.30.0 - Update minimum PHP CS Fixer version to 3.82.0 diff --git a/composer.json b/composer.json index c01245b8..dd389821 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "php": "^7.4 || ^8.0", "ext-filter": "*", "ext-tokenizer": "*", - "friendsofphp/php-cs-fixer": "^3.82" + "friendsofphp/php-cs-fixer": "^3.84" }, "require-dev": { "phpunit/phpunit": "^9.6.22 || 10.5.45 || ^11.5.7" diff --git a/src/Fixer/PhpdocVarAnnotationToAssertFixer.php b/src/Fixer/PhpdocVarAnnotationToAssertFixer.php index f259ae4a..2ae92140 100644 --- a/src/Fixer/PhpdocVarAnnotationToAssertFixer.php +++ b/src/Fixer/PhpdocVarAnnotationToAssertFixer.php @@ -11,6 +11,7 @@ namespace PhpCsFixerCustomFixers\Fixer; +use PhpCsFixer\AbstractPhpdocToTypeDeclarationFixer; use PhpCsFixer\DocBlock\Annotation; use PhpCsFixer\DocBlock\DocBlock; use PhpCsFixer\FixerDefinition\CodeSample; @@ -57,17 +58,18 @@ public function isRisky(): bool public function fix(\SplFileInfo $file, Tokens $tokens): void { - for ($docCommentIndex = $tokens->count() - 1; $docCommentIndex > 0; $docCommentIndex--) { - if (!$tokens[$docCommentIndex]->isGivenKind([\T_DOC_COMMENT])) { - continue; - } + $tokensToInsert = []; + $typesToExclude = []; + + foreach ($tokens->findGivenKind(\T_DOC_COMMENT) as $index => $token) { + $typesToExclude = \array_merge($typesToExclude, self::getTypesToExclude($token->getContent())); - $variableIndex = self::getVariableIndex($tokens, $docCommentIndex); + $variableIndex = self::getVariableIndex($tokens, $index); if ($variableIndex === null) { continue; } - $assertTokens = self::getAssertTokens($tokens, $docCommentIndex, $tokens[$variableIndex]->getContent()); + $assertTokens = self::getAssertTokens($tokens, $index, $tokens[$variableIndex]->getContent(), $typesToExclude); if ($assertTokens === null) { continue; } @@ -82,10 +84,32 @@ public function fix(\SplFileInfo $file, Tokens $tokens): void \array_unshift($assertTokens, new Token([\T_WHITESPACE, $tokens[$variableIndex - 1]->getContent()])); } - $tokens->insertAt($expressionEndIndex + 1, $assertTokens); + $tokensToInsert[$expressionEndIndex + 1] = $assertTokens; + + TokenRemover::removeWithLinesIfPossible($tokens, $index); + } + + $tokens->insertSlices($tokensToInsert); + } - TokenRemover::removeWithLinesIfPossible($tokens, $docCommentIndex); + /** + * @return list + */ + private static function getTypesToExclude(string $content): array + { + /** @var null|\Closure(string): list $getTypesToExclude */ + static $getTypesToExclude = null; + + if ($getTypesToExclude === null) { + /** @var \Closure(string): list $getTypesToExclude */ + $getTypesToExclude = \Closure::bind( + static fn (string $content): array => AbstractPhpdocToTypeDeclarationFixer::getTypesToExclude($content), + null, + AbstractPhpdocToTypeDeclarationFixer::class, + ); } + + return $getTypesToExclude($content); } private static function getVariableIndex(Tokens $tokens, int $docCommentIndex): ?int @@ -114,9 +138,11 @@ private static function getVariableIndex(Tokens $tokens, int $docCommentIndex): } /** + * @param list $typesToExclude + * * @return null|list */ - private static function getAssertTokens(Tokens $tokens, int $docCommentIndex, string $variableName): ?array + private static function getAssertTokens(Tokens $tokens, int $docCommentIndex, string $variableName, array $typesToExclude): ?array { $annotation = self::getAnnotationForVariable($tokens, $docCommentIndex, $variableName); if ($annotation === null) { @@ -136,6 +162,9 @@ private static function getAssertTokens(Tokens $tokens, int $docCommentIndex, st $assertions['null'] = self::getCodeForType('null', $variableName); $type = \substr($type, 1); } + if (\in_array($type, $typesToExclude, true)) { + return null; + } $assertions[$type] = self::getCodeForType($type, $variableName); } diff --git a/tests/Fixer/PhpdocVarAnnotationToAssertFixerTest.php b/tests/Fixer/PhpdocVarAnnotationToAssertFixerTest.php index 9435b575..d058fb98 100644 --- a/tests/Fixer/PhpdocVarAnnotationToAssertFixerTest.php +++ b/tests/Fixer/PhpdocVarAnnotationToAssertFixerTest.php @@ -399,5 +399,167 @@ function ($x) { $x++; return $x + 6; }, $z = 4; ', ]; + + yield 'types defined with `phpstan-type`' => [ + <<<'PHP' + [ + <<<'PHP' + [ + <<<'PHP' + [ + <<<'PHP' + [ + <<<'PHP' + [ + <<<'PHP' +