Skip to content

Commit

Permalink
Add support for attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
olsavmic committed Jun 15, 2022
1 parent c4a662a commit 10637e0
Show file tree
Hide file tree
Showing 10 changed files with 385 additions and 19 deletions.
76 changes: 76 additions & 0 deletions src/Dependency/ExportedNode/ExportedAttributeArgumentNode.php
@@ -0,0 +1,76 @@
<?php declare(strict_types = 1);

namespace PHPStan\Dependency\ExportedNode;

use JsonSerializable;
use PHPStan\Dependency\ExportedNode;

class ExportedAttributeArgumentNode implements ExportedNode, JsonSerializable
{

private ?string $name;

private string $value;

private bool $byRef;

public function __construct(?string $name, string $value, bool $byRef)
{
$this->name = $name;
$this->value = $value;
$this->byRef = $byRef;
}

public function equals(ExportedNode $node): bool
{
if (!$node instanceof self) {
return false;
}

return $this->name === $node->name
&& $this->value === $node->value
&& $this->byRef === $node->byRef;
}

/**
* @param mixed[] $properties
* @return self
*/
public static function __set_state(array $properties): ExportedNode
{
return new self(
$properties['name'],
$properties['value'],
$properties['byRef'],
);
}

/**
* @return mixed
*/
public function jsonSerialize()
{
return [
'type' => self::class,
'data' => [
'name' => $this->name,
'value' => $this->value,
'byRef' => $this->byRef,
],
];
}

/**
* @param mixed[] $data
* @return self
*/
public static function decode(array $data): ExportedNode
{
return new self(
$data['name'],
$data['value'],
$data['byRef'],
);
}

}
92 changes: 92 additions & 0 deletions src/Dependency/ExportedNode/ExportedAttributeNode.php
@@ -0,0 +1,92 @@
<?php declare(strict_types = 1);

namespace PHPStan\Dependency\ExportedNode;

use JsonSerializable;
use PHPStan\Dependency\ExportedNode;

class ExportedAttributeNode implements ExportedNode, JsonSerializable
{

private string $name;

/** @var ExportedAttributeArgumentNode[] $args */
private array $args;

/**
* @param ExportedAttributeArgumentNode[] $args
*/
public function __construct(
string $name,
array $args
)
{
$this->name = $name;
$this->args = $args;
}

public function equals(ExportedNode $node): bool
{
if (!$node instanceof self) {
return false;
}

if (count($this->args) !== count($node->args)) {
return false;
}

foreach ($this->args as $i => $ourAttribute) {
$theirAttribute = $node->args[$i];
if (!$ourAttribute->equals($theirAttribute)) {
return false;
}
}


return $this->name === $node->name;
}

/**
* @param mixed[] $properties
* @return self
*/
public static function __set_state(array $properties): ExportedNode
{
return new self(
$properties['name'],
$properties['args'],
);
}

/**
* @return mixed
*/
public function jsonSerialize()
{
return [
'type' => self::class,
'data' => [
'name' => $this->name,
'args' => $this->args,
],
];
}

/**
* @param mixed[] $data
* @return self
*/
public static function decode(array $data): ExportedNode
{
return new self(
$data['name'],
array_map(static function (array $parameterData): ExportedAttributeArgumentNode {
if ($parameterData['type'] !== ExportedAttributeArgumentNode::class) {
throw new \PHPStan\ShouldNotHappenException();
}
return ExportedAttributeArgumentNode::decode($parameterData['data']);
}, $data['args'])
);
}

}
32 changes: 29 additions & 3 deletions src/Dependency/ExportedNode/ExportedClassConstantNode.php
Expand Up @@ -9,7 +9,14 @@
class ExportedClassConstantNode implements ExportedNode, JsonSerializable
{

public function __construct(private string $name, private string $value)
/**
* @param ExportedAttributeNode[] $attributes
*/
public function __construct(
private string $name,
private string $value,
private array $attributes,
)
{
}

Expand All @@ -19,6 +26,17 @@ public function equals(ExportedNode $node): bool
return false;
}

if (count($this->attributes) !== count($node->attributes)) {
return false;
}

foreach ($this->attributes as $i => $ourAttribute) {
$theirAttribute = $node->attributes[$i];
if (!$ourAttribute->equals($theirAttribute)) {
return false;
}
}

return $this->name === $node->name
&& $this->value === $node->value;
}
Expand All @@ -32,6 +50,7 @@ public static function __set_state(array $properties): ExportedNode
return new self(
$properties['name'],
$properties['value'],
$properties['attributes'],
);
}

Expand All @@ -44,7 +63,13 @@ public static function decode(array $data): ExportedNode
return new self(
$data['name'],
$data['value'],
);
array_map(static function (array $parameterData): ExportedAttributeNode {
if ($parameterData['type'] !== ExportedAttributeNode::class) {
throw new \PHPStan\ShouldNotHappenException();
}
return ExportedAttributeNode::decode($parameterData['data']);
}, $data['attributes']),
);
}

