From 8e1f129701722a52ead961a5af81934b7768a584 Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Wed, 16 Nov 2022 19:14:13 -0400 Subject: [PATCH] Reject `@psalm-consistent-constructor` in function docblocks Fixes vimeo/psalm#8712 --- .../Reflector/FunctionLikeDocblockParser.php | 42 +++++++++++++++---- tests/FunctionLikeDocblockParserTest.php | 5 +++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php index afbc1df9c9a..7ce511bd011 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php @@ -15,6 +15,7 @@ use Psalm\Issue\InvalidDocblock; use Psalm\IssueBuffer; +use function array_keys; use function array_shift; use function array_unique; use function count; @@ -704,17 +705,44 @@ private static function checkUnexpectedTags( PhpParser\Comment\Doc $comment ): void { if (isset($parsed_docblock->tags['psalm-import-type'])) { - foreach ($parsed_docblock->tags['psalm-import-type'] as $offset => $_) { - $info->unexpected_tags['psalm-import-type']['lines'][] = self::docblockLineNumber($comment, $offset); - } + $info->unexpected_tags['psalm-import-type']['lines'] = self::tagOffsetsToLines( + array_keys($parsed_docblock->tags['psalm-import-type']), + $comment + ); } if (isset($parsed_docblock->combined_tags['var'])) { - $info->unexpected_tags['var'] = ['lines' => [], 'suggested_replacement' => 'param']; - foreach ($parsed_docblock->combined_tags['var'] as $offset => $_) { - $info->unexpected_tags['var']['lines'][] = self::docblockLineNumber($comment, $offset); - } + $info->unexpected_tags['var'] = [ + 'lines' => self::tagOffsetsToLines( + array_keys($parsed_docblock->combined_tags['var']), + $comment + ), + 'suggested_replacement' => 'param' + ]; + } + + if (isset($parsed_docblock->tags['psalm-consistent-constructor'])) { + $info->unexpected_tags['psalm-consistent-constructor'] = [ + 'lines' => self::tagOffsetsToLines( + array_keys($parsed_docblock->tags['psalm-consistent-constructor']), + $comment + ), + 'suggested_replacement' => 'psalm-consistent-constructor on a class level', + ]; + } + } + + /** + * @param list $offsets + * @return list + */ + private static function tagOffsetsToLines(array $offsets, PhpParser\Comment\Doc $comment): array + { + $ret = []; + foreach ($offsets as $offset) { + $ret[] = self::docblockLineNumber($comment, $offset); } + return $ret; } private static function docblockLineNumber(PhpParser\Comment\Doc $comment, int $offset): int diff --git a/tests/FunctionLikeDocblockParserTest.php b/tests/FunctionLikeDocblockParserTest.php index 5756333193b..b525edac224 100644 --- a/tests/FunctionLikeDocblockParserTest.php +++ b/tests/FunctionLikeDocblockParserTest.php @@ -135,6 +135,7 @@ public function testReturnsUnexpectedTags(): void $doc = '/** * @psalm-import-type abcd * @var int $p + * @psalm-consistent-constructor */ '; $php_parser_doc = new Doc($doc, 0); @@ -147,6 +148,10 @@ public function testReturnsUnexpectedTags(): void [ 'psalm-import-type' => ['lines' => [1]], 'var' => ['lines' => [2], 'suggested_replacement' => 'param'], + 'psalm-consistent-constructor' => [ + 'lines' => [3], + 'suggested_replacement' => 'psalm-consistent-constructor on a class level' + ] ], $function_docblock->unexpected_tags );