Skip to content

Commit

Permalink
Support PHP 8 attributes and readonly class / property - Close #73
Browse files Browse the repository at this point in the history
  • Loading branch information
sandrokeil committed Jul 3, 2022
1 parent 4a5e7e0 commit 1bec5d8
Show file tree
Hide file tree
Showing 30 changed files with 1,542 additions and 842 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
"require": {
"php": "^7.4 || ^8.0",
"nikic/php-parser": "^4.2",
"nikic/php-parser": "^4.14",
"ext-json": "*"
},
"require-dev": {
Expand Down
1,248 changes: 695 additions & 553 deletions composer.lock

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions src/Builder/AbstractTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

/**
* @see https://github.com/open-code-modeling/php-code-ast for the canonical source repository
* @copyright https://github.com/open-code-modeling/php-code-ast/blob/master/COPYRIGHT.md
* @license https://github.com/open-code-modeling/php-code-ast/blob/master/LICENSE.md MIT License
*/

declare(strict_types=1);
namespace OpenCodeModeling\CodeAst\Builder;

trait AbstractTrait
{
private bool $abstract = false;

public function isAbstract(): bool
{
return $this->abstract;
}

public function setAbstract(bool $abstract): self
{
$this->abstract = $abstract;

return $this;
}
}
64 changes: 64 additions & 0 deletions src/Builder/AttributeBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/**
* @see https://github.com/open-code-modeling/php-code-ast for the canonical source repository
* @copyright https://github.com/open-code-modeling/php-code-ast/blob/master/COPYRIGHT.md
* @license https://github.com/open-code-modeling/php-code-ast/blob/master/LICENSE.md MIT License
*/

declare(strict_types=1);

namespace OpenCodeModeling\CodeAst\Builder;

use PhpParser\Node\Arg;
use PhpParser\Node\Attribute;
use PhpParser\PrettyPrinter\Standard;
use PhpParser\PrettyPrinterAbstract;

final class AttributeBuilder
{
/**
* @var string
*/
private string $name;
private array $args;

private function __construct(string $name, ...$args)
{
$this->name = $name;
$this->args = $args;
}

public static function fromScratch(string $name, ...$args): self
{
return new self($name, ...$args);
}

public static function fromNode(Attribute $attribute, PrettyPrinterAbstract $printer = null): self
{
if (null === $printer) {
$printer = new Standard(['shortArraySyntax' => true]);
}
return new self($attribute->name->toString(), ...array_map(static fn(Arg $arg) => $printer->prettyPrint([$arg]), $attribute->args));
}

public function getName(): string
{
return $this->name;
}

public function setName(string $name): void
{
$this->name = $name;
}

public function getArgs(): array
{
return $this->args;
}

public function setArgs(...$args): void
{
$this->args = $args;
}
}
41 changes: 41 additions & 0 deletions src/Builder/AttributeTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

/**
* @see https://github.com/open-code-modeling/php-code-ast for the canonical source repository
* @copyright https://github.com/open-code-modeling/php-code-ast/blob/master/COPYRIGHT.md
* @license https://github.com/open-code-modeling/php-code-ast/blob/master/LICENSE.md MIT License
*/

declare(strict_types=1);

namespace OpenCodeModeling\CodeAst\Builder;

trait AttributeTrait
{
/**
* @var AttributeBuilder[]
*/
protected array $attributes = [];

public function setAttributes(AttributeBuilder ...$attributes): self
{
$this->attributes = $attributes;

return $this;
}

public function addAttribute(AttributeBuilder $attribute): self
{
$this->attributes[] = $attribute;

return $this;
}

/**
* @return AttributeBuilder[]
*/
public function getAttributes(): array
{
return $this->attributes;
}
}
74 changes: 12 additions & 62 deletions src/Builder/ClassBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,18 @@

final class ClassBuilder implements PhpFile
{
use ReadonlyTrait;
use TypedTrait;
use FinalTrait;
use AbstractTrait;
use StrictTrait;

/** @var string|null */
private ?string $namespace = null;

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

/** @var bool */
private bool $strict = false;

/** @var bool */
private bool $typed = true;

/** @var bool */
private bool $final = false;

/** @var bool */
private bool $abstract = false;

/** @var string|null */
private ?string $extends = null;

Expand Down Expand Up @@ -104,20 +98,6 @@ public function injectVisitors(NodeTraverser $nodeTraverser, Parser $parser): vo
}
}

public function setFinal(bool $final): self
{
$this->final = $final;

return $this;
}

public function setAbstract(bool $abstract): self
{
$this->abstract = $abstract;

return $this;
}

public function setExtends(string $extends): self
{
$this->extends = $extends;
Expand Down Expand Up @@ -456,40 +436,6 @@ public function getName(): ?string
return $this->name;
}

public function setStrict(bool $strict): self
{
$this->strict = $strict;

return $this;
}

public function isStrict(): bool
{
return $this->strict;
}

public function setTyped(bool $typed): self
{
$this->typed = $typed;

return $this;
}

public function isTyped(): bool
{
return $this->typed;
}

public function isFinal(): bool
{
return $this->final;
}

public function isAbstract(): bool
{
return $this->abstract;
}

public function getExtends(): ?string
{
return $this->extends;
Expand Down Expand Up @@ -655,8 +601,8 @@ static function (ClassConstBuilder $const) {
\array_push(
$visitors,
...\array_map(
static function (ClassPropertyBuilder $property) {
return $property->generate();
static function (ClassPropertyBuilder $property) use ($parser) {
return $property->generate($parser);
},
\array_values($this->properties)
)
Expand Down Expand Up @@ -706,6 +652,7 @@ private function unpackNode(Node $node): void
case $node instanceof Node\Stmt\Class_:
$this->name = $node->name->name;
$this->final = $node->isFinal();
$this->isReadonly = $node->isReadonly();

if ($node->extends !== null) {
$this->extends = $node->extends instanceof Node\Name\FullyQualified
Expand Down Expand Up @@ -759,6 +706,9 @@ private function classGenerator(): ClassGenerator
if ($this->abstract) {
$flags |= ClassGenerator::FLAG_ABSTRACT;
}
if ($this->isReadonly) {
$flags |= ClassGenerator::FLAG_READONLY;
}

return new ClassGenerator($this->name, $flags);
}
Expand Down
28 changes: 2 additions & 26 deletions src/Builder/ClassConstBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,14 @@

final class ClassConstBuilder
{
use VisibilityTrait;

/** @var string */
private string $name;

/** @var mixed */
private $value;

/**
* @var int
*/
private int $visibility;

private function __construct()
{
}
Expand Down Expand Up @@ -75,27 +72,6 @@ public function getValue()
return $this->value;
}

public function setPrivate(): self
{
$this->visibility = ClassConstGenerator::FLAG_PRIVATE;

return $this;
}

public function setProtected(): self
{
$this->visibility = ClassConstGenerator::FLAG_PROTECTED;

return $this;
}

public function setPublic(): self
{
$this->visibility = ClassConstGenerator::FLAG_PUBLIC;

return $this;
}

public function generate(): NodeVisitor
{
return new ClassConstant(
Expand Down
Loading

0 comments on commit 1bec5d8

Please sign in to comment.