From ffec9512f04d0d273b545801581f0150160a6474 Mon Sep 17 00:00:00 2001 From: Simon Schaufelberger Date: Sun, 24 Nov 2024 13:28:27 +0100 Subject: [PATCH] [FEATURE] Add traverseStatementsWithCallable --- .../src/AbstractTypoScriptFractor.php | 18 +++++++- .../src/Contract/TypoScriptNodeVisitor.php | 4 +- .../SimpleCallableStatementTraverser.php | 24 ++++++++++ .../NodeVisitor/CallableStatementVisitor.php | 45 +++++++++++++++++++ .../NodeVisitor/StatementVisitorAbstract.php | 30 +++++++++++++ .../src/TypoScriptStatementsIterator.php | 2 +- .../Fixture/StatementCollectingVisitor.php | 3 +- 7 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 packages/fractor-typoscript/src/NodeTraverser/SimpleCallableStatementTraverser.php create mode 100644 packages/fractor-typoscript/src/NodeVisitor/CallableStatementVisitor.php create mode 100644 packages/fractor-typoscript/src/NodeVisitor/StatementVisitorAbstract.php diff --git a/packages/fractor-typoscript/src/AbstractTypoScriptFractor.php b/packages/fractor-typoscript/src/AbstractTypoScriptFractor.php index ccf1844e..9c3c59ef 100644 --- a/packages/fractor-typoscript/src/AbstractTypoScriptFractor.php +++ b/packages/fractor-typoscript/src/AbstractTypoScriptFractor.php @@ -7,12 +7,20 @@ use a9f\Fractor\Application\ValueObject\AppliedRule; use a9f\Fractor\Application\ValueObject\File; use a9f\FractorTypoScript\Contract\TypoScriptFractor; +use a9f\FractorTypoScript\NodeTraverser\SimpleCallableStatementTraverser; use Helmich\TypoScriptParser\Parser\AST\Statement; abstract class AbstractTypoScriptFractor implements TypoScriptFractor { protected File $file; + protected bool $hasChanged = false; + + public function __construct( + private readonly SimpleCallableStatementTraverser $simpleCallableStatementTraverser + ) { + } + /** * @param list $statements */ @@ -21,7 +29,7 @@ final public function beforeTraversal(File $file, array $statements): void $this->file = $file; } - final public function enterNode(Statement $node): Statement|int + final public function enterNode(Statement $node): Statement|int|null { $result = $this->refactor($node); @@ -35,8 +43,9 @@ final public function enterNode(Statement $node): Statement|int return $result; } - final public function leaveNode(Statement $node): void + final public function leaveNode(Statement $node): int|Statement|null { + return null; } /** @@ -45,4 +54,9 @@ final public function leaveNode(Statement $node): void final public function afterTraversal(array $statements): void { } + + protected function traverseStatementsWithCallable(?Statement $statement, callable $callable): void + { + $this->simpleCallableStatementTraverser->traverseNodesWithCallable($statement, $callable); + } } diff --git a/packages/fractor-typoscript/src/Contract/TypoScriptNodeVisitor.php b/packages/fractor-typoscript/src/Contract/TypoScriptNodeVisitor.php index e915171e..db991e04 100644 --- a/packages/fractor-typoscript/src/Contract/TypoScriptNodeVisitor.php +++ b/packages/fractor-typoscript/src/Contract/TypoScriptNodeVisitor.php @@ -17,9 +17,9 @@ interface TypoScriptNodeVisitor */ public function beforeTraversal(File $file, array $statements): void; - public function enterNode(Statement $node): Statement|int; + public function enterNode(Statement $node): Statement|int|null; - public function leaveNode(Statement $node): void; + public function leaveNode(Statement $node): Statement|int|null; /** * @param list $statements diff --git a/packages/fractor-typoscript/src/NodeTraverser/SimpleCallableStatementTraverser.php b/packages/fractor-typoscript/src/NodeTraverser/SimpleCallableStatementTraverser.php new file mode 100644 index 00000000..0a5ce8f4 --- /dev/null +++ b/packages/fractor-typoscript/src/NodeTraverser/SimpleCallableStatementTraverser.php @@ -0,0 +1,24 @@ +traverseDocument(new File('', ''), [$statement]); + } +} diff --git a/packages/fractor-typoscript/src/NodeVisitor/CallableStatementVisitor.php b/packages/fractor-typoscript/src/NodeVisitor/CallableStatementVisitor.php new file mode 100644 index 00000000..b219573d --- /dev/null +++ b/packages/fractor-typoscript/src/NodeVisitor/CallableStatementVisitor.php @@ -0,0 +1,45 @@ +callable = $callable; + } + + public function enterNode(Statement $node): int|null|Statement + { + $originalStatement = $node; + $callable = $this->callable; + /** @var int|Statement|null $newStatement */ + $newStatement = $callable($node); + if ($newStatement === TypoScriptStatementsIterator::REMOVE_NODE) { + $this->statementIdToRemove = \spl_object_id($originalStatement); + return $originalStatement; + } + return $newStatement; + } + + public function leaveNode(Statement $node): int|Statement + { + if ($this->statementIdToRemove !== null && $this->statementIdToRemove === \spl_object_id($node)) { + $this->statementIdToRemove = null; + return TypoScriptStatementsIterator::REMOVE_NODE; + } + return $node; + } +} diff --git a/packages/fractor-typoscript/src/NodeVisitor/StatementVisitorAbstract.php b/packages/fractor-typoscript/src/NodeVisitor/StatementVisitorAbstract.php new file mode 100644 index 00000000..be628d56 --- /dev/null +++ b/packages/fractor-typoscript/src/NodeVisitor/StatementVisitorAbstract.php @@ -0,0 +1,30 @@ +calls[] = sprintf('%s:leaveNode:%s:l-%d', $this->visitorName, $node::class, $node->sourceLine); + return $node; } /**