PHPStan\Analyser\NodeScopeResolver::lookForAssigns PHP Method

lookForAssigns() private method

private lookForAssigns ( Scope $scope, PhpParser\Node $node ) : Scope
$scope Scope
$node PhpParser\Node
return Scope
    private function lookForAssigns(Scope $scope, \PhpParser\Node $node) : Scope
    {
        if ($node instanceof StaticVar) {
            $scope = $scope->assignVariable($node->name, $node->default !== null ? $scope->getType($node->default) : null);
        } elseif ($node instanceof Static_) {
            foreach ($node->vars as $var) {
                $scope = $this->lookForAssigns($scope, $var);
            }
        } elseif ($node instanceof If_) {
            $scope = $this->lookForAssigns($scope, $node->cond);
            $statements = [new StatementList($scope, array_merge([$node->cond], $node->stmts)), new StatementList($scope, $node->else !== null ? $node->else->stmts : ($this->defineVariablesWithoutDefaultBranch ? null : []))];
            foreach ($node->elseifs as $elseIf) {
                $statements[] = new StatementList($scope, array_merge([$elseIf->cond], $elseIf->stmts));
            }
            $scope = $this->lookForAssignsInBranches($scope, $statements);
        } elseif ($node instanceof TryCatch) {
            if (property_exists($node, 'finally') && (isset($node->finally) || $node->finally === null)) {
                $finallyStatements = $node->finally !== null ? $node->finally->stmts : null;
            } elseif (property_exists($node, 'finallyStmts') && (isset($node->finallyStmts) || $node->finallyStmts === null)) {
                $finallyStatements = $node->finallyStmts;
            } else {
                throw new \PHPStan\ShouldNotHappenException();
            }
            $statements = [new StatementList($scope, $node->stmts), new StatementList($scope, $finallyStatements)];
            foreach ($node->catches as $catch) {
                if (isset($catch->types)) {
                    $catchTypes = $catch->types;
                } elseif (isset($catch->type)) {
                    $catchTypes = [$catch->type];
                } else {
                    throw new \PHPStan\ShouldNotHappenException();
                }
                $statements[] = new StatementList($scope->enterCatch($catchTypes, $catch->var), $catch->stmts);
            }
            $scope = $this->lookForAssignsInBranches($scope, $statements);
        } elseif ($node instanceof MethodCall || $node instanceof FuncCall || $node instanceof Expr\StaticCall) {
            if ($node instanceof MethodCall) {
                $scope = $this->lookForAssigns($scope, $node->var);
            }
            foreach ($node->args as $argument) {
                $scope = $this->lookForAssigns($scope, $argument);
            }
            $parametersAcceptor = $this->findParametersAcceptorInFunctionCall($node, $scope);
            if ($parametersAcceptor !== null) {
                $parameters = $parametersAcceptor->getParameters();
                foreach ($node->args as $i => $arg) {
                    $assignByReference = false;
                    if (isset($parameters[$i])) {
                        $assignByReference = $parameters[$i]->isPassedByReference();
                    } elseif (count($parameters) > 0 && $parametersAcceptor->isVariadic()) {
                        $lastParameter = $parameters[count($parameters) - 1];
                        $assignByReference = $lastParameter->isPassedByReference();
                    }
                    if (!$assignByReference) {
                        continue;
                    }
                    $arg = $node->args[$i]->value;
                    if ($arg instanceof Variable && is_string($arg->name)) {
                        $scope = $scope->assignVariable($arg->name, new MixedType(true));
                    }
                }
            }
        } elseif ($node instanceof BinaryOp) {
            $scope = $this->lookForAssigns($scope, $node->left);
            $scope = $this->lookForAssigns($scope, $node->right);
        } elseif ($node instanceof Arg) {
            $scope = $this->lookForAssigns($scope, $node->value);
        } elseif ($node instanceof BooleanNot) {
            $scope = $this->lookForAssigns($scope, $node->expr);
        } elseif ($node instanceof Ternary) {
            $scope = $this->lookForAssigns($scope, $node->else);
        } elseif ($node instanceof List_) {
            if (isset($node->items)) {
                $nodeItems = $node->items;
            } elseif (isset($node->vars)) {
                $nodeItems = $node->vars;
            } else {
                throw new \PHPStan\ShouldNotHappenException();
            }
            foreach ($nodeItems as $item) {
                if ($item === null) {
                    continue;
                }
                $itemValue = $item;
                if ($itemValue instanceof ArrayItem) {
                    $itemValue = $itemValue->value;
                }
                if ($itemValue instanceof Variable) {
                    $scope = $scope->assignVariable($itemValue->name);
                } elseif ($itemValue instanceof ArrayDimFetch && $itemValue->var instanceof Variable) {
                    $scope = $scope->assignVariable($itemValue->var->name);
                } else {
                    $scope = $this->lookForAssigns($scope, $itemValue);
                }
            }
        } elseif ($node instanceof Array_) {
            foreach ($node->items as $item) {
                $scope = $this->lookForAssigns($scope, $item->value);
            }
        } elseif ($node instanceof New_) {
            foreach ($node->args as $arg) {
                $scope = $this->lookForAssigns($scope, $arg);
            }
        } elseif ($node instanceof Do_) {
            foreach ($node->stmts as $statement) {
                $scope = $this->lookForAssigns($scope, $statement);
            }
        } elseif ($node instanceof Switch_) {
            $statements = [];
            $hasDefault = false;
            foreach ($node->cases as $case) {
                if ($case->cond === null) {
                    $hasDefault = true;
                }
                $statements[] = new StatementList($scope, $case->stmts);
            }
            if (!$hasDefault) {
                $statements = [];
            }
            $scope = $this->lookForAssignsInBranches($scope, $statements, true);
        } elseif ($node instanceof Cast) {
            $scope = $this->lookForAssigns($scope, $node->expr);
        } elseif ($this->polluteScopeWithLoopInitialAssignments) {
            if ($node instanceof For_) {
                foreach ($node->init as $initExpr) {
                    $scope = $this->lookForAssigns($scope, $initExpr);
                }
                foreach ($node->cond as $condExpr) {
                    $scope = $this->lookForAssigns($scope, $condExpr);
                }
            } elseif ($node instanceof While_) {
                $scope = $this->lookForAssigns($scope, $node->cond);
            }
        } elseif ($node instanceof ErrorSuppress) {
            $scope = $this->lookForAssigns($scope, $node->expr);
        } elseif ($node instanceof \PhpParser\Node\Stmt\Unset_) {
            foreach ($node->vars as $var) {
                if ($var instanceof Variable && is_string($var->name)) {
                    $scope = $scope->unsetVariable($var->name);
                }
            }
        } elseif ($node instanceof Echo_) {
            foreach ($node->exprs as $echoedExpr) {
                $scope = $this->lookForAssigns($scope, $echoedExpr);
            }
        } elseif ($node instanceof Print_) {
            $scope = $this->lookForAssigns($scope, $node->expr);
        } elseif ($node instanceof Foreach_) {
            $scope = $this->lookForAssigns($scope, $node->expr);
        } elseif ($node instanceof Isset_) {
            foreach ($node->vars as $var) {
                $scope = $this->lookForAssigns($scope, $var);
            }
        } elseif ($node instanceof ArrayDimFetch && $node->dim !== null) {
            $scope = $this->lookForAssigns($scope, $node->dim);
        }
        $scope = $this->updateScopeForVariableAssign($scope, $node);
        return $scope;
    }