From 6363932c56678f5d49a960f65b09fb2c11cd7dd3 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 22 Jan 2024 13:33:28 +0100 Subject: [PATCH] MissingClassConstantTypehintRule should not apply to native types --- .../MissingClassConstantTypehintRule.php | 5 +++- .../MissingClassConstantTypehintRuleTest.php | 20 +++++++++++++++ .../data/class-constant-native-type.php | 25 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Rules/Constants/data/class-constant-native-type.php diff --git a/src/Rules/Constants/MissingClassConstantTypehintRule.php b/src/Rules/Constants/MissingClassConstantTypehintRule.php index 91a3679d3c..dca968ddeb 100644 --- a/src/Rules/Constants/MissingClassConstantTypehintRule.php +++ b/src/Rules/Constants/MissingClassConstantTypehintRule.php @@ -51,7 +51,10 @@ public function processNode(Node $node, Scope $scope): array private function processSingleConstant(ClassReflection $classReflection, string $constantName): array { $constantReflection = $classReflection->getConstant($constantName); - $constantType = $constantReflection->getValueType(); + $constantType = $constantReflection->getPhpDocType(); + if ($constantType === null) { + return []; + } $errors = []; foreach ($this->missingTypehintCheck->getIterableTypesWithMissingValueTypehint($constantType) as $iterableType) { diff --git a/tests/PHPStan/Rules/Constants/MissingClassConstantTypehintRuleTest.php b/tests/PHPStan/Rules/Constants/MissingClassConstantTypehintRuleTest.php index 6bcddaf2d6..5951d8fe71 100644 --- a/tests/PHPStan/Rules/Constants/MissingClassConstantTypehintRuleTest.php +++ b/tests/PHPStan/Rules/Constants/MissingClassConstantTypehintRuleTest.php @@ -46,4 +46,24 @@ public function testBug8957(): void $this->analyse([__DIR__ . '/data/bug-8957.php'], []); } + public function testRuleShouldNotApplyToNativeTypes(): void + { + if (PHP_VERSION_ID < 80300) { + $this->markTestSkipped('This test needs PHP 8.3'); + } + + $this->analyse([__DIR__ . '/data/class-constant-native-type.php'], [ + [ + 'Constant ClassConstantNativeTypeForMissingTypehintRule\Foo::B type has no value type specified in iterable type array.', + 19, + 'See: https://phpstan.org/blog/solving-phpstan-no-value-type-specified-in-iterable-type', + ], + [ + 'Constant ClassConstantNativeTypeForMissingTypehintRule\Foo::D with generic class ClassConstantNativeTypeForMissingTypehintRule\Bar does not specify its types: T', + 24, + 'You can turn this off by setting checkGenericClassInNonGenericObjectType: false in your %configurationFile%.', + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Constants/data/class-constant-native-type.php b/tests/PHPStan/Rules/Constants/data/class-constant-native-type.php new file mode 100644 index 0000000000..fb3b694d57 --- /dev/null +++ b/tests/PHPStan/Rules/Constants/data/class-constant-native-type.php @@ -0,0 +1,25 @@ += 8.3 + +namespace ClassConstantNativeTypeForMissingTypehintRule; + +/** @template T */ +class Bar +{ + +} + +const ConstantWithObjectInstanceForNativeType = new Bar(); + +class Foo +{ + + public const array A = []; + + /** @var array */ + public const array B = []; + + public const Bar C = ConstantWithObjectInstanceForNativeType; + + /** @var Bar */ + public const Bar D = ConstantWithObjectInstanceForNativeType; +}