From db65e96c528278d8006e750a898a55b87578800f Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 2 Aug 2023 21:41:36 +0200 Subject: [PATCH 1/3] MethodExtensions class-name is case-insensitive --- tests/PHPStan/Analyser/NodeScopeResolverTest.php | 1 + tests/PHPStan/Analyser/data/bug-9714.php | 16 ++++++++++++++++ .../Rules/Exceptions/data/unthrown-exception.php | 13 +++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 tests/PHPStan/Analyser/data/bug-9714.php diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index aa3d0fc335..41f308ac30 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -1318,6 +1318,7 @@ public function dataFileAsserts(): iterable } yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7915.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9714.php'); } /** diff --git a/tests/PHPStan/Analyser/data/bug-9714.php b/tests/PHPStan/Analyser/data/bug-9714.php new file mode 100644 index 0000000000..3dbb7d1b87 --- /dev/null +++ b/tests/PHPStan/Analyser/data/bug-9714.php @@ -0,0 +1,16 @@ +xpath('//data'); + assertType('array', $elements); + } +} + diff --git a/tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php b/tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php index 78236201ac..9460df2b9c 100644 --- a/tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php +++ b/tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php @@ -544,3 +544,16 @@ public function doBar(string $s) } } + +class TestCaseInsensitiveClassNames +{ + + public function doFoo(): void + { + try { + new \SimpleXmlElement(''); + } catch (\Exception $e) { + + } + } +} From 760b0fb5cc7a3c94efb472940b03ae0e124ba004 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 3 Aug 2023 08:03:42 +0200 Subject: [PATCH 2/3] fix DynamicReturnTypeExtensionRegistry --- src/Type/DynamicReturnTypeExtensionRegistry.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Type/DynamicReturnTypeExtensionRegistry.php b/src/Type/DynamicReturnTypeExtensionRegistry.php index b747ba4a71..ea3c27a13c 100644 --- a/src/Type/DynamicReturnTypeExtensionRegistry.php +++ b/src/Type/DynamicReturnTypeExtensionRegistry.php @@ -6,6 +6,7 @@ use PHPStan\Reflection\BrokerAwareExtension; use PHPStan\Reflection\ReflectionProvider; use function array_merge; +use function strtolower; class DynamicReturnTypeExtensionRegistry { @@ -46,7 +47,7 @@ public function getDynamicMethodReturnTypeExtensionsForClass(string $className): if ($this->dynamicMethodReturnTypeExtensionsByClass === null) { $byClass = []; foreach ($this->dynamicMethodReturnTypeExtensions as $extension) { - $byClass[$extension->getClass()][] = $extension; + $byClass[strtolower($extension->getClass())][] = $extension; } $this->dynamicMethodReturnTypeExtensionsByClass = $byClass; @@ -62,7 +63,7 @@ public function getDynamicStaticMethodReturnTypeExtensionsForClass(string $class if ($this->dynamicStaticMethodReturnTypeExtensionsByClass === null) { $byClass = []; foreach ($this->dynamicStaticMethodReturnTypeExtensions as $extension) { - $byClass[$extension->getClass()][] = $extension; + $byClass[strtolower($extension->getClass())][] = $extension; } $this->dynamicStaticMethodReturnTypeExtensionsByClass = $byClass; @@ -83,6 +84,7 @@ private function getDynamicExtensionsForType(array $extensions, string $classNam $extensionsForClass = [[]]; $class = $this->reflectionProvider->getClass($className); foreach (array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()) as $extensionClassName) { + $extensionClassName = strtolower($extensionClassName); if (!isset($extensions[$extensionClassName])) { continue; } From 4a3ba7a42d29e118050b3181680600fa39f7b6ed Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 3 Aug 2023 09:10:00 +0200 Subject: [PATCH 3/3] more tests --- .../data/closure-return-type-extensions.php | 3 +++ tests/PHPStan/Analyser/data/enum-from.php | 6 ++++++ .../CatchWithUnthrownExceptionRuleTest.php | 4 ++++ .../data/missing-exception-method-throws.php | 5 +++++ .../Exceptions/data/unthrown-exception.php | 19 +++++++++++++++++++ 5 files changed, 37 insertions(+) diff --git a/tests/PHPStan/Analyser/data/closure-return-type-extensions.php b/tests/PHPStan/Analyser/data/closure-return-type-extensions.php index c171fcffb5..1445bfad9f 100644 --- a/tests/PHPStan/Analyser/data/closure-return-type-extensions.php +++ b/tests/PHPStan/Analyser/data/closure-return-type-extensions.php @@ -18,3 +18,6 @@ $returnType = $closure->call($newThis, new class {}); assertType('true', $returnType); + +$staticallyBoundClosureCaseInsensitive = \closure::bind($closure, $newThis); +assertType('Closure(object): true', $staticallyBoundClosureCaseInsensitive); diff --git a/tests/PHPStan/Analyser/data/enum-from.php b/tests/PHPStan/Analyser/data/enum-from.php index c6ad8a89c9..2a51131141 100644 --- a/tests/PHPStan/Analyser/data/enum-from.php +++ b/tests/PHPStan/Analyser/data/enum-from.php @@ -83,4 +83,10 @@ public function subsetToSuperset(FooIntegerEnumSubset $foo): void assertType('EnumFrom\FooIntegerEnum::BAR', FooIntegerEnum::from($foo->value)); } + public function doCaseInsensitive(): void + { + assertType('1', FooInTeGerEnum::BAR->value); + assertType('null', FooInTeGerEnum::tryFrom(0)); + } + } diff --git a/tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php b/tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php index 3a8dca5beb..c1207449c6 100644 --- a/tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php +++ b/tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php @@ -108,6 +108,10 @@ public function testRule(): void 'Dead catch - Exception is never thrown in the try block.', 532, ], + [ + 'Dead catch - Exception is never thrown in the try block.', + 555, + ], ]); } diff --git a/tests/PHPStan/Rules/Exceptions/data/missing-exception-method-throws.php b/tests/PHPStan/Rules/Exceptions/data/missing-exception-method-throws.php index 51cd4b0ef0..7df5ea9915 100644 --- a/tests/PHPStan/Rules/Exceptions/data/missing-exception-method-throws.php +++ b/tests/PHPStan/Rules/Exceptions/data/missing-exception-method-throws.php @@ -95,4 +95,9 @@ public function dateTimeZoneDoesThrows(string $tz): void new \DateTimeZone($tz); } + public function dateTimeZoneDoesNotThrowCaseInsensitive(): void + { + new \DaTetImezOnE('UTC'); + } + } diff --git a/tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php b/tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php index 9460df2b9c..9254768fc8 100644 --- a/tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php +++ b/tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php @@ -556,4 +556,23 @@ public function doFoo(): void } } + + public function doBar(): void + { + try { + new \SimpleXmlElement('foo'); + } catch (\Exception $e) { + + } + } + + public function doBaz(string $string): void + { + try { + new \SimpleXmlElement($string); + } catch (\Exception $e) { + + } + } + }