Example #1
0
 public function getGoToLocations($offset)
 {
     $this->run();
     $nodes = $this->parser->getNodesAtOffset($offset);
     $locations = [];
     foreach ($this->goToComponents as $goto) {
         $locations = array_merge($locations, $goto->getGoToLocations($offset, $nodes));
     }
     return $locations;
 }
Example #2
0
 /**
  * @param string $fqname
  *
  * @return Fix
  */
 private function getFix($fqname)
 {
     if ($this->insertRange === null) {
         $namespace = null;
         foreach (array_reverse($this->nodePathFromTop) as $ancestor) {
             if ($ancestor instanceof Stmt\Namespace_) {
                 $namespace = $ancestor;
                 break;
             }
         }
         $lastUse = null;
         $stmts = $namespace === null ? $this->parser->getNodes() : $namespace->stmts;
         foreach ($stmts as $stmt) {
             if ($stmt instanceof Stmt\Use_ || $stmt instanceof Stmt\GroupUse) {
                 $lastUse = $stmt;
             }
         }
         if ($lastUse !== null) {
             /** @var Range */
             $range = Range::fromNode($lastUse, $this->file->getPath());
             $startLine = $range->getStart()->getLineAndColumn($this->file)[0];
             $insertLocation = OffsetLocation::move($this->file, $range->getEnd());
             $indent = $this->fixHelper->getIndentOfLines([$this->file->getLine($startLine)]);
             $this->insertText = "\n" . $this->fixHelper->makeIndent($indent) . "use %s;";
         } else {
             $insertLocation = LineAndColumnLocation::moveToStartOfLine($this->file, Range::fromNode($stmts[0], $this->file->getPath())->getStart());
             $this->insertText = "use %s;\n\n";
         }
         $this->insertRange = new Range($insertLocation, OffsetLocation::move($this->file, $insertLocation, -1));
     }
     $fqname = ltrim($fqname, '\\');
     return new Fix([new FixChunk($this->insertRange, sprintf($this->insertText, $fqname))], 'use ' . $fqname);
 }
Example #3
0
 public function complete($offset)
 {
     $this->run();
     $nodes = $this->parser->getNodesAtOffset($offset, true);
     $node = null;
     if (count($nodes) > 0) {
         $node = $nodes[0];
         if ($node instanceof Identifier || $node instanceof ErrorNode\Nothing) {
             $node = count($nodes) > 1 ? $nodes[1] : null;
         }
     }
     $completions = [];
     $ctxClass = null;
     foreach ($nodes as $ctxNode) {
         if ($ctxNode instanceof Stmt\ClassLike) {
             $ctxClass = $ctxNode->hasAttribute('namespacedName') ? Type::nameToString($ctxNode->getAttribute('namespacedName')) : $node->name;
             break;
         }
     }
     if ($node instanceof Expr\MethodCall || $node instanceof Expr\PropertyFetch) {
         $methods = $this->findMethods($node->var->getAttribute('type'));
         $properties = $this->findProperties($node->var->getAttribute('type'));
         $methods = $this->reflection->filterAvailableMembers($methods, $ctxClass);
         $properties = $this->reflection->filterAvailableMembers($properties, $ctxClass);
         $completions = array_merge($this->formatMethods($methods), $this->formatProperties($properties));
     } elseif ($node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\ClassConstFetch) {
         // TODO: Support static call on an object: $object::staticMethod() etc.
         // TODO: Filter out non-static members outside the inheritance
         //       chain - while static calls to them are allowed in PHP, they
         //       are pretty useless.
         $staticOnly = true;
         foreach ($nodes as $ctxNode) {
             if ($ctxNode instanceof Stmt\ClassMethod) {
                 $staticOnly = $ctxNode->isStatic();
                 break;
             }
         }
         $methods = $this->findMethods(Type::object_(Type::nameToString($node->class)), $staticOnly);
         $properties = $this->findProperties(Type::object_(Type::nameToString($node->class)), $staticOnly);
         $consts = $this->findClassConsts(Type::object_(Type::nameToString($node->class)));
         $methods = $this->reflection->filterAvailableMembers($methods, $ctxClass);
         $properties = $this->reflection->filterAvailableMembers($properties, $ctxClass);
         $completions = array_merge($this->formatMethods($methods), $this->formatClassConsts($consts), $this->formatProperties($properties, true));
     }
     return $completions;
 }