Skip to content

Commit

Permalink
PDO::prepare returns BenevolentUnionType
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jan 8, 2022
1 parent 7af63eb commit a9881e3
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
5 changes: 5 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,11 @@ services:
tags:
- phpstan.dynamicFunctionThrowTypeExtension

-
class: PHPStan\Type\Php\PdoPrepareDynamicReturnTypeExtension
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension

-
class: PHPStan\Type\Php\ReflectionClassConstructorThrowTypeExtension
tags:
Expand Down
37 changes: 37 additions & 0 deletions src/Type/Php/PdoPrepareDynamicReturnTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Php;

use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use PHPStan\Type\TypeUtils;

class PdoPrepareDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
{

public function getClass(): string
{
return 'PDO';
}

public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'prepare';
}

public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
{
$returnType = ParametersAcceptorSelector::selectFromArgs(
$scope,
$methodCall->getArgs(),
$methodReflection->getVariants(),
)->getReturnType();

return TypeUtils::toBenevolentUnion($returnType);
}

}
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/classPhpDocs-phpstanPropertyPrefix.php');

yield from $this->gatherAssertTypes(__DIR__ . '/data/array-destructuring-types.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/pdo-prepare.php');
}

/**
Expand Down
17 changes: 17 additions & 0 deletions tests/PHPStan/Analyser/data/pdo-prepare.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace PDOPrepare;

use function PHPStan\Testing\assertType;

class Foo
{

public function doFoo()
{
$database = new \PDO('dsn');
$logDeleteQuery = $database->prepare('DELETE FROM log');
assertType('(PDOStatement|false)', $logDeleteQuery);
}

}

0 comments on commit a9881e3

Please sign in to comment.