From 21bc89f5c8c781cf29adf1750091c02e8083ec13 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 28 Jan 2025 15:55:43 +0700 Subject: [PATCH 1/4] Fix name context on no namespace --- lib/PhpParser/NameContext.php | 10 +++++----- test/PhpParser/NodeVisitor/NameResolverTest.php | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/PhpParser/NameContext.php b/lib/PhpParser/NameContext.php index 2265ecce82..08cdb1da7d 100644 --- a/lib/PhpParser/NameContext.php +++ b/lib/PhpParser/NameContext.php @@ -123,7 +123,7 @@ public function getResolvedName(Name $name, int $type): ?Name { if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) { if (null === $this->namespace) { // outside of a namespace unaliased unqualified is same as fully qualified - return new FullyQualified($name, $name->getAttributes()); + return $this->getNamespaceRelativeName($name->toString(), strtolower($name->toString()), $type, $name->getAttributes()); } // Cannot resolve statically @@ -249,22 +249,22 @@ private function resolveAlias(Name $name, int $type): ?FullyQualified { return null; } - private function getNamespaceRelativeName(string $name, string $lcName, int $type): ?Name { + private function getNamespaceRelativeName(string $name, string $lcName, int $type, array $attributes = []): ?Name { if (null === $this->namespace) { - return new Name($name); + return new Name($name, $attributes); } if ($type === Stmt\Use_::TYPE_CONSTANT) { // The constants true/false/null always resolve to the global symbols, even inside a // namespace, so they may be used without qualification if ($lcName === "true" || $lcName === "false" || $lcName === "null") { - return new Name($name); + return new Name($name, $attributes); } } $namespacePrefix = strtolower($this->namespace . '\\'); if (0 === strpos($lcName, $namespacePrefix)) { - return new Name(substr($name, strlen($namespacePrefix))); + return new Name(substr($name, strlen($namespacePrefix)), $attributes); } return null; diff --git a/test/PhpParser/NodeVisitor/NameResolverTest.php b/test/PhpParser/NodeVisitor/NameResolverTest.php index e2d5c0386a..2aab9f8118 100644 --- a/test/PhpParser/NodeVisitor/NameResolverTest.php +++ b/test/PhpParser/NodeVisitor/NameResolverTest.php @@ -117,8 +117,8 @@ public function testResolveNames(): void { new \Hallo\Bar(); new \Bar(); new \Bar(); - \bar(); - \hi(); + bar(); + hi(); \Hallo\bar(); \foo\bar(); \bar(); @@ -197,7 +197,7 @@ class A extends B implements C, D { #[X] const C = 1; - + public const X A = X::Bar; public const X\Foo B = X\Foo::Bar; public const \X\Foo C = \X\Foo::Bar; From f533ce789144d63526ac2cffb550a676596ee1dd Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 28 Jan 2025 15:58:15 +0700 Subject: [PATCH 2/4] fix doc attributes --- lib/PhpParser/NameContext.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/PhpParser/NameContext.php b/lib/PhpParser/NameContext.php index 08cdb1da7d..ed4695e7af 100644 --- a/lib/PhpParser/NameContext.php +++ b/lib/PhpParser/NameContext.php @@ -249,6 +249,9 @@ private function resolveAlias(Name $name, int $type): ?FullyQualified { return null; } + /** + * @param array $attributes + */ private function getNamespaceRelativeName(string $name, string $lcName, int $type, array $attributes = []): ?Name { if (null === $this->namespace) { return new Name($name, $attributes); From f1f818e6ce191b059f197b708efc28daaaac88bc Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 28 Jan 2025 16:03:30 +0700 Subject: [PATCH 3/4] fix fallback FullyQualified --- lib/PhpParser/NameContext.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/PhpParser/NameContext.php b/lib/PhpParser/NameContext.php index ed4695e7af..ca70e712af 100644 --- a/lib/PhpParser/NameContext.php +++ b/lib/PhpParser/NameContext.php @@ -123,7 +123,13 @@ public function getResolvedName(Name $name, int $type): ?Name { if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) { if (null === $this->namespace) { // outside of a namespace unaliased unqualified is same as fully qualified - return $this->getNamespaceRelativeName($name->toString(), strtolower($name->toString()), $type, $name->getAttributes()); + $relativeName = $this->getNamespaceRelativeName($name->toString(), strtolower($name->toString()), $type, $name->getAttributes()); + + if ($relativeName instanceof Name) { + return $relativeName; + } + + return new FullyQualified($name, $name->getAttributes()); } // Cannot resolve statically From 1f5357da55cfd5348ec4c88130149d9bca1bdf08 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 28 Jan 2025 16:03:45 +0700 Subject: [PATCH 4/4] fix fallback FullyQualified --- lib/PhpParser/NameContext.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/PhpParser/NameContext.php b/lib/PhpParser/NameContext.php index ca70e712af..cbfe81a572 100644 --- a/lib/PhpParser/NameContext.php +++ b/lib/PhpParser/NameContext.php @@ -122,13 +122,13 @@ public function getResolvedName(Name $name, int $type): ?Name { if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) { if (null === $this->namespace) { - // outside of a namespace unaliased unqualified is same as fully qualified $relativeName = $this->getNamespaceRelativeName($name->toString(), strtolower($name->toString()), $type, $name->getAttributes()); if ($relativeName instanceof Name) { return $relativeName; } + // outside of a namespace unaliased unqualified is same as fully qualified return new FullyQualified($name, $name->getAttributes()); }