Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d181276

Browse files
Fix default value code generation for properties and parameters - Close #68
1 parent 1c5fce7 commit d181276

File tree

8 files changed

+328
-45
lines changed

8 files changed

+328
-45
lines changed

‎src/Builder/ClassPropertyBuilder.php

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@ final class ClassPropertyBuilder
5353
*/
5454
private ?DocBlock $docBlock = null;
5555

56+
private PropertyGenerator $propertyGenerator;
57+
5658
private function __construct()
5759
{
5860
}
5961

6062
public static function fromNode(Node\Stmt\Property $node, bool $typed = true): self
6163
{
6264
$self = new self();
63-
6465
$type = null;
6566

6667
switch (true) {
@@ -76,10 +77,33 @@ public static function fromNode(Node\Stmt\Property $node, bool $typed = true): s
7677
}
7778

7879
$self->name = $node->props[0]->name->name;
79-
$self->defaultValue = $node->props[0]->default;
8080
$self->type = $type;
8181
$self->visibility = $node->flags;
8282
$self->typed = $typed;
83+
$self->propertyGenerator = new PropertyGenerator($self->name, $self->type);
84+
85+
$defaultValue = $node->props[0]->default;
86+
87+
switch (true) {
88+
case $defaultValue instanceof Node\Expr\ConstFetch:
89+
$self->defaultValue = $defaultValue->name->toString();
90+
91+
if ($self->defaultValue === 'null') {
92+
$self->defaultValue = null;
93+
}
94+
$self->propertyGenerator->setDefaultValue($self->defaultValue);
95+
break;
96+
case $defaultValue instanceof Node\Expr\ClassConstFetch:
97+
$self->defaultValue = $defaultValue->class->toString() . '::'. $defaultValue->name->toString();
98+
$self->propertyGenerator->setDefaultValue($self->defaultValue);
99+
break;
100+
default:
101+
if ($defaultValue !== null) {
102+
$self->defaultValue = $defaultValue;
103+
$self->propertyGenerator->setDefaultValue($self->defaultValue);
104+
}
105+
break;
106+
}
83107

84108
$comments = $node->getAttribute('comments');
85109

@@ -105,6 +129,7 @@ public static function fromScratch(string $name, string $type, bool $typed = tru
105129
$self->type = $type;
106130
$self->typed = $typed;
107131
$self->visibility = ClassConstGenerator::FLAG_PRIVATE;
132+
$self->propertyGenerator = new PropertyGenerator($self->name, $self->type);
108133

109134
return $self;
110135
}
@@ -203,6 +228,20 @@ public function overrideDocBlock(?DocBlock $docBlock): self
203228
return $this;
204229
}
205230

231+
/**
232+
* @param mixed $defaultValue
233+
*/
234+
public function setDefaultValue($defaultValue): void
235+
{
236+
$this->defaultValue = $defaultValue;
237+
$this->propertyGenerator->setDefaultValue($this->defaultValue);
238+
}
239+
240+
public function getDefaultValue()
241+
{
242+
return $this->defaultValue;
243+
}
244+
206245
public function generate(): NodeVisitor
207246
{
208247
return new Property($this->propertyGenerator());
@@ -211,14 +250,12 @@ public function generate(): NodeVisitor
211250
private function propertyGenerator(): PropertyGenerator
212251
{
213252
$flags = $this->visibility;
253+
$this->propertyGenerator->setFlags($flags);
254+
$this->propertyGenerator->setDocBlockComment($this->docBlockComment);
255+
$this->propertyGenerator->setTypeDocBlockHint($this->typeDocBlockHint);
256+
$this->propertyGenerator->overrideDocBlock($this->docBlock);
214257

215-
$propertyGenerator = new PropertyGenerator($this->name, $this->type, $this->defaultValue, $this->typed, $flags);
216-
217-
$propertyGenerator->setDocBlockComment($this->docBlockComment);
218-
$propertyGenerator->setTypeDocBlockHint($this->typeDocBlockHint);
219-
$propertyGenerator->overrideDocBlock($this->docBlock);
220-
221-
return $propertyGenerator;
258+
return $this->propertyGenerator;
222259
}
223260

224261
public function injectVisitors(NodeTraverser $nodeTraverser): void

‎src/Builder/ParameterBuilder.php

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ final class ParameterBuilder
4141
*/
4242
private ?string $typeDocBlockHint = null;
4343

44+
private ParameterGenerator $parameterGenerator;
45+
4446
private function __construct()
4547
{
4648
}
@@ -66,19 +68,40 @@ public static function fromNode(Node\Param $node): self
6668
$self->type = $type;
6769
$self->variadic = $node->variadic;
6870
$self->passedByReference = $node->byRef;
71+
$self->parameterGenerator = new ParameterGenerator($self->name, $self->type);
72+
73+
$defaultValue = $node->default;
74+
75+
switch (true) {
76+
case $defaultValue instanceof Node\Expr\ConstFetch:
77+
$self->defaultValue = $defaultValue->name->toString();
78+
79+
if ($self->defaultValue === 'null') {
80+
$self->defaultValue = null;
81+
}
82+
$self->parameterGenerator->setDefaultValue($self->defaultValue);
83+
break;
84+
case $defaultValue instanceof Node\Expr\ClassConstFetch:
85+
$self->defaultValue = $defaultValue->class->toString() . '::'. $defaultValue->name->toString();
86+
$self->parameterGenerator->setDefaultValue($self->defaultValue);
87+
break;
88+
default:
89+
if ($defaultValue !== null) {
90+
$self->defaultValue = $defaultValue;
91+
$self->parameterGenerator->setDefaultValue($self->defaultValue);
92+
}
93+
break;
94+
}
6995

7096
return $self;
7197
}
7298

