///|
priv type TSNode Bytes
///|
struct Node {
node : TSNode
tree : Tree
}
///|
#borrow(self, tree)
extern "c" fn ts_node_type(self : TSNode, tree : Tree) -> @c.Pointer[Byte] = "moonbit_ts_node_type"
///|
/// Get the node's type as a string.
pub fn Node::type_(self : Node) -> String {
return decode_c_string(ts_node_type(self.node, self.tree)).unwrap()
}
///|
#borrow(self, tree)
extern "c" fn ts_node_symbol(self : TSNode, tree : Tree) -> Symbol = "moonbit_ts_node_symbol"
///|
/// Get the node's type as a numerical id.
pub fn Node::symbol(self : Node) -> Symbol {
return ts_node_symbol(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_language(self : TSNode, tree : Tree) -> Language = "moonbit_ts_node_language"
///|
/// Get the node's language.
pub fn Node::language(self : Node) -> Language {
return ts_node_language(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_grammar_type(
self : TSNode,
tree : Tree
) -> @c.Pointer[Byte] = "moonbit_ts_node_grammar_type"
///|
/// Get the node's type as it appears in the grammar ignoring aliases as a string.
pub fn Node::grammar_type(self : Node) -> String {
return decode_c_string(ts_node_grammar_type(self.node, self.tree)).unwrap()
}
///|
#borrow(self, tree)
extern "c" fn ts_node_grammar_symbol(self : TSNode, tree : Tree) -> Symbol = "moonbit_ts_node_grammar_symbol"
///|
/// Get the node's type as a numerical id as it appears in the grammar ignoring
/// aliases. This should be used in `Language::next_state` instead of
/// `Node::symbol`.
pub fn Node::grammar_symbol(self : Node) -> Symbol {
return ts_node_grammar_symbol(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_start_byte(self : TSNode, tree : Tree) -> Int = "moonbit_ts_node_start_byte"
///|
/// Get the node's start byte.
pub fn Node::start_byte(self : Node) -> Int {
return ts_node_start_byte(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_start_point(self : TSNode, tree : Tree) -> Point = "moonbit_ts_node_start_point"
///|
/// Get the node's start position in terms of rows and columns.
pub fn Node::start_point(self : Node) -> Point {
return ts_node_start_point(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_end_byte(self : TSNode, tree : Tree) -> Int = "moonbit_ts_node_end_byte"
///|
/// Get the node's end byte.
pub fn Node::end_byte(self : Node) -> Int {
return ts_node_end_byte(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_string(self : TSNode, tree : Tree) -> Bytes = "moonbit_ts_node_string"
///|
/// Get an S-expression representing the node as a string.
pub fn Node::string(self : Node) -> String {
return @encoding.decoder(UTF8).decode_lossy(
ts_node_string(self.node, self.tree),
)
}
///|
pub impl Show for Node with output(self : Node, logger : &@builtin.Logger) -> Unit {
logger.write_string(self.string())
}
///|
/// Get the node's end position in terms of rows and columns.
#borrow(self, tree)
extern "c" fn ts_node_end_point(self : TSNode, tree : Tree) -> Point = "moonbit_ts_node_end_point"
///|
pub fn Node::end_point(self : Node) -> Point {
return ts_node_end_point(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_is_null(self : TSNode, tree : Tree) -> Bool = "moonbit_ts_node_is_null"
///|
/// Check if the node is null. Functions like `Node::child` and
/// `Node::next_sibling` will return a null node to indicate that no such node
/// was found.
pub fn Node::is_null(self : Node) -> Bool {
return ts_node_is_null(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_is_named(self : TSNode, tree : Tree) -> Bool = "moonbit_ts_node_is_named"
///|
/// Check if the node is *named*. Named nodes correspond to named rules in the
/// grammar, whereas *anonymous* nodes correspond to string literals in the
/// grammar.
pub fn Node::is_named(self : Node) -> Bool {
return ts_node_is_named(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_is_missing(self : TSNode, tree : Tree) -> Bool = "moonbit_ts_node_is_missing"
///|
/// Check if the node is *missing*. Missing nodes are inserted by the parser in
/// order to recover from certain kinds of syntax errors.
pub fn Node::is_missing(self : Node) -> Bool {
return ts_node_is_missing(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_is_extra(self : TSNode, tree : Tree) -> Bool = "moonbit_ts_node_is_extra"
///|
/// Check if the node is *extra*. Extra nodes represent things like comments,
/// which are not required the grammar, but can appear anywhere.
pub fn Node::is_extra(self : Node) -> Bool {
return ts_node_is_extra(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_has_changes(self : TSNode, tree : Tree) -> Bool = "moonbit_ts_node_has_changes"
///|
/// Check if a syntax node has been edited.
pub fn Node::has_changes(self : Node) -> Bool {
return ts_node_has_changes(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_has_error(self : TSNode, tree : Tree) -> Bool = "moonbit_ts_node_has_error"
///|
/// Check if the node is a syntax error or contains any syntax errors.
pub fn Node::has_error(self : Node) -> Bool {
return ts_node_has_error(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_is_error(self : TSNode, tree : Tree) -> Bool = "moonbit_ts_node_is_error"
///|
/// Check if the node is a syntax error.
pub fn Node::is_error(self : Node) -> Bool {
return ts_node_is_error(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_parse_state(self : TSNode, tree : Tree) -> StateId = "moonbit_ts_node_parse_state"
///|
/// Get this node's parse state.
pub fn Node::parse_state(self : Node) -> StateId {
return ts_node_parse_state(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_next_parse_state(self : TSNode, tree : Tree) -> StateId = "moonbit_ts_node_next_parse_state"
///|
/// Get the parse state after this node.
pub fn Node::next_parse_state(self : Node) -> StateId {
return ts_node_next_parse_state(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_parent(self : TSNode, tree : Tree) -> TSNode = "moonbit_ts_node_parent"
///|
/// Get the node's immediate parent.
/// Prefer `Node::child_with_descendant` for iterating over the node's ancestors.
pub fn Node::parent(self : Node) -> Node? {
let parent = ts_node_parent(self.node, self.tree)
if ts_node_is_null(parent, self.tree) {
None
} else {
Some({ ..self, node: parent })
}
}
///|
#borrow(self, self_tree, descendant, descendant_tree)
extern "c" fn ts_node_child_with_descendant(
self : TSNode,
self_tree : Tree,
descendant : TSNode,
descendant_tree : Tree
) -> TSNode = "moonbit_ts_node_child_with_descendant"
///|
/// Get the node that contains `descendant`.
///
/// Note that this can return `descendant` itself.
pub fn Node::child_with_descendant(self : Node, descendant : Node) -> Node? {
let child = ts_node_child_with_descendant(
self.node,
self.tree,
descendant.node,
descendant.tree,
)
if ts_node_is_null(child, self.tree) {
None
} else {
Some({ ..self, node: child })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_child(self : TSNode, tree : Tree, index : UInt) -> TSNode = "moonbit_ts_node_child"
///|
fn int_to_uint(value : Int) -> UInt {
guard value >= 0
value.reinterpret_as_uint()
}
///|
fn uint_to_int(value : UInt) -> Int {
guard value <= @int.max_value.reinterpret_as_uint()
value.reinterpret_as_int()
}
///|
/// Get the node's child at the given index, where zero represents the first
/// child.
pub fn Node::child(self : Node, index : Int) -> Node? {
let index = int_to_uint(index)
let child = ts_node_child(self.node, self.tree, index)
if ts_node_is_null(child, self.tree) {
None
} else {
Some({ ..self, node: child })
}
}
///|
/// Get all children of the node.
pub fn Node::children(self : Node) -> Iter[Node] {
Iter::new(fn(yield_) {
for i in 0U.. return IterEnd
IterContinue => continue
}
}
IterContinue
})
}
///|
#borrow(self, tree)
extern "c" fn ts_node_field_name_for_child(
self : TSNode,
tree : Tree,
child_index : UInt
) -> @c.Pointer[Byte] = "moonbit_ts_node_field_name_for_child"
///|
/// Get the field name for node's child at the given index, where zero represents
/// the first child. Returns `None`, if no field is found.
pub fn Node::field_name_for_child(self : Node, child_index : Int) -> String? {
let child_index = int_to_uint(child_index)
let field_name = ts_node_field_name_for_child(
self.node,
self.tree,
child_index,
)
if field_name.is_null() {
return None
}
let buffer = @buffer.new()
for i = 0; field_name[i] != 0; i = i + 1 {
@buffer.write_byte(buffer, field_name[i])
}
let field_name = buffer.contents()
Some(@encoding.decoder(UTF8).decode_lossy(field_name))
}
///|
#borrow(self, tree)
extern "c" fn ts_node_field_name_for_named_child(
self : TSNode,
tree : Tree,
child_index : UInt
) -> @c.Pointer[Byte] = "moonbit_ts_node_field_name_for_named_child"
///|
/// Get the field name for node's named child at the given index, where zero
/// represents the first named child. Returns `None`, if no field is found.
pub fn Node::field_name_for_named_child(
self : Node,
child_index : Int
) -> String? {
let child_index = int_to_uint(child_index)
let field_name = ts_node_field_name_for_named_child(
self.node,
self.tree,
child_index,
)
if field_name.is_null() {
return None
}
let buffer = @buffer.new()
for i = 0; field_name[i] != 0; i = i + 1 {
@buffer.write_byte(buffer, field_name[i])
}
let field_name = buffer.contents()
Some(@encoding.decoder(UTF8).decode_lossy(field_name))
}
///|
#borrow(self, tree)
extern "c" fn ts_node_child_count(self : TSNode, tree : Tree) -> UInt = "moonbit_ts_node_child_count"
///|
/// Get the node's number of children.
pub fn Node::child_count(self : Node) -> Int {
uint_to_int(ts_node_child_count(self.node, self.tree))
}
///|
#borrow(self, tree)
extern "c" fn ts_node_named_child(
self : TSNode,
tree : Tree,
child_index : UInt
) -> TSNode = "moonbit_ts_node_named_child"
///|
/// Get the node's *named* child at the given index.
///
/// See also `Node::is_named`.
pub fn Node::named_child(self : Node, child_index : Int) -> Node? {
let child_index = int_to_uint(child_index)
let child = ts_node_named_child(self.node, self.tree, child_index)
if ts_node_is_null(child, self.tree) {
None
} else {
Some({ ..self, node: child })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_named_child_count(self : TSNode, tree : Tree) -> UInt = "moonbit_ts_node_named_child_count"
///|
/// Get the node's number of *named* children.
///
/// See also `Node::is_named`.
pub fn Node::named_child_count(self : Node) -> Int {
uint_to_int(ts_node_named_child_count(self.node, self.tree))
}
///|
/// Get all named children of the node.
pub fn Node::named_children(self : Node) -> Iter[Node] {
Iter::new(fn(yield_) {
for i in 0U.. return IterEnd
IterContinue => continue
}
}
IterContinue
})
}
///|
/// Get the node's child with the given field name.
#borrow(self, tree, name)
extern "c" fn ts_node_child_by_field_name(
self : TSNode,
tree : Tree,
name : Bytes
) -> TSNode = "moonbit_ts_node_child_by_field_name"
///|
/// Get the node's child with the given field name.
pub fn Node::child_by_field_name(self : Node, name : String) -> Node? {
let name_bytes = @encoding.encode(UTF8, name)
let child = ts_node_child_by_field_name(self.node, self.tree, name_bytes)
if ts_node_is_null(child, self.tree) {
None
} else {
Some({ ..self, node: child })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_child_by_field_id(
self : TSNode,
tree : Tree,
id : FieldId
) -> TSNode = "moonbit_ts_node_child_by_field_id"
///|
/// Get the node's child with the given numerical field id.
///
/// You can convert a field name to an id using the
/// `Language::field_id_for_name` function.
pub fn Node::child_by_field_id(self : Node, id : FieldId) -> Node? {
let child = ts_node_child_by_field_id(self.node, self.tree, id)
if ts_node_is_null(child, self.tree) {
None
} else {
Some({ ..self, node: child })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_next_sibling(self : TSNode, tree : Tree) -> TSNode = "moonbit_ts_node_next_sibling"
///|
/// Get the node's next sibling.
pub fn Node::next_sibling(self : Node) -> Node? {
let next_sibling = ts_node_next_sibling(self.node, self.tree)
if ts_node_is_null(next_sibling, self.tree) {
None
} else {
Some({ ..self, node: next_sibling })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_prev_sibling(self : TSNode, tree : Tree) -> TSNode = "moonbit_ts_node_prev_sibling"
///|
/// Get the node's previous sibling.
pub fn Node::prev_sibling(self : Node) -> Node? {
let prev_sibling = ts_node_prev_sibling(self.node, self.tree)
if ts_node_is_null(prev_sibling, self.tree) {
None
} else {
Some({ ..self, node: prev_sibling })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_next_named_sibling(self : TSNode, tree : Tree) -> TSNode = "moonbit_ts_node_next_named_sibling"
///|
/// Get the node's next *named* sibling.
pub fn Node::next_named_sibling(self : Node) -> Node? {
let next_named_sibling = ts_node_next_named_sibling(self.node, self.tree)
if ts_node_is_null(next_named_sibling, self.tree) {
None
} else {
Some({ ..self, node: next_named_sibling })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_prev_named_sibling(self : TSNode, tree : Tree) -> TSNode = "moonbit_ts_node_prev_named_sibling"
///|
/// Get the node's previous *named* sibling.
pub fn Node::prev_named_sibling(self : Node) -> Node? {
let prev_named_sibling = ts_node_prev_named_sibling(self.node, self.tree)
if ts_node_is_null(prev_named_sibling, self.tree) {
None
} else {
Some({ ..self, node: prev_named_sibling })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_first_child_for_byte(
self : TSNode,
tree : Tree,
byte : UInt
) -> TSNode = "moonbit_ts_node_first_child_for_byte"
///|
/// Get the node's first child that contains or starts after the given byte offset.
pub fn Node::first_child_for_byte(self : Node, byte : Int) -> Node? {
let byte = int_to_uint(byte)
let child = ts_node_first_child_for_byte(self.node, self.tree, byte)
if ts_node_is_null(child, self.tree) {
None
} else {
Some({ ..self, node: child })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_first_named_child_for_byte(
self : TSNode,
tree : Tree,
byte : UInt
) -> TSNode = "moonbit_ts_node_first_named_child_for_byte"
///|
/// Get the node's first named child that contains or starts after the given byte offset.
pub fn Node::first_named_child_for_byte(self : Node, byte : Int) -> Node? {
let byte = int_to_uint(byte)
let child = ts_node_first_named_child_for_byte(self.node, self.tree, byte)
if ts_node_is_null(child, self.tree) {
None
} else {
Some({ ..self, node: child })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_descendant_count(self : TSNode, tree : Tree) -> Int = "moonbit_ts_node_descendant_count"
///|
/// Get the node's number of descendants, including one for the node itself.
pub fn Node::descendant_count(self : Node) -> Int {
return ts_node_descendant_count(self.node, self.tree)
}
///|
#borrow(self, tree)
extern "c" fn ts_node_descendant_for_byte_range(
self : TSNode,
tree : Tree,
start_byte : UInt,
end_byte : UInt
) -> TSNode = "moonbit_ts_node_descendant_for_byte_range"
///|
/// Get the smallest node within this node that spans the given range of bytes.
pub fn Node::descendant_for_byte_range(
self : Node,
start_byte : Int,
end_byte : Int
) -> Node? {
let start_byte = int_to_uint(start_byte)
let end_byte = int_to_uint(end_byte)
let descendant = ts_node_descendant_for_byte_range(
self.node,
self.tree,
start_byte,
end_byte,
)
if ts_node_is_null(descendant, self.tree) {
None
} else {
Some({ ..self, node: descendant })
}
}
///|
#borrow(self, tree, start_point, end_point)
extern "c" fn ts_node_descendant_for_point_range(
self : TSNode,
tree : Tree,
start_point : Point,
end_point : Point
) -> TSNode = "moonbit_ts_node_descendant_for_point_range"
///|
/// Get the smallest node within this node that spans the given range of
/// (row, column) positions.
pub fn Node::descendant_for_point_range(
self : Node,
start_point : Point,
end_point : Point
) -> Node? {
let descendant = ts_node_descendant_for_point_range(
self.node,
self.tree,
start_point,
end_point,
)
if ts_node_is_null(descendant, self.tree) {
None
} else {
Some({ ..self, node: descendant })
}
}
///|
#borrow(self, tree)
extern "c" fn ts_node_named_descendant_for_byte_range(
self : TSNode,
tree : Tree,
start_byte : UInt,
end_byte : UInt
) -> TSNode = "moonbit_ts_node_named_descendant_for_byte_range"
///|
/// Get the smallest named node within this node that spans the given range of
/// bytes.
pub fn Node::named_descendant_for_byte_range(
self : Node,
start_byte : Int,
end_byte : Int
) -> Node? {
let start_byte = int_to_uint(start_byte)
let end_byte = int_to_uint(end_byte)
let descendant = ts_node_named_descendant_for_byte_range(
self.node,
self.tree,
start_byte,
end_byte,
)
if ts_node_is_null(descendant, self.tree) {
None
} else {
Some({ ..self, node: descendant })
}
}
///|
#borrow(self, tree, start_point, end_point)
extern "c" fn ts_node_named_descendant_for_point_range(
self : TSNode,
tree : Tree,
start_point : Point,
end_point : Point
) -> TSNode = "moonbit_ts_node_named_descendant_for_point_range"
///|
/// Get the smallest named node within this node that spans the given
/// (row, column) positions.
pub fn Node::named_descendant_for_point_range(
self : Node,
start_point : Point,
end_point : Point
) -> Node? {
let descendant = ts_node_named_descendant_for_point_range(
self.node,
self.tree,
start_point,
end_point,
)
if ts_node_is_null(descendant, self.tree) {
None
} else {
Some({ ..self, node: descendant })
}
}
///|
#borrow(self, tree, edit)
extern "c" fn ts_node_edit(self : TSNode, tree : Tree, edit : InputEdit) = "moonbit_ts_node_edit"
///|
/// Edit the node to keep it in-sync with source code that has been edited.
///
/// This function is only rarely needed. When you edit a syntax tree with the
/// `Tree::edit` function, all of the nodes that you retrieve from the tree
/// afterward will already reflect the edit. You only need to use `Node::edit`
/// when you have a `Node` instance that you want to keep and continue to use
/// after an edit.
pub fn Node::edit(self : Node, edit : InputEdit) -> Unit {
ts_node_edit(self.node, self.tree, edit)
}
///|
#borrow(self, self_tree, other, other_tree)
extern "c" fn ts_node_eq(
self : TSNode,
self_tree : Tree,
other : TSNode,
other_tree : Tree
) -> Bool = "moonbit_ts_node_eq"
///|
/// Check if two nodes are identical.
pub fn Node::eq(self : Node, other : Node) -> Bool {
ts_node_eq(self.node, self.tree, other.node, other.tree)
}
///|
impl Eq for Node with op_equal(self, other) -> Bool {
ts_node_eq(self.node, self.tree, other.node, other.tree)
}
///|
pub impl ToJson for Node with to_json(self : Node) -> Json {
let child_json = []
for child in self.children() {
child_json.push(child.to_json())
}
if child_json.length() == 0 {
Json::string(self.type_())
} else {
let object = {}
object[self.type_()] = Json::array(child_json)
Json::object(object)
}
}