Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ services:
arguments:
managerClass: Doctrine\Common\Persistence\ObjectManager

dbalTypeGetType:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This service can be marked only with - (because it's very unlikely someone will want to override it) and moved above to other anonymous - services.

class: PHPStan\Type\Doctrine\GetDBALTypeDynamicReturnTypeExtension
tags:
- phpstan.broker.dynamicStaticMethodReturnTypeExtension

## NewExprDynamicReturnTypeExtensions

-
Expand Down
60 changes: 60 additions & 0 deletions src/Type/Doctrine/GetDBALTypeDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Doctrine;

use PhpParser\Node\Expr;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\DynamicStaticMethodReturnTypeExtension;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;

final class GetDBALTypeDynamicReturnTypeExtension implements DynamicStaticMethodReturnTypeExtension
{

public function getClass(): string
{
return 'Doctrine\DBAL\Types\Type';
}

public function isStaticMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->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_) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to ask for $scope->getType($dbalTypeArg) and check against ConstantStringType.

return new ObjectType($dbalTypeArg->value);
}

return ParametersAcceptorSelector::selectSingle(
$methodReflection->getVariants()
)->getReturnType();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);

namespace PHPStan\DoctrineIntegration\DBAL\DBALTypesTypeStaticGetTypeUsage;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file isn't mentioned/tested anywhere?


use Doctrine\DBAL\Types\JsonType;
use Doctrine\DBAL\Types\Type;

final class Example
{
public function typeWithClassConstant(): JsonType
{
return Type::getType(JsonType::class);
}

public function typeWithString(): JsonType
{
return Type::getType('Doctrine\DBAL\Types\JsonType');
}
}
3 changes: 3 additions & 0 deletions tests/DoctrineIntegration/DBAL/phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
includes:
- ../../../extension.neon
- ../../../vendor/phpstan/phpstan/conf/bleedingEdge.neon