/** * Returns the type of the given node in the flow scope. * * If the node cannot be matched to a slot, or simply is not capable of being * refined, then this method returns null. * * @return PhpType|null */ public function getTypeIfRefinable(\PHPParser_Node $node, LinkedFlowScope $scope) { switch (true) { case $node instanceof \PHPParser_Node_Expr_ArrayDimFetch: $varType = $this->getTypeIfRefinable($node->var, $scope); if ($varType && $varType->isArrayType()) { $dim = \Scrutinizer\PhpAnalyzer\PhpParser\NodeUtil::getValue($node->dim); if ($dim->isEmpty()) { return null; } return $dim->flatMap([$varType, 'getItemType'])->getOrCall([$varType, 'getElementType']); } return null; // Handle the common pattern of assigning the result of an expression // inside of a condition, e.g. ``if (null !== $obj = $this->findObj())``. // Handle the common pattern of assigning the result of an expression // inside of a condition, e.g. ``if (null !== $obj = $this->findObj())``. case $node instanceof \PHPParser_Node_Expr_Assign: case $node instanceof \PHPParser_Node_Expr_AssignRef: if (TypeInference::hasQualifiedName($node->var) && null !== ($qualifiedName = TypeInference::getQualifiedName($node->var)) && null !== ($nameVar = $scope->getSlot($node->var->name))) { if (null !== ($nameType = $nameVar->getType())) { return $nameType; } return $node->var->getAttribute('type'); } return null; case $node instanceof \PHPParser_Node_Expr_Variable: if (is_string($node->name)) { $nameVar = $scope->getSlot($node->name); if (null !== $nameVar) { if (null !== $nameVar->getType()) { return $nameVar->getType(); } return $node->getAttribute('type'); } } return null; case $node instanceof \PHPParser_Node_Expr_StaticPropertyFetch: case $node instanceof \PHPParser_Node_Expr_PropertyFetch: if (null === ($qualifiedName = TypeInference::getQualifiedName($node))) { return null; } $propVar = $scope->getSlot($qualifiedName); if (null !== $propVar && null !== $propVar->getType()) { return $propVar->getType(); } if (null !== ($type = $node->getAttribute('type'))) { return $type; } return null; } return null; }