Exemple #1
0
 public function leaveNode(Node $node)
 {
     if (!$node instanceof Expr) {
         return;
     }
     $type = null;
     if ($node instanceof Expr\Assign || $node instanceof Expr\AssignRef) {
         $type = $node->expr->getAttribute('type');
     } elseif ($node instanceof Expr\Ternary) {
         $exprType1 = $node->if === null ? $node->cond->getAttribute('type') : $node->if->getAttribute('type');
         $exprType2 = $node->else->getAttribute('type');
         $type = Type::alternatives([$exprType1, $exprType2]);
     } elseif ($node instanceof Expr\BinaryOp\Coalesce) {
         $exprType1 = $node->left->getAttribute('type');
         $exprType2 = $node->right->getAttribute('type');
         $type = Type::alternatives([$exprType1, $exprType2]);
     } elseif ($node instanceof Expr\ErrorSuppress) {
         $type = $node->expr->getAttribute('type');
     } elseif ($node instanceof Expr\Eval_) {
         $type = Type::mixed_();
     } elseif ($node instanceof Expr\Exit_) {
         $type = Type::null_();
     }
     if ($type !== null || !$node->hasAttribute('type')) {
         if ($type === null) {
             $type = Type::mixed_();
         }
         $node->setAttribute('type', $type);
     }
 }
 public function enterNode(Node $node)
 {
     if ($node->hasAttribute('annotations')) {
         foreach ($node->getAttribute('annotations') as $annotations) {
             foreach ($annotations as $docTag) {
                 if ($docTag instanceof TypedTag) {
                     $docTag->setType($this->resolveDocTagType($docTag->getType()));
                 }
             }
         }
     }
     $result = parent::enterNode($node);
     if ($node instanceof Stmt\Class_) {
         $this->currentClass = $node->getAttribute('namespacedName');
         $this->parentClass = null;
         if ($node->extends !== null) {
             $this->parentClass = $node->extends->getAttribute('resolved');
         }
     } elseif ($node instanceof Stmt\Interface_) {
         $this->currentClass = $node->getAttribute('namespacedName');
         $this->parentClass = null;
     }
     return $result;
 }
