diff --git a/README.md b/README.md index 59f04b3e..93e7ab34 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ This extension provides following features: * Provides correct return type for `Doctrine\ORM\EntityManager::find`, `getReference` and `getPartialReference` when `Foo::class` entity class name is provided as the first argument * Adds missing `matching` method on `Doctrine\Common\Collections\Collection`. This can be turned off by setting `parameters.doctrine.allCollectionsSelectable` to `false`. * Also supports Doctrine ODM. +* Adds `Doctrine\DBAL\Types\Type::getType` return type support. ## Installation diff --git a/composer.json b/composer.json index e2c7ba02..36a1bc4c 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,8 @@ "doctrine/common": "^2.7", "doctrine/orm": "^2.5", "doctrine/collections": "^1.0", - "doctrine/mongodb-odm": "^1.2" + "doctrine/mongodb-odm": "^1.2", + "doctrine/dbal": "^2.9" }, "conflict": { "doctrine/common": "<2.7", diff --git a/extension.neon b/extension.neon index 79e73a3a..6bdfacc1 100644 --- a/extension.neon +++ b/extension.neon @@ -119,6 +119,11 @@ services: arguments: managerClass: Doctrine\Common\Persistence\ObjectManager + dbalTypeGetType: + class: PHPStan\Type\Doctrine\GetDBALTypeDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + ## NewExprDynamicReturnTypeExtensions - diff --git a/src/Type/Doctrine/GetDBALTypeDynamicReturnTypeExtension.php b/src/Type/Doctrine/GetDBALTypeDynamicReturnTypeExtension.php new file mode 100644 index 00000000..fa1224c1 --- /dev/null +++ b/src/Type/Doctrine/GetDBALTypeDynamicReturnTypeExtension.php @@ -0,0 +1,60 @@ +getName() === 'getType'; + } + + public function getTypeFromStaticMethodCall( + MethodReflection $methodReflection, + StaticCall $methodCall, + Scope $scope + ): Type + { + if (count($methodCall->args) === 0) { + return ParametersAcceptorSelector::selectSingle( + $methodReflection->getVariants() + )->getReturnType(); + } + + $dbalTypeArg = $methodCall->args[0]->value; + return $this->detectReturnType($methodReflection, $dbalTypeArg); + } + + private function detectReturnType(MethodReflection $methodReflection, Expr $dbalTypeArg): Type + { + if ($dbalTypeArg instanceof Expr\ClassConstFetch && $dbalTypeArg->class instanceof Name) { + return new ObjectType($dbalTypeArg->class->toString()); + } + + if ($dbalTypeArg instanceof Scalar\String_) { + return new ObjectType($dbalTypeArg->value); + } + + return ParametersAcceptorSelector::selectSingle( + $methodReflection->getVariants() + )->getReturnType(); + } + +} diff --git a/tests/DoctrineIntegration/DBAL/data/dbalTypesTypeStaticGetTypeUsage.php b/tests/DoctrineIntegration/DBAL/data/dbalTypesTypeStaticGetTypeUsage.php new file mode 100644 index 00000000..c1a00c3a --- /dev/null +++ b/tests/DoctrineIntegration/DBAL/data/dbalTypesTypeStaticGetTypeUsage.php @@ -0,0 +1,20 @@ +