99use PHPStan \BetterReflection \Util \GetLastDocComment ;
1010use PHPStan \Broker \AnonymousClassNameHelper ;
1111use PHPStan \Cache \Cache ;
12+ use PHPStan \File \FileHelper ;
1213use PHPStan \Parser \Parser ;
1314use PHPStan \Php \PhpVersion ;
1415use PHPStan \PhpDoc \PhpDocNodeResolver ;
@@ -74,6 +75,7 @@ public function __construct(
7475 private Cache $ cache ,
7576 private AnonymousClassNameHelper $ anonymousClassNameHelper ,
7677 private PhpVersion $ phpVersion ,
78+ private FileHelper $ fileHelper ,
7779 )
7880 {
7981 }
@@ -87,6 +89,8 @@ public function getResolvedPhpDoc(
8789 string $ docComment ,
8890 ): ResolvedPhpDocBlock
8991 {
92+ $ fileName = $ this ->fileHelper ->normalizePath ($ fileName );
93+
9094 if ($ className === null && $ traitName !== null ) {
9195 throw new ShouldNotHappenException ();
9296 }
@@ -189,7 +193,7 @@ private function resolvePhpDocStringToDocNode(string $phpDocString): PhpDocNode
189193 private function getNameScopeMap (string $ fileName ): array
190194 {
191195 if (!isset ($ this ->memoryCache [$ fileName ])) {
192- $ cacheKey = sprintf ('%s-phpdocstring-v18-filter-ast ' , $ fileName );
196+ $ cacheKey = sprintf ('%s-phpdocstring-v19-trait-detection-recursion ' , $ fileName );
193197 $ 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 ());
194198 $ map = $ this ->cache ->load ($ cacheKey , $ variableCacheKey );
195199
@@ -277,6 +281,10 @@ private function createNameScopeMap(
277281 $ this ->phpParser ->parseFile ($ fileName ),
278282 function (Node $ node ) use ($ fileName , $ lookForTrait , &$ traitFound , $ traitMethodAliases , $ originalClassFileName , &$ nameScopeMap , &$ classStack , &$ typeAliasStack , &$ namespace , &$ functionStack , &$ uses , &$ typeMapStack ): ?int {
279283 if ($ node instanceof Node \Stmt \ClassLike) {
284+ if ($ traitFound && $ fileName === $ originalClassFileName ) {
285+ return self ::SKIP_NODE ;
286+ }
287+
280288 if ($ lookForTrait !== null && !$ traitFound ) {
281289 if (!$ node instanceof Node \Stmt \Trait_) {
282290 return self ::SKIP_NODE ;
@@ -296,9 +304,6 @@ function (Node $node) use ($fileName, $lookForTrait, &$traitFound, $traitMethodA
296304 } elseif ((bool ) $ node ->getAttribute ('anonymousClass ' , false )) {
297305 $ className = $ node ->name ->name ;
298306 } else {
299- if ($ traitFound ) {
300- return self ::SKIP_NODE ;
301- }
302307 $ className = ltrim (sprintf ('%s \\%s ' , $ namespace , $ node ->name ->name ), '\\' );
303308 }
304309 $ classStack [] = $ className ;
0 commit comments