diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 8667be4..4cadb4f 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -29,6 +29,7 @@ ->withRules(PhpCsFixer\Config\Rules::fromArray([ 'declare_strict_types' => false, 'final_class' => false, + 'phpdoc_to_property_type' => false, // when turned on it breaks generics phpdoc types 'void_return' => false, ])); diff --git a/CHANGELOG.md b/CHANGELOG.md index 32d035f..1d026d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), For a full diff see [`0.10.0...master`][0.10.0...master]. +### Added + +- Added template/generic annotations for node values ([#333]), by [@smoench] + ## [`0.10.0`][0.10.0] For a full diff see [0.9.0...0.10.0`][0.9.0...0.10.0]. @@ -303,3 +307,4 @@ For a full diff see [`fcfd14e...v0.1.1`][fcfd14e...0.1.1]. [@mdwheele]: https://github.com/mdwheele [@nicmart]: https://github.com/nicmart [@pascalbaljet]: https://github.com/pascalbaljet +[@smoench]: https://github.com/smoench diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 1ceb46c..0492e6e 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,62 +1,64 @@ - + - $value + - static - static + + + + + + + - mixed - static - static - static + + + + - $heights + - array - array - array + + + - $child + - $child - $child - $child - $child - $heights[] - $size + + + + + + - int - int + + - getHeight - getSize - setParent + + + getSize()]]> - \max($heights) + - - ?static - - getDepth + @@ -64,7 +66,7 @@ accept($this)]]> - $nodes + ]]> @@ -73,7 +75,7 @@ accept($this)]]> - $nodes + ]]> @@ -82,7 +84,7 @@ accept($this)]]> - $yield + ]]> @@ -91,18 +93,10 @@ - array[Node] + - - static function (Node $node) { - - leaf + - - - assertSame - - diff --git a/src/Node/Node.php b/src/Node/Node.php index 45002de..c0bece2 100644 --- a/src/Node/Node.php +++ b/src/Node/Node.php @@ -11,15 +11,22 @@ namespace Tree\Node; +/** + * @template TValue + * + * @template-implements NodeInterface + */ class Node implements NodeInterface { + /** @use NodeTrait */ use NodeTrait; /** + * @param null|TValue $value * @param array $children */ public function __construct( - mixed $value = null, + $value = null, array $children = [], ) { $this->setValue($value); diff --git a/src/Node/NodeInterface.php b/src/Node/NodeInterface.php index 0b99a6c..3a34061 100644 --- a/src/Node/NodeInterface.php +++ b/src/Node/NodeInterface.php @@ -17,23 +17,27 @@ * Interface for tree nodes. * * @author Nicolò Martini + * + * @template TValue */ interface NodeInterface { /** * Set the value of the current node. + * + * @param TValue $value */ - public function setValue(mixed $value): static; + public function setValue($value): static; /** * Get the current node value. + * + * @return TValue */ - public function getValue(): mixed; + public function getValue(); /** * Add a child. - * - * @return mixed */ public function addChild(self $child): static; @@ -58,8 +62,6 @@ public function getChildren(): array; * Replace the children set with the given one. * * @param array $children - * - * @return mixed */ public function setChildren(array $children): static; @@ -71,7 +73,7 @@ public function setParent(?self $parent = null): void; /** * Return the parent node. */ - public function getParent(): ?static; + public function getParent(): ?self; /** * Retrieves all ancestors of node excluding current node. @@ -115,7 +117,7 @@ public function isLeaf(): bool; /** * Find the root of the node. */ - public function root(): static; + public function root(): self; /** * Return the distance from the current node to the root. diff --git a/src/Node/NodeTrait.php b/src/Node/NodeTrait.php index fa3edce..b65b5df 100644 --- a/src/Node/NodeTrait.php +++ b/src/Node/NodeTrait.php @@ -13,9 +13,15 @@ use Tree\Visitor\Visitor; +/** + * @template TValue + */ trait NodeTrait { - private mixed $value = null; + /** + * @var TValue + */ + private $value; private ?NodeInterface $parent = null; /** @@ -23,14 +29,20 @@ trait NodeTrait */ private array $children = []; - public function setValue(mixed $value): static + /** + * @param TValue $value + */ + public function setValue($value): static { $this->value = $value; return $this; } - public function getValue(): mixed + /** + * @return TValue + */ + public function getValue() { return $this->value; } @@ -90,7 +102,7 @@ public function setParent(?NodeInterface $parent = null): void $this->parent = $parent; } - public function getParent(): ?static + public function getParent(): ?NodeInterface { return $this->parent; } @@ -153,7 +165,7 @@ public function isLeaf(): bool return [] === $this->children; } - public function root(): static + public function root(): NodeInterface { $node = $this; diff --git a/src/Visitor/PostOrderVisitor.php b/src/Visitor/PostOrderVisitor.php index f37e0d0..71d8f87 100644 --- a/src/Visitor/PostOrderVisitor.php +++ b/src/Visitor/PostOrderVisitor.php @@ -18,7 +18,7 @@ class PostOrderVisitor implements Visitor /** * @return array $node */ - public function visit(NodeInterface $node): mixed + public function visit(NodeInterface $node): array { $nodes = []; diff --git a/src/Visitor/YieldVisitor.php b/src/Visitor/YieldVisitor.php index 09f7dc1..3a84cf6 100644 --- a/src/Visitor/YieldVisitor.php +++ b/src/Visitor/YieldVisitor.php @@ -18,7 +18,7 @@ class YieldVisitor implements Visitor /** * @return array */ - public function visit(NodeInterface $node): mixed + public function visit(NodeInterface $node): array { if ($node->isLeaf()) { return [$node]; diff --git a/test/Unit/Node/NodeTest.php b/test/Unit/Node/NodeTest.php index db89fc8..f8a0fb1 100644 --- a/test/Unit/Node/NodeTest.php +++ b/test/Unit/Node/NodeTest.php @@ -69,6 +69,7 @@ public function testConstructorSetsChildren(): void public function testSetValue(): void { + /** @var Node<\stdClass|string> $node */ $node = new Node(); $node->setValue('string value');