@@ -1336,9 +1336,9 @@ private function processStmtNode( |
1336 | 1336 | $hasYield = false; |
1337 | 1337 | $throwPoints = []; |
1338 | 1338 | foreach ($stmt->vars as $var) { |
1339 | | - $scope = $this->lookForEnterAllowedUndefinedVariable($scope, $var, true); |
| 1339 | + $scope = $this->lookForSetAllowedUndefinedExpressions($scope, $var); |
1340 | 1340 | $scope = $this->processExprNode($var, $scope, $nodeCallback, ExpressionContext::createDeep())->getScope(); |
1341 | | - $scope = $this->lookForExitAllowedUndefinedVariable($scope, $var); |
| 1341 | + $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $var); |
1342 | 1342 | $scope = $scope->unsetExpression($var); |
1343 | 1343 | } |
1344 | 1344 | } elseif ($stmt instanceof Node\Stmt\Use_) { |
@@ -1355,9 +1355,9 @@ private function processStmtNode( |
1355 | 1355 | if (!$var instanceof Variable) { |
1356 | 1356 | throw new ShouldNotHappenException(); |
1357 | 1357 | } |
1358 | | - $scope = $this->lookForEnterAllowedUndefinedVariable($scope, $var, true); |
| 1358 | + $scope = $this->lookForSetAllowedUndefinedExpressions($scope, $var); |
1359 | 1359 | $this->processExprNode($var, $scope, $nodeCallback, ExpressionContext::createDeep()); |
1360 | | - $scope = $this->lookForExitAllowedUndefinedVariable($scope, $var); |
| 1360 | + $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $var); |
1361 | 1361 |
|
1362 | 1362 | if (!is_string($var->name)) { |
1363 | 1363 | continue; |
@@ -1513,56 +1513,40 @@ private function createAstClassReflection(Node\Stmt\ClassLike $stmt, string $cla |
1513 | 1513 | ); |
1514 | 1514 | } |
1515 | 1515 |
|
1516 | | - private function lookForEnterAllowedUndefinedVariable(MutatingScope $scope, Expr $expr, bool $isAllowed): MutatingScope |
| 1516 | + private function lookForSetAllowedUndefinedExpressions(MutatingScope $scope, Expr $expr): MutatingScope |
1517 | 1517 | { |
1518 | | - if (!$expr instanceof ArrayDimFetch || $expr->dim !== null) { |
1519 | | - $scope = $scope->setAllowedUndefinedExpression($expr, $isAllowed); |
1520 | | - } |
1521 | | - if (!$expr instanceof Variable) { |
1522 | | - return $this->lookForVariableCallback($scope, $expr, static fn (MutatingScope $scope, Expr $expr): MutatingScope => $scope->setAllowedUndefinedExpression($expr, $isAllowed)); |
1523 | | - } |
1524 | | - |
1525 | | - return $scope; |
| 1518 | + return $this->lookForExpressionCallback($scope, $expr, static fn (MutatingScope $scope, Expr $expr): MutatingScope => $scope->setAllowedUndefinedExpression($expr)); |
1526 | 1519 | } |
1527 | 1520 |
|
1528 | | - private function lookForExitAllowedUndefinedVariable(MutatingScope $scope, Expr $expr): MutatingScope |
| 1521 | + private function lookForUnsetAllowedUndefinedExpressions(MutatingScope $scope, Expr $expr): MutatingScope |
1529 | 1522 | { |
1530 | | - if (!$expr instanceof ArrayDimFetch || $expr->dim !== null) { |
1531 | | - $scope = $scope->unsetAllowedUndefinedExpression($expr); |
1532 | | - } |
1533 | | - if (!$expr instanceof Variable) { |
1534 | | - return $this->lookForVariableCallback($scope, $expr, static fn (MutatingScope $scope, Expr $expr): MutatingScope => $scope->unsetAllowedUndefinedExpression($expr)); |
1535 | | - } |
1536 | | - |
1537 | | - return $scope; |
| 1523 | + return $this->lookForExpressionCallback($scope, $expr, static fn (MutatingScope $scope, Expr $expr): MutatingScope => $scope->unsetAllowedUndefinedExpression($expr)); |
1538 | 1524 | } |
1539 | 1525 |
|
1540 | 1526 | /** |
1541 | 1527 | * @param Closure(MutatingScope $scope, Expr $expr): MutatingScope $callback |
1542 | 1528 | */ |
1543 | | - private function lookForVariableCallback(MutatingScope $scope, Expr $expr, Closure $callback): MutatingScope |
| 1529 | + private function lookForExpressionCallback(MutatingScope $scope, Expr $expr, Closure $callback): MutatingScope |
1544 | 1530 | { |
1545 | | - if ($expr instanceof Variable) { |
| 1531 | + if (!$expr instanceof ArrayDimFetch || $expr->dim !== null) { |
1546 | 1532 | $scope = $callback($scope, $expr); |
1547 | | - } elseif ($expr instanceof ArrayDimFetch) { |
1548 | | - if ($expr->dim !== null) { |
1549 | | - $scope = $callback($scope, $expr); |
1550 | | - } |
| 1533 | + } |
1551 | 1534 |
|
1552 | | - $scope = $this->lookForVariableCallback($scope, $expr->var, $callback); |
| 1535 | + if ($expr instanceof ArrayDimFetch) { |
| 1536 | + $scope = $this->lookForExpressionCallback($scope, $expr->var, $callback); |
1553 | 1537 | } elseif ($expr instanceof PropertyFetch || $expr instanceof Expr\NullsafePropertyFetch) { |
1554 | | - $scope = $this->lookForVariableCallback($scope, $expr->var, $callback); |
| 1538 | + $scope = $this->lookForExpressionCallback($scope, $expr->var, $callback); |
1555 | 1539 | } elseif ($expr instanceof StaticPropertyFetch) { |
1556 | 1540 | if ($expr->class instanceof Expr) { |
1557 | | - $scope = $this->lookForVariableCallback($scope, $expr->class, $callback); |
| 1541 | + $scope = $this->lookForExpressionCallback($scope, $expr->class, $callback); |
1558 | 1542 | } |
1559 | 1543 | } elseif ($expr instanceof Array_ || $expr instanceof List_) { |
1560 | 1544 | foreach ($expr->items as $item) { |
1561 | 1545 | if ($item === null) { |
1562 | 1546 | continue; |
1563 | 1547 | } |
1564 | 1548 |
|
1565 | | - $scope = $this->lookForVariableCallback($scope, $item->value, $callback); |
| 1549 | + $scope = $this->lookForExpressionCallback($scope, $item->value, $callback); |
1566 | 1550 | } |
1567 | 1551 | } |
1568 | 1552 |
|
@@ -2321,10 +2305,10 @@ static function (?Type $offsetType, Type $valueType) use (&$arrayType): void { |
2321 | 2305 | ); |
2322 | 2306 | } elseif ($expr instanceof Coalesce) { |
2323 | 2307 | $nonNullabilityResult = $this->ensureNonNullability($scope, $expr->left, false); |
2324 | | - $condScope = $this->lookForEnterAllowedUndefinedVariable($nonNullabilityResult->getScope(), $expr->left, true); |
| 2308 | + $condScope = $this->lookForSetAllowedUndefinedExpressions($nonNullabilityResult->getScope(), $expr->left); |
2325 | 2309 | $condResult = $this->processExprNode($expr->left, $condScope, $nodeCallback, $context->enterDeep()); |
2326 | 2310 | $scope = $this->revertNonNullability($condResult->getScope(), $nonNullabilityResult->getSpecifiedExpressions()); |
2327 | | - $scope = $this->lookForExitAllowedUndefinedVariable($scope, $expr->left); |
| 2311 | + $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $expr->left); |
2328 | 2312 |
|
2329 | 2313 | $rightScope = $scope->filterByFalseyValue(new Expr\Isset_([$expr->left])); |
2330 | 2314 | $rightResult = $this->processExprNode($expr->right, $rightScope, $nodeCallback, $context->enterDeep()); |
@@ -2395,26 +2379,26 @@ static function (?Type $offsetType, Type $valueType) use (&$arrayType): void { |
2395 | 2379 | } |
2396 | 2380 | } elseif ($expr instanceof Expr\Empty_) { |
2397 | 2381 | $nonNullabilityResult = $this->ensureNonNullability($scope, $expr->expr, true); |
2398 | | - $scope = $this->lookForEnterAllowedUndefinedVariable($nonNullabilityResult->getScope(), $expr->expr, true); |
| 2382 | + $scope = $this->lookForSetAllowedUndefinedExpressions($nonNullabilityResult->getScope(), $expr->expr); |
2399 | 2383 | $result = $this->processExprNode($expr->expr, $scope, $nodeCallback, $context->enterDeep()); |
2400 | 2384 | $scope = $result->getScope(); |
2401 | 2385 | $hasYield = $result->hasYield(); |
2402 | 2386 | $throwPoints = $result->getThrowPoints(); |
2403 | 2387 | $scope = $this->revertNonNullability($scope, $nonNullabilityResult->getSpecifiedExpressions()); |
2404 | | - $scope = $this->lookForExitAllowedUndefinedVariable($scope, $expr->expr); |
| 2388 | + $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $expr->expr); |
2405 | 2389 | } elseif ($expr instanceof Expr\Isset_) { |
2406 | 2390 | $hasYield = false; |
2407 | 2391 | $throwPoints = []; |
2408 | 2392 | $nonNullabilityResults = []; |
2409 | 2393 | foreach ($expr->vars as $var) { |
2410 | 2394 | $nonNullabilityResult = $this->ensureNonNullability($scope, $var, true); |
2411 | | - $scope = $this->lookForEnterAllowedUndefinedVariable($nonNullabilityResult->getScope(), $var, true); |
| 2395 | + $scope = $this->lookForSetAllowedUndefinedExpressions($nonNullabilityResult->getScope(), $var); |
2412 | 2396 | $result = $this->processExprNode($var, $scope, $nodeCallback, $context->enterDeep()); |
2413 | 2397 | $scope = $result->getScope(); |
2414 | 2398 | $hasYield = $hasYield || $result->hasYield(); |
2415 | 2399 | $throwPoints = array_merge($throwPoints, $result->getThrowPoints()); |
2416 | 2400 | $nonNullabilityResults[] = $nonNullabilityResult; |
2417 | | - $scope = $this->lookForExitAllowedUndefinedVariable($scope, $var); |
| 2401 | + $scope = $this->lookForUnsetAllowedUndefinedExpressions($scope, $var); |
2418 | 2402 | } |
2419 | 2403 | foreach (array_reverse($nonNullabilityResults) as $nonNullabilityResult) { |
2420 | 2404 | $scope = $this->revertNonNullability($scope, $nonNullabilityResult->getSpecifiedExpressions()); |
@@ -3466,7 +3450,7 @@ static function (): void { |
3466 | 3450 | if ($arrayItem->value instanceof ArrayDimFetch && $arrayItem->value->dim === null) { |
3467 | 3451 | $itemScope = $itemScope->enterExpressionAssign($arrayItem->value); |
3468 | 3452 | } |
3469 | | - $itemScope = $this->lookForEnterAllowedUndefinedVariable($itemScope, $arrayItem->value, true); |
| 3453 | + $itemScope = $this->lookForSetAllowedUndefinedExpressions($itemScope, $arrayItem->value); |
3470 | 3454 | $itemResult = $this->processExprNode($arrayItem, $itemScope, $nodeCallback, $context->enterDeep()); |
3471 | 3455 | $hasYield = $hasYield || $itemResult->hasYield(); |
3472 | 3456 | $throwPoints = array_merge($throwPoints, $itemResult->getThrowPoints()); |
|