73-
public static function fromScratch(
74-
string $name,
75-
?string $type = null,
76-
$defaultValue = null
77-
): self {
99+
public static function fromScratch(string $name, ?string $type = null): self
100+
{
78101
$self = new self();
79102
$self->name = $name;
80103
$self->type = $type;
81-
$self->defaultValue = $defaultValue;
104+
$self->parameterGenerator = newParameterGenerator($self->name, $self->type);
82105

83106
return $self;
84107
}
@@ -112,6 +135,7 @@ public function getDefaultValue()
112135
public function setDefaultValue($defaultValue): self
113136
{
114137
$this->defaultValue = $defaultValue;
138+
$this->parameterGenerator->setDefaultValue($this->defaultValue);
115139

116140
return $this;
117141
}
@@ -166,11 +190,10 @@ public function setTypeDocBlockHint(?string $typeDocBlockHint): self
166190

167191
public function generate(): ParameterGenerator
168192
{
169-
$methodGenerator = new ParameterGenerator($this->name, $this->type, $this->defaultValue, $this->passedByReference);
170-
171-
$methodGenerator->setTypeDocBlockHint($this->typeDocBlockHint);
172-
$methodGenerator->setVariadic($this->variadic);
193+
$this->parameterGenerator->setPassedByReference($this->passedByReference);
194+
$this->parameterGenerator->setTypeDocBlockHint($this->typeDocBlockHint);
195+
$this->parameterGenerator->setVariadic($this->variadic);
173196

174-
return $methodGenerator;
197+
return $this->parameterGenerator;
175198
}
176199
}