Exemple #3
0
 /**
  * @param Node|array|mixed $nodes
  * @param int              $offset
  * @param (Comment|Node)[] $result
  * @param bool             $rightAdjustment
  *
  * @return bool True iff anything in $nodes include offset.
  */
 private function getNodeAtOffsetRecursive($nodes, $offset, array &$result, $rightAdjustment)
 {
     if ($nodes instanceof Node) {
         $comments = $nodes->getAttribute('comments', []);
         foreach ($comments as $comment) {
             if ($comment instanceof Comment\Doc) {
                 $start = $comment->getFilePos();
                 $end = $start + strlen($comment->getText());
                 if ($start <= $offset && $end + $rightAdjustment > $offset) {
                     $result[] = $nodes;
                     $result[] = $comment;
                     return true;
                 }
             }
         }
         // Namespace node needs special handling as it can be a no-braces namespace
         // where offsets include only declaration and not the logically contained statements.
         $isNamespace = $nodes instanceof Node\Stmt\Namespace_;
         $inRange = $nodes->getAttribute('startFilePos') <= $offset && $nodes->getAttribute('endFilePos') + $rightAdjustment >= $offset;
         if ($isNamespace || $inRange) {
             $result[] = $nodes;
             foreach ($nodes->getSubNodeNames() as $subnode) {
                 if ($this->getNodeAtOffsetRecursive($nodes->{$subnode}, $offset, $result, $rightAdjustment)) {
                     return true;
                 }
             }
             if ($inRange) {
                 return true;
             }
         }
     } elseif (is_array($nodes)) {
         foreach ($nodes as $node) {
             if ($this->getNodeAtOffsetRecursive($node, $offset, $result, $rightAdjustment)) {
                 return true;
             }
         }
     }
     return false;
 }
 public function enterNode(Node $node)
 {
     if ($node->hasAttribute('comments')) {
         $lastDocComment = null;
         foreach ($node->getAttribute('comments') as $comment) {
             if ($comment instanceof Comment\Doc) {
                 $lastDocComment = $comment;
             }
         }
         if ($lastDocComment) {
             list($shortDescription, $longDescription, $annotations) = $this->parse($lastDocComment->getText());
             if (!empty($shortDescription)) {
                 $node->setAttribute('shortDescription', $shortDescription);
             }
             if (!empty($longDescription)) {
                 $node->setAttribute('longDescription', $longDescription);
             }
             if (!empty($annotations)) {
                 $node->setAttribute('annotations', $annotations);
             }
         }
     }
 }
 public function leaveNode(Node $node)
 {
     if ($node instanceof Stmt\Function_ || $node instanceof Stmt\ClassMethod || $node instanceof Expr\Closure) {
         array_pop($this->functionScopeStack);
     } elseif ($node instanceof Stmt\ClassLike) {
         array_pop($this->classStack);
         array_pop($this->functionScopeStack);
     }
     if (!$node instanceof Expr) {
         return;
     }
     $type = null;
     $reflections = null;
     if ($node instanceof Expr\Variable) {
         if (is_string($node->name)) {
             if ($node->name === 'this') {
                 $type = $this->getCurrentClass();
             } elseif (array_key_exists('$' . $node->name, $this->getCurrentFunctionScope())) {
                 $type = $this->getCurrentFunctionScope()['$' . $node->name];
             }
         }
     } elseif ($node instanceof Expr\FuncCall) {
         $reflections = [];
         if ($node->name instanceof Name) {
             $reflections = $this->reflection->findFunction(Type::nameToString($node->name));
         } else {
             $reflections = $this->findMethods($node->name->getAttribute('type'), '__invoke');
         }
         $type = $this->functionsReturnType($reflections);
         // TODO: ConstFetch
     } elseif ($node instanceof Expr\MethodCall) {
         $reflections = [];
         if (is_string($node->name) || $node->name instanceof Identifier) {
             $reflections = $this->findMethods($node->var->getAttribute('type'), (string) $node->name);
         }
         $type = $this->functionsReturnType($reflections);
     } elseif ($node instanceof Expr\StaticCall) {
         $reflections = [];
         if ($node->class instanceof Name && (is_string($node->name) || $node->name instanceof Identifier)) {
             $reflections = $this->findMethods(Type::object_(Type::nameToString($node->class)), (string) $node->name, true);
         }
         $type = $this->functionsReturnType($reflections);
     } elseif ($node instanceof Expr\PropertyFetch) {
         $reflections = [];
         if (is_string($node->name) || $node->name instanceof Identifier) {
             $reflections = $this->findProperties($node->var->getAttribute('type'), '$' . (string) $node->name);
         }
         $type = $this->variablesType($reflections);
     } elseif ($node instanceof Expr\StaticPropertyFetch) {
         $reflections = [];
         if ($node->class instanceof Name && is_string($node->name)) {
             $reflections = $this->findProperties(Type::object_(Type::nameToString($node->class)), '$' . $node->name, true);
         }
         $type = $this->variablesType($reflections);
     } elseif ($node instanceof Expr\ClassConstFetch) {
         // TODO ::class
         $reflections = [];
         if ($node->class instanceof Name) {
             $reflections = $this->findClassConsts(Type::object_(Type::nameToString($node->class)), (string) $node->name);
         }
         $type = $this->constsType($reflections);
     } elseif ($node instanceof Expr\ArrayDimFetch) {
         $arrayType = $node->var->getAttribute('type');
         $altTypes = [$arrayType];
         if ($arrayType instanceof AlternativesType) {
             $altTypes = $arrayType->getAlternatives();
         }
         $types = [];
         foreach ($altTypes as $altType) {
             if ($altType instanceof ArrayType) {
                 $types[] = $altType->getValueType();
             } elseif ($altType instanceof ObjectType) {
                 $types[] = $this->functionsReturnType($this->findMethods($altType, 'offsetGet'));
                 // TODO: check for ArrayAccess
             }
         }
         $type = $types !== [] ? Type::alternatives($types) : Type::mixed_();
     } elseif ($node instanceof Expr\Array_) {
         $type = Type::array_();
     } elseif ($node instanceof Expr\New_) {
         if ($node->class instanceof Name) {
             $type = Type::object_(Type::nameToString($node->class));
         } else {
             $type = Type::object_();
         }
     } elseif ($node instanceof Expr\Clone_) {
         $type = $node->expr->getAttribute('type');
     } elseif ($node instanceof Expr\Closure) {
         $type = Type::object_('\\Closure');
     } elseif ($node instanceof Expr\Cast\Array_) {
         $exprType = $node->expr->getAttribute('type');
         $altTypes = [$exprType];
         if ($exprType instanceof AlternativesType) {
             $altTypes = $exprType->getAlternatives();
         }
         $types = [];
         foreach ($altTypes as $altType) {
             if ($altType instanceof ArrayType) {
                 $types[] = $altType;
             } else {
                 $types[] = Type::array_();
                 // TODO primitives: (array)int --> int[]
             }
         }
         $type = $types !== [] ? Type::alternatives($types) : Type::mixed_();
     } elseif ($node instanceof Expr\Cast\Object_) {
         $exprType = $node->expr->getAttribute('type');
         $altTypes = [$exprType];
         if ($exprType instanceof AlternativesType) {
             $altTypes = $exprType->getAlternatives();
         }
         $types = [];
         foreach ($altTypes as $altType) {
             if ($altType instanceof ObjectType) {
                 $types[] = $altType;
             } else {
                 $types[] = Type::object_('\\stdClass');
             }
         }
         $type = $types !== [] ? Type::alternatives($types) : Type::mixed_();
     } elseif ($node instanceof Expr\Include_) {
         $type = Type::mixed_();
         // TODO: Yield_
         // TODO: YieldFrom
     }
     if ($type !== null) {
         $node->setAttribute('type', $type);
     }
     if ($reflections !== null) {
         $node->setAttribute('reflections', $reflections);
     }
 }
Exemple #6
0
 /**
  * @param Node   $node
  * @param string $filePath
  *
  * @return self
  */
 public static function fromNode(Node $node, $filePath)
 {
     return new self(new OffsetLocation($filePath, $node->getAttribute('startFilePos')), new OffsetLocation($filePath, $node->getAttribute('endFilePos')));
 }
Exemple #7
0
 /**
  * @param Method|Property                $member
  * @param Stmt\ClassMethod|Stmt\Property $node
  * @param ClassLike                      $class  Class member is defined in.
  *
  * @return 
  */
 protected function processMember($member, Node $node, ClassLike $class)
 {
     $member->setAccessibility($node->isPrivate() ? ClassLike::M_PRIVATE : ($node->isProtected() ? ClassLike::M_PROTECTED : ClassLike::M_PUBLIC));
     $member->setStatic($node->isStatic());
     $member->setClass($class);
 }