diff --git a/src/Complete/CompleteEngine.php b/src/Complete/CompleteEngine.php index 6cd3511..5345d90 100644 --- a/src/Complete/CompleteEngine.php +++ b/src/Complete/CompleteEngine.php @@ -129,20 +129,25 @@ protected function processFileContent(Project $project, $lines, $line, $file){ $this->indexProcessor->clearResultNodes(); $parser = $this->parser; $parser->addProcessor($this->indexProcessor); - $nodes = $parser->parseContent($fqcn, $file, $content); + $nodes = $parser->parseContent($file, $content); $this->generator->processFileNodes( $project->getIndex(), $nodes ); + /** @var \Entity\Node\Uses */ + $uses = $parser->getUses(); $this->scopeProcessor->setIndex($project->getIndex()); $this->scopeProcessor->setLine($line); $this->scopeProcessor->clearResultNodes(); $parser->addProcessor($this->scopeProcessor); - $scopeNodes = $parser->parseContent($fqcn, $file, $content); + $scopeNodes = $parser->parseContent($file, $content, $uses); $contentHash = hash('sha1', $content); $this->cachePool[$file] = [$contentHash, $nodes, $scopeNodes]; } - return $scopeNodes[0]; + if(count($scopeNodes)){ + return $scopeNodes[0]; + } + return null; } private function isValidCache($file, $content){ @@ -151,7 +156,9 @@ private function isValidCache($file, $content){ return $hash === $contentHash; } + /** @var Parser */ private $parser; + /** @property IndexGenerator */ private $generator; private $contextResolver; private $completerFactory; diff --git a/src/Entity/FQCN.php b/src/Entity/FQCN.php index ecaec8a..1c692c8 100644 --- a/src/Entity/FQCN.php +++ b/src/Entity/FQCN.php @@ -35,6 +35,10 @@ public function __construct($className, $namespace = "", $isArray=false){ } $this->addPart($className); } + + /** + * @inheritdoc + */ public function join(FQN $join){ $result = new self($join->getLast()); $resultParts = $this->getParts(); diff --git a/src/Entity/FQN.php b/src/Entity/FQN.php index 3236d41..67048c7 100644 --- a/src/Entity/FQN.php +++ b/src/Entity/FQN.php @@ -20,6 +20,12 @@ public function __construct($namespace = ""){ $this->parts = []; } } + + /** + * Joins FQN to the clone of the current FQN and returns it + * + * @return FQN + */ public function join(FQN $join){ $result = new self(); $resultParts = $this->getParts(); diff --git a/src/Entity/Node/ClassData.php b/src/Entity/Node/ClassData.php index 92b2bf4..8e813aa 100644 --- a/src/Entity/Node/ClassData.php +++ b/src/Entity/Node/ClassData.php @@ -53,6 +53,17 @@ public function getName(){ } public function setParent($parent){ $this->parent = $parent; + if($parent instanceof ClassData){ + foreach($this->methods->all() as $method){ + if($method->doc === Comment::INHERIT_MARK){ + $parentMethod = $parent->methods->get($method->name); + if($parentMethod instanceof MethodData){ + $method->doc = $parentMethod->doc; + $method->setReturn($parentMethod->getReturn()); + } + } + } + } } public function addInterface($interface){ $fqcn = $interface instanceof InterfaceData ? $interface->fqcn : $interface; diff --git a/src/Entity/Node/Comment.php b/src/Entity/Node/Comment.php index 2ccf6f2..e2c3489 100644 --- a/src/Entity/Node/Comment.php +++ b/src/Entity/Node/Comment.php @@ -7,13 +7,13 @@ use Entity\Node\Variable; class Comment { + const INHERIT_MARK = 'inheritdoc'; public function __construct($doc){ $this->doc = $doc; } public function addVar(Variable $var){ $this->vars[$var->getName()] = $var; - } public function addProperty(ClassProperty $prop){ $this->properties[$prop->name] = $prop; @@ -55,7 +55,7 @@ public function getVar($name){ if(array_key_exists($name, $this->vars)){ $var = $this->vars[$name]; } - if($var instanceof Variable && array_key_exists('', $this->vars)){ + if(!$var instanceof Variable && array_key_exists('', $this->vars)){ $var = $this->vars['']; } return $var; @@ -69,10 +69,17 @@ public function getReturn(){ public function getDoc(){ return $this->doc; } + public function markInheritDoc(){ + $this->inheritDoc = true; + } + public function isInheritDoc(){ + return $this->inheritDoc; + } private $return; private $doc = ""; private $vars = []; private $throws = []; private $properties = []; + private $inheritDoc = false; } diff --git a/src/Entity/Node/MethodData.php b/src/Entity/Node/MethodData.php index d02cc6d..256f30b 100644 --- a/src/Entity/Node/MethodData.php +++ b/src/Entity/Node/MethodData.php @@ -53,7 +53,7 @@ public function getReturnStr(){ public function getReturn(){ return $this->return; } - public function setReturn(FQCN $fqcn){ + public function setReturn(FQCN $fqcn = null){ $this->return = $fqcn; } public function isPublic() { diff --git a/src/Generator/IndexGenerator.php b/src/Generator/IndexGenerator.php index de8c747..be61013 100644 --- a/src/Generator/IndexGenerator.php +++ b/src/Generator/IndexGenerator.php @@ -113,8 +113,9 @@ public function generateProjectIndex(Index $index){ $all = count($classMap); foreach($index->getClassMap() as $fqcn => $file) { $start = microtime(1); - $this->processFile($index, $fqcn, $file, false, false); + $this->processFile($index, $file, false, false); $end = microtime(1) - $start; + $this->getLogger()->addDebug("Indexing: [$end]s"); $this->getLogger()->addDebug("Memory: ". memory_get_usage()); $globalTime += $end; @@ -126,16 +127,11 @@ public function generateProjectIndex(Index $index){ gc_enable(); } - public function processFile(Index $index, $fqcn, $file, + public function processFile(Index $index, $file, $rewrite=false, $createCache=true ){ $this->getLogger() ->addInfo("processing $file"); - - $fqcn = $this->getClassUtils()->getParser() - ->parseFQCN($fqcn); - $this->getLogger() - ->addInfo(sprintf("FQCN: %s", $fqcn->toString())); if($index->isParsed($file) && !$rewrite){ return; } @@ -145,7 +141,7 @@ public function processFile(Index $index, $fqcn, $file, $parser = $this->getClassUtils()->getParser(); $parser->addProcessor($processor); $nodes = $this->getClassUtils()->getParser() - ->parseFile($fqcn, $file, $createCache); + ->parseFile($file, null, $createCache); $end = microtime(1) - $startParser; $this->getLogger() ->addInfo("Parsing: [$end]s"); diff --git a/src/Parser/CommentParser.php b/src/Parser/CommentParser.php index 5e6f4cd..50ee93c 100644 --- a/src/Parser/CommentParser.php +++ b/src/Parser/CommentParser.php @@ -15,6 +15,7 @@ class CommentParser { public function __construct(UseParser $useParser){ $this->useParser = $useParser; } + /** * Parses DocComment block * @@ -66,6 +67,9 @@ protected function parseDoc(Comment $comment, $text){ $this->createProperty($tag) ); break; + case "inheritdoc": + $comment->markInheritDoc(); + break; } } } diff --git a/src/Parser/MethodParser.php b/src/Parser/MethodParser.php index 0144018..05e728b 100644 --- a/src/Parser/MethodParser.php +++ b/src/Parser/MethodParser.php @@ -4,6 +4,7 @@ use Entity\Node\MethodData; use Entity\Node\MethodParam; +use Entity\Node\Comment; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Param; use PhpParser\Node\Name; @@ -39,15 +40,20 @@ public function parse(ClassMethod $node) $method->setType($node->type); $comments = $node->getAttribute("comments"); if(is_array($comments)){ - /** @var \Entity\Node\Comment $comment */ + /** @var Comment */ $comment = $this->commentParser->parse( $comments[count($comments)-1]->getText() ); - $method->doc = $comment->getDoc(); - $method->return = $comment->getReturn(); - foreach($comment->getVars() as $var){ - if($var instanceof MethodParam){ - $method->addParam($var); + if($comment->isInheritDoc()){ + $method->doc = Comment::INHERIT_MARK; + } + else { + $method->doc = $comment->getDoc(); + $method->return = $comment->getReturn(); + foreach($comment->getVars() as $var){ + if($var instanceof MethodParam){ + $method->addParam($var); + } } } } diff --git a/src/Parser/Parser.php b/src/Parser/Parser.php index aac06ac..7157797 100644 --- a/src/Parser/Parser.php +++ b/src/Parser/Parser.php @@ -3,7 +3,6 @@ namespace Parser; use Entity\FQN; -use Entity\FQCN; use Entity\Node\Uses; use Utils\PathResolver; use PhpParser\Parser AS ASTGenerator; @@ -30,12 +29,12 @@ public function __construct( $this->astPool = []; $this->logger = $logger; } - public function parseFile(FQN $fqcn, $file, $createCache=true){ + public function parseFile($file, Uses $uses = null, $createCache=true){ $file = $this->path->getAbsolutePath($file); $content = $this->path->read($file); - return $this->parseContent($fqcn, $file, $content, $createCache); + return $this->parseContent($file, $content, $uses, $createCache); } - public function parseContent(FQN $fqcn, $file, $content, $createCache=true){ + public function parseContent($file, $content, Uses $uses = null, $createCache=true){ if($createCache){ $hash = hash('md5', $content); if(!array_key_exists($file, $this->astPool)){ @@ -43,12 +42,8 @@ public function parseContent(FQN $fqcn, $file, $content, $createCache=true){ } list($oldHash, $ast) = $this->astPool[$file]; } - if($fqcn instanceof FQCN){ - $uses = new Uses($this->parseFQCN($fqcn->getNamespace())); - } - else { - $uses = new Uses($fqcn); - $fqcn = new FQCN('', $fqcn->getParts()); + if(!$uses instanceof Uses){ + $uses = new Uses(new FQN); } $this->setUses($uses); $this->setFileInfo($uses, $file); @@ -77,9 +72,13 @@ public function parseContent(FQN $fqcn, $file, $content, $createCache=true){ return $nodes; } public function setUses(Uses $uses){ + $this->uses = $uses; $this->useParser->setUses($uses); $this->namespaceParser->setUses($uses); } + public function getUses(){ + return $this->uses; + } public function parseFQCN($fqcn){ return $this->useParser->parseFQCN($fqcn); } @@ -121,4 +120,5 @@ protected function setFileInfo(Uses $uses, $file){ /** @var NamespaceParser */ private $namespaceParser; private $useParser; + private $uses; } diff --git a/src/Parser/Processor/ScopeProcessor.php b/src/Parser/Processor/ScopeProcessor.php index af3afd9..cca235b 100644 --- a/src/Parser/Processor/ScopeProcessor.php +++ b/src/Parser/Processor/ScopeProcessor.php @@ -22,7 +22,6 @@ use PhpParser\Node\Expr\Assign; use PhpParser\Node\Stmt\Use_; use PhpParser\Node\Stmt\Class_; -use PhpParser\Node\Stmt\Namespace_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Expr\Closure; @@ -31,15 +30,13 @@ public function __construct( UseParser $useParser, NodeTypeResolver $typeResolver, CommentParser $commentParser, - ParamParser $paramParser, - NamespaceParser $namespaceParser + ParamParser $paramParser ){ $this->resultNodes = []; $this->useParser = $useParser; $this->typeResolver = $typeResolver; $this->commentParser = $commentParser; $this->paramParser = $paramParser; - $this->namespaceParser = $namespaceParser; } public function setLine($line){ $this->line = $line; @@ -52,9 +49,6 @@ public function enterNode(Node $node){ if($node instanceof Class_){ $this->createScopeFromClass($node); } - elseif($node instanceof Namespace_){ - $this->namespaceParser->parse($node); - } elseif($node instanceof ClassMethod){ $this->createScopeFromMethod($node); } @@ -204,5 +198,4 @@ protected function createScope(){ private $commentParser; /** @property ParamParser */ private $paramParser; - private $namespaceParser; }