Skip to content

Commit 9616473

Browse files
committed
before scope
1 parent 09fcd20 commit 9616473

File tree

3 files changed

+34
-11
lines changed

3 files changed

+34
-11
lines changed

src/Analyser/ExpressionResult.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ final class ExpressionResult
2323
*/
2424
public function __construct(
2525
private MutatingScope $scope,
26+
private MutatingScope $beforeScope,
2627
private bool $hasYield,
2728
private bool $isAlwaysTerminating,
2829
private array $throwPoints,
@@ -40,6 +41,11 @@ public function getScope(): MutatingScope
4041
return $this->scope;
4142
}
4243

44+
public function getBeforeScope(): MutatingScope
45+
{
46+
return $this->beforeScope;
47+
}
48+
4349
public function hasYield(): bool
4450
{
4551
return $this->hasYield;

src/Analyser/Fiber/FiberScope.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public function getType(Expr $node): Type
1919
new ExpressionAnalysisRequest($node, $this),
2020
);
2121

22-
return $exprResult->getScope()->toMutatingScope()->getType($node);
22+
return $exprResult->getBeforeScope()->toMutatingScope()->getType($node);
2323
}
2424

2525
/** @api */
@@ -30,7 +30,7 @@ public function getNativeType(Expr $expr): Type
3030
new ExpressionAnalysisRequest($expr, $this),
3131
);
3232

33-
return $exprResult->getScope()->toMutatingScope()->getNativeType($expr);
33+
return $exprResult->getBeforeScope()->toMutatingScope()->getNativeType($expr);
3434
}
3535

3636
public function getKeepVoidType(Expr $node): Type
@@ -40,7 +40,7 @@ public function getKeepVoidType(Expr $node): Type
4040
new ExpressionAnalysisRequest($node, $this),
4141
);
4242

43-
return $exprResult->getScope()->toMutatingScope()->getKeepVoidType($node);
43+
return $exprResult->getBeforeScope()->toMutatingScope()->getKeepVoidType($node);
4444
}
4545

4646
}

src/Analyser/NodeScopeResolver.php

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2570,7 +2570,9 @@ public function processExprNode(
25702570
throw new ShouldNotHappenException();
25712571
}
25722572

2573-
return $this->processExprNode($stmt, $newExpr, $scope, $storage, $nodeCallback, $context);
2573+
$newExprResult = $this->processExprNode($stmt, $newExpr, $scope, $storage, $nodeCallback, $context);
2574+
$storage->storeResult($expr, $newExprResult);
2575+
return $newExprResult;
25742576
}
25752577

25762578
$existingExprResult = $storage->findResult($expr);
@@ -2581,6 +2583,7 @@ public function processExprNode(
25812583
throw new ShouldNotHappenException(sprintf('Expr %s on line %d has already been analysed', get_class($expr), $expr->getStartLine()));
25822584
}
25832585

2586+
$originalScope = $scope;
25842587
$this->callNodeCallbackWithExpression($nodeCallback, $expr, $scope, $storage, $context);
25852588

25862589
if ($expr instanceof Variable) {
@@ -2630,6 +2633,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
26302633
);
26312634
}
26322635

2636+
$beforeScope = $scope;
26332637
$result = $this->processExprNode($stmt, $expr->expr, $scope, $storage, $nodeCallback, $context->enterDeep());
26342638
$hasYield = $result->hasYield();
26352639
$throwPoints = $result->getThrowPoints();
@@ -2641,7 +2645,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
26412645
$scope = $scope->exitExpressionAssign($expr->expr);
26422646
}
26432647

2644-
$result = new ExpressionResult($scope, $hasYield, $isAlwaysTerminating, $throwPoints, $impurePoints);
2648+
$result = new ExpressionResult($scope, $beforeScope, $hasYield, $isAlwaysTerminating, $throwPoints, $impurePoints);
26452649
$this->storeResult($storage, $expr, $result);
26462650

