Skip to content

Commit

Permalink
added Traverser
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Oct 19, 2021
1 parent 8747352 commit 1dc9962
Show file tree
Hide file tree
Showing 8 changed files with 460 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/Neon/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,11 @@ abstract class Node

/** @return mixed */
abstract public function toValue();


/** @return self[] */
public function getSubNodes(): array
{
return [];
}
}
6 changes: 6 additions & 0 deletions src/Neon/Node/ArrayItemNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,10 @@ public function toValue()
{
throw new \LogicException;
}


public function getSubNodes(): array
{
return $this->key ? [$this->key, $this->value] : [$this->value];
}
}
6 changes: 6 additions & 0 deletions src/Neon/Node/ArrayNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,10 @@ public function toValue(): array
{
return ArrayItemNode::itemsToArray($this->items);
}


public function getSubNodes(): array
{
return $this->items;
}
}
6 changes: 6 additions & 0 deletions src/Neon/Node/EntityChainNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@ public function toValue(): Neon\Entity
}
return new Neon\Entity(Neon\Neon::CHAIN, $entities);
}


public function getSubNodes(): array
{
return $this->chain;
}
}
36 changes: 36 additions & 0 deletions src/Neon/Traverser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/**
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*/

declare(strict_types=1);

namespace Nette\Neon;


/** @internal */
final class Traverser
{
/** @var callable(Node): void */
private $callback;


/** @param callable(Node): void $callback */
public function traverse(Node $node, callable $callback): Node
{
$this->callback = $callback;
return $this->traverseNode($node);
}


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

declare(strict_types=1);

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


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


$input = '
# hello
first: # first comment
# another comment
- a # a comment
next:
- [k,
l, m:
n]
second:
sub:
a: 1
b: 2
third:
- entity(a: 1)
- entity(a: 1)foo()bar
# world
';


$lexer = new Neon\Lexer;
$parser = new Neon\Parser;
$stream = $lexer->tokenize($input);
$node = $parser->parse($stream);

$traverser = new Traverser;
$traverser->traverse($node, function (Node $node) use ($stream) {
$node->code = '';
foreach (array_slice($stream->getTokens(), $node->startPos, $node->endPos - $node->startPos + 1) as $token) {
$node->code .= $token->value;
}
unset($node->startPos, $node->endPos);
});

Assert::matchFile(__DIR__ . '/fixtures/Parser.nodes.txt', var_export($node, true));
34 changes: 34 additions & 0 deletions tests/Neon/Traverser.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

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


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

$visitor = function (Node $node) {
if ($node instanceof Node\EntityNode) {
foreach ($node->attributes as $i => $attr) {
$attr->key = $attr->key ?? new Node\LiteralNode("key$i");
}
}
};

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

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

Assert::equal([
'a' => new Nette\Neon\Entity(
'foo',
['key0' => 1, 'key1' => 2, 'key2' => 3]
),
], $value);

0 comments on commit 1dc9962

Please sign in to comment.