diff --git a/src/ast/children.rs b/src/ast/children.rs index 6a7117f..5748b2c 100644 --- a/src/ast/children.rs +++ b/src/ast/children.rs @@ -18,7 +18,7 @@ use crate::ast::node::tuple_arguments::*; use crate::ast::node::type_use::*; use crate::ast::node::use_statement::*; -pub enum ChildRef<'a> { +pub enum NodeRef<'a> { Identifier(&'a Identifier), FullyQualifiedName(&'a FullyQualifiedName), TypeUse(&'a TypeUse), @@ -34,47 +34,89 @@ pub enum ChildRef<'a> { Parameter(&'a Parameter), ReturnType(&'a ReturnType), References(&'a References), + CompilationUnit(&'a CompilationUnit), UseStatement(&'a UseStatement), ModuleLevelDeclaration(&'a ModuleLevelDeclaration), InterfaceLevelDeclaration(&'a InterfaceLevelDeclaration), ClassLevelDeclaration(&'a ClassLevelDeclaration), + ModuleDeclaration(&'a ModuleDeclaration), + InterfaceDeclaration(&'a InterfaceDeclaration), + ClassDeclaration(&'a ClassDeclaration), + FunctionDefinition(&'a FunctionDefinition), + OperatorFunctionDefinition(&'a OperatorFunctionDefinition), + PlatformFunctionDeclaration(&'a PlatformFunctionDeclaration), + InterfaceFunctionDeclaration(&'a InterfaceFunctionDeclaration), + InterfaceOperatorFunctionDeclaration(&'a InterfaceOperatorFunctionDeclaration), FunctionBody(&'a FunctionBody), ClassConstructor(&'a ClassConstructor), ClassConstructorParameter(&'a ClassConstructorParameter), + PropertyDeclaration(&'a PropertyDeclaration), + FieldDeclaration(&'a FieldDeclaration), BlockStatement(&'a BlockStatement), Statement(&'a Statement), + VariableDeclarationStatement(&'a VariableDeclarationStatement), + AssignStatement(&'a AssignStatement), + CallStatement(&'a CallStatement), + ReturnStatement(&'a ReturnStatement), IfStatement(&'a IfStatement), + IfElseStatement(&'a IfElseStatement), ElseIfs(&'a ElseIfs), ElseBlock(&'a ElseBlock), + WhileStatement(&'a WhileStatement), + ForStatement(&'a ForStatement), Expression(&'a Expression), + TernaryExpression(&'a TernaryExpression), + BinaryExpression(&'a BinaryExpression), + PrefixExpression(&'a PrefixExpression), + SuffixExpression(&'a SuffixExpression), + CallExpression(&'a CallExpression), TurboFish(&'a TurboFish), CallArguments(&'a CallArguments), CallArgument(&'a CallArgument), + Closure(&'a Closure), ClosureCaptures(&'a ClosureCaptures), ClosureCapture(&'a ClosureCapture), ClosureParameters(&'a ClosureParameters), ClosureParameter(&'a ClosureParameter), + ObjectAccess(&'a ObjectAccess), ObjectNavigations(&'a ObjectNavigations), ObjectNavigation(&'a ObjectNavigation), + Literal(&'a Literal), DString(&'a DString), DStringPart(&'a DStringPart), } -pub trait HasChildren { - fn children(&self) -> Vec; +pub trait NodeInner { + fn children(&self) -> Vec; + + fn as_node_ref(&self) -> NodeRef; } -impl HasChildren for FullyQualifiedName { - fn children(&self) -> Vec { - self.identifiers() - .iter() - .map(|id| ChildRef::Identifier(*id)) - .collect() +impl NodeInner for Identifier { + fn children(&self) -> Vec { + vec![] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::Identifier(self) } } -impl HasChildren for TypeUse { - fn children(&self) -> Vec { +impl NodeInner for FullyQualifiedName { + fn children(&self) -> Vec { + self.identifiers() + .iter() + .map(|id| NodeRef::Identifier(*id)) + .collect() + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::FullyQualifiedName(self) + } +} + +impl NodeInner for TypeUse { + fn children(&self) -> Vec { match self { TypeUse::Primitive(primitive_type_use) => primitive_type_use.children(), TypeUse::InterfaceOrClass(interface_or_class_type_use) => { @@ -84,14 +126,18 @@ impl HasChildren for TypeUse { TypeUse::Function(function_type_use) => function_type_use.children(), } } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::TypeUse(self) + } } -impl HasChildren for PrimitiveTypeUse { - fn children(&self) -> Vec { +impl NodeInner for PrimitiveTypeUse { + fn children(&self) -> Vec { match self { PrimitiveTypeUse::Array(generics) => { if let Some(generics) = generics { - vec![ChildRef::GenericArguments(&generics)] + vec![NodeRef::GenericArguments(&generics)] } else { vec![] } @@ -99,141 +145,206 @@ impl HasChildren for PrimitiveTypeUse { _ => vec![], } } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::PrimitiveTypeUse(self) + } } -impl HasChildren for InterfaceOrClassTypeUse { - fn children(&self) -> Vec { +impl NodeInner for InterfaceOrClassTypeUse { + fn children(&self) -> Vec { let mut children = vec![]; - children.push(ChildRef::FullyQualifiedName(self.fqn())); - children.push(ChildRef::GenericArguments(self.generics())); + children.push(NodeRef::FullyQualifiedName(self.fqn())); + children.push(NodeRef::GenericArguments(self.generics())); children } -} - -impl HasChildren for TupleTypeUse { - fn children(&self) -> Vec { - vec![ChildRef::TupleArguments(self.arguments())] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::InterfaceOrClassTypeUse(self) } } -impl HasChildren for FunctionTypeUse { - fn children(&self) -> Vec { +impl NodeInner for TupleTypeUse { + fn children(&self) -> Vec { + vec![NodeRef::TupleArguments(self.arguments())] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::TupleTypeUse(self) + } +} + +impl NodeInner for FunctionTypeUse { + fn children(&self) -> Vec { vec![ - ChildRef::GenericParameters(self.generics()), - ChildRef::Parameters(self.parameters()), - ChildRef::ReturnType(self.return_type()), + NodeRef::GenericParameters(self.generics()), + NodeRef::Parameters(self.parameters()), + NodeRef::ReturnType(self.return_type()), ] } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::FunctionTypeUse(self) + } } -impl HasChildren for GenericArguments { - fn children(&self) -> Vec { +impl NodeInner for GenericArguments { + fn children(&self) -> Vec { self.arguments() .iter() - .map(|type_use| ChildRef::TypeUse(*type_use)) + .map(|type_use| NodeRef::TypeUse(*type_use)) .collect() } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::GenericArguments(self) + } } -impl HasChildren for GenericParameters { - fn children(&self) -> Vec { +impl NodeInner for GenericParameters { + fn children(&self) -> Vec { self.identifiers() .iter() - .map(|id| ChildRef::Identifier(*id)) + .map(|id| NodeRef::Identifier(*id)) .collect() } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::GenericParameters(self) + } } -impl HasChildren for TupleArguments { - fn children(&self) -> Vec { +impl NodeInner for TupleArguments { + fn children(&self) -> Vec { self.type_uses() .iter() - .map(|type_use| ChildRef::TypeUse(*type_use)) + .map(|type_use| NodeRef::TypeUse(*type_use)) .collect() } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::TupleArguments(self) + } } -impl HasChildren for ImplementsList { - fn children(&self) -> Vec { +impl NodeInner for ImplementsList { + fn children(&self) -> Vec { self.type_uses() .iter() - .map(|type_use| ChildRef::TypeUse(*type_use)) + .map(|type_use| NodeRef::TypeUse(*type_use)) .collect() } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ImplementsList(self) + } } -impl HasChildren for Parameters { - fn children(&self) -> Vec { +impl NodeInner for Parameters { + fn children(&self) -> Vec { self.parameters() .iter() - .map(|parameter| ChildRef::Parameter(*parameter)) + .map(|parameter| NodeRef::Parameter(*parameter)) .collect() } -} - -impl HasChildren for Parameter { - fn children(&self) -> Vec { - vec![ - ChildRef::Identifier(self.identifier()), - ChildRef::TypeUse(self.type_use()), - ] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::Parameters(self) } } -impl HasChildren for ReturnType { - fn children(&self) -> Vec { +impl NodeInner for Parameter { + fn children(&self) -> Vec { vec![ - ChildRef::TypeUse(self.declared_type()), - ChildRef::References(self.references()), + NodeRef::Identifier(self.identifier()), + NodeRef::TypeUse(self.type_use()), ] } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::Parameter(self) + } } -impl HasChildren for CompilationUnit { - fn children(&self) -> Vec { +impl NodeInner for ReturnType { + fn children(&self) -> Vec { + vec![ + NodeRef::TypeUse(self.declared_type()), + NodeRef::References(self.references()), + ] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ReturnType(self) + } +} + +impl NodeInner for References { + fn children(&self) -> Vec { + self.identifiers() + .iter() + .map(|identifier| NodeRef::Identifier(*identifier)) + .collect() + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::References(self) + } +} + +impl NodeInner for CompilationUnit { + fn children(&self) -> Vec { let mut children = vec![]; if let Some(namespace) = self.namespace() { - children.push(ChildRef::FullyQualifiedName(namespace)); + children.push(NodeRef::FullyQualifiedName(namespace)); } children.extend( self.use_statements() .iter() - .map(|use_statement| ChildRef::UseStatement(*use_statement)), + .map(|use_statement| NodeRef::UseStatement(*use_statement)), ); children.extend( self.declarations() .iter() - .map(|declaration| ChildRef::ModuleLevelDeclaration(*declaration)), + .map(|declaration| NodeRef::ModuleLevelDeclaration(*declaration)), ); children } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::CompilationUnit(self) + } } -impl HasChildren for UseStatement { - fn children(&self) -> Vec { +impl NodeInner for UseStatement { + fn children(&self) -> Vec { let mut children = vec![]; children.extend( self.identifiers() .iter() - .map(|identifier| ChildRef::Identifier(*identifier)), + .map(|identifier| NodeRef::Identifier(*identifier)), ); match self.last() { UseStatementLast::Identifier(identifier) => { - children.push(ChildRef::Identifier(identifier)) + children.push(NodeRef::Identifier(identifier)) } UseStatementLast::Identifiers(identifiers) => children.extend( identifiers .iter() - .map(|identifier| ChildRef::Identifier(identifier.clone())), + .map(|identifier| NodeRef::Identifier(identifier.clone())), ), UseStatementLast::Star => {} } children } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::UseStatement(self) + } } -impl HasChildren for ModuleLevelDeclaration { - fn children(&self) -> Vec { +impl NodeInner for ModuleLevelDeclaration { + fn children(&self) -> Vec { use crate::ast::node::level::ModuleLevelDeclaration::*; match self { Module(module_declaration) => module_declaration.children(), @@ -245,10 +356,14 @@ impl HasChildren for ModuleLevelDeclaration { } } } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ModuleLevelDeclaration(self) + } } -impl HasChildren for InterfaceLevelDeclaration { - fn children(&self) -> Vec { +impl NodeInner for InterfaceLevelDeclaration { + fn children(&self) -> Vec { use crate::ast::node::level::InterfaceLevelDeclaration::*; match self { Module(module_declaration) => module_declaration.children(), @@ -260,10 +375,14 @@ impl HasChildren for InterfaceLevelDeclaration { } } } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::InterfaceLevelDeclaration(self) + } } -impl HasChildren for ClassLevelDeclaration { - fn children(&self) -> Vec { +impl NodeInner for ClassLevelDeclaration { + fn children(&self) -> Vec { use crate::ast::node::level::ClassLevelDeclaration::*; match self { Module(module_declaration) => module_declaration.children(), @@ -280,180 +399,240 @@ impl HasChildren for ClassLevelDeclaration { Field(field_declaration) => field_declaration.children(), } } -} - -impl HasChildren for ModuleDeclaration { - fn children(&self) -> Vec { - let mut children = vec![]; - children.push(ChildRef::Identifier(self.identifier())); - children.extend( - self.declarations() - .iter() - .map(|declaration| ChildRef::ModuleLevelDeclaration(*declaration)), - ); - children + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ClassLevelDeclaration(self) } } -impl HasChildren for InterfaceDeclaration { - fn children(&self) -> Vec { +impl NodeInner for ModuleDeclaration { + fn children(&self) -> Vec { let mut children = vec![]; - children.push(ChildRef::Identifier(self.identifier())); - children.push(ChildRef::GenericParameters(self.generics())); - children.push(ChildRef::ImplementsList(self.implements())); + children.push(NodeRef::Identifier(self.identifier())); children.extend( self.declarations() .iter() - .map(|declaration| ChildRef::InterfaceLevelDeclaration(*declaration)), + .map(|declaration| NodeRef::ModuleLevelDeclaration(*declaration)), ); children } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ModuleDeclaration(self) + } } -impl HasChildren for ClassDeclaration { - fn children(&self) -> Vec { +impl NodeInner for InterfaceDeclaration { + fn children(&self) -> Vec { let mut children = vec![]; - children.push(ChildRef::Identifier(self.identifier())); - children.push(ChildRef::GenericParameters(self.generics())); + children.push(NodeRef::Identifier(self.identifier())); + children.push(NodeRef::GenericParameters(self.generics())); + children.push(NodeRef::ImplementsList(self.implements())); + children.extend( + self.declarations() + .iter() + .map(|declaration| NodeRef::InterfaceLevelDeclaration(*declaration)), + ); + children + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::InterfaceDeclaration(self) + } +} + +impl NodeInner for ClassDeclaration { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(NodeRef::Identifier(self.identifier())); + children.push(NodeRef::GenericParameters(self.generics())); if let Some(class_constructor) = self.class_constructor() { - children.push(ChildRef::ClassConstructor(class_constructor)); + children.push(NodeRef::ClassConstructor(class_constructor)); } - children.push(ChildRef::ImplementsList(self.implements())); + children.push(NodeRef::ImplementsList(self.implements())); children.extend( self.declarations() .iter() - .map(|declaration| ChildRef::ClassLevelDeclaration(*declaration)), + .map(|declaration| NodeRef::ClassLevelDeclaration(*declaration)), ); children } -} - -impl HasChildren for FunctionDefinition { - fn children(&self) -> Vec { - vec![ - ChildRef::GenericParameters(self.generics()), - ChildRef::Identifier(self.identifier()), - ChildRef::Parameters(self.parameters()), - ChildRef::ReturnType(self.return_type()), - ChildRef::FunctionBody(self.body()), - ] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ClassDeclaration(self) } } -impl HasChildren for OperatorFunctionDefinition { - fn children(&self) -> Vec { +impl NodeInner for FunctionDefinition { + fn children(&self) -> Vec { vec![ - ChildRef::GenericParameters(self.generics()), - ChildRef::Parameters(self.parameters()), - ChildRef::ReturnType(self.return_type()), - ChildRef::FunctionBody(self.body()), + NodeRef::GenericParameters(self.generics()), + NodeRef::Identifier(self.identifier()), + NodeRef::Parameters(self.parameters()), + NodeRef::ReturnType(self.return_type()), + NodeRef::FunctionBody(self.body()), ] } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::FunctionDefinition(self) + } } -impl HasChildren for PlatformFunctionDeclaration { - fn children(&self) -> Vec { +impl NodeInner for OperatorFunctionDefinition { + fn children(&self) -> Vec { vec![ - ChildRef::GenericParameters(self.generics()), - ChildRef::Identifier(self.identifier()), - ChildRef::Parameters(self.parameters()), - ChildRef::ReturnType(self.return_type()), + NodeRef::GenericParameters(self.generics()), + NodeRef::Parameters(self.parameters()), + NodeRef::ReturnType(self.return_type()), + NodeRef::FunctionBody(self.body()), ] } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::OperatorFunctionDefinition(self) + } } -impl HasChildren for InterfaceFunctionDeclaration { - fn children(&self) -> Vec { +impl NodeInner for PlatformFunctionDeclaration { + fn children(&self) -> Vec { + vec![ + NodeRef::GenericParameters(self.generics()), + NodeRef::Identifier(self.identifier()), + NodeRef::Parameters(self.parameters()), + NodeRef::ReturnType(self.return_type()), + ] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::PlatformFunctionDeclaration(self) + } +} + +impl NodeInner for InterfaceFunctionDeclaration { + fn children(&self) -> Vec { let mut children = vec![ - ChildRef::GenericParameters(self.generics()), - ChildRef::Identifier(self.identifier()), - ChildRef::Parameters(self.parameters()), - ChildRef::ReturnType(self.return_type()), + NodeRef::GenericParameters(self.generics()), + NodeRef::Identifier(self.identifier()), + NodeRef::Parameters(self.parameters()), + NodeRef::ReturnType(self.return_type()), ]; if let Some(body) = self.body() { - children.push(ChildRef::FunctionBody(body)) + children.push(NodeRef::FunctionBody(body)) } children } -} - -impl HasChildren for InterfaceOperatorFunctionDeclaration { - fn children(&self) -> Vec { - let mut children = vec![ - ChildRef::GenericParameters(self.generics()), - ChildRef::Parameters(self.parameters()), - ChildRef::ReturnType(self.return_type()), - ]; - if let Some(body) = self.body() { - children.push(ChildRef::FunctionBody(body)) - } - children + + fn as_node_ref(&self) -> NodeRef { + NodeRef::InterfaceFunctionDeclaration(self) } } -impl HasChildren for FunctionBody { - fn children(&self) -> Vec { +impl NodeInner for InterfaceOperatorFunctionDeclaration { + fn children(&self) -> Vec { + let mut children = vec![ + NodeRef::GenericParameters(self.generics()), + NodeRef::Parameters(self.parameters()), + NodeRef::ReturnType(self.return_type()), + ]; + if let Some(body) = self.body() { + children.push(NodeRef::FunctionBody(body)) + } + children + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::InterfaceOperatorFunctionDeclaration(self) + } +} + +impl NodeInner for FunctionBody { + fn children(&self) -> Vec { match self { Self::Equals(expression) => expression.children(), Self::Block(block_statement) => block_statement.children(), - Self::Alias(identifier) => vec![ChildRef::Identifier(identifier.as_ref())], + Self::Alias(identifier) => vec![NodeRef::Identifier(identifier.as_ref())], } } -} - -impl HasChildren for ClassConstructor { - fn children(&self) -> Vec { - self.parameters() - .iter() - .map(|parameter| ChildRef::ClassConstructorParameter(*parameter)) - .collect() + + fn as_node_ref(&self) -> NodeRef { + NodeRef::FunctionBody(self) } } -impl HasChildren for ClassConstructorParameter { - fn children(&self) -> Vec { +impl NodeInner for ClassConstructor { + fn children(&self) -> Vec { + self.parameters() + .iter() + .map(|parameter| NodeRef::ClassConstructorParameter(*parameter)) + .collect() + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ClassConstructor(self) + } +} + +impl NodeInner for ClassConstructorParameter { + fn children(&self) -> Vec { match self { Self::Property(property_declaration) => property_declaration.children(), Self::Field(field_declaration) => field_declaration.children(), } } -} - -impl HasChildren for PropertyDeclaration { - fn children(&self) -> Vec { - vec![ - ChildRef::Identifier(self.identifier()), - ChildRef::TypeUse(self.declared_type()), - ] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ClassConstructorParameter(self) } } -impl HasChildren for FieldDeclaration { - fn children(&self) -> Vec { +impl NodeInner for PropertyDeclaration { + fn children(&self) -> Vec { vec![ - ChildRef::Identifier(self.identifier()), - ChildRef::TypeUse(self.declared_type()), + NodeRef::Identifier(self.identifier()), + NodeRef::TypeUse(self.declared_type()), ] } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::PropertyDeclaration(self) + } } -impl HasChildren for BlockStatement { - fn children(&self) -> Vec { +impl NodeInner for FieldDeclaration { + fn children(&self) -> Vec { + vec![ + NodeRef::Identifier(self.identifier()), + NodeRef::TypeUse(self.declared_type()), + ] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::FieldDeclaration(self) + } +} + +impl NodeInner for BlockStatement { + fn children(&self) -> Vec { let mut children = vec![]; children.extend( self.statements() .iter() - .map(|statement| ChildRef::Statement(statement)), + .map(|statement| NodeRef::Statement(statement)), ); if let Some(expression) = self.expression() { - children.push(ChildRef::Expression(expression)); + children.push(NodeRef::Expression(expression)); } children } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::BlockStatement(self) + } } -impl HasChildren for Statement { - fn children(&self) -> Vec { +impl NodeInner for Statement { + fn children(&self) -> Vec { use crate::ast::node::statement::Statement::*; match self { BlockStatement(block_statement) => block_statement.children(), @@ -469,104 +648,148 @@ impl HasChildren for Statement { ForStatement(for_statement) => for_statement.children(), } } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::Statement(self) + } } -impl HasChildren for VariableDeclarationStatement { - fn children(&self) -> Vec { +impl NodeInner for VariableDeclarationStatement { + fn children(&self) -> Vec { let mut children = vec![]; - children.push(ChildRef::Identifier(self.identifier())); + children.push(NodeRef::Identifier(self.identifier())); if let Some(declared_type) = self.declared_type() { - children.push(ChildRef::TypeUse(declared_type)); + children.push(NodeRef::TypeUse(declared_type)); } if let Some(initializer) = self.initializer() { - children.push(ChildRef::Expression(initializer)); + children.push(NodeRef::Expression(initializer)); } children } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::VariableDeclarationStatement(self) + } } -impl HasChildren for AssignStatement { - fn children(&self) -> Vec { +impl NodeInner for AssignStatement { + fn children(&self) -> Vec { vec![ - ChildRef::Expression(self.lhs()), - ChildRef::Expression(self.rhs()), + NodeRef::Expression(self.lhs()), + NodeRef::Expression(self.rhs()), ] } -} - -impl HasChildren for CallStatement { - fn children(&self) -> Vec { - vec![ChildRef::Expression(self.expression())] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::AssignStatement(self) } } -impl HasChildren for ReturnStatement { - fn children(&self) -> Vec { +impl NodeInner for CallStatement { + fn children(&self) -> Vec { + vec![NodeRef::Expression(self.expression())] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::CallStatement(self) + } +} + +impl NodeInner for ReturnStatement { + fn children(&self) -> Vec { if let Some(expression) = self.expression() { - vec![ChildRef::Expression(expression)] + vec![NodeRef::Expression(expression)] } else { vec![] } } -} - -impl HasChildren for IfStatement { - fn children(&self) -> Vec { - vec![ - ChildRef::Expression(self.condition()), - ChildRef::BlockStatement(self.then_block()), - ] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ReturnStatement(self) } } -impl HasChildren for IfElseStatement { - fn children(&self) -> Vec { +impl NodeInner for IfStatement { + fn children(&self) -> Vec { + vec![ + NodeRef::Expression(self.condition()), + NodeRef::BlockStatement(self.then_block()), + ] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::IfStatement(self) + } +} + +impl NodeInner for IfElseStatement { + fn children(&self) -> Vec { let mut children = vec![]; - children.push(ChildRef::IfStatement(self.if_statement())); - children.push(ChildRef::ElseIfs(self.else_ifs())); + children.push(NodeRef::IfStatement(self.if_statement())); + children.push(NodeRef::ElseIfs(self.else_ifs())); if let Some(else_block) = self.else_block() { - children.push(ChildRef::ElseBlock(else_block)); + children.push(NodeRef::ElseBlock(else_block)); } children } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::IfElseStatement(self) + } } -impl HasChildren for ElseIfs { - fn children(&self) -> Vec { +impl NodeInner for ElseIfs { + fn children(&self) -> Vec { self.if_statements() .iter() - .map(|statement| ChildRef::IfStatement(statement)) + .map(|statement| NodeRef::IfStatement(statement)) .collect() } -} - -impl HasChildren for ElseBlock { - fn children(&self) -> Vec { - vec![ChildRef::BlockStatement(self.block_statement())] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ElseIfs(self) } } -impl HasChildren for WhileStatement { - fn children(&self) -> Vec { +impl NodeInner for ElseBlock { + fn children(&self) -> Vec { + vec![NodeRef::BlockStatement(self.block_statement())] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ElseBlock(self) + } +} + +impl NodeInner for WhileStatement { + fn children(&self) -> Vec { vec![ - ChildRef::Expression(self.condition()), - ChildRef::BlockStatement(self.body()), + NodeRef::Expression(self.condition()), + NodeRef::BlockStatement(self.body()), ] } -} - -impl HasChildren for ForStatement { - fn children(&self) -> Vec { - vec![ - ChildRef::Identifier(self.variable()), - ChildRef::Expression(self.iterator()), - ChildRef::BlockStatement(self.body()), - ] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::WhileStatement(self) } } -impl HasChildren for Expression { - fn children(&self) -> Vec { +impl NodeInner for ForStatement { + fn children(&self) -> Vec { + vec![ + NodeRef::Identifier(self.variable()), + NodeRef::Expression(self.iterator()), + NodeRef::BlockStatement(self.body()), + ] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ForStatement(self) + } +} + +impl NodeInner for Expression { + fn children(&self) -> Vec { use crate::ast::node::expression::Expression::*; match self { Ternary(ternary) => ternary.children(), @@ -580,175 +803,255 @@ impl HasChildren for Expression { Closure(closure) => closure.children(), } } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::Expression(self) + } } -impl HasChildren for TernaryExpression { - fn children(&self) -> Vec { +impl NodeInner for TernaryExpression { + fn children(&self) -> Vec { vec![ - ChildRef::Expression(self.condition()), - ChildRef::Expression(self.true_expression()), - ChildRef::Expression(self.false_expression()), + NodeRef::Expression(self.condition()), + NodeRef::Expression(self.true_expression()), + NodeRef::Expression(self.false_expression()), ] } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::TernaryExpression(self) + } } -impl HasChildren for BinaryExpression { - fn children(&self) -> Vec { +impl NodeInner for BinaryExpression { + fn children(&self) -> Vec { vec![ - ChildRef::Expression(self.left()), - ChildRef::Expression(self.right()), + NodeRef::Expression(self.left()), + NodeRef::Expression(self.right()), ] } -} - -impl HasChildren for PrefixExpression { - fn children(&self) -> Vec { - vec![ChildRef::Expression(self.expression())] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::BinaryExpression(self) } } -impl HasChildren for SuffixExpression { - fn children(&self) -> Vec { - vec![ChildRef::Expression(self.expression())] +impl NodeInner for PrefixExpression { + fn children(&self) -> Vec { + vec![NodeRef::Expression(self.expression())] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::PrefixExpression(self) } } -impl HasChildren for CallExpression { - fn children(&self) -> Vec { +impl NodeInner for SuffixExpression { + fn children(&self) -> Vec { + vec![NodeRef::Expression(self.expression())] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::SuffixExpression(self) + } +} + +impl NodeInner for CallExpression { + fn children(&self) -> Vec { let mut children = vec![]; - children.push(ChildRef::Expression(self.callee())); + children.push(NodeRef::Expression(self.callee())); if let Some(turbo_fish) = self.turbo_fish() { - children.push(ChildRef::TurboFish(turbo_fish)); + children.push(NodeRef::TurboFish(turbo_fish)); } - children.push(ChildRef::CallArguments(self.arguments())); + children.push(NodeRef::CallArguments(self.arguments())); children } -} - -impl HasChildren for TurboFish { - fn children(&self) -> Vec { - vec![ChildRef::GenericArguments(self.generics())] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::CallExpression(self) } } -impl HasChildren for CallArguments { - fn children(&self) -> Vec { +impl NodeInner for TurboFish { + fn children(&self) -> Vec { + vec![NodeRef::GenericArguments(self.generics())] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::TurboFish(self) + } +} + +impl NodeInner for CallArguments { + fn children(&self) -> Vec { self.arguments() .iter() - .map(|argument| ChildRef::CallArgument(*argument)) + .map(|argument| NodeRef::CallArgument(*argument)) .collect() } -} - -impl HasChildren for CallArgument { - fn children(&self) -> Vec { - vec![ChildRef::Expression(self.expression())] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::CallArguments(self) } } -impl HasChildren for Closure { - fn children(&self) -> Vec { +impl NodeInner for CallArgument { + fn children(&self) -> Vec { + vec![NodeRef::Expression(self.expression())] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::CallArgument(self) + } +} + +impl NodeInner for Closure { + fn children(&self) -> Vec { let mut children = vec![]; - children.push(ChildRef::ClosureCaptures(self.captures())); - children.push(ChildRef::ClosureParameters(self.parameters())); + children.push(NodeRef::ClosureCaptures(self.captures())); + children.push(NodeRef::ClosureParameters(self.parameters())); children.extend( self.statements() .iter() - .map(|statement| ChildRef::Statement(statement)), + .map(|statement| NodeRef::Statement(statement)), ); if let Some(expression) = self.expression() { - children.push(ChildRef::Expression(expression)); + children.push(NodeRef::Expression(expression)); } children } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::Closure(self) + } } -impl HasChildren for ClosureCaptures { - fn children(&self) -> Vec { +impl NodeInner for ClosureCaptures { + fn children(&self) -> Vec { self.captures() .iter() - .map(|capture| ChildRef::ClosureCapture(*capture)) + .map(|capture| NodeRef::ClosureCapture(*capture)) .collect() } -} - -impl HasChildren for ClosureCapture { - fn children(&self) -> Vec { - vec![ChildRef::Identifier(self.identifier())] + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ClosureCaptures(self) } } -impl HasChildren for ClosureParameters { - fn children(&self) -> Vec { +impl NodeInner for ClosureCapture { + fn children(&self) -> Vec { + vec![NodeRef::Identifier(self.identifier())] + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ClosureCapture(self) + } +} + +impl NodeInner for ClosureParameters { + fn children(&self) -> Vec { self.parameters() .iter() - .map(|parameter| ChildRef::ClosureParameter(*parameter)) + .map(|parameter| NodeRef::ClosureParameter(*parameter)) .collect() } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ClosureParameters(self) + } } -impl HasChildren for ClosureParameter { - fn children(&self) -> Vec { +impl NodeInner for ClosureParameter { + fn children(&self) -> Vec { let mut children = vec![]; - children.push(ChildRef::Identifier(self.identifier())); + children.push(NodeRef::Identifier(self.identifier())); if let Some(type_use) = self.type_use() { - children.push(ChildRef::TypeUse(type_use)); + children.push(NodeRef::TypeUse(type_use)); } children } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ClosureParameter(self) + } } -impl HasChildren for ObjectAccess { - fn children(&self) -> Vec { +impl NodeInner for ObjectAccess { + fn children(&self) -> Vec { vec![ - ChildRef::Expression(self.receiver()), - ChildRef::ObjectNavigations(self.navigations()), + NodeRef::Expression(self.receiver()), + NodeRef::ObjectNavigations(self.navigations()), ] } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ObjectAccess(self) + } } -impl HasChildren for ObjectNavigations { - fn children(&self) -> Vec { +impl NodeInner for ObjectNavigations { + fn children(&self) -> Vec { self.navigations() .iter() - .map(|navigation| ChildRef::ObjectNavigation(*navigation)) + .map(|navigation| NodeRef::ObjectNavigation(*navigation)) .collect() } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ObjectNavigations(self) + } } -impl HasChildren for ObjectNavigation { - fn children(&self) -> Vec { +impl NodeInner for ObjectNavigation { + fn children(&self) -> Vec { vec![match self { - ObjectNavigation::Identifier(identifier) => ChildRef::Identifier(identifier), - ObjectNavigation::Index(index_expression) => ChildRef::Expression(index_expression), + ObjectNavigation::Identifier(identifier) => NodeRef::Identifier(identifier), + ObjectNavigation::Index(index_expression) => NodeRef::Expression(index_expression), }] } -} - -impl HasChildren for Literal { - fn children(&self) -> Vec { - match self { - Literal::DString(d_string) => vec![ChildRef::DString(d_string)], - Literal::BacktickString(d_string) => vec![ChildRef::DString(d_string)], - _ => vec![], - } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::ObjectNavigation(self) } } -impl HasChildren for DString { - fn children(&self) -> Vec { +impl NodeInner for Literal { + fn children(&self) -> Vec { + match self { + Literal::DString(d_string) => vec![NodeRef::DString(d_string)], + Literal::BacktickString(d_string) => vec![NodeRef::DString(d_string)], + _ => vec![], + } + } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::Literal(self) + } +} + +impl NodeInner for DString { + fn children(&self) -> Vec { self.parts() .iter() - .map(|part| ChildRef::DStringPart(*part)) + .map(|part| NodeRef::DStringPart(*part)) .collect() } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::DString(self) + } } -impl HasChildren for DStringPart { - fn children(&self) -> Vec { +impl NodeInner for DStringPart { + fn children(&self) -> Vec { match self { - DStringPart::Expression(expression) => vec![ChildRef::Expression(expression)], + DStringPart::Expression(expression) => vec![NodeRef::Expression(expression)], _ => vec![], } } + + fn as_node_ref(&self) -> NodeRef { + NodeRef::DStringPart(self) + } } diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 3303ace..e22f418 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -3,3 +3,4 @@ pub mod children; pub mod node; pub mod pretty_print; pub mod unparse; +mod walk; diff --git a/src/ast/walk.rs b/src/ast/walk.rs new file mode 100644 index 0000000..b86e15b --- /dev/null +++ b/src/ast/walk.rs @@ -0,0 +1,145 @@ +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); + } + } + } +}