Skip to content

Commit aae15e8

Browse files
committed
Introduce DocBlock classes for code generation
1 parent 450a8b6 commit aae15e8

9 files changed

+584
-0
lines changed

src/Code/DocBlock/DocBlock.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/**
4+
* @see https://github.com/open-code-modeling/php-code-ast for the canonical source repository
5+
* @copyright https://github.com/open-code-modeling/php-code-ast/blob/master/COPYRIGHT.md
6+
* @license https://github.com/open-code-modeling/php-code-ast/blob/master/LICENSE.md MIT License
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace OpenCodeModeling\CodeAst\Code\DocBlock;
12+
13+
use OpenCodeModeling\CodeAst\Code\DocBlock\Tag\Tag;
14+
15+
final class DocBlock
16+
{
17+
/**
18+
* @var string
19+
*/
20+
protected $comment;
21+
22+
/**
23+
* @var Tag[]
24+
*/
25+
protected $tags;
26+
27+
public function __construct(?string $comment, Tag ...$tags)
28+
{
29+
$this->setComment($comment);
30+
$this->tags = $tags;
31+
}
32+
33+
public function setComment(?string $comment): self
34+
{
35+
$this->comment = $comment;
36+
37+
return $this;
38+
}
39+
40+
public function getComment(): ?string
41+
{
42+
return $this->comment;
43+
}
44+
45+
public function addTag(Tag ...$tags): self
46+
{
47+
foreach ($tags as $tag) {
48+
$this->tags[] = $tag;
49+
}
50+
51+
return $this;
52+
}
53+
54+
public function generate(): string
55+
{
56+
$comment = "/**\n";
57+
58+
if ($this->comment) {
59+
$comment .= ' * ' . \trim(\preg_replace("/\n/", "\n * ", $this->comment)) . "\n *\n";
60+
}
61+
62+
foreach ($this->tags as $tag) {
63+
$comment .= ' * ' . $tag->generate() . "\n";
64+
}
65+
66+
return \preg_replace("/ \* \n/", " *\n", $comment) . "\n */";
67+
}
68+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
/**
4+
* @see https://github.com/open-code-modeling/php-code-ast for the canonical source repository
5+
* @copyright https://github.com/open-code-modeling/php-code-ast/blob/master/COPYRIGHT.md
6+
* @license https://github.com/open-code-modeling/php-code-ast/blob/master/LICENSE.md MIT License
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace OpenCodeModeling\CodeAst\Code\DocBlock\Tag;
12+
13+
/**
14+
* Code is largely lifted from the Zend\Code\Generator\DocBlock\Tag\AbstractTypeableTag implementation in
15+
* Zend Code, released with the copyright and license below. It is modified to work with PHP AST.
16+
*
17+
* @see https://github.com/zendframework/zend-code for the canonical source repository
18+
* @copyright Copyright (c) 2005-2019 Zend Technologies USA Inc. (http://www.zend.com)
19+
* @license https://github.com/zendframework/zend-code/blob/master/LICENSE.md New BSD License
20+
*
21+
* This abstract class can be used as parent for all tags
22+
* that use a type part in their content.
23+
*
24+
* @see http://www.phpdoc.org/docs/latest/for-users/phpdoc/types.html
25+
* @internal
26+
*/
27+
abstract class AbstractTypeableTag implements Tag
28+
{
29+
/**
30+
* @var string
31+
*/
32+
protected $description;
33+
34+
/**
35+
* @var array
36+
*/
37+
protected $types = [];
38+
39+
/**
40+
* @param string|string[] $types
41+
* @param string $description
42+
*/
43+
public function __construct($types = [], ?string $description = null)
44+
{
45+
if (! empty($types)) {
46+
$this->setTypes($types);
47+
}
48+
49+
if (! empty($description)) {
50+
$this->setDescription($description);
51+
}
52+
}
53+
54+
public function setDescription(string $description): self
55+
{
56+
$this->description = $description;
57+
58+
return $this;
59+
}
60+
61+
public function getDescription(): ?string
62+
{
63+
return $this->description;
64+
}
65+
66+
/**
67+
* Array of types or string with types delimited by pipe (|)
68+
* e.g. array('int', 'null') or "int|null"
69+
*
70+
* @param array|string $types
71+
* @return AbstractTypeableTag
72+
*/
73+
public function setTypes($types): self
74+
{
75+
if (\is_string($types)) {
76+
$types = \explode('|', $types);
77+
}
78+
$this->types = $types;
79+
80+
return $this;
81+
}
82+
83+
/**
84+
* @return array
85+
*/
86+
public function getTypes(): array
87+
{
88+
return $this->types;
89+
}
90+
91+
/**
92+
* @param string $delimiter
93+
* @return string
94+
*/
95+
public function getTypesAsString($delimiter = '|'): string
96+
{
97+
return \implode($delimiter, $this->types);
98+
}
99+
}