/**
Expand All @@ -58,7 +83,8 @@ public function jsonSerialize()
'data' => [
'name' => $this->name,
'value' => $this->value,
],
'attributes' => $this->attributes,
],
];
}

Expand Down
28 changes: 24 additions & 4 deletions src/Dependency/ExportedNode/ExportedClassNode.php
Expand Up @@ -17,7 +17,8 @@ class ExportedClassNode implements ExportedNode, JsonSerializable
* @param string[] $usedTraits
* @param ExportedTraitUseAdaptation[] $traitUseAdaptations
* @param ExportedNode[] $statements
*/
* @param ExportedAttributeNode[] $attributes
*/
public function __construct(
private string $name,
private ?ExportedPhpDocNode $phpDoc,
Expand All @@ -28,6 +29,7 @@ public function __construct(
private array $usedTraits,
private array $traitUseAdaptations,
private array $statements,
private array $attributes,
)
{
}
Expand All @@ -50,6 +52,16 @@ public function equals(ExportedNode $node): bool
return false;
}

if (count($this->attributes) !== count($node->attributes)) {
return false;
}

foreach ($this->attributes as $i => $attribute) {
if (!$attribute->equals($node->attributes[$i];)) {
return false;
}
}

if (count($this->traitUseAdaptations) !== count($node->traitUseAdaptations)) {
return false;
}
Expand Down Expand Up @@ -96,8 +108,9 @@ public static function __set_state(array $properties): ExportedNode
$properties['implements'],
$properties['usedTraits'],
$properties['traitUseAdaptations'],
$properties['statements'],
);
$properties['statements'],
$properties['attributes'],
);
}

/**
Expand All @@ -118,7 +131,8 @@ public function jsonSerialize()
'usedTraits' => $this->usedTraits,
'traitUseAdaptations' => $this->traitUseAdaptations,
'statements' => $this->statements,
],
'attributes' => $this->attributes,
],
];
}

Expand Down Expand Up @@ -147,6 +161,12 @@ public static function decode(array $data): ExportedNode

return $nodeType::decode($node['data']);
}, $data['statements']),
array_map(static function (array $parameterData): ExportedAttributeNode {
if ($parameterData['type'] !== ExportedAttributeNode::class) {
throw new \PHPStan\ShouldNotHappenException();
}
return ExportedAttributeNode::decode($parameterData['data']);
}, $data['attributes']),
);
}

Expand Down
33 changes: 31 additions & 2 deletions src/Dependency/ExportedNode/ExportedEnumNode.php
Expand Up @@ -4,6 +4,7 @@

use JsonSerializable;
use PHPStan\Dependency\ExportedNode;
use PHPStan\ShouldNotHappenException;
use ReturnTypeWillChange;
use function array_map;
use function count;
Expand All @@ -14,8 +15,16 @@ class ExportedEnumNode implements ExportedNode, JsonSerializable
/**
* @param string[] $implements
* @param ExportedNode[] $statements
* @param ExportedAttributeNode[] $attributes
*/
public function __construct(private string $name, private ?string $scalarType, private ?ExportedPhpDocNode $phpDoc, private array $implements, private array $statements)
public function __construct(
private string $name,
private ?string $scalarType,
private ?ExportedPhpDocNode $phpDoc,
private array $implements,
private array $statements,
private array $attributes,
)
{
}

Expand Down Expand Up @@ -49,6 +58,18 @@ public function equals(ExportedNode $node): bool
return false;
}

if (count($this->attributes) !== count($node->attributes)) {
return false;
}

foreach ($this->attributes as $i => $attribute) {
if ($attribute->equals($node->attributes[$i])) {
continue;
}

return false;
}

return $this->name === $node->name
&& $this->scalarType === $node->scalarType
&& $this->implements === $node->implements;
Expand All @@ -65,7 +86,8 @@ public static function __set_state(array $properties): ExportedNode
$properties['scalarType'],
$properties['phpDoc'],
$properties['implements'],
$properties['statements'],
$properties['statements'],
$properties['attributes'],
);
}

Expand All @@ -83,6 +105,7 @@ public function jsonSerialize()
'phpDoc' => $this->phpDoc,
'implements' => $this->implements,
'statements' => $this->statements,
'attributes' => $this->attributes,
],
];
}
Expand All @@ -103,6 +126,12 @@ public static function decode(array $data): ExportedNode

return $nodeType::decode($node['data']);
}, $data['statements']),
array_map(static function (array $parameterData): ExportedAttributeNode {
if ($parameterData['type'] !== ExportedAttributeNode::class) {
throw new ShouldNotHappenException();
}
return ExportedAttributeNode::decode($parameterData['data']);
}, $data['attributes']),
);
}

Expand Down

0 comments on commit 10637e0

Please sign in to comment.