Add depth-first traversal (walk_depth_first) to walk.rs.
This commit is contained in:
parent
22deb90c3e
commit
d38b30b755
File diff suppressed because it is too large
Load Diff
@ -3,3 +3,4 @@ pub mod children;
|
||||
pub mod node;
|
||||
pub mod pretty_print;
|
||||
pub mod unparse;
|
||||
mod walk;
|
||||
|
145
src/ast/walk.rs
Normal file
145
src/ast/walk.rs
Normal file
@ -0,0 +1,145 @@
|
||||
use crate::ast::children::{NodeInner, NodeRef};
|
||||
|
||||
pub fn walk_depth_first<F>(node: &dyn NodeInner, f: &mut F)
|
||||
where
|
||||
F: FnMut(NodeRef),
|
||||
{
|
||||
use NodeRef::*;
|
||||
for child in node.children() {
|
||||
match child {
|
||||
Identifier(identifier) => walk_depth_first(identifier, f),
|
||||
FullyQualifiedName(fqn) => {
|
||||
walk_depth_first(fqn, f);
|
||||
}
|
||||
TypeUse(type_use) => walk_depth_first(type_use, f),
|
||||
PrimitiveTypeUse(primitive_type_use) => walk_depth_first(primitive_type_use, f),
|
||||
InterfaceOrClassTypeUse(interface_or_class_type_use) => {
|
||||
walk_depth_first(interface_or_class_type_use, f)
|
||||
}
|
||||
TupleTypeUse(tuple_type_use) => walk_depth_first(tuple_type_use, f),
|
||||
FunctionTypeUse(function_type_use) => walk_depth_first(function_type_use, f),
|
||||
GenericArguments(generic_arguments) => walk_depth_first(generic_arguments, f),
|
||||
GenericParameters(generic_parameters) => walk_depth_first(generic_parameters, f),
|
||||
TupleArguments(tuple_arguments) => walk_depth_first(tuple_arguments, f),
|
||||
ImplementsList(implements) => walk_depth_first(implements, f),
|
||||
Parameters(parameters) => walk_depth_first(parameters, f),
|
||||
Parameter(parameter) => walk_depth_first(parameter, f),
|
||||
ReturnType(return_type) => walk_depth_first(return_type, f),
|
||||
References(references) => walk_depth_first(references, f),
|
||||
UseStatement(use_statement) => walk_depth_first(use_statement, f),
|
||||
CompilationUnit(compilation_unit) => walk_depth_first(compilation_unit, f),
|
||||
ModuleLevelDeclaration(module_level_declaration) => {
|
||||
walk_depth_first(module_level_declaration, f)
|
||||
}
|
||||
InterfaceLevelDeclaration(interface_level_declaration) => {
|
||||
walk_depth_first(interface_level_declaration, f)
|
||||
}
|
||||
ClassLevelDeclaration(class_level_declaration) => {
|
||||
walk_depth_first(class_level_declaration, f)
|
||||
}
|
||||
ModuleDeclaration(module_declaration) => walk_depth_first(module_declaration, f),
|
||||
InterfaceDeclaration(interface_declaration) => {
|
||||
walk_depth_first(interface_declaration, f)
|
||||
}
|
||||
ClassDeclaration(class_declaration) => walk_depth_first(class_declaration, f),
|
||||
FunctionDefinition(function_definition) => walk_depth_first(function_definition, f),
|
||||
OperatorFunctionDefinition(operator_function_definition) => {
|
||||
walk_depth_first(operator_function_definition, f)
|
||||
}
|
||||
PlatformFunctionDeclaration(platform_function_declaration) => {
|
||||
walk_depth_first(platform_function_declaration, f)
|
||||
}
|
||||
InterfaceFunctionDeclaration(interface_function_declaration) => {
|
||||
walk_depth_first(interface_function_declaration, f)
|
||||
}
|
||||
InterfaceOperatorFunctionDeclaration(interface_operator_function_declaration) => {
|
||||
walk_depth_first(interface_operator_function_declaration, f)
|
||||
}
|
||||
FunctionBody(function_body) => walk_depth_first(function_body, f),
|
||||
ClassConstructor(class_constructor) => walk_depth_first(class_constructor, f),
|
||||
ClassConstructorParameter(class_constructor_parameter) => {
|
||||
walk_depth_first(class_constructor_parameter, f)
|
||||
}
|
||||
PropertyDeclaration(property_declaration) => walk_depth_first(property_declaration, f),
|
||||
FieldDeclaration(field_declaration) => walk_depth_first(field_declaration, f),
|
||||
BlockStatement(block) => walk_depth_first(block, f),
|
||||
Statement(statement) => walk_depth_first(statement, f),
|
||||
VariableDeclarationStatement(variable_declaration) => {
|
||||
walk_depth_first(variable_declaration, f)
|
||||
}
|
||||
AssignStatement(assign_statement) => walk_depth_first(assign_statement, f),
|
||||
CallStatement(call_statement) => walk_depth_first(call_statement, f),
|
||||
ReturnStatement(return_statement) => walk_depth_first(return_statement, f),
|
||||
IfStatement(if_statement) => walk_depth_first(if_statement, f),
|
||||
IfElseStatement(if_else_statement) => walk_depth_first(if_else_statement, f),
|
||||
ElseIfs(else_ifs) => walk_depth_first(else_ifs, f),
|
||||
ElseBlock(else_block) => walk_depth_first(else_block, f),
|
||||
WhileStatement(while_statement) => walk_depth_first(while_statement, f),
|
||||
ForStatement(for_statement) => walk_depth_first(for_statement, f),
|
||||
Expression(expression) => walk_depth_first(expression, f),
|
||||
TernaryExpression(ternary_expression) => walk_depth_first(ternary_expression, f),
|
||||
BinaryExpression(binary_expression) => walk_depth_first(binary_expression, f),
|
||||
PrefixExpression(prefix_expression) => walk_depth_first(prefix_expression, f),
|
||||
SuffixExpression(suffix_expression) => walk_depth_first(suffix_expression, f),
|
||||
CallExpression(call_expression) => walk_depth_first(call_expression, f),
|
||||
TurboFish(turbo_fish) => walk_depth_first(turbo_fish, f),
|
||||
CallArguments(call_arguments) => walk_depth_first(call_arguments, f),
|
||||
CallArgument(call_argument) => walk_depth_first(call_argument, f),
|
||||
Closure(closure) => walk_depth_first(closure, f),
|
||||
ClosureCaptures(closure_captures) => walk_depth_first(closure_captures, f),
|
||||
ClosureCapture(closure_capture) => walk_depth_first(closure_capture, f),
|
||||
ClosureParameters(closure_parameters) => walk_depth_first(closure_parameters, f),
|
||||
ClosureParameter(closure_parameter) => walk_depth_first(closure_parameter, f),
|
||||
ObjectAccess(object_access) => walk_depth_first(object_access, f),
|
||||
ObjectNavigations(object_navigations) => walk_depth_first(object_navigations, f),
|
||||
ObjectNavigation(object_navigations) => walk_depth_first(object_navigations, f),
|
||||
Literal(literal) => walk_depth_first(literal, f),
|
||||
DString(d_string) => walk_depth_first(d_string, f),
|
||||
DStringPart(d_string_part) => walk_depth_first(d_string_part, f),
|
||||
}
|
||||
}
|
||||
f(node.as_node_ref());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ast::build::build_ast;
|
||||
use crate::ast::children::NodeRef;
|
||||
use crate::ast::walk::walk_depth_first;
|
||||
use crate::parser::{DeimosParser, Rule};
|
||||
use indoc::indoc;
|
||||
use pest::Parser;
|
||||
|
||||
#[test]
|
||||
fn collect_identifiers() {
|
||||
let parse_result = DeimosParser::parse(
|
||||
Rule::CompilationUnit,
|
||||
indoc! {"
|
||||
ns greeter;
|
||||
|
||||
class Greeter {}
|
||||
|
||||
fn main() {
|
||||
let greeter = Greeter();
|
||||
}
|
||||
"},
|
||||
);
|
||||
match parse_result {
|
||||
Ok(cu_pairs) => {
|
||||
let cu = build_ast("greeter.dm", 0, cu_pairs.into_iter().next().unwrap());
|
||||
let mut identifier_count = 0;
|
||||
walk_depth_first(&cu, &mut |node_ref| match node_ref {
|
||||
NodeRef::Identifier(identifier) => {
|
||||
dbg!(identifier);
|
||||
identifier_count += 1;
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
assert_eq!(identifier_count, 5);
|
||||
}
|
||||
Err(err) => {
|
||||
panic!("{}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user