Skip to content

Commit

Permalink
Merge pull request #83 from weirdan/fix-issues
Browse files Browse the repository at this point in the history
Fix issues introduced/detected in recent Psalm versions
  • Loading branch information
weirdan authored Aug 24, 2020
2 parents 6b873b5 + 55c3629 commit 619506c
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 24 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
89 changes: 66 additions & 23 deletions src/Hooks/TestCaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -68,12 +69,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];
}
Expand Down Expand Up @@ -101,12 +104,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;
}
Expand Down Expand Up @@ -498,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<string,array<int,string>>} */
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<string,array<int,string>>
*/
$specials = $parsed_docblock->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(
Expand Down
26 changes: 26 additions & 0 deletions src/VersionUtils.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Psalm\PhpUnitPlugin;

use Composer\Semver\Comparator;
use Composer\Semver\VersionParser;
use PackageVersions\Versions;

abstract class VersionUtils
{
public static function packageVersionIs(string $package, string $op, string $ref): bool
{
/**
* @psalm-suppress DeprecatedClass
* @psalm-suppress ArgumentTypeCoercion
*/
$currentVersion = (string) explode('@', Versions::getVersion($package))[0];

$parser = new VersionParser();

$currentVersion = $parser->normalize($currentVersion);
$ref = $parser->normalize($ref);

return Comparator::compare($currentVersion, $op, $ref);
}
}

0 comments on commit 619506c

Please sign in to comment.