private function updateScopeForVariableAssign(Scope $scope, \PhpParser\Node $node) : Scope
{
if ($node instanceof Assign || $node instanceof AssignRef || $node instanceof Isset_) {
if ($node instanceof Assign || $node instanceof AssignRef) {
$vars = [$node->var];
} elseif ($node instanceof Isset_) {
$vars = $node->vars;
} else {
throw new \PHPStan\ShouldNotHappenException();
}
foreach ($vars as $var) {
$scope = $this->assignVariable($scope, $var, $node instanceof Assign || $node instanceof AssignRef ? $scope->getType($node->expr) : null);
}
if ($node instanceof Assign || $node instanceof AssignRef) {
$scope = $this->lookForAssigns($scope, $node->expr);
$comment = CommentHelper::getDocComment($node);
if ($comment !== null && $node->var instanceof Variable && is_string($node->var->name)) {
$variableName = $node->var->name;
$processVarAnnotation = function (string $matchedType, string $matchedVariableName) use($scope, $variableName) : Scope {
$fileTypeMap = $this->fileTypeMapper->getTypeMap($scope->getFile());
if (isset($fileTypeMap[$matchedType]) && $matchedVariableName === $variableName) {
return $scope->assignVariable($matchedVariableName, $fileTypeMap[$matchedType]);
}
return $scope;
};
if (preg_match('#@var\\s+' . FileTypeMapper::TYPE_PATTERN . '\\s+\\$([a-zA-Z0-9_]+)#', $comment, $matches)) {
$scope = $processVarAnnotation($matches[1], $matches[2]);
} elseif (preg_match('#@var\\s+\\$([a-zA-Z0-9_]+)\\s+' . FileTypeMapper::TYPE_PATTERN . '#', $comment, $matches)) {
$scope = $processVarAnnotation($matches[2], $matches[1]);
}
}
}
if ($node instanceof Isset_) {
foreach ($vars as $var) {
if ($var instanceof PropertyFetch) {
$scope = $scope->specifyFetchedPropertyFromIsset($var);
}
}
}
}
return $scope;
}