Skip to content

Commit 1f4e5f6

Browse files
committed
Traverser: can return different nodes
1 parent ef691f8 commit 1f4e5f6

File tree

6 files changed

+61
-9
lines changed

6 files changed

+61
-9
lines changed

src/Neon/Node/ArrayItemNode.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,6 @@ public function toString(): string
8585

8686
public function getSubNodes(): array
8787
{
88-
return $this->key ? [$this->key, $this->value] : [$this->value];
88+
return $this->key ? [&$this->key, &$this->value] : [&$this->value];
8989
}
9090
}

src/Neon/Node/ArrayNode.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public function toString(): string
5353

5454
public function getSubNodes(): array
5555
{
56-
return $this->items;
56+
$res = [];
57+
foreach ($this->items as &$item) {
58+
$res[] = &$item;
59+
}
60+
return $res;
5761
}
5862
}

src/Neon/Node/EntityChainNode.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public function toString(): string
4646

4747
public function getSubNodes(): array
4848
{
49-
return $this->chain;
49+
$res = [];
50+
foreach ($this->chain as &$item) {
51+
$res[] = &$item;
52+
}
53+
return $res;
5054
}
5155
}

src/Neon/Node/EntityNode.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public function toString(): string
5252

5353
public function getSubNodes(): array
5454
{
55-
return array_merge([$this->value], $this->attributes);
55+
$res = [&$this->value];
56+
foreach ($this->attributes as &$item) {
57+
$res[] = &$item;
58+
}
59+
return $res;
5660
}
5761
}

src/Neon/Traverser.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
/** @internal */
1414
final class Traverser
1515
{
16-
/** @var callable(Node): void */
16+
/** @var callable(Node): ?Node */
1717
private $callback;
1818

1919

20-
/** @param callable(Node): void $callback */
20+
/** @param callable(Node): ?Node $callback */
2121
public function traverse(Node $node, callable $callback): Node
2222
{
2323
$this->callback = $callback;
@@ -27,9 +27,9 @@ public function traverse(Node $node, callable $callback): Node
2727

2828
private function traverseNode(Node $node): Node
2929
{
30-
($this->callback)($node);
31-
foreach ($node->getSubNodes() as $subnode) {
32-
$this->traverseNode($subnode);
30+
$node = ($this->callback)($node) ?? $node;
31+
foreach ($node->getSubNodes() as &$subnode) {
32+
$subnode = $this->traverseNode($subnode);
3333
}
3434
return $node;
3535
}

tests/Neon/Traverser.alter.phpt

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nette\Neon;
6+
use Nette\Neon\Node;
7+
use Tester\Assert;
8+
9+
10+
require __DIR__ . '/../bootstrap.php';
11+
12+
$visitor = function (Node $node) {
13+
return clone $node;
14+
};
15+
16+
$decoder = new Neon\Decoder;
17+
$node = $decoder->parseToNode('
18+
a: foo(1, 2, 3)
19+
');
20+
21+
$traverser = new Neon\Traverser;
22+
$newNode = $traverser->traverse($node, $visitor);
23+
24+
Assert::equal($node, $newNode);
25+
Assert::notSame($node, $newNode);
26+
27+
Assert::equal($node->items[0], $newNode->items[0]);
28+
Assert::notSame($node->items[0], $newNode->items[0]);
29+
30+
Assert::equal($node->items[0]->key, $newNode->items[0]->key);
31+
Assert::notSame($node->items[0]->key, $newNode->items[0]->key);
32+
33+
Assert::equal($node->items[0]->value, $newNode->items[0]->value);
34+
Assert::notSame($node->items[0]->value, $newNode->items[0]->value);
35+
36+
Assert::equal($node->items[0]->value->value, $newNode->items[0]->value->value);
37+
Assert::notSame($node->items[0]->value->value, $newNode->items[0]->value->value);
38+
39+
Assert::equal($node->items[0]->value->attributes[0], $newNode->items[0]->value->attributes[0]);
40+
Assert::notSame($node->items[0]->value->attributes[0], $newNode->items[0]->value->attributes[0]);

0 commit comments

Comments
 (0)