Skip to content

Commit fe599b0

Browse files
authored
fix fatal error on query reflection with AssignOp operators (#450)
1 parent 8dde717 commit fe599b0

11 files changed

+143
-9
lines changed

.phpstan-dba-mysqli.cache

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.phpstan-dba-pdo-mysql.cache

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Ast/ExpressionFinder.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PhpParser\Node;
88
use PhpParser\Node\Expr;
99
use PhpParser\Node\Expr\Assign;
10+
use PhpParser\Node\Expr\AssignOp;
1011
use PhpParser\Node\Expr\MethodCall;
1112
use PhpParser\Node\Expr\Variable;
1213
use PhpParser\Node\FunctionLike;
@@ -28,15 +29,25 @@ public function __construct()
2829
/**
2930
* @param Variable|MethodCall $expr
3031
*/
31-
public function findQueryStringExpression(Expr $expr): ?Expr
32+
public function findAssignmentExpression(Expr $expr, bool $skipAssignOps = false): ?Expr
3233
{
3334
$current = $expr;
3435
while (null !== $current) {
36+
$matchedAssignOp = false;
37+
3538
/** @var Assign|null $assign */
36-
$assign = $this->findFirstPreviousOfNode($current, function ($node) {
39+
$assign = $this->findFirstPreviousOfNode($current, function ($node) use (&$matchedAssignOp) {
40+
if ($node instanceof Node\Stmt\Expression && $node->expr instanceof AssignOp) {
41+
$matchedAssignOp = true;
42+
}
43+
3744
return $node instanceof Assign;
3845
});
3946

47+
if ($skipAssignOps && $matchedAssignOp) {
48+
return null;
49+
}
50+
4051
if (null !== $assign) {
4152
if ($expr instanceof Variable && $this->resolveName($assign->var) === $this->resolveName($expr)) {
4253
return $assign->expr;

src/PdoReflection/PdoStatementReflection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ final class PdoStatementReflection
2424
public function findPrepareQueryStringExpression(MethodCall $methodCall): ?Expr
2525
{
2626
$exprFinder = new ExpressionFinder();
27-
$queryExpr = $exprFinder->findQueryStringExpression($methodCall);
27+
$queryExpr = $exprFinder->findAssignmentExpression($methodCall);
2828

2929
// resolve query parameter from "prepare"
3030
if ($queryExpr instanceof MethodCall) {

src/QueryReflection/QueryReflection.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ private function resolveQueryExpr(Expr $queryExpr, Scope $scope): ?string
174174
{
175175
if ($queryExpr instanceof Expr\Variable) {
176176
$finder = new ExpressionFinder();
177-
$queryStringExpr = $finder->findQueryStringExpression($queryExpr);
177+
$queryStringExpr = $finder->findAssignmentExpression($queryExpr);
178178

179179
if (null !== $queryStringExpr) {
180180
return $this->resolveQueryStringExpr($queryStringExpr, $scope);
@@ -191,7 +191,8 @@ private function resolveQueryStringExpr(Expr $queryExpr, Scope $scope, bool $res
191191
{
192192
if (true === $resolveVariables && $queryExpr instanceof Expr\Variable) {
193193
$finder = new ExpressionFinder();
194-
$assignExpr = $finder->findQueryStringExpression($queryExpr);
194+
// atm we cannot reason about variables which are manipulated via assign ops
195+
$assignExpr = $finder->findAssignmentExpression($queryExpr, true);
195196

196197
if (null !== $assignExpr) {
197198
return $this->resolveQueryStringExpr($assignExpr, $scope);

tests/default/config/.phpunit-phpstan-dba-mysqli.cache

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/default/config/.phpunit-phpstan-dba-pdo-mysql.cache

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/rules/SyntaxErrorInQueryMethodRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,4 +231,9 @@ public function testMysqliExecuteQuery(): void
231231
],
232232
]);
233233
}
234+
235+
public function testBugRexstan165()
236+
{
237+
$this->analyse([__DIR__.'/data/bug-rexstan-165.php'], []);
238+
}
234239
}

tests/rules/config/.phpunit-phpstan-dba-mysqli.cache

Lines changed: 50 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/rules/config/.phpunit-phpstan-dba-pdo-mysql.cache

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)