public abstract class Node extends Object implements NodeInterface, Cloneable
| Modifier and Type | Class and Description |
|---|---|
static interface |
Node.Child
Marks fields that represent child nodes of this node.
|
static interface |
Node.Children
Marks array fields that are children of this node.
|
| Modifier | Constructor and Description |
|---|---|
protected |
Node() |
| Modifier and Type | Method and Description |
|---|---|
void |
accept(NodeVisitor nodeVisitor)
Invokes the
NodeVisitor.visit(Node) method for this node and recursively also for all
child nodes. |
void |
adoptChildren() |
<T> T |
atomic(Callable<T> closure) |
void |
atomic(Runnable closure) |
Node |
copy()
Creates a shallow copy of this node.
|
Node |
deepCopy()
Creates a deep copy of this node.
|
Iterable<Node> |
getChildren()
Iterator over the children of this node.
|
NodeCost |
getCost()
Returns a rough estimate for the cost of this
Node. |
Map<String,Object> |
getDebugProperties()
Returns properties of this node interesting for debugging and can be overwritten by
subclasses to add their own custom properties.
|
String |
getDescription()
Returns a user-readable description of the purpose of the Node, or "" if no description is
available.
|
SourceSection |
getEncapsulatingSourceSection()
Retrieves the segment of guest language source code that is represented by this Node, if
present; otherwise retrieves the segment represented by the nearest AST ancestor that has
this information.
|
protected Lock |
getLock()
Returns a lock object that can be used to synchronize modifications to the AST.
|
Node |
getParent()
The current parent node of this node.
|
RootNode |
getRootNode()
Get the root node of the tree a node belongs to.
|
SourceSection |
getSourceSection()
Retrieves the segment of guest language source code that is represented by this Node.
|
protected <T extends Node> |
insert(T newChild)
Method that updates the link to the parent in the specified new child node to this node.
|
protected <T extends Node> |
insert(T[] newChildren)
Method that updates the link to the parent in the array of specified new child nodes to this
node.
|
boolean |
isSafelyReplaceableBy(Node newNode)
Checks if this node can be replaced by another node: tree structure & type.
|
protected boolean |
isTaggedWith(Class<?> tag)
Returns
true if this node should be considered tagged by a given tag else
false. |
protected void |
onReplace(Node newNode,
CharSequence reason)
Intended to be implemented by subclasses of
Node to receive a notification when the
node is rewritten. |
<T extends Node> |
replace(T newNode)
Replaces this node with another node.
|
<T extends Node> |
replace(T newNode,
CharSequence reason)
Replaces this node with another node.
|
String |
toString()
Converts this node to a textual representation useful for debugging.
|
public NodeCost getCost()
Node. This estimate can be used by
runtime systems or guest languages to implement heuristics based on Truffle ASTs. This method
is intended to be overridden by subclasses. The default implementation returns the value of
NodeInfo.cost() of the NodeInfo annotation declared at the subclass. If no
NodeInfo annotation is declared the method returns NodeCost.MONOMORPHIC as a
default value.public SourceSection getSourceSection()
null. If your node represents a
segment of the source code, override this method and return a final or
CompilerDirectives.CompilationFinal field in your node to the caller.
To define node with fixed SourceSection that doesn't change after node
construction use:
private finalTo create a node which can associate and change theSourceSectionsection; NodeWithFixedSourceSection(SourceSectionsection) { this.section = section; } @OverridepublicSourceSectiongetSourceSection() { return section; }
SourceSection later at any point
of time use:
@CompilerDirectives.CompilerDirectives.CompilationFinalprivateSourceSectionsection; final void changeSourceSection(SourceSectionsourceSection) {CompilerDirectives.transferToInterpreterAndInvalidate(); this.section = sourceSection; } @OverridepublicSourceSectiongetSourceSection() { return section; }
public SourceSection getEncapsulatingSourceSection()
protected final <T extends Node> T[] insert(T[] newChildren)
newChildren - the array of new children whose parent should be updatedprotected final <T extends Node> T insert(T newChild)
newChild - the new child whose parent should be updatedpublic final void adoptChildren()
public Map<String,Object> getDebugProperties()
public final Node getParent()
public final <T extends Node> T replace(T newNode, CharSequence reason)
Node.getSourceSection()) associated with this node, it is transferred to the new node.newNode - the new node that is the replacementreason - a description of the reason for the replacementpublic final <T extends Node> T replace(T newNode)
Node.getSourceSection()) associated with this node, it is transferred to the new node.newNode - the new node that is the replacementpublic final boolean isSafelyReplaceableBy(Node newNode)
protected void onReplace(Node newNode, CharSequence reason)
Node to receive a notification when the
node is rewritten. This method is invoked before the actual replace has happened.newNode - the replacement nodereason - the reason the replace suppliedpublic final void accept(NodeVisitor nodeVisitor)
NodeVisitor.visit(Node) method for this node and recursively also for all
child nodes.nodeVisitor - the visitorpublic final Iterable<Node> getChildren()
public Node copy()
public Node deepCopy()
public final RootNode getRootNode()
RootNode or null if there is none.public String toString()
public final void atomic(Runnable closure)
public final <T> T atomic(Callable<T> closure)
protected final Lock getLock()
protected boolean isTaggedWith(Class<?> tag)
true if this node should be considered tagged by a given tag else
false. The method is only invoked for tags which are explicitly declared as
provided by the
language. If the source section of the
node returns null then this node is considered to be not tagged by any tag.
Tags are used by guest languages to indicate that a node is a member of a
certain category of nodes. For example a debugger
instrument might require a
guest language to tag all nodes as halt locations that should be considered as such.
The node implementor may decide how to implement tagging for nodes. The simplest way to
implement tagging using Java types is by overriding the Node.isTaggedWith(Class) method.
This example shows how to tag a node subclass and all its subclasses as expression and
statement:
class ExpressionNode extendsNode{ @Overrideprotected boolean isTaggedWith(Class<?> tag) { if (tag == ExpressionTag.class) { return true; } return super.isTaggedWith(tag); } }
Often it is impossible to just rely on the node's Java type to implement tagging. This example shows how to use local state to implement tagging for a node.
class StatementNode extendsNode{ private boolean isDebuggerHalt; public void setDebuggerHalt(boolean isDebuggerHalt) { this.isDebuggerHalt = isDebuggerHalt; } @Overrideprotected boolean isTaggedWith(Class<?> tag) { if (tag ==Debugger.HaltTag.class) { return isDebuggerHalt; } return super.isTaggedWith(tag); } }
The implementation of isTaggedWith method must ensure that its result is stable after the
parent root node was wrapped in a CallTarget using
TruffleRuntime.createCallTarget(RootNode). The result is stable if the result of
calling this method for a particular tag remains always the same.
public String getDescription()