diff --git a/dictionaries/CallMap.php b/dictionaries/CallMap.php index 5c8237d3831..7fff4094083 100644 --- a/dictionaries/CallMap.php +++ b/dictionaries/CallMap.php @@ -9892,7 +9892,7 @@ 'PDO::sqliteCreateCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'], 'PDO::sqliteCreateFunction' => ['bool', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'], 'pdo_drivers' => ['array'], -'PDOException::getCode' => ['string'], +'PDOException::getCode' => ['int|string'], 'PDOException::getFile' => ['string'], 'PDOException::getLine' => ['int'], 'PDOException::getMessage' => ['string'], diff --git a/dictionaries/CallMap_historical.php b/dictionaries/CallMap_historical.php index 8ca16b883dc..eca9d13fb40 100644 --- a/dictionaries/CallMap_historical.php +++ b/dictionaries/CallMap_historical.php @@ -4890,7 +4890,7 @@ 'PDO::sqliteCreateAggregate' => ['bool', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'], 'PDO::sqliteCreateCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'], 'PDO::sqliteCreateFunction' => ['bool', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'], - 'PDOException::getCode' => ['string'], + 'PDOException::getCode' => ['int|string'], 'PDOException::getFile' => ['string'], 'PDOException::getLine' => ['int'], 'PDOException::getMessage' => ['string'], diff --git a/dictionaries/PropertyMap.php b/dictionaries/PropertyMap.php index e0f91665df6..1b2ffd01f0d 100644 --- a/dictionaries/PropertyMap.php +++ b/dictionaries/PropertyMap.php @@ -366,7 +366,7 @@ ], 'pdoexception' => [ 'errorinfo' => 'array', - 'code' => 'string', + 'code' => 'int|string', ], 'domnode' => [ 'nodeName' => 'string', diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php index a5dc24d171c..76d3dfa8e25 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php @@ -29,6 +29,7 @@ use Psalm\Type\Atomic\TNamedObject; use Psalm\Type\Atomic\TTemplateParam; use Psalm\Type\Union; +use RuntimeException; use Throwable; use UnexpectedValueException; @@ -97,16 +98,14 @@ public static function fetch( if ($premixin_method_id->method_name === 'getcode' && $premixin_method_id->fq_class_name !== Exception::class + && $premixin_method_id->fq_class_name !== RuntimeException::class + && $premixin_method_id->fq_class_name !== PDOException::class && ( $codebase->classImplements($premixin_method_id->fq_class_name, Throwable::class) || $codebase->interfaceExtends($premixin_method_id->fq_class_name, Throwable::class) ) ) { - if ($premixin_method_id->fq_class_name === PDOException::class) { - return Type::getString(); - } else { - return Type::getInt(true); // TODO: Remove the flag in Psalm 5 - } + return Type::getInt(true); // TODO: Remove the flag in Psalm 5 } if ($declaring_method_id && $declaring_method_id !== $method_id) { diff --git a/tests/ReturnTypeProvider/ExceptionCodeTest.php b/tests/ReturnTypeProvider/ExceptionCodeTest.php index 84e8acb28e5..a6aa3b8ee7a 100644 --- a/tests/ReturnTypeProvider/ExceptionCodeTest.php +++ b/tests/ReturnTypeProvider/ExceptionCodeTest.php @@ -13,27 +13,33 @@ public function providerValidCodeParse(): iterable { yield 'RuntimeException' => [ 'getCode(); - } + /** @var \RuntimeException $e */ + $code = $e->getCode(); + ', + ['$code' => 'int|string'], + ]; + yield 'CustomRuntimeException' => [ + 'getCode(); ', - [], + ['$code' => 'int'], ]; yield 'LogicException' => [ 'getCode(); - } + /** @var \LogicException $e */ + $code = $e->getCode(); ', - [], + ['$code' => 'int'], ]; yield 'PDOException' => [ 'getCode(); - } + /** @var \PDOException $e */ + $code = $e->getCode(); ', - [], + ['$code' => 'int|string'], ]; yield 'CustomThrowable' => [ '