Skip to content

Commit 9252876

Browse files
committed
Support Node\NullableType in Builder classes - Close #47
1 parent 5473149 commit 9252876

File tree

5 files changed

+115
-7
lines changed

5 files changed

+115
-7
lines changed

src/Builder/ClassMethodBuilder.php

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use OpenCodeModeling\CodeAst\Code\DocBlock\DocBlock;
1616
use OpenCodeModeling\CodeAst\Code\MethodGenerator;
1717
use OpenCodeModeling\CodeAst\NodeVisitor\ClassMethod;
18+
use PhpParser\Comment\Doc;
1819
use PhpParser\Node;
1920
use PhpParser\NodeTraverser;
2021
use PhpParser\NodeVisitor;
@@ -77,8 +78,22 @@ public static function fromNode(Node\Stmt\ClassMethod $node, bool $typed = true,
7778

7879
$self = new self();
7980

81+
$returnType = null;
82+
83+
switch (true) {
84+
case $node->returnType instanceof Node\Name:
85+
case $node->returnType instanceof Node\Identifier:
86+
$returnType = $node->returnType->toString();
87+
break;
88+
case $node->returnType instanceof Node\NullableType:
89+
$returnType = '?' . $node->returnType->type->toString();
90+
break;
91+
default:
92+
break;
93+
}
94+
8095
$self->name = $node->name->toString();
81-
$self->returnType = $node->returnType ? $node->returnType->toString() : null;
96+
$self->returnType = $returnType;
8297
$self->visibility = $node->flags;
8398
$self->abstract = ($node->flags & MethodGenerator::FLAG_ABSTRACT) > 0;
8499
$self->final = ($node->flags & MethodGenerator::FLAG_FINAL) > 0;
@@ -93,6 +108,20 @@ public static function fromNode(Node\Stmt\ClassMethod $node, bool $typed = true,
93108
$self->body = $printer->prettyPrint($node->stmts);
94109
}
95110

111+
$comments = $node->getAttribute('comments');
112+
113+
if ($comments !== null
114+
&& $comments[0] instanceof Doc
115+
) {
116+
$comments = \explode("\n", $comments[0]->getReformattedText());
117+
118+
foreach ($comments as $comment) {
119+
if (0 === \strpos($comment, ' * @return ')) {
120+
$self->setReturnTypeDocBlockHint(\substr($comment, 11));
121+
}
122+
}
123+
}
124+
96125
return $self;
97126
}
98127

@@ -122,13 +151,23 @@ public function setBody(string $body): self
122151
return $this;
123152
}
124153

154+
public function body(): string
155+
{
156+
return $this->body;
157+
}
158+
125159
public function setReturnType(?string $returnType): self
126160
{
127161
$this->returnType = $returnType;
128162

129163
return $this;
130164
}
131165

166+
public function getReturnType(): ?string
167+
{
168+
return $this->returnType;
169+
}
170+
132171
public function getName(): string
133172
{
134173
return $this->name;
@@ -175,6 +214,21 @@ public function setPublic(): self
175214
return $this;
176215
}
177216

