Skip to content

Commit f8e647c

Browse files
committed
added CommentParser class and comment parsing for methods
1 parent 3df7a74 commit f8e647c

9 files changed

Lines changed: 231 additions & 23 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
use Parser\CommentParser;
4+
use Parser\UseParser;
5+
use Entity\Node\Comment;
6+
use Entity\Node\Uses;
7+
use Entity\FQCN;
8+
9+
describe('CommentParser', function(){
10+
beforeEach(function(){
11+
$this->useParser = new UseParser;
12+
$this->useParser->setUses(
13+
new Uses(
14+
$this->useParser->parseFQCN('Entity\Node')
15+
)
16+
);
17+
$this->parser = new CommentParser($this->useParser);
18+
$this->simpleDoc = <<<'DOCBLOCK'
19+
/**
20+
* This is a short description
21+
*
22+
* This is a long description
23+
*
24+
* @param MethodParam $myParamName A test param
25+
* @param Comment $anotherParam
26+
* @throws \Exception
27+
* @return Comment
28+
*/
29+
DOCBLOCK;
30+
$this->comment = $this->parser->parse($this->simpleDoc);
31+
});
32+
describe('parse()', function(){
33+
it('returns Comment', function(){
34+
$result = $this->comment;
35+
expect($result)->to->be->an->instanceof(Comment::class);
36+
});
37+
it('creates vars for all params', function(){
38+
$comment = $this->comment;
39+
expect(count($comment->getVars()))->to->equal(2);
40+
});
41+
it('creates return FQCN', function(){
42+
$comment = $this->comment;
43+
expect($comment->getReturn())->to->be->an->instanceof(FQCN::class);
44+
expect($comment->getReturn()->toString())->to->equal('Entity\Node\Comment');
45+
});
46+
});
47+
describe('createMethodParam()', function(){
48+
it('sets var name', function(){
49+
$comment = $this->comment;
50+
$var = array_shift($comment->getVars());
51+
expect($var->getName())->to->equal('myParamName');
52+
});
53+
it('sets var type', function(){
54+
$comment = $this->comment;
55+
$var = array_pop($comment->getVars());
56+
expect($var->getType())->to->be->an->instanceof(FQCN::class);
57+
expect($var->getType()->toString())->to->equal(
58+
'Entity\Node\Comment'
59+
);
60+
});
61+
});
62+
describe('trimComment()', function(){
63+
it('removes * and spaces', function(){
64+
$result = $this->comment;
65+
$trimmedDoc = <<<'DOCBLOCK'
66+
67+
This is a short description
68+
69+
This is a long description
70+
71+
@param MethodParam $myParamName A test param
72+
@param Comment $anotherParam
73+
@throws \Exception
74+
@return Comment
75+
76+
DOCBLOCK;
77+
expect($result->getDoc())->to->equal($trimmedDoc);
78+
});
79+
});
80+
});

src/Complete/Completer/ObjectCompleter.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
use Entity\Completion\Context;
77
use Entity\Completion\Entry;
88
use Entity\Completion\Scope;
9+
use Psr\Log\LoggerInterface;
910

