Property definitions

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