Skip to content

Commit a0371fc

Browse files
committed
Store variable name expr before scope
1 parent fa40c6b commit a0371fc

1 file changed

Lines changed: 52 additions & 43 deletions

File tree

src/Analyser/NodeScopeResolver.php

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5954,61 +5954,70 @@ private function processAssignVar(
59545954
$impurePoints = [];
59555955
$isAlwaysTerminating = false;
59565956
$isAssignOp = $assignedExpr instanceof Expr\AssignOp && !$enterExpressionAssign;
5957-
if ($var instanceof Variable && is_string($var->name)) {
5957+
if ($var instanceof Variable) {
59585958
$this->storeBeforeScope($storage, $var, $scope);
59595959
$result = $processExprCallback($scope);
59605960
$hasYield = $result->hasYield();
59615961
$throwPoints = $result->getThrowPoints();
59625962
$impurePoints = $result->getImpurePoints();
59635963
$isAlwaysTerminating = $result->isAlwaysTerminating();
5964-
if (in_array($var->name, Scope::SUPERGLOBAL_VARIABLES, true)) {
5965-
$impurePoints[] = new ImpurePoint($scope, $var, 'superglobal', 'assign to superglobal variable', true);
5966-
}
5967-
$assignedExpr = $this->unwrapAssign($assignedExpr);
5968-
$type = $scope->getType($assignedExpr);
5969-
5970-
$conditionalExpressions = [];
5971-
if ($assignedExpr instanceof Ternary) {
5972-
$if = $assignedExpr->if;
5973-
if ($if === null) {
5974-
$if = $assignedExpr->cond;
5975-
}
5976-
$condScope = $this->processExprNode($stmt, $assignedExpr->cond, $scope, $storage, new NoopNodeCallback(), ExpressionContext::createDeep())->getScope();
5977-
$truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($condScope, $assignedExpr->cond, TypeSpecifierContext::createTruthy());
5978-
$falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($condScope, $assignedExpr->cond, TypeSpecifierContext::createFalsey());
5979-
$truthyScope = $condScope->filterBySpecifiedTypes($truthySpecifiedTypes);
5980-
$falsyScope = $condScope->filterBySpecifiedTypes($falseySpecifiedTypes);
5981-
$truthyType = $truthyScope->getType($if);
5982-
$falseyType = $falsyScope->getType($assignedExpr->else);
5964+
$scopeBeforeAssignEval = $scope;
5965+
$scope = $result->getScope();
5966+
if (is_string($var->name)) {
5967+
if (in_array($var->name, Scope::SUPERGLOBAL_VARIABLES, true)) {
5968+
$impurePoints[] = new ImpurePoint($scopeBeforeAssignEval, $var, 'superglobal', 'assign to superglobal variable', true);
5969+
}
5970+
$assignedExpr = $this->unwrapAssign($assignedExpr);
5971+
$type = $scopeBeforeAssignEval->getType($assignedExpr);
5972+
5973+
$conditionalExpressions = [];
5974+
if ($assignedExpr instanceof Ternary) {
5975+
$if = $assignedExpr->if;
5976+
if ($if === null) {
5977+
$if = $assignedExpr->cond;
5978+
}
5979+
$condScope = $this->processExprNode($stmt, $assignedExpr->cond, $scope, $storage, new NoopNodeCallback(), ExpressionContext::createDeep())->getScope();
5980+
$truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($condScope, $assignedExpr->cond, TypeSpecifierContext::createTruthy());
5981+
$falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($condScope, $assignedExpr->cond, TypeSpecifierContext::createFalsey());
5982+
$truthyScope = $condScope->filterBySpecifiedTypes($truthySpecifiedTypes);
5983+
$falsyScope = $condScope->filterBySpecifiedTypes($falseySpecifiedTypes);
5984+
$truthyType = $truthyScope->getType($if);
5985+
$falseyType = $falsyScope->getType($assignedExpr->else);
59835986

5984-
if (
5985-
$truthyType->isSuperTypeOf($falseyType)->no()
5986-
&& $falseyType->isSuperTypeOf($truthyType)->no()
5987-
) {
5988-
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
5989-
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
5990-
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
5991-
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
5987+
if (
5988+
$truthyType->isSuperTypeOf($falseyType)->no()
5989+
&& $falseyType->isSuperTypeOf($truthyType)->no()
5990+
) {
5991+
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
5992+
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
5993+
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
5994+
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($condScope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
5995+
}
59925996
}
5993-
}
59945997

5995-
$scopeBeforeAssignEval = $scope;
5996-
$scope = $result->getScope();
5997-
$truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createTruthy());
5998-
$falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createFalsey());
5998+
$truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createTruthy());
5999+
$falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createFalsey());
59996000

6000-
$truthyType = TypeCombinator::removeFalsey($type);
6001-
$falseyType = TypeCombinator::intersect($type, StaticTypeFactory::falsey());
6001+
$truthyType = TypeCombinator::removeFalsey($type);
6002+
$falseyType = TypeCombinator::intersect($type, StaticTypeFactory::falsey());
60026003

6003-
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
6004-
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
6005-
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
6006-
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
6004+
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
6005+
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $truthySpecifiedTypes, $truthyType);
6006+
$conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
6007+
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
60076008

6008-
$this->callNodeCallback($nodeCallback, new VariableAssignNode($var, $assignedExpr), $scopeBeforeAssignEval, $storage);
6009-
$scope = $scope->assignVariable($var->name, $type, $scope->getNativeType($assignedExpr), TrinaryLogic::createYes());
6010-
foreach ($conditionalExpressions as $exprString => $holders) {
6011-
$scope = $scope->addConditionalExpressions($exprString, $holders);
6009+
$this->callNodeCallback($nodeCallback, new VariableAssignNode($var, $assignedExpr), $scopeBeforeAssignEval, $storage);
6010+
$scope = $scope->assignVariable($var->name, $type, $scope->getNativeType($assignedExpr), TrinaryLogic::createYes());
6011+
foreach ($conditionalExpressions as $exprString => $holders) {
6012+
$scope = $scope->addConditionalExpressions($exprString, $holders);
6013+
}
6014+
} else {
6015+
$nameExprResult = $this->processExprNode($stmt, $var->name, $scope, $storage, $nodeCallback, $context);
6016+
$hasYield = $hasYield || $nameExprResult->hasYield();
6017+
$throwPoints = array_merge($throwPoints, $nameExprResult->getThrowPoints());
6018+
$impurePoints = array_merge($impurePoints, $nameExprResult->getImpurePoints());
6019+
$isAlwaysTerminating = $isAlwaysTerminating || $nameExprResult->isAlwaysTerminating();
6020+
$scope = $nameExprResult->getScope();
60126021
}
60136022
} elseif ($var instanceof ArrayDimFetch) {
60146023
$dimFetchStack = [];

0 commit comments

Comments
 (0)