‎src/Code/ParameterGenerator.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,18 @@ final class ParameterGenerator
5555
/**
5656
* @param string $name
5757
* @param string|null $type
58-
* @param mixed $defaultValue
5958
* @param bool $passByReference
6059
*/
6160
public function __construct(
6261
string $name,
6362
string $type = null,
64-
$defaultValue = null,
6563
bool $passByReference = false
6664
) {
6765
$this->setName($name);
6866

6967
if (null !== $type) {
7068
$this->setType($type);
7169
}
72-
if (null !== $defaultValue) {
73-
$this->setDefaultValue($defaultValue);
74-
}
7570
if (false !== $passByReference) {
7671
$this->setPassedByReference(true);
7772
}
@@ -111,8 +106,6 @@ public function getName(): string
111106
/**
112107
* Set the default value of the parameter.
113108
*
114-
* Certain variables are difficult to express
115-
*
116109
* @param ValueGenerator|mixed $defaultValue
117110
* @return ParameterGenerator
118111
*/

‎src/Code/PropertyGenerator.php

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ final class PropertyGenerator extends AbstractMemberGenerator
5959
public function __construct(
6060
string $name = null,
6161
string $type = null,
62-
$defaultValue = null,
6362
bool $typed = true,
6463
int $flags = self::FLAG_PRIVATE
6564
) {
@@ -71,10 +70,6 @@ public function __construct(
7170
$this->setType($type);
7271
}
7372

74-
if (null !== $defaultValue) {
75-
$this->setDefaultValue($defaultValue);
76-
}
77-
7873
$this->typed = $typed;
7974

8075
if ($flags !== self::FLAG_PUBLIC) {
@@ -117,19 +112,16 @@ public function overrideDocBlock(?DocBlock $docBlock): void
117112
}
118113

119114
/**
120-
* @param ValueGenerator|mixed $defaultValue
121-
* @param string $defaultValueType
115+
* Set the default value of the parameter.
122116
*
117+
* @param ValueGenerator|mixed $defaultValue
123118
* @return PropertyGenerator
124119
*/
125-
public function setDefaultValue(
126-
$defaultValue,
127-
$defaultValueType = ValueGenerator::TYPE_AUTO
128-
): self {
120+
public function setDefaultValue($defaultValue): self
121+
{
129122
if (! $defaultValue instanceof ValueGenerator) {
130-
$defaultValue = new ValueGenerator($defaultValue, $defaultValueType);
123+
$defaultValue = new ValueGenerator($defaultValue);
131124
}
132-
133125
$this->defaultValue = $defaultValue;
134126

135127
return $this;

‎tests/Builder/ClassPropertyBuilderTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
use OpenCodeModeling\CodeAst\Builder\ClassBuilder;
1414
use OpenCodeModeling\CodeAst\Builder\ClassPropertyBuilder;
15+
use OpenCodeModeling\CodeAst\Code\PropertyGenerator;
1516
use PhpParser\NodeTraverser;
1617
use PhpParser\Parser;
1718
use PhpParser\ParserFactory;
@@ -207,4 +208,32 @@ class TestClass
207208

208209
$this->assertSame($expected, $this->printer->prettyPrintFile($nodeTraverser->traverse($this->parser->parse(''))));
209210
}
211+
212+
/**
213+
* @test
214+
*/
215+
public function it_generates_property_with_default_value_from_node(): void
216+
{
217+
$classBuilder = ClassBuilder::fromScratch('TestClass');
218+
$classBuilder->addProperty(
219+
ClassPropertyBuilder::fromNode(
220+
(new PropertyGenerator('recordData', 'array'))->setDefaultValue(null)->generate()
221+
)
222+
);
223+
224+
$nodeTraverser = new NodeTraverser();
225+
$classBuilder->injectVisitors($nodeTraverser, $this->parser);
226+
227+
$expected = <<<'EOF'
228+
<?php
229+
230+
declare (strict_types=1);
231+
class TestClass
232+
{
233+
private array $recordData = null;
234+
}
235+
EOF;
236+
237+
$this->assertSame($expected, $this->printer->prettyPrintFile($nodeTraverser->traverse($this->parser->parse(''))));
238+
}
210239
}

‎tests/Builder/ParameterBuilderTest.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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 OpenCodeModelingTest\CodeAst\Builder;
12+
13+
use OpenCodeModeling\CodeAst\Builder\ClassBuilder;
14+
use OpenCodeModeling\CodeAst\Builder\ClassMethodBuilder;
15+
use OpenCodeModeling\CodeAst\Builder\ParameterBuilder;
16+
use PhpParser\NodeTraverser;
17+
use PhpParser\Parser;
18+
use PhpParser\ParserFactory;
19+
use PhpParser\PrettyPrinter\Standard;
20+
use PHPUnit\Framework\TestCase;
21+
22+
final class ParameterBuilderTest extends TestCase
23+
{
24+
/**
25+
* @var Parser
26+
*/
27+
private Parser $parser;
28+
29+
/**
30+
* @var Standard
31+
*/
32+
private Standard $printer;
33+
34+
public function setUp(): void
35+
{
36+
$this->parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7);
37+
$this->printer = new Standard(['shortArraySyntax' => true]);
38+
}
39+
40+
/**
41+
* @test
42+
*/
43+
public function it_generates_property_with_default_value_from_node(): void
44+
{
45+
$method = ClassMethodBuilder::fromScratch('setRecordData')
46+
->setReturnType('void')
47+
->setParameters(
48+
ParameterBuilder::fromScratch('recordData', 'array')->setDefaultValue(null)
49+
);
50+
$classBuilder = ClassBuilder::fromScratch('TestClass');
51+
$classBuilder->addMethod($method);
52+
53+
$nodeTraverser = new NodeTraverser();
54+
$classBuilder->injectVisitors($nodeTraverser, $this->parser);
55+
56+
$expected = <<<'EOF'
57+
<?php
58+
59+
declare (strict_types=1);
60+
class TestClass
61+
{
62+
public function setRecordData(array $recordData = null) : void
63+
{
64+
}
65+
}
66+
EOF;
67+
$this->assertSame($expected, $this->printer->prettyPrintFile($nodeTraverser->traverse($this->parser->parse(''))));
68+
69+
$classBuilder = ClassBuilder::fromNodes(...$nodeTraverser->traverse($this->parser->parse('')));
70+
$nodeTraverser = new NodeTraverser();
71+
$classBuilder->injectVisitors($nodeTraverser, $this->parser);
72+
73+
$this->assertSame($expected, $this->printer->prettyPrintFile($nodeTraverser->traverse($this->parser->parse(''))));
74+
}
75+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /