pub struct Node {
pub kind: NodeKind,
pub location: ByteSpan,
}Expand description
Core AST node representing any Perl language construct within parsing workflows.
This is the fundamental building block for representing parsed Perl code. Each node contains both the semantic information (kind) and positional information (location) necessary for comprehensive script analysis.
§LSP Workflow Role
Nodes flow through tooling stages:
- Parse: Created by the parser as it builds the syntax tree
- Index: Visited to build symbol and reference tables
- Navigate: Used to resolve definitions, references, and call hierarchy
- Complete: Provides contextual information for completion and hover
- Analyze: Drives semantic analysis and diagnostics
§Memory Optimization
The structure is designed for efficient memory usage during large-scale parsing:
SourceLocationuses compact position encoding for large filesNodeKindenum variants minimize memory overhead for common constructs- Clone operations are optimized for shared analysis workflows
§Examples
Construct a variable declaration node manually:
use perl_ast::{Node, NodeKind, SourceLocation};
let loc = SourceLocation { start: 0, end: 11 };
let var = Node::new(
NodeKind::Variable { sigil: "$".to_string(), name: "x".to_string() },
loc,
);
let decl = Node::new(
NodeKind::VariableDeclaration {
declarator: "my".to_string(),
variable: Box::new(var),
attributes: vec![],
initializer: None,
},
loc,
);
assert_eq!(decl.kind.kind_name(), "VariableDeclaration");Typically you obtain nodes from the parser rather than constructing them by hand:
use perl_parser::Parser;
let mut parser = Parser::new("my $x = 42;");
let ast = parser.parse()?;
println!("AST: {}", ast.to_sexp());Fields§
§kind: NodeKindThe specific type and semantic content of this AST node
location: ByteSpanSource position information for error reporting and code navigation
Implementations§
Source§impl Node
impl Node
Sourcepub fn new(kind: NodeKind, location: ByteSpan) -> Node
pub fn new(kind: NodeKind, location: ByteSpan) -> Node
Create a new AST node with the given kind and source location.
§Examples
use perl_ast::{Node, NodeKind, SourceLocation};
let node = Node::new(
NodeKind::Number { value: "42".to_string() },
SourceLocation { start: 0, end: 2 },
);
assert_eq!(node.kind.kind_name(), "Number");
assert_eq!(node.location.start, 0);Sourcepub fn to_sexp(&self) -> String
pub fn to_sexp(&self) -> String
Convert the AST to a tree-sitter compatible S-expression.
Produces a parenthesized representation compatible with tree-sitter’s S-expression format, useful for debugging and snapshot testing.
§Examples
use perl_ast::{Node, NodeKind, SourceLocation};
let loc = SourceLocation { start: 0, end: 2 };
let num = Node::new(NodeKind::Number { value: "42".to_string() }, loc);
let program = Node::new(
NodeKind::Program { statements: vec![num] },
loc,
);
let sexp = program.to_sexp();
assert!(sexp.starts_with("(source_file"));Sourcepub fn to_sexp_inner(&self) -> String
pub fn to_sexp_inner(&self) -> String
Convert the AST to S-expression format that unwraps expression statements in programs
Sourcepub fn for_each_child_mut<F>(&mut self, f: F)
pub fn for_each_child_mut<F>(&mut self, f: F)
Call a function on every direct child node of this node.
This enables depth-first traversal for operations like heredoc content attachment. The closure receives a mutable reference to each child node.
Sourcepub fn for_each_child<'a, F>(&'a self, f: F)
pub fn for_each_child<'a, F>(&'a self, f: F)
Call a function on every direct child node of this node (immutable version).
This enables depth-first traversal for read-only operations like AST analysis. The closure receives an immutable reference to each child node.
Sourcepub fn count_nodes(&self) -> usize
pub fn count_nodes(&self) -> usize
Count the total number of nodes in this subtree (inclusive).
§Examples
use perl_ast::{Node, NodeKind, SourceLocation};
let loc = SourceLocation { start: 0, end: 1 };
let leaf = Node::new(NodeKind::Number { value: "1".to_string() }, loc);
assert_eq!(leaf.count_nodes(), 1);
let program = Node::new(
NodeKind::Program { statements: vec![leaf] },
loc,
);
assert_eq!(program.count_nodes(), 2);Sourcepub fn children(&self) -> Vec<&Node>
pub fn children(&self) -> Vec<&Node>
Collect direct child nodes into a vector for convenience APIs.
§Examples
use perl_ast::{Node, NodeKind, SourceLocation};
let loc = SourceLocation { start: 0, end: 1 };
let stmt = Node::new(NodeKind::Number { value: "1".to_string() }, loc);
let program = Node::new(
NodeKind::Program { statements: vec![stmt] },
loc,
);
assert_eq!(program.children().len(), 1);Sourcepub fn first_child(&self) -> Option<&Node>
pub fn first_child(&self) -> Option<&Node>
Get the first direct child node, if any.
Optimized to avoid allocating the children vector.