Skip to content

Commit 8234dc0

Browse files
committed
Fix namespace of named type in class constant native type by patching PHP-Parser
1 parent 6b5c6e4 commit 8234dc0

File tree

7 files changed

+54
-2
lines changed

7 files changed

+54
-2
lines changed

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@
9797
"patches/ReflectionProperty.patch",
9898
"patches/SessionHandler.patch"
9999
],
100+
"nikic/php-parser": [
101+
"patches/NameResolver.patch"
102+
],
100103
"rector/rector": [
101104
"patches/NameNodeMapper.patch"
102105
]

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

patches/NameResolver.patch

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--- lib/PhpParser/NodeVisitor/NameResolver.php 2023-11-28 14:02:15
2+
+++ lib/PhpParser/NodeVisitor/NameResolver.php 2023-11-28 14:03:53
3+
@@ -119,6 +119,9 @@
4+
}
5+
} else if ($node instanceof Stmt\ClassConst) {
6+
$this->resolveAttrGroups($node);
7+
+ if (null !== $node->type) {
8+
+ $node->type = $this->resolveType($node->type);
9+
+ }
10+
} else if ($node instanceof Stmt\EnumCase) {
11+
$this->resolveAttrGroups($node);
12+
} elseif ($node instanceof Expr\StaticCall

src/Reflection/ClassReflection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ public function getConstant(string $name): ConstantReflection
993993

994994
$nativeType = null;
995995
if ($reflectionConstant->getType() !== null) {
996-
$nativeType = TypehintHelper::decideTypeFromReflection($reflectionConstant->getType(), null, $this);
996+
$nativeType = TypehintHelper::decideTypeFromReflection($reflectionConstant->getType(), null, $declaringClass);
997997
} elseif ($this->signatureMapProvider->hasClassConstantMetadata($declaringClass->getName(), $name)) {
998998
$nativeType = $this->signatureMapProvider->getClassConstantMetadata($declaringClass->getName(), $name)['nativeType'];
999999
}

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,7 @@ public function dataFileAsserts(): iterable
925925

926926
if (PHP_VERSION_ID >= 80300) {
927927
yield from $this->gatherAssertTypes(__DIR__ . '/data/class-constant-native-type.php');
928+
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Constants/data/bug-10212.php');
928929
}
929930

930931
if (PHP_VERSION_ID >= 80000) {

tests/PHPStan/Rules/Constants/ValueAssignedToClassConstantRuleTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,18 @@ public function testNativeType(): void
8686
]);
8787
}
8888

89+
public function testBug10212(): void
90+
{
91+
if (PHP_VERSION_ID < 80300) {
92+
$this->markTestSkipped('Test requires PHP 8.3.');
93+
}
94+
95+
$this->analyse([__DIR__ . '/data/bug-10212.php'], [
96+
[
97+
'Constant Bug10212\HelloWorld::B (Bug10212\X\Foo) does not accept value Bug10212\Foo::Bar.',
98+
15,
99+
],
100+
]);
101+
}
102+
89103
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php // lint >= 8.3
2+
3+
namespace Bug10212;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
enum Foo
8+
{
9+
case Bar;
10+
}
11+
12+
class HelloWorld
13+
{
14+
public const string A = 'foo';
15+
public const X\Foo B = Foo::Bar;
16+
public const Foo C = Foo::Bar;
17+
}
18+
19+
function(HelloWorld $hw): void {
20+
assertType(X\Foo::class, $hw::B);
21+
assertType(Foo::class, $hw::C);
22+
};

0 commit comments

Comments
 (0)