Skip to content

Commit ffec951

Browse files
committed
[FEATURE] Add traverseStatementsWithCallable
1 parent 5c01876 commit ffec951

File tree

7 files changed

+120
-6
lines changed

7 files changed

+120
-6
lines changed

packages/fractor-typoscript/src/AbstractTypoScriptFractor.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@
77
use a9f\Fractor\Application\ValueObject\AppliedRule;
88
use a9f\Fractor\Application\ValueObject\File;
99
use a9f\FractorTypoScript\Contract\TypoScriptFractor;
10+
use a9f\FractorTypoScript\NodeTraverser\SimpleCallableStatementTraverser;
1011
use Helmich\TypoScriptParser\Parser\AST\Statement;
1112

1213
abstract class AbstractTypoScriptFractor implements TypoScriptFractor
1314
{
1415
protected File $file;
1516

17+
protected bool $hasChanged = false;
18+
19+
public function __construct(
20+
private readonly SimpleCallableStatementTraverser $simpleCallableStatementTraverser
21+
) {
22+
}
23+
1624
/**
1725
* @param list<Statement> $statements
1826
*/
@@ -21,7 +29,7 @@ final public function beforeTraversal(File $file, array $statements): void
2129
$this->file = $file;
2230
}
2331

24-
final public function enterNode(Statement $node): Statement|int
32+
final public function enterNode(Statement $node): Statement|int|null
2533
{
2634
$result = $this->refactor($node);
2735

@@ -35,8 +43,9 @@ final public function enterNode(Statement $node): Statement|int
3543
return $result;
3644
}
3745

38-
final public function leaveNode(Statement $node): void
46+
final public function leaveNode(Statement $node): int|Statement|null
3947
{
48+
return null;
4049
}
4150

4251
/**
@@ -45,4 +54,9 @@ final public function leaveNode(Statement $node): void
4554
final public function afterTraversal(array $statements): void
4655
{
4756
}
57+
58+
protected function traverseStatementsWithCallable(?Statement $statement, callable $callable): void
59+
{
60+
$this->simpleCallableStatementTraverser->traverseNodesWithCallable($statement, $callable);
61+
}
4862
}

packages/fractor-typoscript/src/Contract/TypoScriptNodeVisitor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ interface TypoScriptNodeVisitor
1717
*/
1818
public function beforeTraversal(File $file, array $statements): void;
1919

20-
public function enterNode(Statement $node): Statement|int;
20+
public function enterNode(Statement $node): Statement|int|null;
2121

22-
public function leaveNode(Statement $node): void;
22+
public function leaveNode(Statement $node): Statement|int|null;
2323

2424
/**
2525
* @param list<Statement> $statements
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorTypoScript\NodeTraverser;
6+
7+
use a9f\Fractor\Application\ValueObject\File;
8+
use a9f\FractorTypoScript\NodeVisitor\CallableStatementVisitor;
9+
use a9f\FractorTypoScript\TypoScriptStatementsIterator;
10+
use Helmich\TypoScriptParser\Parser\AST\Statement;
11+
12+
final class SimpleCallableStatementTraverser
13+
{
14+
public function traverseNodesWithCallable(?Statement $statement, callable $callable): void
15+
{
16+
if ($statement === null) {
17+
return;
18+
}
19+
$callableStatementVisitor = new CallableStatementVisitor($callable);
20+
21+
$nodeTraverser = new TypoScriptStatementsIterator([$callableStatementVisitor]);
22+
$nodeTraverser->traverseDocument(new File('', ''), [$statement]);
23+
}
24+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorTypoScript\NodeVisitor;
6+
7+
use a9f\FractorTypoScript\TypoScriptStatementsIterator;
8+
use Helmich\TypoScriptParser\Parser\AST\Statement;
9+
10+
final class CallableStatementVisitor extends StatementVisitorAbstract
11+
{
12+
/**
13+
* @var callable(Statement): (Statement|int|null)
14+
*/
15+
private $callable;
16+
17+
private ?int $statementIdToRemove = null;
18+
19+
public function __construct(callable $callable)
20+
{
21+
$this->callable = $callable;
22+
}
23+
24+
public function enterNode(Statement $node): int|null|Statement
25+
{
26+
$originalStatement = $node;
27+
$callable = $this->callable;
28+
/** @var int|Statement|null $newStatement */
29+
$newStatement = $callable($node);
30+
if ($newStatement === TypoScriptStatementsIterator::REMOVE_NODE) {
31+
$this->statementIdToRemove = \spl_object_id($originalStatement);
32+
return $originalStatement;
33+
}
34+
return $newStatement;
35+
}
36+
37+
public function leaveNode(Statement $node): int|Statement
38+
{
39+
if ($this->statementIdToRemove !== null && $this->statementIdToRemove === \spl_object_id($node)) {
40+
$this->statementIdToRemove = null;
41+
return TypoScriptStatementsIterator::REMOVE_NODE;
42+
}
43+
return $node;
44+
}
45+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace a9f\FractorTypoScript\NodeVisitor;
6+
7+
use a9f\Fractor\Application\ValueObject\File;
8+
use a9f\FractorTypoScript\Contract\TypoScriptNodeVisitor;
9+
use Helmich\TypoScriptParser\Parser\AST\Statement;
10+
11+
abstract class StatementVisitorAbstract implements TypoScriptNodeVisitor
12+
{
13+
public function beforeTraversal(File $file, array $statements): void
14+
{
15+
}
16+
17+
public function enterNode(Statement $node): int|null|Statement
18+
{
19+
return null;
20+
}
21+
22+
public function leaveNode(Statement $node): int|null|Statement
23+
{
24+
return null;
25+
}
26+
27+
public function afterTraversal(array $statements): void
28+
{
29+
}
30+
}

packages/fractor-typoscript/src/TypoScriptStatementsIterator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ private function processStatementList(array $statements): array
6969
return array_merge(...$resultingStatements);
7070
}
7171

72-
private function traverseNode(Statement $node): int|Statement
72+
private function traverseNode(Statement $node): int|Statement|null
7373
{
7474
$lastCalledVisitor = null;
7575
$result = $node;

packages/fractor-typoscript/tests/TypoScriptStatementsIterator/Fixture/StatementCollectingVisitor.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ public function enterNode(Statement $node): Statement|int
3333
return $node;
3434
}
3535

36-
public function leaveNode(Statement $node): void
36+
public function leaveNode(Statement $node): int|Statement|null
3737
{
3838
$this->calls[] = sprintf('%s:leaveNode:%s:l-%d', $this->visitorName, $node::class, $node->sourceLine);
39+
return $node;
3940
}
4041

4142
/**

0 commit comments

Comments
 (0)