Lines Matching refs:node
4 The most common way to work with the AST is by using a node traverser and one or more node visitors.
13 public function leaveNode(Node $node) {
14 if ($node instanceof Node\Scalar\Int_) {
15 return new Node\Scalar\String_((string) $node->value);
39 Each node visitor implements an interface with following four methods:
44 public function enterNode(Node $node);
45 public function leaveNode(Node $node);
54 The `enterNode()` method is called when a node is first encountered, before its children are
93 the node will have already been visited and necessary information collected.
102 There are a number of ways in which the AST can be modified from inside a node visitor. The first
106 public function leaveNode(Node $node) {
107 if ($node instanceof Node\Scalar\LNumber) {
109 $node->value++;
114 The second is to replace a node entirely by returning a new node:
117 public function leaveNode(Node $node) {
118 if ($node instanceof Node\Expr\BinaryOp\BooleanAnd) {
120 return new Node\Expr\BooleanNot($node);
126 where you perform the replacement: If a node is replaced in enterNode, then the recursive traversal
127 will also consider the children of the new node. If you aren't careful, this can lead to infinite
131 public function enterNode(Node $node) {
132 if ($node instanceof Node\Expr\BinaryOp\BooleanAnd) {
134 return new Node\Expr\BooleanNot($node);
143 Finally, there are three special replacement types. The first is removal of a node:
146 public function leaveNode(Node $node) {
147 if ($node instanceof Node\Stmt\Return_) {
156 more node types like `Arg` or `Expr\ArrayItem`, which are also always part of lists).
163 public function leaveNode(Node $node) {
164 if ($node instanceof Node\Stmt\Expression
165 && $node->expr instanceof Node\Expr\FuncCall
166 && $node->expr->name instanceof Node\Name
167 && $node->expr->name->toString() === 'var_dump'
182 public function leaveNode(Node $node) {
183 if ($node instanceof Node\Stmt\Else_) {
189 This is only safe to do if the subnode the node is stored in is nullable. `Node\Stmt\Else_` only
192 Next to removing nodes, it is also possible to replace one node with multiple nodes. This
196 public function leaveNode(Node $node) {
197 if ($node instanceof Node\Stmt\Return_ && $node->expr !== null) {
201 new Node\Stmt\Expression(new Node\Expr\Assign($var, $node->expr)),
218 instruct the traverser to not recurse into the class node:
222 public function enterNode(Node $node) {
223 if ($node instanceof Node\Stmt\Class_) {
224 $this->classes[] = $node;
233 If you are only looking for one specific node, it is also possible to abort the traversal entirely
234 after finding it. For example, if you are looking for the node of a class with a certain name (and
240 public function enterNode(Node $node) {
241 if ($node instanceof Node\Stmt\Class_ &&
242 $node->namespacedName->toString() === 'Foo\Bar\Baz'
244 $this->class = $node;
289 That is, when visiting a node, `enterNode()` and `leaveNode()` will always be called for all
310 visitors, and all *subsequent* visitors will not visit the current node.
312 * If a visitor returns a replacement node, subsequent visitors will be passed the replacement node,
314 * If a visitor returns `REMOVE_NODE`, subsequent visitors will not see this node.
315 * If a visitor returns `REPLACE_WITH_NULL`, subsequent visitors will not see this node.
316 * If a visitor returns an array of replacement nodes, subsequent visitors will see neither the node
319 Simple node finding
322 While the node visitor mechanism is very flexible, creating a node visitor can be overly cumbersome
324 satisfy a certain callback, or which are instances of a certain node type. A couple of examples are
336 $extendingClasses = $nodeFinder->find($stmts, function(Node $node) {
337 return $node instanceof Node\Stmt\Class_
338 && $node->extends !== null;
345 $class = $nodeFinder->findFirst($stmts, function(Node $node) use ($name) {
346 return $node instanceof Node\Stmt\Class_
347 && $node->resolvedName->toString() === $name;
351 Internally, the `NodeFinder` also uses a node traverser. It only simplifies the interface for a
357 The node visitor mechanism is somewhat rigid, in that it prescribes an order in which nodes should
359 reverse direction: When working on a node, you might want to check if the parent node satisfies a