26472651
return $result;
@@ -2683,6 +2687,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
26832687
if ($expr instanceof Expr\AssignOp\Coalesce) {
26842688
$result = new ExpressionResult(
26852689
$result->getScope()->mergeWith($originalScope),
2690+
$originalScope,
26862691
$result->hasYield(),
26872692
$result->isAlwaysTerminating(),
26882693
$result->getThrowPoints(),
@@ -3188,12 +3193,14 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
31883193
$impurePoints = array_merge($impurePoints, $result->getImpurePoints());
31893194
$isAlwaysTerminating = $isAlwaysTerminating || $result->isAlwaysTerminating();
31903195
} elseif ($expr instanceof Expr\NullsafeMethodCall) {
3196+
$beforeScope = $scope;
31913197
$nonNullabilityResult = $this->ensureShallowNonNullability($scope, $scope, $expr->var);
31923198
$exprResult = $this->processExprNode($stmt, new MethodCall($expr->var, $expr->name, $expr->args, array_merge($expr->getAttributes(), ['virtualNullsafeMethodCall' => true])), $nonNullabilityResult->getScope(), $storage, $nodeCallback, $context);
31933199
$scope = $this->revertNonNullability($exprResult->getScope(), $nonNullabilityResult->getSpecifiedExpressions());
31943200

31953201
$result = new ExpressionResult(
31963202
$scope,
3203+
$beforeScope,
31973204
$exprResult->hasYield(),
31983205
false,
31993206
$exprResult->getThrowPoints(),
@@ -3402,12 +3409,14 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
34023409
}
34033410
}
34043411
} elseif ($expr instanceof Expr\NullsafePropertyFetch) {
3412+
$beforeScope = $scope;
34053413
$nonNullabilityResult = $this->ensureShallowNonNullability($scope, $scope, $expr->var);
34063414
$exprResult = $this->processExprNode($stmt, new PropertyFetch($expr->var, $expr->name, array_merge($expr->getAttributes(), ['virtualNullsafePropertyFetch' => true])), $nonNullabilityResult->getScope(), $storage, $nodeCallback, $context);
34073415
$scope = $this->revertNonNullability($exprResult->getScope(), $nonNullabilityResult->getSpecifiedExpressions());
34083416

34093417
$result = new ExpressionResult(
34103418
$scope,
3419+
$beforeScope,
34113420
$exprResult->hasYield(),
34123421
false,
34133422
$exprResult->getThrowPoints(),
@@ -3448,11 +3457,13 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
34483457
$scope = $result->getScope();
34493458
}
34503459
} elseif ($expr instanceof Expr\Closure) {
3460+
$beforeScope = $scope;
34513461
$processClosureResult = $this->processClosureNode($stmt, $expr, $scope, $storage, $nodeCallback, $context, null);
34523462
$scope = $processClosureResult->getScope();
34533463

34543464
$result = new ExpressionResult(
34553465
$scope,
3466+
$beforeScope,
34563467
false,
34573468
false,
34583469
[],
@@ -3465,6 +3476,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
34653476
$result = $this->processArrowFunctionNode($stmt, $expr, $scope, $storage, $nodeCallback, null);
34663477
$exprResult = new ExpressionResult(
34673478
$result->getScope(),
3479+
$scope,
34683480
$result->hasYield(),
34693481
false,
34703482
[],
@@ -3571,6 +3583,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
35713583

35723584
$result = new ExpressionResult(
35733585
$leftMergedWithRightScope,
3586+
$scope,
35743587
$leftResult->hasYield() || $rightResult->hasYield(),
35753588
$leftResult->isAlwaysTerminating(),
35763589
array_merge($leftResult->getThrowPoints(), $rightResult->getThrowPoints()),
@@ -3594,6 +3607,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
35943607

35953608
$result = new ExpressionResult(
35963609
$leftMergedWithRightScope,
3610+
$scope,
35973611
$leftResult->hasYield() || $rightResult->hasYield(),
35983612
$leftResult->isAlwaysTerminating(),
35993613
array_merge($leftResult->getThrowPoints(), $rightResult->getThrowPoints()),
@@ -3851,7 +3865,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
38513865
}
38523866
} elseif ($expr instanceof List_) {
38533867
// only in assign and foreach, processed elsewhere
3854-
return new ExpressionResult($scope, false, false, [], []);
3868+
return new ExpressionResult($scope, $scope, false, false, [], []);
38553869
} elseif ($expr instanceof New_) {
38563870
$parametersAcceptor = null;
38573871
$constructorReflection = null;
@@ -4067,6 +4081,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
40674081

40684082
$result = new ExpressionResult(
40694083
$finalScope,
4084+
$scope,
40704085
$ternaryCondResult->hasYield(),
40714086
$isAlwaysTerminating,
40724087
$throwPoints,
@@ -4422,6 +4437,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
44224437

44234438
$result = new ExpressionResult(
44244439
$scope,
4440+
$originalScope,
44254441
$hasYield,
44264442
$isAlwaysTerminating,
44274443
$throwPoints,
@@ -5167,7 +5183,7 @@ private function processArrowFunctionNode(
51675183
$this->callNodeCallback($nodeCallback, new InArrowFunctionNode($arrowFunctionType, $expr), $arrowFunctionScope, $storage);
51685184
$exprResult = $this->processExprNode($stmt, $expr->expr, $arrowFunctionScope, $storage, $nodeCallback, ExpressionContext::createTopLevel());
51695185

5170-
$result = new ExpressionResult($scope, false, $exprResult->isAlwaysTerminating(), $exprResult->getThrowPoints(), $exprResult->getImpurePoints());
5186+
$result = new ExpressionResult($scope, $scope, false, $exprResult->isAlwaysTerminating(), $exprResult->getThrowPoints(), $exprResult->getImpurePoints());
51715187
$this->storeResult($storage, $expr, $result);
51725188

51735189
return $result;
@@ -5799,7 +5815,7 @@ private function processArgs(
57995815
}
58005816

58015817
// not storing this, it's scope after processing all args
5802-
return new ExpressionResult($scope, $hasYield, $isAlwaysTerminating, $throwPoints, $impurePoints);
5818+
return new ExpressionResult($scope, $scope, $hasYield, $isAlwaysTerminating, $throwPoints, $impurePoints);
58035819
}
58045820

58055821
/**
@@ -5903,6 +5919,7 @@ private function processAssignVar(
59035919
bool $enterExpressionAssign,
59045920
): ExpressionResult
59055921
{
5922+
$originalScope = $scope;
59065923
$this->callNodeCallback($nodeCallback, $var, $enterExpressionAssign ? $scope->enterExpressionAssign($var) : $scope, $storage);
59075924
$hasYield = false;
59085925
$throwPoints = [];
@@ -6350,7 +6367,7 @@ private function processAssignVar(
63506367
new GetOffsetValueTypeExpr($assignedExpr, $dimExpr),
63516368
$nodeCallback,
63526369
$context,
6353-
static fn (MutatingScope $scope): ExpressionResult => new ExpressionResult($scope, false, false, [], []),
6370+
static fn (MutatingScope $scope): ExpressionResult => new ExpressionResult($scope, $scope, false, false, [], []),
63546371
$enterExpressionAssign,
63556372
);
63566373
$scope = $result->getScope();
@@ -6436,7 +6453,7 @@ private function processAssignVar(
64366453
}
64376454

64386455
// stored where processAssignVar is called
6439-
return new ExpressionResult($scope, $hasYield, $isAlwaysTerminating, $throwPoints, $impurePoints);
6456+
return new ExpressionResult($scope, $originalScope, $hasYield, $isAlwaysTerminating, $throwPoints, $impurePoints);
64406457
}
64416458

64426459
/**
@@ -6452,7 +6469,7 @@ private function processVirtualAssign(MutatingScope $scope, ExpressionResultStor
64526469
$assignedExpr,
64536470
new VirtualAssignNodeCallback($nodeCallback),
64546471
ExpressionContext::createDeep(),
6455-
static fn (MutatingScope $scope): ExpressionResult => new ExpressionResult($scope, false, false, [], []),
6472+
static fn (MutatingScope $scope): ExpressionResult => new ExpressionResult($scope, $scope, false, false, [], []),
64566473
false,
64576474
);
64586475
}

0 commit comments

Comments
 (0)