src/Code/DocBlock/Tag/GenericTag.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
/**
4+
* @see https://github.com/open-code-modeling/php-code-ast for the canonical source repository
5+
* @copyright https://github.com/open-code-modeling/php-code-ast/blob/master/COPYRIGHT.md
6+
* @license https://github.com/open-code-modeling/php-code-ast/blob/master/LICENSE.md MIT License
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace OpenCodeModeling\CodeAst\Code\DocBlock\Tag;
12+
13+
/**
14+
* Code is largely lifted from the Zend\Code\Generator\DocBlock\Tag\GenericTag implementation in
15+
* Zend Code, released with the copyright and license below. It is modified to work with PHP AST.
16+
*
17+
* @see https://github.com/zendframework/zend-code for the canonical source repository
18+
* @copyright Copyright (c) 2005-2019 Zend Technologies USA Inc. (http://www.zend.com)
19+
* @license https://github.com/zendframework/zend-code/blob/master/LICENSE.md New BSD License
20+
*/
21+
final class GenericTag implements Tag
22+
{
23+
/**
24+
* @var string
25+
*/
26+
protected $name;
27+
28+
/**
29+
* @var string
30+
*/
31+
protected $content;
32+
33+
public function __construct(?string $name = null, ?string $content = null)
34+
{
35+
if (! empty($name)) {
36+
$this->setName($name);
37+
}
38+
39+
if (! empty($content)) {
40+
$this->setContent($content);
41+
}
42+
}
43+
44+
/**
45+
* @param string $name
46+
* @return GenericTag
47+
*/
48+
public function setName($name): self
49+
{
50+
$this->name = \ltrim($name, '@');
51+
52+
return $this;
53+
}
54+
55+
/**
56+
* @return string
57+
*/
58+
public function getName(): string
59+
{
60+
return $this->name;
61+
}
62+
63+
/**
64+
* @param string $content
65+
* @return GenericTag
66+
*/
67+
public function setContent($content): self
68+
{
69+
$this->content = $content;
70+
71+
return $this;
72+
}
73+
74+
/**
75+
* @return string
76+
*/
77+
public function getContent(): string
78+
{
79+
return $this->content;
80+
}
81+
82+
/**
83+
* @return string
84+
*/
85+
public function generate(): string
86+
{
87+
$output = '@' . $this->name
88+
. (! empty($this->content) ? ' ' . $this->content : '');
89+
90+
return $output;
91+
}
92+
}

src/Code/DocBlock/Tag/MethodTag.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
/**
4+
* @see https://github.com/open-code-modeling/php-code-ast for the canonical source repository
5+
* @copyright https://github.com/open-code-modeling/php-code-ast/blob/master/COPYRIGHT.md
6+
* @license https://github.com/open-code-modeling/php-code-ast/blob/master/LICENSE.md MIT License
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace OpenCodeModeling\CodeAst\Code\DocBlock\Tag;
12+
13+
/**
14+
* Code is largely lifted from the Zend\Code\Generator\DocBlock\Tag\MethodTag implementation in
15+
* Zend Code, released with the copyright and license below. It is modified to work with PHP AST.
16+
*
17+
* @see https://github.com/zendframework/zend-code for the canonical source repository
18+
* @copyright Copyright (c) 2005-2019 Zend Technologies USA Inc. (http://www.zend.com)
19+
* @license https://github.com/zendframework/zend-code/blob/master/LICENSE.md New BSD License
20+
*/
21+
final class MethodTag extends AbstractTypeableTag
22+
{
23+
/**
24+
* @var string
25+
*/
26+
protected $methodName;
27+
28+
/**
29+
* @var bool
30+
*/
31+
protected $isStatic = false;
32+
33+
public function __construct(
34+
?string $methodName = null,
35+
array $types = [],
36+
?string $description = null,
37+
bool $isStatic = false
38+
) {
39+
if (! empty($methodName)) {
40+
$this->setMethodName($methodName);
41+
}
42+
43+
$this->setIsStatic((bool) $isStatic);
44+
45+
parent::__construct($types, $description);
46+
}
47+
48+
/**
49+
* @return string
50+
*/
51+
public function getName(): string
52+
{
53+
return 'method';
54+
}
55+
56+
/**
57+
* @param bool $isStatic
58+
* @return MethodTag
59+
*/
60+
public function setIsStatic($isStatic): self
61+
{
62+
$this->isStatic = $isStatic;
63+
64+
return $this;
65+
}
66+
67+
/**
68+
* @return bool
69+
*/
70+
public function isStatic(): bool
71+
{
72+
return $this->isStatic;
73+
}
74+
75+
/**
76+
* @param string $methodName
77+
* @return MethodTag
78+
*/
79+
public function setMethodName(string $methodName): self
80+
{
81+
$this->methodName = \rtrim($methodName, ')(');
82+
83+
return $this;
84+
}
85+
86+
/**
87+
* @return string
88+
*/
89+
public function getMethodName(): string
90+
{
91+
return $this->methodName;
92+
}
93+
94+
/**
95+
* @return string
96+
*/
97+
public function generate(): string
98+
{
99+
$output = '@method'
100+
. ($this->isStatic ? ' static' : '')
101+
. (! empty($this->types) ? ' ' . $this->getTypesAsString() : '')
102+
. (! empty($this->methodName) ? ' ' . $this->methodName . '()' : '')
103+
. (! empty($this->description) ? ' ' . $this->description : '');
104+
105+
return $output;
106+
}
107+
}

0 commit comments

Comments
 (0)