/** * @param Element $element * @param Node $node */ protected function init(Element $element, Node $node) { $element->setName($node->hasAttribute('namespacedName') ? Type::nameToString($node->getAttribute('namespacedName')) : $node->name); if ($node->hasAttribute('startFilePos')) { $element->setLocation(new OffsetLocation($this->path, $node->getAttribute('startFilePos'))); } }
/** * @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 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; }
public function enterNode(Node $node) { if (!$node instanceof Stmt\Property) { $annotations = []; if ($node->hasAttribute('annotations')) { $annotations = $node->getAttribute('annotations'); } if (!empty($annotations['var'])) { foreach ($annotations['var'] as $varTag) { $name = $varTag->getIdentifier(); if (empty($name)) { $var = $node; if ($var instanceof Stmt\Foreach_) { $var = $var->valueVar; } elseif ($var instanceof Stmt\For_) { $var = $var->init; } elseif ($var instanceof Stmt\Global_ && count($var->vars) === 1) { $var = $var->vars[0]; } if ($var instanceof Expr\Assign || $var instanceof Expr\AssignRef || $var instanceof Expr\AssignOp) { $var = $var->var; } if ($var instanceof Expr\Variable && is_string($var->name)) { $name = '$' . $var->name; } } if (!empty($name)) { $this->getCurrentFunctionScope()[$name] = $varTag->getType(); } } } } if ($node instanceof Name) { $self = $this->getCurrentClass(); if (!empty($self) && !empty($self->getClass())) { $resolved = null; // Treating `static` as `self` is the best we can do here. if ($node->toString() === 'self' || $node->toString() === 'static') { $resolved = $self->getClass(); } elseif ($node->toString() === 'parent') { $selfClass = $this->reflection->findClass($self->getClass()); if (!empty($selfClass) && $selfClass[0] instanceof Class_ && !empty($selfClass[0]->getExtends())) { $resolved = $selfClass[0]->getExtends(); } } if (!empty($resolved)) { $node->setAttribute('resolved', new Name\FullyQualified(ltrim($resolved, '\\'), $node->getAttributes())); } } } elseif ($node instanceof Stmt\Function_) { $scope = []; $functions = $this->reflection->findFunction($node->hasAttribute('namespacedName') ? Type::nameToString($node->getAttribute('namespacedName')) : $node->name); if (!empty($functions)) { foreach ($functions[0]->getParams() as $param) { $scope[$param->getName()] = $param->getDocType(); } } $this->functionScopeStack[] = $scope; } elseif ($node instanceof Stmt\ClassMethod) { $scope = []; $class = $this->getCurrentClass(); if (!empty($class) && !empty($class->getClass())) { $method = $this->reflection->findMethod($class->getClass(), $node->name); if (!empty($method)) { foreach ($method->getParams() as $param) { $scope[$param->getName()] = $param->getDocType(); } } } $this->functionScopeStack[] = $scope; } elseif ($node instanceof Expr\Closure) { $scope = []; $parentScope =& $this->getCurrentFunctionScope(); foreach ($node->uses as $use) { if (array_key_exists('$' . $use->var, $parentScope)) { $scope['$' . $use->var] = $parentScope['$' . $use->var]; } } foreach ($node->params as $param) { $scope['$' . $param->name] = Type::fromString(Type::nameToString($param->type)); } $this->functionScopeStack[] = $scope; } elseif ($node instanceof Stmt\ClassLike) { $className = $node->hasAttribute('namespacedName') ? Type::nameToString($node->getAttribute('namespacedName')) : $node->name; $this->classStack[] = Type::object_($className); // for isolation, in case of illegal statements in class def: $this->functionScopeStack[] = []; } }
/** * @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'))); }