/**
  * 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;
 }