From e32ecf8e866c35cecb144d9fe22d14ed33135fff Mon Sep 17 00:00:00 2001 From: ondrejmirtes Date: Tue, 29 Nov 2022 00:03:22 +0000 Subject: [PATCH 1/2] Update PhpStorm stubs --- composer.json | 2 +- composer.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 2e929ca007..94136eb214 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "hoa/compiler": "3.17.08.08", "hoa/exception": "^1.0", "hoa/regex": "1.17.01.13", - "jetbrains/phpstorm-stubs": "dev-master#a221d6e3064973fbad90af817f4d380d84baa74c", + "jetbrains/phpstorm-stubs": "dev-master#d07464d9afbfd62c9dd7ae830c91ec0711e13a46", "nette/bootstrap": "^3.0", "nette/di": "^3.0.11", "nette/finder": "^2.5", diff --git a/composer.lock b/composer.lock index 7f7f7217fd..d2fd47a203 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "db3123830b4823a2ef63faec3bde6865", + "content-hash": "91daa065ec3fea94feba0f4fa3a66794", "packages": [ { "name": "clue/ndjson-react", @@ -1292,12 +1292,12 @@ "source": { "type": "git", "url": "https://github.com/JetBrains/phpstorm-stubs.git", - "reference": "a221d6e3064973fbad90af817f4d380d84baa74c" + "reference": "d07464d9afbfd62c9dd7ae830c91ec0711e13a46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/a221d6e3064973fbad90af817f4d380d84baa74c", - "reference": "a221d6e3064973fbad90af817f4d380d84baa74c", + "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/d07464d9afbfd62c9dd7ae830c91ec0711e13a46", + "reference": "d07464d9afbfd62c9dd7ae830c91ec0711e13a46", "shasum": "" }, "require-dev": { @@ -1333,7 +1333,7 @@ "support": { "source": "https://github.com/JetBrains/phpstorm-stubs/tree/master" }, - "time": "2022-11-14T13:21:14+00:00" + "time": "2022-11-28T21:23:56+00:00" }, { "name": "nette/bootstrap", From 6459f85242108b8ca3b38653182f8daa26014160 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 1 Dec 2022 15:15:47 +0100 Subject: [PATCH 2/2] DateTimeZoneConstructorThrowTypeExtension --- conf/config.neon | 5 ++ ...eTimeZoneConstructorThrowTypeExtension.php | 50 +++++++++++++++++++ ...CheckedExceptionInMethodThrowsRuleTest.php | 4 ++ .../data/missing-exception-method-throws.php | 10 ++++ 4 files changed, 69 insertions(+) create mode 100644 src/Type/Php/DateTimeZoneConstructorThrowTypeExtension.php diff --git a/conf/config.neon b/conf/config.neon index 24d0a2bea9..27369f0126 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -1347,6 +1347,11 @@ services: tags: - phpstan.dynamicStaticMethodThrowTypeExtension + - + class: PHPStan\Type\Php\DateTimeZoneConstructorThrowTypeExtension + tags: + - phpstan.dynamicStaticMethodThrowTypeExtension + - class: PHPStan\Type\Php\DsMapDynamicReturnTypeExtension tags: diff --git a/src/Type/Php/DateTimeZoneConstructorThrowTypeExtension.php b/src/Type/Php/DateTimeZoneConstructorThrowTypeExtension.php new file mode 100644 index 0000000000..4240b2b85f --- /dev/null +++ b/src/Type/Php/DateTimeZoneConstructorThrowTypeExtension.php @@ -0,0 +1,50 @@ +getName() === '__construct' && $methodReflection->getDeclaringClass()->getName() === DateTimeZone::class; + } + + public function getThrowTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope): ?Type + { + if (count($methodCall->getArgs()) === 0) { + return null; + } + + $valueType = $scope->getType($methodCall->getArgs()[0]->value); + $constantStrings = TypeUtils::getConstantStrings($valueType); + + foreach ($constantStrings as $constantString) { + try { + new DateTimeZone($constantString->getValue()); + } catch (\Exception $e) { // phpcs:ignore + return $methodReflection->getThrowType(); + } + + $valueType = TypeCombinator::remove($valueType, $constantString); + } + + if (!$valueType instanceof NeverType) { + return $methodReflection->getThrowType(); + } + + return null; + } + +} diff --git a/tests/PHPStan/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRuleTest.php b/tests/PHPStan/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRuleTest.php index 9f195bb503..d085543b84 100644 --- a/tests/PHPStan/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRuleTest.php +++ b/tests/PHPStan/Rules/Exceptions/MissingCheckedExceptionInMethodThrowsRuleTest.php @@ -40,6 +40,10 @@ public function testRule(): void 'Method MissingExceptionMethodThrows\Foo::doLorem2() throws checked exception InvalidArgumentException but it\'s missing from the PHPDoc @throws tag.', 34, ], + [ + 'Method MissingExceptionMethodThrows\Foo::dateTimeZoneDoesThrows() throws checked exception Exception but it\'s missing from the PHPDoc @throws tag.', + 95, + ], ]); } 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 8914d535d9..51cd4b0ef0 100644 --- a/tests/PHPStan/Rules/Exceptions/data/missing-exception-method-throws.php +++ b/tests/PHPStan/Rules/Exceptions/data/missing-exception-method-throws.php @@ -85,4 +85,14 @@ private function throwsInterface(): void } + public function dateTimeZoneDoesNotThrow(): void + { + new \DateTimeZone('UTC'); + } + + public function dateTimeZoneDoesThrows(string $tz): void + { + new \DateTimeZone($tz); + } + }