Skip to content

Commit a9881e3

Browse files
committed
PDO::prepare returns BenevolentUnionType
1 parent 7af63eb commit a9881e3

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

Diff for: conf/config.neon

+5
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,11 @@ services:
11441144
tags:
11451145
- phpstan.dynamicFunctionThrowTypeExtension
11461146

1147+
-
1148+
class: PHPStan\Type\Php\PdoPrepareDynamicReturnTypeExtension
1149+
tags:
1150+
- phpstan.broker.dynamicMethodReturnTypeExtension
1151+
11471152
-
11481153
class: PHPStan\Type\Php\ReflectionClassConstructorThrowTypeExtension
11491154
tags:
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Php;
4+
5+
use PhpParser\Node\Expr\MethodCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Reflection\MethodReflection;
8+
use PHPStan\Reflection\ParametersAcceptorSelector;
9+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
10+
use PHPStan\Type\Type;
11+
use PHPStan\Type\TypeUtils;
12+
13+
class PdoPrepareDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
14+
{
15+
16+
public function getClass(): string
17+
{
18+
return 'PDO';
19+
}
20+
21+
public function isMethodSupported(MethodReflection $methodReflection): bool
22+
{
23+
return $methodReflection->getName() === 'prepare';
24+
}
25+
26+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
27+
{
28+
$returnType = ParametersAcceptorSelector::selectFromArgs(
29+
$scope,
30+
$methodCall->getArgs(),
31+
$methodReflection->getVariants(),
32+
)->getReturnType();
33+
34+
return TypeUtils::toBenevolentUnion($returnType);
35+
}
36+
37+
}

Diff for: tests/PHPStan/Analyser/NodeScopeResolverTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ public function dataFileAsserts(): iterable
594594
yield from $this->gatherAssertTypes(__DIR__ . '/data/classPhpDocs-phpstanPropertyPrefix.php');
595595

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

599600
/**

Diff for: tests/PHPStan/Analyser/data/pdo-prepare.php

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace PDOPrepare;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo
8+
{
9+
10+
public function doFoo()
11+
{
12+
$database = new \PDO('dsn');
13+
$logDeleteQuery = $database->prepare('DELETE FROM log');
14+
assertType('(PDOStatement|false)', $logDeleteQuery);
15+
}
16+
17+
}

0 commit comments

Comments
 (0)