Skip to content

Commit a4ba8b8

Browse files
committed
Add high level API for methods - Close #17
1 parent 1e117cf commit a4ba8b8

10 files changed

+589
-14
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ $classFactory
2929

3030
$nodeTraverser = new PhpParser\NodeTraverser();
3131

32-
$classFactory->injectVisitors($nodeTraverser);
32+
$classFactory->injectVisitors($nodeTraverser, $parser);
3333

3434
print_r($printer->prettyPrintFile($nodeTraverser->traverse($ast)));
3535
```

src/Builder/ClassBuilder.php

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use PhpParser\Node;
2222
use PhpParser\NodeTraverser;
2323
use PhpParser\NodeVisitor;
24+
use PhpParser\Parser;
2425

2526
final class ClassBuilder
2627
{
@@ -60,6 +61,9 @@ final class ClassBuilder
6061
/** @var ClassPropertyBuilder[] */
6162
private $properties = [];
6263

64+
/** @var ClassMethodBuilder[] */
65+
private $methods = [];
66+
6367
private function __construct()
6468
{
6569
}
@@ -90,9 +94,9 @@ public static function fromScratch(
9094
return $self;
9195
}
9296

93-
public function injectVisitors(NodeTraverser $nodeTraverser): void
97+
public function injectVisitors(NodeTraverser $nodeTraverser, Parser $parser): void
9498
{
95-
foreach ($this->generate() as $visitor) {
99+
foreach ($this->generate($parser) as $visitor) {
96100
$nodeTraverser->addVisitor($visitor);
97101
}
98102
}
@@ -153,6 +157,13 @@ public function setProperties(ClassPropertyBuilder ...$properties): self
153157
return $this;
154158
}
155159

160+
public function setMethods(ClassMethodBuilder ...$methods): self
161+
{
162+
$this->methods = $methods;
163+
164+
return $this;
165+
}
166+
156167
public function getNamespace(): ?string
157168
{
158169
return $this->namespace;
@@ -229,9 +240,18 @@ public function getProperties(): array
229240
}
230241

231242
/**
243+
* @return ClassMethodBuilder[]
244+
*/
245+
public function getMethods(): array
246+
{
247+
return $this->methods;
248+
}
249+
250+
/**
251+
* @param Parser $parser
232252
* @return NodeVisitor[]
233253
*/
234-
public function generate(): array
254+
public function generate(Parser $parser): array
235255
{
236256
/** @var NodeVisitor[] $visitors */
237257
$visitors = [];
@@ -281,6 +301,17 @@ static function (ClassPropertyBuilder $property) {
281301
)
282302
);
283303
}
304+
if (\count($this->methods) > 0) {
305+
\array_push(
306+
$visitors,
307+
...\array_map(
308+
static function (ClassMethodBuilder $method) use ($parser) {
309+
return $method->generate($parser);
310+
},
311+
$this->methods
312+
)
313+
);
314+
}
284315

285316
return $visitors;
286317
}
@@ -348,6 +379,9 @@ static function (Node\Name $name) {
348379
case $node instanceof Node\Stmt\Property:
349380
$this->properties[] = ClassPropertyBuilder::fromNode($node);
350381
break;
382+
case $node instanceof Node\Stmt\ClassMethod:
383+
$this->methods[] = ClassMethodBuilder::fromNode($node);
384+
break;
351385
default:
352386
break;
353387
}

src/Builder/ClassMethodBuilder.php

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
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\Builder;
12+
13+
use OpenCodeModeling\CodeAst\Code\BodyGenerator;
14+
use OpenCodeModeling\CodeAst\Code\ClassConstGenerator;
15+
use OpenCodeModeling\CodeAst\Code\DocBlock\DocBlock;
16+
use OpenCodeModeling\CodeAst\Code\MethodGenerator;
17+
use OpenCodeModeling\CodeAst\NodeVisitor\ClassMethod;
18+
use PhpParser\Node;
19+
use PhpParser\NodeTraverser;
20+
use PhpParser\NodeVisitor;
21+
use PhpParser\Parser;
22+
23+
final class ClassMethodBuilder
24+
{
25+
/** @var string */
26+
private $name;
27+
28+
/** @var ParameterBuilder[] */
29+
private $parameters = [];
30+
31+
/** @var string */
32+
private $body = '';
33+
34+
/** @var string|null */
35+
private $returnType;
36+
37+
/**
38+
* @var int
39+
*/
40+
private $visibility;
41+
42+
/** @var bool */
43+
private $typed = false;
44+
45+
/**
46+
* @var string|null
47+
*/
48+
private $docBlockComment;
49+
50+
/**
51+
* @var string|null
52+
*/
53+
private $returnTypeDocBlockHint;
54+
55+
/**
56+
* @var DocBlock|null
57+
*/
58+
private $docBlock;
59+
60+
private function __construct()
61+
{
62+
}
63+
64+
public static function fromNode(Node\Stmt\ClassMethod $node): self
65+
{
66+
$self = new self();
67+
68+
$self->name = $node->name->toString();
69+
$self->returnType = $node->returnType ? $node->returnType->toString() : null;
70+
$self->visibility = $node->flags;
71+
72+
foreach ($node->params as $param) {
73+
$self->parameters[] = ParameterBuilder::fromNode($param);
74+
}
75+
76+
if ($self->returnType !== null) {
77+
$self->typed = true;
78+
}
79+
80+
return $self;
81+
}
82+
83+
public static function fromScratch(
84+
string $name,
85+
bool $typed = true
86+
): self {
87+
$self = new self();
88+
$self->name = $name;
89+
$self->typed = $typed;
90+
$self->visibility = ClassConstGenerator::FLAG_PUBLIC;
91+
92+
return $self;
93+
}
94+
95+
public function setParameters(ParameterBuilder ...$parameters): self
96+
{
97+
$this->parameters = $parameters;
98+
99+
return $this;
100+
}
101+
102+
public function setBody(string $body): self
103+
{
104+
$this->body = $body;
105+
106+
return $this;
107+
}
108+
109+
public function setReturnType(?string $returnType): self
110+
{
111+
$this->returnType = $returnType;
112+
113+
return $this;
114+
}
115+
116+
public function getName(): string
117+
{
118+
return $this->name;
119+
}
120+
121+
/**
122+
* @return ParameterBuilder[]
123+
*/
124+
public function getParameters(): array
125+
{
126+
return $this->parameters;
127+
}
128+
129+
public function isTyped(): bool
130+
{
131+
return $this->typed;
132+
}
133+
134+
public function setPrivate(): self
135+
{
136+
$this->visibility = ClassConstGenerator::FLAG_PRIVATE;
137+
138+
return $this;
139+
}
140+
141+
public function setProtected(): self
142+
{
143+
$this->visibility = ClassConstGenerator::FLAG_PROTECTED;
144+
145+
return $this;
146+
}
147+
148+
public function setPublic(): self
149+
{
150+
$this->visibility = ClassConstGenerator::FLAG_PUBLIC;
151+
152+
return $this;
153+
}
154+
155+
public function getDocBlockComment(): ?string
156+
{
157+
return $this->docBlockComment;
158+
}
159+
160+
public function setDocBlockComment(?string $docBlockComment): void
161+
{
162+
$this->docBlockComment = $docBlockComment;
163+
}
164+
165+
public function getReturnTypeDocBlockHint(): string
166+
{
167+
return $this->returnTypeDocBlockHint;
168+
}
169+
170+
public function setReturnTypeDocBlockHint(?string $typeDocBlockHint): void
171+
{
172+
$this->returnTypeDocBlockHint = $typeDocBlockHint;
173+
}
174+
175+
public function getDocBlock(): ?DocBlock
176+
{
177+
return $this->docBlock;
178+
}
179+
180+
public function overrideDocBlock(?DocBlock $docBlock): void
181+
{
182+
$this->docBlock = $docBlock;
183+
}
184+
185+
public function generate(Parser $parser): NodeVisitor
186+
{
187+
return new ClassMethod($this->methodGenerator($parser));
188+
}
189+
190+
private function methodGenerator(Parser $parser): MethodGenerator
191+
{
192+
$flags = $this->visibility;
193+
194+
$body = new BodyGenerator($parser, $this->body);
195+
196+
$methodGenerator = new MethodGenerator(
197+
$this->name,
198+
\array_map(static function (ParameterBuilder $builder) {
199+
return $builder->generate();
200+
}, $this->parameters),
201+
$flags,
202+
$body
203+
);
204+
205+
$methodGenerator->setReturnType($this->returnType);
206+
$methodGenerator->setTyped($this->typed);
207+
$methodGenerator->setDocBlockComment($this->docBlockComment);
208+
$methodGenerator->setReturnTypeDocBlockHint($this->returnTypeDocBlockHint);
209+
$methodGenerator->overrideDocBlock($this->docBlock);
210+
211+
return $methodGenerator;
212+
}
213+
214+
public function injectVisitors(NodeTraverser $nodeTraverser, Parser $parser): void
215+
{
216+
$nodeTraverser->addVisitor($this->generate($parser));
217+
}
218+
}

src/Builder/ClassPropertyBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public static function fromNode(Node\Stmt\Property $node): self
7272
return $self;
7373
}
7474

75-
public static function fromScratch(string $name, $type, bool $typed = true): self
75+
public static function fromScratch(string $name, string $type, bool $typed = true): self
7676
{
7777
$self = new self();
7878
$self->name = $name;

0 commit comments

Comments
 (0)