nitc :: ANode :: defaultinit
# Root of the AST class-hierarchy
abstract class ANode
# Location is set during AST building. Once built, location can not be null.
# However, manual instantiated nodes may need more care.
var location: Location is writable, noinit
# The location of the important part of the node (identifier or whatever)
fun hot_location: Location do return location
# Display a message for the colored location of the node
fun debug(message: String)
do
sys.stderr.write "{hot_location} {self.class_name}: {message}\n{hot_location.colored_line("0;32")}\n"
end
# Is `self` a token or a pure-structural production like `AQId`?
fun is_structural: Bool do return false
# Write the subtree on stdout.
#
# Visit the subtree and display it with additional and useful information.
#
# By default, this displays all kind of nodes and the corresponding lines of codes.
#
# See `ASTDump` for details.
fun dump_tree(display_structural, display_line: nullable Bool)
do
var d = new ASTDump(display_structural or else true, display_line or else true)
d.enter_visit(self)
d.write_to(sys.stdout)
end
# Information to display on a node
#
# Refine this method to add additional information on each node type.
fun dump_info(v: ASTDump): String do return ""
# Parent of the node in the AST
var parent: nullable ANode = null
# The topmost ancestor of the element
# This just apply `parent` until the first one
fun root: ANode
do
var res = self
loop
var p = res.parent
if p == null then return res
res = p
end
end
# The most specific common parent between `self` and `other`
# Return null if the two node are unrelated (distinct root)
fun common_parent(other: ANode): nullable ANode
do
# First, get the same depth
var s: nullable ANode = self
var o: nullable ANode = other
var d = s.depth - o.depth
while d > 0 do
s = s.parent
d -= 1
end
while d < 0 do
o = o.parent
d += 1
end
assert o.depth == s.depth
# Second, go up until same in found
while s != o do
s = s.parent
o = o.parent
end
return s
end
# Number of nodes between `self` and the `root` of the AST
# ENSURE `self == self.root implies result == 0 `
# ENSURE `self != self.root implies result == self.parent.depth + 1`
fun depth: Int
do
var n = self
var res = 0
loop
var p = n.parent
if p == null then return res
n = p
res += 1
end
end
# Replace a child with an other node in the AST
private fun replace_child(old_child: ANode, new_child: nullable ANode) is abstract
# Detach a node from its parent
# Aborts if the node is not detachable. use `replace_with` instead
# REQUIRE: parent != null
# REQUIRE: is_detachable
# ENDURE: parent == null
fun detach
do
assert parent != null
parent.replace_child(self, null)
parent = null
end
# Replace itself with an other node in the AST
# REQUIRE: parent != null
# ENSURE: node.parent == old(parent)
# ENSURE: parent == null
fun replace_with(node: ANode)
do
assert parent != null
parent.replace_child(self, node)
parent = null
end
# Visit all nodes in order.
# Thus, call `v.enter_visit(e)` for each child `e`
fun visit_all(v: Visitor) is abstract
# Do a deep search and return an array of tokens that match a given text
fun collect_tokens_by_text(text: String): Array[Token]
do
var v = new CollectTokensByTextVisitor(text)
v.enter_visit(self)
return v.result
end
# Do a deep search and return an array of node that are annotated
# The attached node can be retrieved by two invocations of parent
fun collect_annotations_by_name(name: String): Array[AAnnotation]
do
var v = new CollectAnnotationsByNameVisitor(name)
v.enter_visit(self)
return v.result
end
end
src/parser/parser_nodes.nit:23,1--161,3