Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions packages/fractor-typoscript/src/AbstractTypoScriptFractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<Statement> $statements
*/
Expand All @@ -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);

Expand All @@ -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;
}

/**
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Statement> $statements
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace a9f\FractorTypoScript\NodeTraverser;

use a9f\Fractor\Application\ValueObject\File;
use a9f\FractorTypoScript\NodeVisitor\CallableStatementVisitor;
use a9f\FractorTypoScript\TypoScriptStatementsIterator;
use Helmich\TypoScriptParser\Parser\AST\Statement;

final class SimpleCallableStatementTraverser
{
public function traverseNodesWithCallable(?Statement $statement, callable $callable): void
{
if ($statement === null) {
return;
}
$callableStatementVisitor = new CallableStatementVisitor($callable);

$nodeTraverser = new TypoScriptStatementsIterator([$callableStatementVisitor]);
$nodeTraverser->traverseDocument(new File('', ''), [$statement]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace a9f\FractorTypoScript\NodeVisitor;

use a9f\FractorTypoScript\TypoScriptStatementsIterator;
use Helmich\TypoScriptParser\Parser\AST\Statement;

final class CallableStatementVisitor extends StatementVisitorAbstract
{
/**
* @var callable(Statement): (Statement|int|null)
*/
private $callable;

private ?int $statementIdToRemove = null;

public function __construct(callable $callable)
{
$this->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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace a9f\FractorTypoScript\NodeVisitor;

use a9f\Fractor\Application\ValueObject\File;
use a9f\FractorTypoScript\Contract\TypoScriptNodeVisitor;
use Helmich\TypoScriptParser\Parser\AST\Statement;

abstract class StatementVisitorAbstract implements TypoScriptNodeVisitor
{
public function beforeTraversal(File $file, array $statements): void
{
}

public function enterNode(Statement $node): int|null|Statement
{
return null;
}

public function leaveNode(Statement $node): int|null|Statement
{
return null;
}

public function afterTraversal(array $statements): void
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private function processStatementList(array $statements): array
return array_merge(...$resultingStatements);
}

private function traverseNode(Statement $node): int|Statement
private function traverseNode(Statement $node): int|Statement|null
{
$lastCalledVisitor = null;
$result = $node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ public function enterNode(Statement $node): Statement|int
return $node;
}

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

/**
Expand Down