Skip to content

Commit c280be4

Browse files
authored
extract PhpDocUtil (#435)
1 parent ac2596a commit c280be4

File tree

2 files changed

+82
-27
lines changed

2 files changed

+82
-27
lines changed

src/PhpDoc/PhpDocUtil.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace staabm\PHPStanDba\PhpDoc;
4+
5+
use PhpParser\Node\Expr;
6+
use PhpParser\Node\Expr\CallLike;
7+
use PhpParser\Node\Identifier;
8+
use PhpParser\Node\Name;
9+
use PHPStan\Analyser\Scope;
10+
use PHPStan\Reflection\MethodReflection;
11+
12+
final class PhpDocUtil
13+
{
14+
/**
15+
* @api
16+
*/
17+
public static function commentContains(string $text, CallLike $callike, Scope $scope): bool
18+
{
19+
$methodReflection = self::getMethodReflection($callike, $scope);
20+
21+
if (null !== $methodReflection) {
22+
// atm no resolved phpdoc for methods
23+
// see https://github.com/phpstan/phpstan/discussions/7657
24+
$phpDocString = $methodReflection->getDocComment();
25+
if (null !== $phpDocString && false !== strpos($phpDocString, $text)) {
26+
return true;
27+
}
28+
}
29+
30+
return false;
31+
}
32+
33+
/**
34+
* Returns a unquoted plain string following a annotation.
35+
*
36+
* @param string $annotation e.g. '@phpstandba-inference-placeholder'
37+
*/
38+
public static function matchStringAnnotation(string $annotation, CallLike $callike, Scope $scope): ?string
39+
{
40+
$methodReflection = self::getMethodReflection($callike, $scope);
41+
42+
if (null !== $methodReflection) {
43+
// atm no resolved phpdoc for methods
44+
// see https://github.com/phpstan/phpstan/discussions/7657
45+
$phpDocString = $methodReflection->getDocComment();
46+
if (null !== $phpDocString && preg_match('/'.$annotation.'\s+(.+)$/m', $phpDocString, $matches)) {
47+
$placeholder = $matches[1];
48+
49+
if (\in_array($placeholder[0], ['"', "'"], true)) {
50+
$placeholder = trim($placeholder, $placeholder[0]);
51+
}
52+
53+
return $placeholder;
54+
}
55+
}
56+
57+
return null;
58+
}
59+
60+
private static function getMethodReflection(CallLike $callike, Scope $scope): ?MethodReflection
61+
{
62+
$methodReflection = null;
63+
if ($callike instanceof Expr\StaticCall) {
64+
if ($callike->class instanceof Name && $callike->name instanceof Identifier) {
65+
$classType = $scope->resolveTypeByName($callike->class);
66+
$methodReflection = $scope->getMethodReflection($classType, $callike->name->name);
67+
}
68+
} elseif ($callike instanceof Expr\MethodCall && $callike->name instanceof Identifier) {
69+
$classReflection = $scope->getClassReflection();
70+
if (null !== $classReflection && $classReflection->hasMethod($callike->name->name)) {
71+
$methodReflection = $classReflection->getMethod($callike->name->name, $scope);
72+
}
73+
}
74+
75+
return $methodReflection;
76+
}
77+
}

src/QueryReflection/QueryReflection.php

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
use PhpParser\Node\Expr;
88
use PhpParser\Node\Expr\BinaryOp\Concat;
9-
use PhpParser\Node\Identifier;
10-
use PhpParser\Node\Name;
119
use PhpParser\Node\Scalar\Encapsed;
1210
use PhpParser\Node\Scalar\EncapsedStringPart;
1311
use PHPStan\Analyser\Scope;
@@ -24,6 +22,7 @@
2422
use staabm\PHPStanDba\Ast\ExpressionFinder;
2523
use staabm\PHPStanDba\DbaException;
2624
use staabm\PHPStanDba\Error;
25+
use staabm\PHPStanDba\PhpDoc\PhpDocUtil;
2726
use staabm\PHPStanDba\UnresolvableQueryException;
2827

2928
final class QueryReflection
@@ -202,34 +201,13 @@ private function resolveQueryStringExpr(Expr $queryExpr, Scope $scope, bool $res
202201
}
203202

204203
if ($queryExpr instanceof Expr\CallLike) {
205-
$methodReflection = null;
206-
if ($queryExpr instanceof Expr\StaticCall) {
207-
if ($queryExpr->class instanceof Name && $queryExpr->name instanceof Identifier) {
208-
$classType = $scope->resolveTypeByName($queryExpr->class);
209-
$methodReflection = $scope->getMethodReflection($classType, $queryExpr->name->name);
210-
}
211-
} elseif ($queryExpr instanceof Expr\MethodCall && $queryExpr->name instanceof Identifier) {
212-
$classReflection = $scope->getClassReflection();
213-
if (null !== $classReflection && $classReflection->hasMethod($queryExpr->name->name)) {
214-
$methodReflection = $classReflection->getMethod($queryExpr->name->name, $scope);
215-
}
216-
}
217-
218-
if (null !== $methodReflection) {
219-
// atm no resolved phpdoc for methods
220-
// see https://github.com/phpstan/phpstan/discussions/7657
221-
$phpDocString = $methodReflection->getDocComment();
222-
if (null !== $phpDocString && preg_match('/@phpstandba-inference-placeholder\s+(.+)$/m', $phpDocString, $matches)) {
223-
$placeholder = $matches[1];
204+
$placeholder = PhpDocUtil::matchStringAnnotation('@phpstandba-inference-placeholder', $queryExpr, $scope);
224205

225-
if (\in_array($placeholder[0], ['"', "'"], true)) {
226-
$placeholder = trim($placeholder, $placeholder[0]);
227-
}
228-
229-
return $placeholder;
230-
}
206+
if (null !== $placeholder) {
207+
return $placeholder;
231208
}
232209
}
210+
233211
if ($queryExpr instanceof Concat) {
234212
$left = $queryExpr->left;
235213
$right = $queryExpr->right;

0 commit comments

Comments
 (0)