Skip to content

Commit

Permalink
Fix resolving types in @var above use statement
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Feb 5, 2021
1 parent 6b85d98 commit 4fff79c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 14 deletions.
30 changes: 16 additions & 14 deletions src/Type/FileTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ private function shouldPhpDocNodeBeCachedToDisk(PhpDocNode $phpDocNode): bool
private function getResolvedPhpDocMap(string $fileName): array
{
if (!isset($this->memoryCache[$fileName])) {
$cacheKey = sprintf('%s-phpdocstring-v3', $fileName);
$cacheKey = sprintf('%s-phpdocstring-v4-uses', $fileName);
$variableCacheKey = implode(',', array_map(static function (array $file): string {
return sprintf('%s-%d', $file['filename'], $file['modifiedTime']);
}, $this->getCachedDependentFilesWithTimestamps($fileName)));
Expand Down Expand Up @@ -353,19 +353,6 @@ function (\PhpParser\Node $node) use ($fileName, $lookForTrait, $traitMethodAlia
return null;
} elseif ($node instanceof \PhpParser\Node\Stmt\Namespace_) {
$namespace = (string) $node->name;
} elseif ($node instanceof \PhpParser\Node\Stmt\Use_ && $node->type === \PhpParser\Node\Stmt\Use_::TYPE_NORMAL) {
foreach ($node->uses as $use) {
$uses[strtolower($use->getAlias()->name)] = (string) $use->name;
}
} elseif ($node instanceof \PhpParser\Node\Stmt\GroupUse) {
$prefix = (string) $node->prefix;
foreach ($node->uses as $use) {
if ($node->type !== \PhpParser\Node\Stmt\Use_::TYPE_NORMAL && $use->type !== \PhpParser\Node\Stmt\Use_::TYPE_NORMAL) {
continue;
}

$uses[strtolower($use->getAlias()->name)] = sprintf('%s\\%s', $prefix, (string) $use->name);
}
} elseif ($node instanceof Node\Stmt\ClassMethod) {
$functionName = $node->name->name;
if (array_key_exists($functionName, $traitMethodAliases)) {
Expand Down Expand Up @@ -454,6 +441,21 @@ function (\PhpParser\Node $node) use ($fileName, $lookForTrait, $traitMethodAlia
return self::POP_TYPE_MAP_STACK;
}

if ($node instanceof \PhpParser\Node\Stmt\Use_ && $node->type === \PhpParser\Node\Stmt\Use_::TYPE_NORMAL) {
foreach ($node->uses as $use) {
$uses[strtolower($use->getAlias()->name)] = (string) $use->name;
}
} elseif ($node instanceof \PhpParser\Node\Stmt\GroupUse) {
$prefix = (string) $node->prefix;
foreach ($node->uses as $use) {
if ($node->type !== \PhpParser\Node\Stmt\Use_::TYPE_NORMAL && $use->type !== \PhpParser\Node\Stmt\Use_::TYPE_NORMAL) {
continue;
}

$uses[strtolower($use->getAlias()->name)] = sprintf('%s\\%s', $prefix, (string) $use->name);
}
}

return null;
},
static function (\PhpParser\Node $node, $callbackResult) use ($lookForTrait, &$namespace, &$functionName, &$classStack, &$uses, &$typeMapStack): void {
Expand Down
21 changes: 21 additions & 0 deletions tests/PHPStan/Rules/PhpDoc/InvalidPhpDocVarTagTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,25 @@ public function testRule(): void
]);
}

public function testBug4486(): void
{
$this->analyse([__DIR__ . '/data/bug-4486.php'], [
[
'PHPDoc tag @var for variable $one contains unknown class Bug4486\ClassName1.',
10,
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
],
[
'PHPDoc tag @var for variable $two contains unknown class Bug4486\ClassName2.',
10,
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
],
[
'PHPDoc tag @var for variable $three contains unknown class Some\Namespaced\ClassName1.',
15,
'Learn more at https://phpstan.org/user-guide/discovering-symbols',
],
]);
}

}
15 changes: 15 additions & 0 deletions tests/PHPStan/Rules/PhpDoc/data/bug-4486.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Bug4486;

/**
* @var ClassName1 $one
* @var ClassName2 $two
*/

use \Some\Namespaced\ClassName1;
use \Some\Namespaced\ClassName2;

/**
* @var ClassName1 $three
*/

0 comments on commit 4fff79c

Please sign in to comment.