217+
public function isPrivate(): bool
218+
{
219+
return (bool) ($this->visibility & ClassConstGenerator::FLAG_PRIVATE);
220+
}
221+
222+
public function isProtected(): bool
223+
{
224+
return (bool) ($this->visibility & ClassConstGenerator::FLAG_PROTECTED);
225+
}
226+
227+
public function isPublic(): bool
228+
{
229+
return (bool) ($this->visibility & ClassConstGenerator::FLAG_PUBLIC);
230+
}
231+
178232
public function getDocBlockComment(): ?string
179233
{
180234
return $this->docBlockComment;

src/Builder/ClassPropertyBuilder.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,23 @@ public static function fromNode(Node\Stmt\Property $node, bool $typed = true): s
6161
{
6262
$self = new self();
6363

64+
$type = null;
65+
66+
switch (true) {
67+
case $node->type instanceof Node\Name:
68+
case $node->type instanceof Node\Identifier:
69+
$type = $node->type->toString();
70+
break;
71+
case $node->type instanceof Node\NullableType:
72+
$type = '?' . $node->type->type->toString();
73+
break;
74+
default:
75+
break;
76+
}
77+
6478
$self->name = $node->props[0]->name->name;
6579
$self->defaultValue = $node->props[0]->default;
66-
$self->type = $node->type ? $node->type->toString() : null;
80+
$self->type = $type;
6781
$self->visibility = $node->flags;
6882
$self->typed = $typed;
6983

@@ -138,6 +152,21 @@ public function setPublic(): self
138152
return $this;
139153
}
140154

155+
public function isPrivate(): bool
156+
{
157+
return (bool) ($this->visibility & ClassConstGenerator::FLAG_PRIVATE);
158+
}
159+
160+
public function isProtected(): bool
161+
{
162+
return (bool) ($this->visibility & ClassConstGenerator::FLAG_PROTECTED);
163+
}
164+
165+
public function isPublic(): bool
166+
{
167+
return (bool) ($this->visibility & ClassConstGenerator::FLAG_PUBLIC);
168+
}
169+
141170
public function getDocBlockComment(): ?string
142171
{
143172
return $this->docBlockComment;

src/Builder/ParameterBuilder.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,23 @@ private function __construct()
4747

4848
public static function fromNode(Node\Param $node): self
4949
{
50+
$type = null;
51+
52+
switch (true) {
53+
case $node->type instanceof Node\Name:
54+
case $node->type instanceof Node\Identifier:
55+
$type = $node->type->toString();
56+
break;
57+
case $node->type instanceof Node\NullableType:
58+
$type = '?' . $node->type->type->toString();
59+
break;
60+
default:
61+
break;
62+
}
63+
5064
$self = new self();
5165
$self->name = $node->var->name;
52-
$self->type = $node->type ? $node->type->toString() : null;
66+
$self->type = $type;
5367
$self->variadic = $node->variadic;
5468
$self->passedByReference = $node->byRef;
5569

tests/Builder/ClassMethodBuilderTest.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class TestClass
139139
public function setActive() : void
140140
{
141141
}
142-
public final function doSomething() : void
142+
protected final function doSomething() : ?MyResult
143143
{
144144
}
145145
}
@@ -156,10 +156,14 @@ public final function doSomething() : void
156156
$this->assertSame('setActive', $methods[0]->getName());
157157
$this->assertFalse($methods[0]->isAbstract());
158158
$this->assertFalse($methods[0]->isFinal());
159+
$this->assertTrue($methods[0]->isPublic());
160+
$this->assertSame('void', $methods[0]->getReturnType());
159161

160162
$this->assertSame('doSomething', $methods[1]->getName());
161163
$this->assertFalse($methods[1]->isAbstract());
162164
$this->assertTrue($methods[1]->isFinal());
165+
$this->assertTrue($methods[1]->isProtected());
166+
$this->assertSame('?MyResult', $methods[1]->getReturnType());
163167

164168
$nodeTraverser = new NodeTraverser();
165169
$classFactory->injectVisitors($nodeTraverser, $this->parser);
@@ -248,7 +252,7 @@ public function it_generates_method_with_args_for_empty_class_from_template(): v
248252
249253
class TestClass
250254
{
251-
public function setActive(bool $active) : void
255+
public function setActive(?bool $active) : void
252256
{
253257
}
254258
}
@@ -264,6 +268,7 @@ public function setActive(bool $active) : void
264268
$this->assertCount(1, $methods[0]->getParameters());
265269

266270
$this->assertSame('setActive', $methods[0]->getName());
271+
$this->assertTrue($methods[0]->isPublic());
267272

268273
$parameters = $methods[0]->getParameters();
269274

@@ -272,7 +277,7 @@ public function setActive(bool $active) : void
272277
$parameter = $parameters[0];
273278

274279
$this->assertSame('active', $parameter->getName());
275-
$this->assertSame('bool', $parameter->getType());
280+
$this->assertSame('?bool', $parameter->getType());
276281

277282
$nodeTraverser = new NodeTraverser();
278283
$classFactory->injectVisitors($nodeTraverser, $this->parser);

tests/Builder/ClassPropertyBuilderTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public function it_generates_property_for_empty_class_from_template(): void
7878
class TestClass
7979
{
8080
private string $aggregateId;
81+
protected ?string $name;
8182
}
8283
EOF;
8384

@@ -87,10 +88,15 @@ class TestClass
8788

8889
$properties = $classFactory->getProperties();
8990

90-
$this->assertCount(1, $properties);
91+
$this->assertCount(2, $properties);
9192

9293
$this->assertSame('aggregateId', $properties['aggregateId']->getName());
9394
$this->assertSame('string', $properties['aggregateId']->getType());
95+
$this->assertTrue($properties['aggregateId']->isPrivate());
96+
97+
$this->assertSame('name', $properties['name']->getName());
98+
$this->assertSame('?string', $properties['name']->getType());
99+
$this->assertTrue($properties['name']->isProtected());
94100

95101
$nodeTraverser = new NodeTraverser();
96102
$classFactory->injectVisitors($nodeTraverser, $this->parser);

0 commit comments

Comments
 (0)