1011
class ObjectCompleter {
12+
public function __construct(LoggerInterface $logger){
13+
$this->logger = $logger;
14+
}
1115
public function getEntries(Project $project, Context $context, Scope $scope){
1216
if($context->isThis()){
1317
return $this->getEntriesForThis($project, $context, $scope);
@@ -33,6 +37,7 @@ protected function getEntriesForVar(
3337
if(empty($fqcn)){
3438
return [];
3539
}
40+
$this->logger->addDebug('Creating completion for ' . $fqcn->toString());
3641
$class = $index->findClassByFQCN($fqcn);
3742
$entries = [];
3843
foreach($class->methods->all() AS $method){
@@ -72,4 +77,6 @@ protected function getEntriesForThis(
7277
}
7378
return $entries;
7479
}
80+
81+
private $logger;
7582
}

src/Entity/Node/Comment.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Entity\Node;
4+
5+
use Entity\FQCN;
6+
7+
class Comment {
8+
private $return;
9+
private $doc = "";
10+
private $vars = [];
11+
private $throws = [];
12+
public function __construct($doc){
13+
$this->doc = $doc;
14+
}
15+
public function addVar(Variable $var){
16+
$this->vars[$var->getName()] = $var;
17+
}
18+
public function getVars(){
19+
return $this->vars;
20+
}
21+
public function setReturn(FQCN $fqcn){
22+
$this->return = $fqcn;
23+
}
24+
public function getReturn(){
25+
return $this->return;
26+
}
27+
public function getDoc(){
28+
return $this->doc;
29+
}
30+
}

src/Entity/Node/MethodData.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@ public function getParamsStr(){
3030
$paramsStr = [];
3131
foreach($this->arguments as $argument){
3232
$curParam = [];
33-
if($argument->type){
34-
$curParam[] = $argument->type;
33+
if($argument->getType()){
34+
$curParam[] = $argument->getType();
3535
}
36-
$curParam[] = sprintf("$%s", $argument->name);
36+
$curParam[] = sprintf("$%s", $argument->getName());
3737
$paramsStr[] = implode(" ", $curParam);
3838
}
3939
return implode(", ", $paramsStr);
4040
}
4141
public function getReturn(){
42+
if($this->return instanceof FQCN){
43+
return $this->return->toString();
44+
}
4245
return "none";
4346
}
4447
public function isPublic() {

src/Entity/Node/MethodParam.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
namespace Entity\Node;
44

5-
class MethodParam {
6-
public $name = "";
7-
public $type = "";
5+
class MethodParam extends Variable {
86
public $default = "";
97
}

src/Entity/Node/Variable.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ public function getFQCN(){
1515
public function setFQCN($fqcn){
1616
$this->fqcn = $fqcn;
1717
}
18+
public function setType($fqcn){
19+
$this->setFQCN($fqcn);
20+
}
21+
public function getType(){
22+
return $this->getFQCN();
23+
}
1824
private $name;
1925
private $fqcn;
2026
}

src/Parser/CommentParser.php

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,90 @@
22

33
namespace Parser;
44

5-
class CommentParser {
5+
use phpDocumentor\Reflection\DocBlock;
6+
use phpDocumentor\Reflection\DocBlock\Tag;
7+
use Entity\Node\Comment;
8+
use Entity\Node\MethodParam;
9+
use Entity\Node\Variable;
610

7-
private $docCommentParser;
11+
class CommentParser {
812

9-
public function __construct($docCommentParser = null){
10-
$this->docCommentParser = $docCommentParser;
13+
public function __construct(UseParser $useParser){
14+
$this->useParser = $useParser;
1115
}
16+
/**
17+
* Parses DocComment block
18+
*
19+
* @param string $doc
20+
* @return Comment
21+
*/
1222
public function parse($doc){
23+
$text = $doc;
1324
if(is_array($doc)){
1425
$doc = array_shift($doc);
15-
return $doc->getText();
26+
$text = $doc->getText();
27+
}
28+
$comment = new Comment(
29+
$this->trimComment($text)
30+
);
31+
$this->parseDoc($comment, $text);
32+
33+
return $comment;
34+
}
35+
36+
/**
37+
* This is a method description
38+
*
39+
* @param string $text
40+
* @return DocBlock
41+
*/
42+
protected function parseDoc(Comment $comment, $text){
43+
$block = new DocBlock($text);
44+
foreach($block->getTags() AS $tag){
45+
switch($tag->getName()){
46+
case "param":
47+
$comment->addVar(
48+
$this->createMethodParam($tag)
49+
);
50+
break;
51+
case "var":
52+
$comment->addVar(
53+
$this->createVar($tag)
54+
);
55+
break;
56+
case "return":
57+
$comment->setReturn(
58+
$this->getFQCN($tag->getType())
59+
);
60+
break;
61+
}
1662
}
17-
return $doc;
63+
}
64+
protected function createMethodParam(Tag $tag){
65+
$name = trim($tag->getVariableName(), '$');
66+
$param = new MethodParam($name);
67+
$param->setType($this->getFQCN($tag->getType()));
68+
return $param;
69+
}
70+
protected function createVar(Tag $tag){
71+
$name = trim($tag->getVariableName(), '$');
72+
$param = new Variable($name);
73+
return $param;
74+
}
75+
protected function getFQCN($type){
76+
return $this->useParser->parseType($type);
1877
}
1978
protected function trimComment($comment){
2079
$lines = explode("\n", $comment);
2180
foreach($lines AS $key => $line){
2281
$lines[$key] = preg_replace([
2382
"/^\/\**/",
24-
"/^ *\*/"
83+
"/^ *\* */",
84+
"/\**\/$/"
2585
], "", $line);
2686
}
87+
return implode("\n", $lines);
2788
}
89+
90+
private $useParser;
2891
}

src/Parser/MethodParser.php

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@
99
use PhpParser\Node\Name;
1010

1111
class MethodParser{
12-
/** @var $useParser UseParser */
13-
private $useParser;
1412

1513
/**
1614
* Constructs
15+
*
16+
* @param UseParser $useParser
1717
*/
18-
public function __construct(UseParser $useParser)
18+
public function __construct(
19+
UseParser $useParser,
20+
CommentParser $commentParser
21+
)
1922
{
20-
$this->useParser = $useParser;
23+
$this->useParser = $useParser;
24+
$this->commentParser = $commentParser;
2125
}
2226

2327
/**
@@ -37,18 +41,26 @@ public function parse(ClassMethod $node)
3741
$method->addParam($this->parseMethodArgument($child));
3842
}
3943
}
40-
if(is_array($comments))
41-
$method->doc = $comments[count($comments)-1]->getText();
44+
if(is_array($comments)){
45+
$comment = $this->commentParser->parse(
46+
$comments[count($comments)-1]->getText()
47+
);
48+
$method->doc = $comment->getDoc();
49+
$method->return = $comment->getReturn();
50+
}
4251
return $method;
4352
}
4453
protected function parseMethodArgument(Param $node){
45-
$param = new MethodParam();
46-
$param->name = $node->name;
54+
$param = new MethodParam($node->name);
4755
if($node->type instanceof Name)
48-
$param->type = $this->useParser->getFQCN($node->type);
56+
$param->setFQCN($this->useParser->getFQCN($node->type));
4957
else{
50-
$param->type = $node->type;
58+
$param->setType($node->type);
5159
}
5260
return $param;
5361
}
62+
63+
/** @var $useParser UseParser */
64+
private $useParser;
65+
private $commentParser;
5466
}

src/Parser/UseParser.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ public function parse(Use_ $node){
1616
$this->uses->add($fqcn, $use->alias);
1717
}
1818
}
19+
public function parseType($type){
20+
$fqcn = $this->uses->find($type);
21+
if(!empty($fqcn)){
22+
return $fqcn;
23+
}
24+
return $this->uses->getFQCN()->join(
25+
$this->parseFQCN($type)
26+
);
27+
}
1928
public function getFQCN(Name $node = null){
2029
if($node === null)
2130
return $node;

0 commit comments

Comments
 (0)