From 8f51df0ce86fe24bfa47885598bbdb51e2e94366 Mon Sep 17 00:00:00 2001 From: Martin Herndl Date: Sat, 20 Nov 2021 22:10:04 +0100 Subject: [PATCH 1/2] Add ThrowableReturnTypeExtension --- conf/config.neon | 5 ++++ src/Type/Php/ThrowableReturnTypeExtension.php | 29 +++++++++++++++++++ .../Analyser/NodeScopeResolverTest.php | 1 + tests/PHPStan/Analyser/data/bug-6001.php | 11 +++++++ tests/PHPStan/Analyser/data/generics.php | 2 +- 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/Type/Php/ThrowableReturnTypeExtension.php create mode 100644 tests/PHPStan/Analyser/data/bug-6001.php diff --git a/conf/config.neon b/conf/config.neon index 7f494ce35b..0b8b0ca3d3 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -1268,6 +1268,11 @@ services: tags: - phpstan.broker.dynamicFunctionReturnTypeExtension + - + class: PHPStan\Type\Php\ThrowableReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + - class: PHPStan\Type\Php\ParseUrlFunctionDynamicReturnTypeExtension tags: diff --git a/src/Type/Php/ThrowableReturnTypeExtension.php b/src/Type/Php/ThrowableReturnTypeExtension.php new file mode 100644 index 0000000000..cecc727bf0 --- /dev/null +++ b/src/Type/Php/ThrowableReturnTypeExtension.php @@ -0,0 +1,29 @@ +getName() === 'getCode'; + } + + public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type + { + return new BenevolentUnionType([new IntegerType(), new StringType()]); + } +} diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index e9ffac52e5..475ed7d688 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -530,6 +530,7 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4743.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5017.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5992.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6001.php'); if (PHP_VERSION_ID >= 70400) { yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5458.php'); diff --git a/tests/PHPStan/Analyser/data/bug-6001.php b/tests/PHPStan/Analyser/data/bug-6001.php new file mode 100644 index 0000000000..0e950940cd --- /dev/null +++ b/tests/PHPStan/Analyser/data/bug-6001.php @@ -0,0 +1,11 @@ +getCode()); + +assertType('(int|string)', (new \RuntimeException())->getCode()); + +assertType('(int|string)', (new \PDOException())->getCode()); diff --git a/tests/PHPStan/Analyser/data/generics.php b/tests/PHPStan/Analyser/data/generics.php index 032fa71f17..f35120282e 100644 --- a/tests/PHPStan/Analyser/data/generics.php +++ b/tests/PHPStan/Analyser/data/generics.php @@ -1400,7 +1400,7 @@ public function process($class): void { } function (\Throwable $e): void { - assertType('mixed', $e->getCode()); + assertType('(int|string)', $e->getCode()); }; function (): void { From 34fef9a31dc7e4423131462a25a5f53ea9cdfd1a Mon Sep 17 00:00:00 2001 From: Martin Herndl Date: Sat, 20 Nov 2021 22:26:05 +0100 Subject: [PATCH 2/2] Fix CS --- src/Type/Php/ThrowableReturnTypeExtension.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Type/Php/ThrowableReturnTypeExtension.php b/src/Type/Php/ThrowableReturnTypeExtension.php index cecc727bf0..3fc33738a0 100644 --- a/src/Type/Php/ThrowableReturnTypeExtension.php +++ b/src/Type/Php/ThrowableReturnTypeExtension.php @@ -12,6 +12,7 @@ final class ThrowableReturnTypeExtension implements \PHPStan\Type\DynamicMethodReturnTypeExtension { + public function getClass(): string { return \Throwable::class; @@ -26,4 +27,5 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method { return new BenevolentUnionType([new IntegerType(), new StringType()]); } + }