diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 46500b7d12..80abad6e94 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -293,6 +293,9 @@ jobs: OUTPUT=$(../bashunit -a exit_code "1" "../../bin/phpstan") echo "$OUTPUT" ../bashunit -a contains 'Method StubFiles\Foo::doFoo() has no return type specified.' "$OUTPUT" + - script: | + cd e2e/nested-trait-use + ../../bin/phpstan analyze steps: - name: "Checkout" diff --git a/e2e/nested-trait-use/framework/Builder.php b/e2e/nested-trait-use/framework/Builder.php new file mode 100644 index 0000000000..b8d4025be5 --- /dev/null +++ b/e2e/nested-trait-use/framework/Builder.php @@ -0,0 +1,5 @@ + */ + protected static string $builder = Builder::class; + + public function newBuilder(): Builder + { + return new static::$builder(); + } +} diff --git a/e2e/nested-trait-use/main.php b/e2e/nested-trait-use/main.php new file mode 100644 index 0000000000..08cdc532a4 --- /dev/null +++ b/e2e/nested-trait-use/main.php @@ -0,0 +1,10 @@ +newBuilder()); +} diff --git a/e2e/nested-trait-use/phpstan.neon b/e2e/nested-trait-use/phpstan.neon new file mode 100644 index 0000000000..a4b094892f --- /dev/null +++ b/e2e/nested-trait-use/phpstan.neon @@ -0,0 +1,8 @@ +parameters: + level: 9 + tmpDir: tmp + paths: + - main.php + scanDirectories: + - src + - framework diff --git a/e2e/nested-trait-use/src/ChildModel.php b/e2e/nested-trait-use/src/ChildModel.php new file mode 100644 index 0000000000..9310f7939e --- /dev/null +++ b/e2e/nested-trait-use/src/ChildModel.php @@ -0,0 +1,12 @@ + */ + use HasBuilder; + protected static string $builder = CustomBuilder::class; +} diff --git a/e2e/nested-trait-use/src/CustomBuilder.php b/e2e/nested-trait-use/src/CustomBuilder.php new file mode 100644 index 0000000000..a2a93aecd9 --- /dev/null +++ b/e2e/nested-trait-use/src/CustomBuilder.php @@ -0,0 +1,7 @@ + */ + use BaseHasBuilder; +} diff --git a/e2e/nested-trait-use/tmp/.gitignore b/e2e/nested-trait-use/tmp/.gitignore new file mode 100644 index 0000000000..d6b7ef32c8 --- /dev/null +++ b/e2e/nested-trait-use/tmp/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/Type/FileTypeMapper.php b/src/Type/FileTypeMapper.php index f867d9cc15..2c281f58ca 100644 --- a/src/Type/FileTypeMapper.php +++ b/src/Type/FileTypeMapper.php @@ -329,7 +329,7 @@ private function getNameScopeMap(string $fileName): array { if (!isset($this->memoryCache[$fileName])) { $cacheKey = sprintf('ftm-%s', $fileName); - $variableCacheKey = sprintf('v3-%s', ComposerHelper::getPhpDocParserVersion()); + $variableCacheKey = sprintf('v4-%s', ComposerHelper::getPhpDocParserVersion()); $cached = $this->loadCachedPhpDocNodeMap($cacheKey, $variableCacheKey); if ($cached === null) { [$nameScopeMap, $files] = $this->createPhpDocNodeMap($fileName, null, null, [], $fileName); @@ -642,7 +642,7 @@ function (Node $node) use ($fileName, $lookForTrait, &$traitFound, $traitMethodA $traitMethodAliases[$traitName] ?? [], $originalClassFileName, ); - $nameScopeMap = array_merge($nameScopeMap, array_map(static fn ($originalNameScope) => $originalNameScope->getTraitData() === null ? $originalNameScope->withTraitData($fileName, $className, $traitName, $lookForTrait, $docComment) : $originalNameScope, $traitNameScopeMap)); + $nameScopeMap = array_merge($nameScopeMap, array_map(static fn ($originalNameScope) => $originalNameScope->getTraitData() === null ? $originalNameScope->withTraitData($originalClassFileName, $className, $traitName, $lookForTrait, $docComment) : $originalNameScope, $traitNameScopeMap)); $files = array_merge($files, $traitFiles); } }