From 0cc2e86928ce7c6749594e5b5f097d09c4de66b5 Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Mon, 24 Aug 2020 19:49:16 +0300 Subject: [PATCH 1/3] Fixed ParamNameMismatch Also removed unused uses --- src/Hooks/TestCaseHandler.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Hooks/TestCaseHandler.php b/src/Hooks/TestCaseHandler.php index 34a09fa..e397ea6 100644 --- a/src/Hooks/TestCaseHandler.php +++ b/src/Hooks/TestCaseHandler.php @@ -68,12 +68,14 @@ private static function getDescendants(Codebase $codebase, string $name): array * {@inheritDoc} */ public static function afterClassLikeVisit( - ClassLike $class_node, - ClassLikeStorage $class_storage, + ClassLike $stmt, + ClassLikeStorage $storage, FileSource $statements_source, Codebase $codebase, array &$file_replacements = [] ) { + $class_node = $stmt; + $class_storage = $storage; if (self::hasInitializers($class_storage, $class_node)) { $class_storage->custom_metadata[__NAMESPACE__] = ['hasInitializers' => true]; } @@ -101,12 +103,14 @@ public static function afterClassLikeVisit( * {@inheritDoc} */ public static function afterStatementAnalysis( - ClassLike $class_node, - ClassLikeStorage $class_storage, + ClassLike $stmt, + ClassLikeStorage $classlike_storage, StatementsSource $statements_source, Codebase $codebase, array &$file_replacements = [] ) { + $class_node = $stmt; + $class_storage = $classlike_storage; if (!$codebase->classExtends($class_storage->name, TestCase::class)) { return null; } From 206ca87c6692965e0def516ba0213c1cf1df9e8c Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Mon, 24 Aug 2020 21:37:29 +0300 Subject: [PATCH 2/3] Fix DeprecatedMethod --- composer.json | 3 +- src/Hooks/TestCaseHandler.php | 77 ++++++++++++++++++++++++++--------- src/VersionUtils.php | 26 ++++++++++++ 3 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 src/VersionUtils.php diff --git a/composer.json b/composer.json index c935674..4005e25 100755 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "require": { "php": "^7.1.3", "ext-simplexml": "*", - "ocramius/package-versions": "^1.3", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/package-versions-deprecated": "^1.10", "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0", "vimeo/psalm": "^3.6.2 || dev-master" }, diff --git a/src/Hooks/TestCaseHandler.php b/src/Hooks/TestCaseHandler.php index e397ea6..51bd73c 100644 --- a/src/Hooks/TestCaseHandler.php +++ b/src/Hooks/TestCaseHandler.php @@ -14,6 +14,7 @@ use Psalm\FileSource; use Psalm\IssueBuffer; use Psalm\Issue; +use Psalm\PhpUnitPlugin\VersionUtils; use Psalm\Plugin\Hook\AfterClassLikeAnalysisInterface; use Psalm\Plugin\Hook\AfterClassLikeVisitInterface; use Psalm\Plugin\Hook\AfterCodebasePopulatedInterface; @@ -502,27 +503,65 @@ private static function isBeforeInitializer(ClassMethod $method): bool private static function getSpecials(ClassMethod $method): array { $docblock = $method->getDocComment(); + if (!$docblock) { + return []; + } - if ($docblock) { - try { - /** @psalm-suppress DeprecatedMethod */ - $parsed_comment = DocComment::parse( - (string)$docblock->getReformattedText(), - self::getCommentLine($docblock) - ); - } catch (DocblockParseException $e) { - return []; - } - if (isset($parsed_comment['specials'])) { - return array_map( - static function (array $lines): array { - return array_map('trim', $lines); - }, - $parsed_comment['specials'] - ); - } + try { + $parsed_comment = self::getParsedComment($docblock); + } catch (DocblockParseException $e) { + return []; + } + + if (!isset($parsed_comment['specials'])) { + return []; + } + + return array_map( + function (array $lines) { + return array_map('trim', $lines); + }, + $parsed_comment['specials'] + ); + } + + /** @return array{description:string, specials:array>} */ + private static function getParsedComment(Doc $comment): array + { + if (VersionUtils::packageVersionIs('vimeo/psalm', '>=', '3.11.6')) { + // explanation for the suppressions below + // Oldest supported psalm versions did not have parsePreservingLength() at all + // Versions between 3.6 and 3.11.6 had that, but it was returning array + + /** @psalm-suppress UndefinedMethod for oldest versions */ + $parsed_docblock = DocComment::parsePreservingLength($comment); + + /** + * @psalm-suppress InvalidPropertyFetch + * @var string + */ + $description = $parsed_docblock->description; + + /** + * @psalm-suppress InvalidPropertyFetch + * @var array> + */ + $specials = $parsed_docblock->combined_tags; + + return [ + 'description' => $description, + 'specials' => $specials, + ]; + } else { + // before 3.11.6 parsePreservingLength() was returning array, + // but parse() wasn't deprecated, so we just use that + + /** @psalm-suppress DeprecatedMethod for newer Psalm versions */ + return DocComment::parse( + (string) $comment->getReformattedText(), + self::getCommentLine($comment) + ); } - return []; } private static function queueClassLikeForScanning( diff --git a/src/VersionUtils.php b/src/VersionUtils.php new file mode 100644 index 0000000..8a37b45 --- /dev/null +++ b/src/VersionUtils.php @@ -0,0 +1,26 @@ +normalize($currentVersion); + $ref = $parser->normalize($ref); + + return Comparator::compare($currentVersion, $op, $ref); + } +} From 55c362994c95b1380156fe91e2c2735a7002f6c7 Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Mon, 24 Aug 2020 22:15:09 +0300 Subject: [PATCH 3/3] Use tags instead of combined_tags `combined_tags` appear to contain only known tags --- src/Hooks/TestCaseHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hooks/TestCaseHandler.php b/src/Hooks/TestCaseHandler.php index 51bd73c..eed29ba 100644 --- a/src/Hooks/TestCaseHandler.php +++ b/src/Hooks/TestCaseHandler.php @@ -546,7 +546,7 @@ private static function getParsedComment(Doc $comment): array * @psalm-suppress InvalidPropertyFetch * @var array> */ - $specials = $parsed_docblock->combined_tags; + $specials = $parsed_docblock->tags; return [ 'description' => $description,