Skip to content

Commit

Permalink
Traverser: can return different nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Nov 9, 2021
1 parent ef691f8 commit 1f4e5f6
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/Neon/Node/ArrayItemNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ public function toString(): string

public function getSubNodes(): array
{
return $this->key ? [$this->key, $this->value] : [$this->value];
return $this->key ? [&$this->key, &$this->value] : [&$this->value];
}
}
6 changes: 5 additions & 1 deletion src/Neon/Node/ArrayNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public function toString(): string

public function getSubNodes(): array
{
return $this->items;
$res = [];
foreach ($this->items as &$item) {
$res[] = &$item;
}
return $res;
}
}
6 changes: 5 additions & 1 deletion src/Neon/Node/EntityChainNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public function toString(): string

public function getSubNodes(): array
{
return $this->chain;
$res = [];
foreach ($this->chain as &$item) {
$res[] = &$item;
}
return $res;
}
}
6 changes: 5 additions & 1 deletion src/Neon/Node/EntityNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public function toString(): string

public function getSubNodes(): array
{
return array_merge([$this->value], $this->attributes);
$res = [&$this->value];
foreach ($this->attributes as &$item) {
$res[] = &$item;
}
return $res;
}
}
10 changes: 5 additions & 5 deletions src/Neon/Traverser.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
/** @internal */
final class Traverser
{
/** @var callable(Node): void */
/** @var callable(Node): ?Node */
private $callback;


/** @param callable(Node): void $callback */
/** @param callable(Node): ?Node $callback */
public function traverse(Node $node, callable $callback): Node
{
$this->callback = $callback;
Expand All @@ -27,9 +27,9 @@ public function traverse(Node $node, callable $callback): Node

private function traverseNode(Node $node): Node
{
($this->callback)($node);
foreach ($node->getSubNodes() as $subnode) {
$this->traverseNode($subnode);
$node = ($this->callback)($node) ?? $node;
foreach ($node->getSubNodes() as &$subnode) {
$subnode = $this->traverseNode($subnode);
}
return $node;
}
Expand Down
40 changes: 40 additions & 0 deletions tests/Neon/Traverser.alter.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

use Nette\Neon;
use Nette\Neon\Node;
use Tester\Assert;


require __DIR__ . '/../bootstrap.php';

$visitor = function (Node $node) {
return clone $node;
};

$decoder = new Neon\Decoder;
$node = $decoder->parseToNode('
a: foo(1, 2, 3)
');

$traverser = new Neon\Traverser;
$newNode = $traverser->traverse($node, $visitor);

Assert::equal($node, $newNode);
Assert::notSame($node, $newNode);

Assert::equal($node->items[0], $newNode->items[0]);
Assert::notSame($node->items[0], $newNode->items[0]);

Assert::equal($node->items[0]->key, $newNode->items[0]->key);
Assert::notSame($node->items[0]->key, $newNode->items[0]->key);

Assert::equal($node->items[0]->value, $newNode->items[0]->value);
Assert::notSame($node->items[0]->value, $newNode->items[0]->value);

Assert::equal($node->items[0]->value->value, $newNode->items[0]->value->value);
Assert::notSame($node->items[0]->value->value, $newNode->items[0]->value->value);

Assert::equal($node->items[0]->value->attributes[0], $newNode->items[0]->value->attributes[0]);
Assert::notSame($node->items[0]->value->attributes[0], $newNode->items[0]->value->attributes[0]);

0 comments on commit 1f4e5f6

Please sign in to comment.