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 node;
|
||||||
pub mod pretty_print;
|
pub mod pretty_print;
|
||||||
pub mod unparse;
|
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