Skip to content

Commit 53ddd1a

Browse files
committed
Always pass alternative node callback around
1 parent d7b13c2 commit 53ddd1a

26 files changed

+157
-56
lines changed

src/Analyser/Generator/ExprAnalysisRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function __construct(
2525
public readonly Expr $expr,
2626
public readonly GeneratorScope $scope,
2727
public readonly ExpressionContext $context,
28-
public readonly mixed $alternativeNodeCallback = null,
28+
public readonly mixed $alternativeNodeCallback,
2929
)
3030
{
3131
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);

src/Analyser/Generator/ExprHandler.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
namespace PHPStan\Analyser\Generator;
44

55
use Generator;
6+
use PhpParser\Node;
67
use PhpParser\Node\Expr;
78
use PhpParser\Node\Stmt;
89
use PHPStan\Analyser\ExpressionContext;
10+
use PHPStan\Analyser\Scope;
911

1012
/**
1113
* @template T of Expr
@@ -22,8 +24,16 @@ public function supports(Expr $expr): bool;
2224

2325
/**
2426
* @param T $expr
27+
* @param (callable(Node, Scope, callable(Node, Scope): void): void)|null $alternativeNodeCallback
2528
* @return Generator<int, ExprAnalysisRequest|AlternativeNodeCallbackRequest|NodeCallbackRequest|TypeExprRequest, ExprAnalysisResult|TypeExprResult, ExprAnalysisResult>
2629
*/
27-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator;
30+
public function analyseExpr(
31+
Stmt $stmt,
32+
Expr $expr,
33+
GeneratorScope $scope,
34+
ExprAnalysisResultStorage $storage,
35+
ExpressionContext $context,
36+
?callable $alternativeNodeCallback,
37+
): Generator;
2838

2939
}

src/Analyser/Generator/ExprHandler/AssignHandler.php

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,14 @@ public function supports(Expr $expr): bool
9797
return $expr instanceof Assign || $expr instanceof Expr\AssignRef;
9898
}
9999

