Skip to content

Commit 11176c7

Browse files
committed
Fix looking for PHPDocs in trait in anonymous class in trait
1 parent 63838ee commit 11176c7

File tree

5 files changed

+68
-5
lines changed

5 files changed

+68
-5
lines changed

src/Type/FileTypeMapper.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ private function resolvePhpDocStringToDocNode(string $phpDocString): PhpDocNode
205205
private function getNameScopeMap(string $fileName): array
206206
{
207207
if (!isset($this->memoryCache[$fileName])) {
208-
$cacheKey = sprintf('%s-phpdocstring-v15-shebang', $fileName);
208+
$cacheKey = sprintf('%s-phpdocstring-v16-look-for-trait', $fileName);
209209
$variableCacheKey = implode(',', array_map(static fn (array $file): string => sprintf('%s-%d', $file['filename'], $file['modifiedTime']), $this->getCachedDependentFilesWithTimestamps($fileName)));
210210
$map = $this->cache->load($cacheKey, $variableCacheKey);
211211

@@ -284,20 +284,24 @@ private function createNameScopeMap(
284284
}
285285
$namespace = null;
286286

287+
$traitFound = false;
288+
287289
/** @var array<string|null> $functionStack */
288290
$functionStack = [];
289291
$uses = [];
290292
$this->processNodes(
291293
$this->phpParser->parseFile($fileName),
292-
function (Node $node) use ($fileName, $lookForTrait, $traitMethodAliases, $originalClassFileName, &$nameScopeMap, &$classStack, &$typeAliasStack, &$namespace, &$functionStack, &$uses, &$typeMapStack): ?int {
294+
function (Node $node) use ($fileName, $lookForTrait, &$traitFound, $traitMethodAliases, $originalClassFileName, &$nameScopeMap, &$classStack, &$typeAliasStack, &$namespace, &$functionStack, &$uses, &$typeMapStack): ?int {
293295
if ($node instanceof Node\Stmt\ClassLike) {
294-
if ($lookForTrait !== null) {
296+
if ($lookForTrait !== null && !$traitFound) {
295297
if (!$node instanceof Node\Stmt\Trait_) {
296298
return self::SKIP_NODE;
297299
}
298300
if ((string) $node->namespacedName !== $lookForTrait) {
299301
return self::SKIP_NODE;
300302
}
303+
304+
$traitFound = true;
301305
} else {
302306
if ($node->name === null) {
303307
if (!$node instanceof Node\Stmt\Class_) {
@@ -308,6 +312,9 @@ function (Node $node) use ($fileName, $lookForTrait, $traitMethodAliases, $origi
308312
} elseif ((bool) $node->getAttribute('anonymousClass', false)) {
309313
$className = $node->name->name;
310314
} else {
315+
if ($traitFound) {
316+
return self::SKIP_NODE;
317+
}
311318
$className = ltrim(sprintf('%s\\%s', $namespace, $node->name->name), '\\');
312319
}
313320
$classStack[] = $className;

tests/PHPStan/Analyser/AnalyserIntegrationTest.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,18 +500,31 @@ public function testBug6300(): void
500500
$this->assertSame(24, $errors[1]->getLine());
501501
}
502502

503+
public function testBug6253(): void
504+
{
505+
$errors = $this->runAnalyse(
506+
__DIR__ . '/data/bug-6253.php',
507+
[
508+
__DIR__ . '/data/bug-6253.php',
509+
__DIR__ . '/data/bug-6253-app-scope-trait.php',
510+
__DIR__ . '/data/bug-6253-collection-trait.php',
511+
],
512+
);
513+
$this->assertNoErrors($errors);
514+
}
515+
503516
/**
504517
* @return Error[]
505518
*/
506-
private function runAnalyse(string $file): array
519+
private function runAnalyse(string $file, ?array $allAnalysedFiles = null): array
507520
{
508521
$file = $this->getFileHelper()->normalizePath($file);
509522
/** @var Analyser $analyser */
510523
$analyser = self::getContainer()->getByType(Analyser::class);
511524
/** @var FileHelper $fileHelper */
512525
$fileHelper = self::getContainer()->getByType(FileHelper::class);
513526
/** @var Error[] $errors */
514-
$errors = $analyser->analyse([$file])->getErrors();
527+
$errors = $analyser->analyse([$file], null, null, true, $allAnalysedFiles)->getErrors();
515528
foreach ($errors as $error) {
516529
$this->assertSame($fileHelper->normalizePath($file), $error->getFilePath());
517530
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Bug6253;
4+
5+
trait AppScopeTrait
6+
{
7+
/**
8+
* @return int
9+
*/
10+
public function getApp()
11+
{
12+
return 1;
13+
}
14+
15+
/**
16+
* @return self
17+
*/
18+
public function setApp()
19+
{
20+
return new self();
21+
}
22+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Bug6253;
4+
5+
trait CollectionTrait
6+
{
7+
public function doFoo(): void
8+
{
9+
$c = new class () {
10+
use AppScopeTrait;
11+
};
12+
}
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Bug6253;
4+
5+
class CollectionMock
6+
{
7+
use CollectionTrait;
8+
}

0 commit comments

Comments
 (0)