9
9
use PHPStan \BetterReflection \Util \GetLastDocComment ;
10
10
use PHPStan \Broker \AnonymousClassNameHelper ;
11
11
use PHPStan \Cache \Cache ;
12
+ use PHPStan \File \FileHelper ;
12
13
use PHPStan \Parser \Parser ;
13
14
use PHPStan \Php \PhpVersion ;
14
15
use PHPStan \PhpDoc \PhpDocNodeResolver ;
@@ -74,6 +75,7 @@ public function __construct(
74
75
private Cache $ cache ,
75
76
private AnonymousClassNameHelper $ anonymousClassNameHelper ,
76
77
private PhpVersion $ phpVersion ,
78
+ private FileHelper $ fileHelper ,
77
79
)
78
80
{
79
81
}
@@ -87,6 +89,8 @@ public function getResolvedPhpDoc(
87
89
string $ docComment ,
88
90
): ResolvedPhpDocBlock
89
91
{
92
+ $ fileName = $ this ->fileHelper ->normalizePath ($ fileName );
93
+
90
94
if ($ className === null && $ traitName !== null ) {
91
95
throw new ShouldNotHappenException ();
92
96
}
@@ -189,7 +193,7 @@ private function resolvePhpDocStringToDocNode(string $phpDocString): PhpDocNode
189
193
private function getNameScopeMap (string $ fileName ): array
190
194
{
191
195
if (!isset ($ this ->memoryCache [$ fileName ])) {
192
- $ cacheKey = sprintf ('%s-phpdocstring-v18-filter-ast ' , $ fileName );
196
+ $ cacheKey = sprintf ('%s-phpdocstring-v19-trait-detection-recursion ' , $ fileName );
193
197
$ variableCacheKey = sprintf ('%s-%s ' , implode (', ' , array_map (static fn (array $ file ): string => sprintf ('%s-%d ' , $ file ['filename ' ], $ file ['modifiedTime ' ]), $ this ->getCachedDependentFilesWithTimestamps ($ fileName ))), $ this ->phpVersion ->getVersionString ());
194
198
$ map = $ this ->cache ->load ($ cacheKey , $ variableCacheKey );
195
199
@@ -277,6 +281,10 @@ private function createNameScopeMap(
277
281
$ this ->phpParser ->parseFile ($ fileName ),
278
282
function (Node $ node ) use ($ fileName , $ lookForTrait , &$ traitFound , $ traitMethodAliases , $ originalClassFileName , &$ nameScopeMap , &$ classStack , &$ typeAliasStack , &$ namespace , &$ functionStack , &$ uses , &$ typeMapStack ): ?int {
279
283
if ($ node instanceof Node \Stmt \ClassLike) {
284
+ if ($ traitFound && $ fileName === $ originalClassFileName ) {
285
+ return self ::SKIP_NODE ;
286
+ }
287
+
280
288
if ($ lookForTrait !== null && !$ traitFound ) {
281
289
if (!$ node instanceof Node \Stmt \Trait_) {
282
290
return self ::SKIP_NODE ;
@@ -296,9 +304,6 @@ function (Node $node) use ($fileName, $lookForTrait, &$traitFound, $traitMethodA
296
304
} elseif ((bool ) $ node ->getAttribute ('anonymousClass ' , false )) {
297
305
$ className = $ node ->name ->name ;
298
306
} else {
299
- if ($ traitFound ) {
300
- return self ::SKIP_NODE ;
301
- }
302
307
$ className = ltrim (sprintf ('%s \\%s ' , $ namespace , $ node ->name ->name ), '\\' );
303
308
}
304
309
$ classStack [] = $ className ;
0 commit comments