100-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator
100+
public function analyseExpr(
101+
Stmt $stmt,
102+
Expr $expr,
103+
GeneratorScope $scope,
104+
ExprAnalysisResultStorage $storage,
105+
ExpressionContext $context,
106+
?callable $alternativeNodeCallback,
107+
): Generator
101108
{
102109
$gen = $this->processAssignVar(
103110
$scope,
@@ -106,7 +113,8 @@ public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprA
106113
$expr->expr,
107114
$storage,
108115
$context,
109-
static function (GeneratorScope $scope) use ($stmt, $expr, $context): Generator {
116+
$alternativeNodeCallback,
117+
static function (GeneratorScope $scope) use ($stmt, $expr, $context, $alternativeNodeCallback): Generator {
110118
$impurePoints = [];
111119
if ($expr instanceof AssignRef) {
112120
$referencedExpr = $expr->expr;
@@ -134,7 +142,7 @@ static function (GeneratorScope $scope) use ($stmt, $expr, $context): Generator
134142
);
135143
}
136144

137-
$result = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep());
145+
$result = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
138146
$scope = $result->scope;
139147

140148
if ($expr instanceof AssignRef) {
@@ -360,6 +368,7 @@ private function processStmtVarAnnotation(GeneratorScope $scope, Node\Stmt $stmt
360368
}
361369

362370
/**
371+
* @param (callable(Node, Scope, callable(Node, Scope): void): void)|null $alternativeNodeCallback
363372
* @param Closure(GeneratorScope $scope): Generator<int, ExprAnalysisRequest|NodeCallbackRequest|TypeExprRequest, ExprAnalysisResult|TypeExprResult, ExprAnalysisResult> $processExprCallback
364373
* @return Generator<int, ExprAnalysisRequest|NodeCallbackRequest|TypeExprRequest, ExprAnalysisResult|TypeExprResult, ExprAnalysisResult>
365374
*/
@@ -370,6 +379,7 @@ private function processAssignVar(
370379
Expr $assignedExpr,
371380
ExprAnalysisResultStorage $storage,
372381
ExpressionContext $context,
382+
?callable $alternativeNodeCallback,
373383
Closure $processExprCallback,
374384
bool $enterExpressionAssign,
375385
): Generator
@@ -394,13 +404,13 @@ private function processAssignVar(
394404
if ($if === null) {
395405
$if = $assignedExpr->cond;
396406
}
397-
$truthyResult = yield new ExprAnalysisRequest($stmt, $if, $scope, $context->enterDeep());
407+
$truthyResult = yield new ExprAnalysisRequest($stmt, $if, $scope, $context->enterDeep(), $alternativeNodeCallback);
398408
if ($assignedExpr->if === null) {
399409
$condResult = $truthyResult;
400410
} else {
401-
$condResult = yield new ExprAnalysisRequest($stmt, $assignedExpr->cond, $scope, $context->enterDeep());
411+
$condResult = yield new ExprAnalysisRequest($stmt, $assignedExpr->cond, $scope, $context->enterDeep(), $alternativeNodeCallback);
402412
}
403-
$falseyResult = yield new ExprAnalysisRequest($stmt, $assignedExpr->else, $scope, $context->enterDeep());
413+
$falseyResult = yield new ExprAnalysisRequest($stmt, $assignedExpr->else, $scope, $context->enterDeep(), $alternativeNodeCallback);
404414

405415
if (
406416
$truthyResult->type->isSuperTypeOf($falseyResult->type)->no()
@@ -479,7 +489,7 @@ private function processAssignVar(
479489
if ($enterExpressionAssign) {
480490
$scope = $scope->enterExpressionAssign($var);
481491
}
482-
$varResult = yield new ExprAnalysisRequest($stmt, $var, $scope, $context->enterDeep());
492+
$varResult = yield new ExprAnalysisRequest($stmt, $var, $scope, $context->enterDeep(), $alternativeNodeCallback);
483493
$hasYield = $varResult->hasYield;
484494
$throwPoints = $varResult->throwPoints;
485495
$impurePoints = $varResult->impurePoints;
@@ -507,7 +517,7 @@ private function processAssignVar(
507517
$offsetNativeTypes[] = [null, $dimFetch];
508518

509519
} else {
510-
$dimExprResult = yield new ExprAnalysisRequest($stmt, $dimExpr, $scope, $context->enterDeep());
520+
$dimExprResult = yield new ExprAnalysisRequest($stmt, $dimExpr, $scope, $context->enterDeep(), $alternativeNodeCallback);
511521
$offsetTypes[] = [$dimExprResult->type, $dimFetch];
512522
$offsetNativeTypes[] = [$dimExprResult->nativeType, $dimFetch];
513523

@@ -653,7 +663,7 @@ static function (): void {
653663
specifiedFalseyTypes: new SpecifiedTypes(),
654664
);
655665
} elseif ($var instanceof PropertyFetch) {
656-
$objectResult = yield new ExprAnalysisRequest($stmt, $var->var, $scope, $context);
666+
$objectResult = yield new ExprAnalysisRequest($stmt, $var->var, $scope, $context, $alternativeNodeCallback);
657667
$hasYield = $objectResult->hasYield;
658668
$throwPoints = $objectResult->throwPoints;
659669
$impurePoints = $objectResult->impurePoints;
@@ -664,7 +674,7 @@ static function (): void {
664674
if ($var->name instanceof Node\Identifier) {
665675
$propertyName = $var->name->name;
666676
} else {
667-
$propertyNameResult = yield new ExprAnalysisRequest($stmt, $var->name, $scope, $context);
677+
$propertyNameResult = yield new ExprAnalysisRequest($stmt, $var->name, $scope, $context, $alternativeNodeCallback);
668678
$hasYield = $hasYield || $propertyNameResult->hasYield;
669679
$throwPoints = array_merge($throwPoints, $propertyNameResult->throwPoints);
670680
$impurePoints = array_merge($impurePoints, $propertyNameResult->impurePoints);
@@ -775,7 +785,7 @@ static function (): void {
775785
if ($var->class instanceof Node\Name) {
776786
$propertyHolderType = $scope->resolveTypeByName($var->class);
777787
} else {
778-
$varClassResult = yield new ExprAnalysisRequest($stmt, $var->class, $scope, $context);
788+
$varClassResult = yield new ExprAnalysisRequest($stmt, $var->class, $scope, $context, $alternativeNodeCallback);
779789
$propertyHolderType = $varClassResult->type;
780790
}
781791

@@ -788,7 +798,7 @@ static function (): void {
788798
if ($var->name instanceof Node\Identifier) {
789799
$propertyName = $var->name->name;
790800
} else {
791-
$propertyNameResult = yield new ExprAnalysisRequest($stmt, $var->name, $scope, $context);
801+
$propertyNameResult = yield new ExprAnalysisRequest($stmt, $var->name, $scope, $context, $alternativeNodeCallback);
792802
$hasYield = $propertyNameResult->hasYield;
793803
$throwPoints = $propertyNameResult->throwPoints;
794804
$impurePoints = $propertyNameResult->impurePoints;
@@ -884,15 +894,15 @@ static function (): void {
884894
$itemScope = $this->lookForSetAllowedUndefinedExpressions($itemScope, $arrayItem->value);
885895
yield new NodeCallbackRequest($arrayItem, $itemScope);
886896
if ($arrayItem->key !== null) {
887-
$keyResult = yield new ExprAnalysisRequest($stmt, $arrayItem->key, $itemScope, $context->enterDeep());
897+
$keyResult = yield new ExprAnalysisRequest($stmt, $arrayItem->key, $itemScope, $context->enterDeep(), $alternativeNodeCallback);
888898
$hasYield = $hasYield || $keyResult->hasYield;
889899
$throwPoints = array_merge($throwPoints, $keyResult->throwPoints);
890900
$impurePoints = array_merge($impurePoints, $keyResult->impurePoints);
891901
$isAlwaysTerminating = $isAlwaysTerminating || $keyResult->isAlwaysTerminating;
892902
$itemScope = $keyResult->scope;
893903
}
894904

895-
$valueResult = yield new ExprAnalysisRequest($stmt, $arrayItem->value, $itemScope, $context->enterDeep());
905+
$valueResult = yield new ExprAnalysisRequest($stmt, $arrayItem->value, $itemScope, $context->enterDeep(), $alternativeNodeCallback);
896906
$hasYield = $hasYield || $valueResult->hasYield;
897907
$throwPoints = array_merge($throwPoints, $valueResult->throwPoints);
898908
$impurePoints = array_merge($impurePoints, $valueResult->impurePoints);
@@ -910,6 +920,7 @@ static function (): void {
910920
new GetOffsetValueTypeExpr($assignedExpr, $dimExpr),
911921
$storage,
912922
$context,
923+
$alternativeNodeCallback,
913924
static function (GeneratorScope $scope): Generator {
914925
yield from [];
915926
return new ExprAnalysisResult(
@@ -964,7 +975,8 @@ static function (GeneratorScope $scope): Generator {
964975
}
965976

966977
// 1. eval root expr
967-
$varResult = yield new ExprAnalysisRequest($stmt, $var, $scope, $context->enterDeep());
978+
$varResult = yield new ExprAnalysisRequest($stmt, $var, $scope, $context->enterDeep(), static function () {
979+
}); // todo Noop...
968980
$hasYield = $varResult->hasYield;
969981
$throwPoints = $varResult->throwPoints;
970982
$impurePoints = $varResult->impurePoints;

src/Analyser/Generator/ExprHandler/CastIntHandler.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,16 @@ public function supports(Expr $expr): bool
2727
return $expr instanceof Int_;
2828
}
2929

30-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator
30+
public function analyseExpr(
31+
Stmt $stmt,
32+
Expr $expr,
33+
GeneratorScope $scope,
34+
ExprAnalysisResultStorage $storage,
35+
ExpressionContext $context,
36+
?callable $alternativeNodeCallback,
37+
): Generator
3138
{
32-
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep());
39+
$exprResult = yield new ExprAnalysisRequest($stmt, $expr->expr, $scope, $context->enterDeep(), $alternativeNodeCallback);
3340

3441
return new ExprAnalysisResult(
3542
$exprResult->type->toInteger(),

src/Analyser/Generator/ExprHandler/ClassConstFetchHandler.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,14 @@ public function supports(Expr $expr): bool
3030
return $expr instanceof ClassConstFetch;
3131
}
3232

33-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator
33+
public function analyseExpr(
34+
Stmt $stmt,
35+
Expr $expr,
36+
GeneratorScope $scope,
37+
ExprAnalysisResultStorage $storage,
38+
ExpressionContext $context,
39+
?callable $alternativeNodeCallback,
40+
): Generator
3441
{
3542
if (
3643
$expr->class instanceof Name

src/Analyser/Generator/ExprHandler/ClosureHandler.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,16 @@ public function supports(Expr $expr): bool
2929
return $expr instanceof Closure;
3030
}
3131

32-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator
32+
public function analyseExpr(
33+
Stmt $stmt,
34+
Expr $expr,
35+
GeneratorScope $scope,
36+
ExprAnalysisResultStorage $storage,
37+
ExpressionContext $context,
38+
?callable $alternativeNodeCallback,
39+
): Generator
3340
{
34-
$result = yield new StmtsAnalysisRequest($expr->stmts, $scope, StatementContext::createTopLevel()); // @phpstan-ignore generator.valueType
41+
$result = yield new StmtsAnalysisRequest($expr->stmts, $scope, StatementContext::createTopLevel(), $alternativeNodeCallback); // @phpstan-ignore generator.valueType
3542
$scope = $result->scope;
3643

3744
return new ExprAnalysisResult(

src/Analyser/Generator/ExprHandler/FuncCallHandler.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,21 @@ public function supports(Expr $expr): bool
3535
return $expr instanceof FuncCall;
3636
}
3737

38-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator
38+
public function analyseExpr(
39+
Stmt $stmt,
40+
Expr $expr,
41+
GeneratorScope $scope,
42+
ExprAnalysisResultStorage $storage,
43+
ExpressionContext $context,
44+
?callable $alternativeNodeCallback,
45+
): Generator
3946
{
4047
$throwPoints = [];
4148
$impurePoints = [];
4249
$isAlwaysTerminating = false;
4350
$hasYield = false;
4451
if ($expr->name instanceof Expr) {
45-
$nameResult = yield new ExprAnalysisRequest($stmt, $expr->name, $scope, $context->enterDeep());
52+
$nameResult = yield new ExprAnalysisRequest($stmt, $expr->name, $scope, $context->enterDeep(), $alternativeNodeCallback);
4653
$scope = $nameResult->scope;
4754
$throwPoints = $nameResult->throwPoints;
4855
$impurePoints = $nameResult->impurePoints;
@@ -53,7 +60,7 @@ public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprA
5360
$argTypes = [];
5461

5562
foreach ($expr->getArgs() as $arg) {
56-
$argResult = yield new ExprAnalysisRequest($stmt, $arg->value, $scope, $context->enterDeep());
63+
$argResult = yield new ExprAnalysisRequest($stmt, $arg->value, $scope, $context->enterDeep(), $alternativeNodeCallback);
5764
$argTypes[] = $argResult->type;
5865
$scope = $argResult->scope;
5966
$throwPoints = array_merge($throwPoints, $argResult->throwPoints);

src/Analyser/Generator/ExprHandler/LiteralArrayHandler.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ public function supports(Expr $expr): bool
4040
return $expr instanceof Array_;
4141
}
4242

43-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator
43+
public function analyseExpr(
44+
Stmt $stmt,
45+
Expr $expr,
46+
GeneratorScope $scope,
47+
ExprAnalysisResultStorage $storage,
48+
ExpressionContext $context,
49+
?callable $alternativeNodeCallback,
50+
): Generator
4451
{
4552
// todo oversizedArrayBuilder
4653
$arrayBuilder = ConstantArrayTypeBuilder::createEmpty();
@@ -56,15 +63,15 @@ public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprA
5663
yield new NodeCallbackRequest($arrayItem, $scope);
5764
$keyResult = null;
5865
if ($arrayItem->key !== null) {
59-
$keyResult = yield new ExprAnalysisRequest($stmt, $arrayItem->key, $scope, $context->enterDeep());
66+
$keyResult = yield new ExprAnalysisRequest($stmt, $arrayItem->key, $scope, $context->enterDeep(), $alternativeNodeCallback);
6067
$hasYield = $hasYield || $keyResult->hasYield;
6168
$throwPoints = array_merge($throwPoints, $keyResult->throwPoints);
6269
$impurePoints = array_merge($impurePoints, $keyResult->impurePoints);
6370
$isAlwaysTerminating = $isAlwaysTerminating || $keyResult->isAlwaysTerminating;
6471
$scope = $keyResult->scope;
6572
}
6673

67-
$valueResult = yield new ExprAnalysisRequest($stmt, $arrayItem->value, $scope, $context->enterDeep());
74+
$valueResult = yield new ExprAnalysisRequest($stmt, $arrayItem->value, $scope, $context->enterDeep(), $alternativeNodeCallback);
6875
$hasYield = $hasYield || $valueResult->hasYield;
6976
$throwPoints = array_merge($throwPoints, $valueResult->throwPoints);
7077
$impurePoints = array_merge($impurePoints, $valueResult->impurePoints);

src/Analyser/Generator/ExprHandler/MethodCallHandler.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,20 @@ public function supports(Expr $expr): bool
3030
return $expr instanceof MethodCall;
3131
}
3232

33-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator
33+
public function analyseExpr(
34+
Stmt $stmt,
35+
Expr $expr,
36+
GeneratorScope $scope,
37+
ExprAnalysisResultStorage $storage,
38+
ExpressionContext $context,
39+
?callable $alternativeNodeCallback,
40+
): Generator
3441
{
3542
if (!$expr->name instanceof Identifier) {
3643
throw new ShouldNotHappenException('Not implemented');
3744
}
3845

39-
$varResult = yield new ExprAnalysisRequest($stmt, $expr->var, $scope, $context->enterDeep());
46+
$varResult = yield new ExprAnalysisRequest($stmt, $expr->var, $scope, $context->enterDeep(), $alternativeNodeCallback);
4047
$throwPoints = $varResult->throwPoints;
4148
$impurePoints = $varResult->impurePoints;
4249
$isAlwaysTerminating = $varResult->isAlwaysTerminating;
@@ -45,7 +52,7 @@ public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprA
4552
$argTypes = [];
4653

4754
foreach ($expr->getArgs() as $arg) {
48-
$argResult = yield new ExprAnalysisRequest($stmt, $arg->value, $scope, $context->enterDeep());
55+
$argResult = yield new ExprAnalysisRequest($stmt, $arg->value, $scope, $context->enterDeep(), $alternativeNodeCallback);
4956
$argTypes[] = $argResult->type;
5057
$scope = $argResult->scope;
5158
$throwPoints = array_merge($throwPoints, $argResult->throwPoints);

src/Analyser/Generator/ExprHandler/NewHandler.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,14 @@ public function supports(Expr $expr): bool
2929
return $expr instanceof New_;
3030
}
3131

32-
public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprAnalysisResultStorage $storage, ExpressionContext $context): Generator
32+
public function analyseExpr(
33+
Stmt $stmt,
34+
Expr $expr,
35+
GeneratorScope $scope,
36+
ExprAnalysisResultStorage $storage,
37+
ExpressionContext $context,
38+
?callable $alternativeNodeCallback,
39+
): Generator
3340
{
3441
if (!$expr->class instanceof Name) {
3542
throw new ShouldNotHappenException('Not implemented');

0 commit comments

Comments
 (0)