///|
/// SyntaxData - Internal data for red tree nodes
pub(all) struct SyntaxData {
green : GreenNode
parent : SyntaxNode?
offset : TextSize
} derive(Eq, Debug)
///|
/// SyntaxNode - A node in the red tree with navigation capabilities
/// Provides absolute positions and parent references
pub(all) struct SyntaxNode {
data : SyntaxData
} derive(Eq, Debug)
///|
pub fn SyntaxNode::new_root(green : GreenNode) -> SyntaxNode {
SyntaxNode::{
data: SyntaxData::{ green, parent: None, offset: TextSize::zero() },
}
}
///|
fn SyntaxNode::new_child(
green : GreenNode,
parent : SyntaxNode,
offset : TextSize,
) -> SyntaxNode {
SyntaxNode::{ data: SyntaxData::{ green, parent: Some(parent), offset } }
}
///|
pub fn SyntaxNode::kind(self : SyntaxNode) -> SyntaxKind {
self.data.green.kind()
}
///|
pub fn SyntaxNode::text_range(self : SyntaxNode) -> TextRange {
TextRange::at(self.data.offset, self.data.green.text_len())
}
///|
pub fn SyntaxNode::text_len(self : SyntaxNode) -> TextSize {
self.data.green.text_len()
}
///|
pub fn SyntaxNode::parent(self : SyntaxNode) -> SyntaxNode? {
self.data.parent
}
///|
pub fn SyntaxNode::green(self : SyntaxNode) -> GreenNode {
self.data.green
}
///|
/// Collect all children (nodes and tokens) as array
pub fn SyntaxNode::children(self : SyntaxNode) -> Array[SyntaxElement] {
let green_children = self.data.green.children()
let base_offset = self.data.offset
let result : Array[SyntaxElement] = []
for i = 0; i < green_children.length(); i = i + 1 {
let green_child = green_children[i]
let child_offset = base_offset + green_child.rel_offset()
let element = match green_child {
GreenChild::Node(node~, ..) => {
let node = SyntaxNode::new_child(node, self, child_offset)
SyntaxElement::Node(node)
}
GreenChild::Token(token~, ..) => {
let token = SyntaxToken::new(token, self, child_offset)
SyntaxElement::Token(token)
}
}
result.push(element)
}
result
}
///|
/// Collect child nodes only
pub fn SyntaxNode::child_nodes(self : SyntaxNode) -> Array[SyntaxNode] {
let result : Array[SyntaxNode] = []
for child in self.children() {
match child {
Node(n) => result.push(n)
Token(_) => ()
}
}
result
}
///|
/// Collect child tokens only
pub fn SyntaxNode::child_tokens(self : SyntaxNode) -> Array[SyntaxToken] {
let result : Array[SyntaxToken] = []
for child in self.children() {
match child {
Node(_) => ()
Token(t) => result.push(t)
}
}
result
}
///|
/// Get child at index
pub fn SyntaxNode::child_at(self : SyntaxNode, index : Int) -> SyntaxElement? {
let green_children = self.data.green.children()
if index < 0 || index >= green_children.length() {
return None
}
let green_child = green_children[index]
let child_offset = self.data.offset + green_child.rel_offset()
match green_child {
GreenChild::Node(node~, ..) => {
let node = SyntaxNode::new_child(node, self, child_offset)
Some(SyntaxElement::Node(node))
}
GreenChild::Token(token~, ..) => {
let token = SyntaxToken::new(token, self, child_offset)
Some(SyntaxElement::Token(token))
}
}
}
///|
/// Get number of children
pub fn SyntaxNode::children_count(self : SyntaxNode) -> Int {
self.data.green.children_count()
}
///|
/// Get first child
pub fn SyntaxNode::first_child(self : SyntaxNode) -> SyntaxElement? {
self.child_at(0)
}
///|
/// Get last child
pub fn SyntaxNode::last_child(self : SyntaxNode) -> SyntaxElement? {
let count = self.children_count()
if count == 0 {
None
} else {
self.child_at(count - 1)
}
}
///|
/// Get first child node
pub fn SyntaxNode::first_child_node(self : SyntaxNode) -> SyntaxNode? {
let nodes = self.child_nodes()
if nodes.is_empty() {
None
} else {
Some(nodes[0])
}
}
///|
/// Get first child token
pub fn SyntaxNode::first_child_token(self : SyntaxNode) -> SyntaxToken? {
let tokens = self.child_tokens()
if tokens.is_empty() {
None
} else {
Some(tokens[0])
}
}