Skip to content

Commit 036142c

Browse files
committed
Support PHP 8 attributes and readonly class / property - Close #73
1 parent 4a5e7e0 commit 036142c

30 files changed

+1543
-842
lines changed

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"require": {
2828
"php": "^7.4 || ^8.0",
29-
"nikic/php-parser": "^4.2",
29+
"nikic/php-parser": "^4.14",
3030
"ext-json": "*"
3131
},
3232
"require-dev": {

composer.lock

+695-553
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Builder/AbstractTrait.php

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
namespace OpenCodeModeling\CodeAst\Builder;
11+
12+
trait AbstractTrait
13+
{
14+
private bool $abstract = false;
15+
16+
public function isAbstract(): bool
17+
{
18+
return $this->abstract;
19+
}
20+
21+
public function setAbstract(bool $abstract): self
22+
{
23+
$this->abstract = $abstract;
24+
25+
return $this;
26+
}
27+
}

src/Builder/AttributeBuilder.php

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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 PhpParser\Node\Arg;
14+
use PhpParser\Node\Attribute;
15+
use PhpParser\PrettyPrinter\Standard;
16+
use PhpParser\PrettyPrinterAbstract;
17+
18+
final class AttributeBuilder
19+
{
20+
/**
21+
* @var string
22+
*/
23+
private string $name;
24+
private array $args;
25+
26+
private function __construct(string $name, ...$args)
27+
{
28+
$this->name = $name;
29+
$this->args = $args;
30+
}
31+
32+
public static function fromScratch(string $name, ...$args): self
33+
{
34+
return new self($name, ...$args);
35+
}
36+
37+
public static function fromNode(Attribute $attribute, PrettyPrinterAbstract $printer = null): self
38+
{
39+
if (null === $printer) {
40+
$printer = new Standard(['shortArraySyntax' => true]);
41+
}
42+
43+
return new self($attribute->name->toString(), ...\array_map(static fn (Arg $arg) => $printer->prettyPrint([$arg]), $attribute->args));
44+
}
45+
46+
public function getName(): string
47+
{
48+
return $this->name;
49+
}
50+
51+
public function setName(string $name): void
52+
{
53+
$this->name = $name;
54+
}
55+
56+
public function getArgs(): array
57+
{
58+
return $this->args;
59+
}
60+
61+
public function setArgs(...$args): void
62+
{
63+
$this->args = $args;
64+
}
65+
}

src/Builder/AttributeTrait.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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+
trait AttributeTrait
14+
{
15+
/**
16+
* @var AttributeBuilder[]
17+
*/
18+
protected array $attributes = [];
19+
20+
public function setAttributes(AttributeBuilder ...$attributes): self
21+
{
22+
$this->attributes = $attributes;
23+
24+
return $this;
25+
}
26+
27+
public function addAttribute(AttributeBuilder $attribute): self
28+
{
29+
$this->attributes[] = $attribute;
30+
31+
return $this;
32+
}
33+
34+
/**
35+
* @return AttributeBuilder[]
36+
*/
37+
public function getAttributes(): array
38+
{
39+
return $this->attributes;
40+
}
41+
}

src/Builder/ClassBuilder.php

+12-62
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,18 @@
2525

2626
final class ClassBuilder implements PhpFile
2727
{
28+
use ReadonlyTrait;
29+
use TypedTrait;
30+
use FinalTrait;
31+
use AbstractTrait;
32+
use StrictTrait;
33+
2834
/** @var string|null */
2935
private ?string $namespace = null;
3036

3137
/** @var string|null */
3238
private ?string $name = null;
3339

34-
/** @var bool */
35-
private bool $strict = false;
36-
37-
/** @var bool */
38-
private bool $typed = true;
39-
40-
/** @var bool */
41-
private bool $final = false;
42-
43-
/** @var bool */
44-
private bool $abstract = false;
45-
4640
/** @var string|null */
4741
private ?string $extends = null;
4842

@@ -104,20 +98,6 @@ public function injectVisitors(NodeTraverser $nodeTraverser, Parser $parser): vo
10498
}
10599
}
106100

107-
public function setFinal(bool $final): self
108-
{
109-
$this->final = $final;
110-
111-
return $this;
112-
}
113-
114-
public function setAbstract(bool $abstract): self
115-
{
116-
$this->abstract = $abstract;
117-
118-
return $this;
119-
}
120-
121101
public function setExtends(string $extends): self
122102
{
123103
$this->extends = $extends;
@@ -456,40 +436,6 @@ public function getName(): ?string
456436
return $this->name;
457437
}
458438

459-
public function setStrict(bool $strict): self
460-
{
461-
$this->strict = $strict;
462-
463-
return $this;
464-
}
465-
466-
public function isStrict(): bool
467-
{
468-
return $this->strict;
469-
}
470-
471-
public function setTyped(bool $typed): self
472-
{
473-
$this->typed = $typed;
474-
475-
return $this;
476-
}
477-
478-
public function isTyped(): bool
479-
{
480-
return $this->typed;
481-
}
482-
483-
public function isFinal(): bool
484-
{
485-
return $this->final;
486-
}
487-
488-
public function isAbstract(): bool
489-
{
490-
return $this->abstract;
491-
}
492-
493439
public function getExtends(): ?string
494440
{
495441
return $this->extends;
@@ -655,8 +601,8 @@ static function (ClassConstBuilder $const) {
655601
\array_push(
656602
$visitors,
657603
...\array_map(
658-
static function (ClassPropertyBuilder $property) {
659-
return $property->generate();
604+
static function (ClassPropertyBuilder $property) use ($parser) {
605+
return $property->generate($parser);
660606
},
661607
\array_values($this->properties)
662608
)
@@ -706,6 +652,7 @@ private function unpackNode(Node $node): void
706652
case $node instanceof Node\Stmt\Class_:
707653
$this->name = $node->name->name;
708654
$this->final = $node->isFinal();
655+
$this->isReadonly = $node->isReadonly();
709656

710657
if ($node->extends !== null) {
711658
$this->extends = $node->extends instanceof Node\Name\FullyQualified
@@ -759,6 +706,9 @@ private function classGenerator(): ClassGenerator
759706
if ($this->abstract) {
760707
$flags |= ClassGenerator::FLAG_ABSTRACT;
761708
}
709+
if ($this->isReadonly) {
710+
$flags |= ClassGenerator::FLAG_READONLY;
711+
}
762712

763713
return new ClassGenerator($this->name, $flags);
764714
}

src/Builder/ClassConstBuilder.php

+2-26
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,14 @@
1919

2020
final class ClassConstBuilder
2121
{
22+
use VisibilityTrait;
23+
2224
/** @var string */
2325
private string $name;
2426

2527
/** @var mixed */
2628
private $value;
2729

28-
/**
29-
* @var int
30-
*/
31-
private int $visibility;
32-
3330
private function __construct()
3431
{
3532
}
@@ -75,27 +72,6 @@ public function getValue()
7572
return $this->value;
7673
}
7774

78-
public function setPrivate(): self
79-
{
80-
$this->visibility = ClassConstGenerator::FLAG_PRIVATE;
81-
82-
return $this;
83-
}
84-
85-
public function setProtected(): self
86-
{
87-
$this->visibility = ClassConstGenerator::FLAG_PROTECTED;
88-
89-
return $this;
90-
}
91-
92-
public function setPublic(): self
93-
{
94-
$this->visibility = ClassConstGenerator::FLAG_PUBLIC;
95-
96-
return $this;
97-
}
98-
9975
public function generate(): NodeVisitor
10076
{
10177
return new ClassConstant(

0 commit comments

Comments
 (0)