/** * Declares a refined type in {@code scope} for the name represented by * {@code node}. It must be possible to refine the type of the given node in * the given scope, as determined by {@link #getTypeIfRefinable}. */ protected function declareNameInScope(LinkedFlowScope $scope, \PHPParser_Node $node, PhpType $type) { switch (true) { case $node instanceof \PHPParser_Node_Expr_Variable: if (is_string($node->name)) { $scope->inferSlotType($node->name, $type); } break; case $node instanceof \PHPParser_Node_Expr_StaticPropertyFetch: case $node instanceof \PHPParser_Node_Expr_PropertyFetch: if (null !== ($qualifiedName = TypeInference::getQualifiedName($node))) { $origType = $node->getAttribute('type') ?: $this->typeRegistry->getNativeType('unknown'); $scope->inferQualifiedSlot($node, $qualifiedName, $origType, $type); } break; // Something like: if (is_array($functions = getFunctionNames())) { } // Something like: if (is_array($functions = getFunctionNames())) { } case $node instanceof \PHPParser_Node_Expr_Assign: case $node instanceof \PHPParser_Node_Expr_AssignRef: $this->declareNameInScope($scope, $node->var, $type); break; case $node instanceof \PHPParser_Node_Expr_ArrayDimFetch: $dim = \Scrutinizer\PhpAnalyzer\PhpParser\NodeUtil::getValue($node->dim); if ($dim->isDefined() && null !== ($slotType = $node->var->getAttribute('type')) && $slotType->isArrayType()) { $newSlotType = $slotType->inferItemType($dim->get(), $type); $this->declareNameInScope($scope, $node->var, $newSlotType); } break; } }