use crate::ast::children::{NodeInner, NodeRef}; pub fn walk_depth_first(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); // } // } // } // }