2

Im using https://github.com/nikic/PHP-Parser. What is a good strategy when wanting to INSERT a node in the AST? With the traverser I can UPDATE and DELETE nodes easily using a NodeTraverser class. But how can I "INSERT before" or "INSERT after" a node?

Example: When traversing an AST namespace I want to INSERT a Use statement just before the first non-use statement.

I started working with beforeTraverse and afterTraverse to find indexes of arrays but it seems overly complicated. Any ideas?

ajthinking
  • 3,386
  • 8
  • 45
  • 75

1 Answers1

2

It is possible to replace one node with multiple nodes. This only works inside leaveNode and only if the parent structure is an array.

public function leaveNode(Node $node) {
    if ($node instanceof Node\Stmt\Return_ && $node->expr !== null) {
        // Convert "return foo();" into "$retval = foo(); return $retval;"
        $var = new Node\Expr\Variable('retval');
        return [
            new Node\Stmt\Expression(new Node\Expr\Assign($var, $node->expr)),
            new Node\Stmt\Return_($var),
        ];
    }
}

See last section in Modyfing the AST

ajthinking
  • 3,386
  • 8
  • 45
  • 75
  • Insufficient in my case. I need to add a `use` statement in the namespace, but ONLY IF the alias will actually be used in the class defined later inside that same `Namespace_` node. At the moment of `leave()`ing the `Use_` node, I haven't even begun visiting the `Class_` node and determining whether I will be making changes to it that will make use of the class I might want to `Use_`. So I must record that information in the visitor, and apply it when leaving the `Namespace_` node. – Szczepan Hołyszewski Nov 28 '22 at 20:26