diff --git a/src/ast/build.rs b/src/ast/build.rs index 1f1dea4..46145a3 100644 --- a/src/ast/build.rs +++ b/src/ast/build.rs @@ -427,29 +427,37 @@ fn build_namespace(file_id: usize, namespace_pair: Pair) -> FullyQualified fn build_use_statement(file_id: usize, use_statement_pair: Pair) -> UseStatement { let as_span = use_statement_pair.as_span(); + let range = Range { + start: as_span.start(), + end: as_span.end(), + }; + let mut inner = use_statement_pair.into_inner(); let inner_length = inner.len(); inner.next().unwrap(); // use - let mut identifiers = vec![]; - let mut last = None; + let mut prefixes = vec![]; + let mut built: Option = None; for (i, inner_pair) in inner.into_iter().enumerate() { if i != inner_length - 2 { - identifiers.push(Box::new(expect_and_use( - file_id, - inner_pair, - Rule::Identifier, - build_identifier, - ))); + prefixes.push(inner_pair.as_str()); } else { - last = Some(Box::new(match inner_pair.as_rule() { - Rule::Identifier => { - UseStatementLast::Identifier(Box::new(build_identifier(file_id, inner_pair))) - } - Rule::Star => UseStatementLast::Star, - Rule::UseList => UseStatementLast::Identifiers( + built = Some(match inner_pair.as_rule() { + Rule::Identifier => UseStatement::Concrete(ConcreteUseStatement::new( + prefixes.iter().map(|s| s.to_string()).collect(), + vec![Box::new(expect_and_use( + file_id, + inner_pair, + Rule::Identifier, + build_identifier, + ))], + file_id, + range, + )), + Rule::UseList => UseStatement::Concrete(ConcreteUseStatement::new( + prefixes.iter().map(|s| s.to_string()).collect(), inner_pair .into_inner() .map(|identifier_pair| { @@ -461,21 +469,20 @@ fn build_use_statement(file_id: usize, use_statement_pair: Pair) -> UseSta )) }) .collect(), - ), + file_id, + range, + )), + Rule::Star => UseStatement::Star(StarUseStatement::new( + prefixes.iter().map(|s| s.to_string()).collect(), + file_id, + range, + )), _ => unreachable!(), - })); + }); } } - UseStatement::new( - identifiers, - last.unwrap(), - file_id, - Range { - start: as_span.start(), - end: as_span.end(), - }, - ) + built.unwrap() } fn build_module_level_declaration(file_id: usize, pair: Pair) -> ModuleLevelDeclaration { diff --git a/src/ast/children.rs b/src/ast/children.rs index 5748b2c..248e029 100644 --- a/src/ast/children.rs +++ b/src/ast/children.rs @@ -88,7 +88,7 @@ pub enum NodeRef<'a> { pub trait NodeInner { fn children(&self) -> Vec; - + fn as_node_ref(&self) -> NodeRef; } @@ -96,7 +96,7 @@ impl NodeInner for Identifier { fn children(&self) -> Vec { vec![] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::Identifier(self) } @@ -109,7 +109,7 @@ impl NodeInner for FullyQualifiedName { .map(|id| NodeRef::Identifier(*id)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::FullyQualifiedName(self) } @@ -126,7 +126,7 @@ impl NodeInner for TypeUse { TypeUse::Function(function_type_use) => function_type_use.children(), } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::TypeUse(self) } @@ -145,7 +145,7 @@ impl NodeInner for PrimitiveTypeUse { _ => vec![], } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::PrimitiveTypeUse(self) } @@ -158,7 +158,7 @@ impl NodeInner for InterfaceOrClassTypeUse { children.push(NodeRef::GenericArguments(self.generics())); children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::InterfaceOrClassTypeUse(self) } @@ -168,7 +168,7 @@ impl NodeInner for TupleTypeUse { fn children(&self) -> Vec { vec![NodeRef::TupleArguments(self.arguments())] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::TupleTypeUse(self) } @@ -182,7 +182,7 @@ impl NodeInner for FunctionTypeUse { NodeRef::ReturnType(self.return_type()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::FunctionTypeUse(self) } @@ -195,7 +195,7 @@ impl NodeInner for GenericArguments { .map(|type_use| NodeRef::TypeUse(*type_use)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::GenericArguments(self) } @@ -208,7 +208,7 @@ impl NodeInner for GenericParameters { .map(|id| NodeRef::Identifier(*id)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::GenericParameters(self) } @@ -221,7 +221,7 @@ impl NodeInner for TupleArguments { .map(|type_use| NodeRef::TypeUse(*type_use)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::TupleArguments(self) } @@ -234,7 +234,7 @@ impl NodeInner for ImplementsList { .map(|type_use| NodeRef::TypeUse(*type_use)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ImplementsList(self) } @@ -247,7 +247,7 @@ impl NodeInner for Parameters { .map(|parameter| NodeRef::Parameter(*parameter)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::Parameters(self) } @@ -260,7 +260,7 @@ impl NodeInner for Parameter { NodeRef::TypeUse(self.type_use()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::Parameter(self) } @@ -273,7 +273,7 @@ impl NodeInner for ReturnType { NodeRef::References(self.references()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ReturnType(self) } @@ -286,7 +286,7 @@ impl NodeInner for References { .map(|identifier| NodeRef::Identifier(*identifier)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::References(self) } @@ -310,7 +310,7 @@ impl NodeInner for CompilationUnit { ); children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::CompilationUnit(self) } @@ -319,25 +319,18 @@ impl NodeInner for CompilationUnit { impl NodeInner for UseStatement { fn children(&self) -> Vec { let mut children = vec![]; - children.extend( - self.identifiers() - .iter() - .map(|identifier| NodeRef::Identifier(*identifier)), - ); - match self.last() { - UseStatementLast::Identifier(identifier) => { - children.push(NodeRef::Identifier(identifier)) - } - UseStatementLast::Identifiers(identifiers) => children.extend( - identifiers + match self { + UseStatement::Concrete(concrete_use_statement) => children.extend( + concrete_use_statement + .identifiers() .iter() - .map(|identifier| NodeRef::Identifier(identifier.clone())), + .map(|identifier| NodeRef::Identifier(*identifier)) ), - UseStatementLast::Star => {} + UseStatement::Star(_) => {} } children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::UseStatement(self) } @@ -356,7 +349,7 @@ impl NodeInner for ModuleLevelDeclaration { } } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ModuleLevelDeclaration(self) } @@ -375,7 +368,7 @@ impl NodeInner for InterfaceLevelDeclaration { } } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::InterfaceLevelDeclaration(self) } @@ -399,7 +392,7 @@ impl NodeInner for ClassLevelDeclaration { Field(field_declaration) => field_declaration.children(), } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ClassLevelDeclaration(self) } @@ -416,7 +409,7 @@ impl NodeInner for ModuleDeclaration { ); children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ModuleDeclaration(self) } @@ -435,7 +428,7 @@ impl NodeInner for InterfaceDeclaration { ); children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::InterfaceDeclaration(self) } @@ -457,7 +450,7 @@ impl NodeInner for ClassDeclaration { ); children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ClassDeclaration(self) } @@ -473,7 +466,7 @@ impl NodeInner for FunctionDefinition { NodeRef::FunctionBody(self.body()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::FunctionDefinition(self) } @@ -488,7 +481,7 @@ impl NodeInner for OperatorFunctionDefinition { NodeRef::FunctionBody(self.body()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::OperatorFunctionDefinition(self) } @@ -503,7 +496,7 @@ impl NodeInner for PlatformFunctionDeclaration { NodeRef::ReturnType(self.return_type()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::PlatformFunctionDeclaration(self) } @@ -522,7 +515,7 @@ impl NodeInner for InterfaceFunctionDeclaration { } children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::InterfaceFunctionDeclaration(self) } @@ -540,7 +533,7 @@ impl NodeInner for InterfaceOperatorFunctionDeclaration { } children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::InterfaceOperatorFunctionDeclaration(self) } @@ -554,7 +547,7 @@ impl NodeInner for FunctionBody { Self::Alias(identifier) => vec![NodeRef::Identifier(identifier.as_ref())], } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::FunctionBody(self) } @@ -567,7 +560,7 @@ impl NodeInner for ClassConstructor { .map(|parameter| NodeRef::ClassConstructorParameter(*parameter)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ClassConstructor(self) } @@ -580,7 +573,7 @@ impl NodeInner for ClassConstructorParameter { Self::Field(field_declaration) => field_declaration.children(), } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ClassConstructorParameter(self) } @@ -593,7 +586,7 @@ impl NodeInner for PropertyDeclaration { NodeRef::TypeUse(self.declared_type()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::PropertyDeclaration(self) } @@ -606,7 +599,7 @@ impl NodeInner for FieldDeclaration { NodeRef::TypeUse(self.declared_type()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::FieldDeclaration(self) } @@ -625,7 +618,7 @@ impl NodeInner for BlockStatement { } children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::BlockStatement(self) } @@ -648,7 +641,7 @@ impl NodeInner for Statement { ForStatement(for_statement) => for_statement.children(), } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::Statement(self) } @@ -666,7 +659,7 @@ impl NodeInner for VariableDeclarationStatement { } children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::VariableDeclarationStatement(self) } @@ -679,7 +672,7 @@ impl NodeInner for AssignStatement { NodeRef::Expression(self.rhs()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::AssignStatement(self) } @@ -689,7 +682,7 @@ impl NodeInner for CallStatement { fn children(&self) -> Vec { vec![NodeRef::Expression(self.expression())] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::CallStatement(self) } @@ -703,7 +696,7 @@ impl NodeInner for ReturnStatement { vec![] } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ReturnStatement(self) } @@ -716,7 +709,7 @@ impl NodeInner for IfStatement { NodeRef::BlockStatement(self.then_block()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::IfStatement(self) } @@ -732,7 +725,7 @@ impl NodeInner for IfElseStatement { } children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::IfElseStatement(self) } @@ -745,7 +738,7 @@ impl NodeInner for ElseIfs { .map(|statement| NodeRef::IfStatement(statement)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ElseIfs(self) } @@ -755,7 +748,7 @@ impl NodeInner for ElseBlock { fn children(&self) -> Vec { vec![NodeRef::BlockStatement(self.block_statement())] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ElseBlock(self) } @@ -768,7 +761,7 @@ impl NodeInner for WhileStatement { NodeRef::BlockStatement(self.body()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::WhileStatement(self) } @@ -782,7 +775,7 @@ impl NodeInner for ForStatement { NodeRef::BlockStatement(self.body()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ForStatement(self) } @@ -803,7 +796,7 @@ impl NodeInner for Expression { Closure(closure) => closure.children(), } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::Expression(self) } @@ -817,7 +810,7 @@ impl NodeInner for TernaryExpression { NodeRef::Expression(self.false_expression()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::TernaryExpression(self) } @@ -830,7 +823,7 @@ impl NodeInner for BinaryExpression { NodeRef::Expression(self.right()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::BinaryExpression(self) } @@ -840,7 +833,7 @@ impl NodeInner for PrefixExpression { fn children(&self) -> Vec { vec![NodeRef::Expression(self.expression())] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::PrefixExpression(self) } @@ -850,7 +843,7 @@ impl NodeInner for SuffixExpression { fn children(&self) -> Vec { vec![NodeRef::Expression(self.expression())] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::SuffixExpression(self) } @@ -866,7 +859,7 @@ impl NodeInner for CallExpression { children.push(NodeRef::CallArguments(self.arguments())); children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::CallExpression(self) } @@ -876,7 +869,7 @@ impl NodeInner for TurboFish { fn children(&self) -> Vec { vec![NodeRef::GenericArguments(self.generics())] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::TurboFish(self) } @@ -889,7 +882,7 @@ impl NodeInner for CallArguments { .map(|argument| NodeRef::CallArgument(*argument)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::CallArguments(self) } @@ -899,7 +892,7 @@ impl NodeInner for CallArgument { fn children(&self) -> Vec { vec![NodeRef::Expression(self.expression())] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::CallArgument(self) } @@ -920,7 +913,7 @@ impl NodeInner for Closure { } children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::Closure(self) } @@ -933,7 +926,7 @@ impl NodeInner for ClosureCaptures { .map(|capture| NodeRef::ClosureCapture(*capture)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ClosureCaptures(self) } @@ -943,7 +936,7 @@ impl NodeInner for ClosureCapture { fn children(&self) -> Vec { vec![NodeRef::Identifier(self.identifier())] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ClosureCapture(self) } @@ -956,7 +949,7 @@ impl NodeInner for ClosureParameters { .map(|parameter| NodeRef::ClosureParameter(*parameter)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ClosureParameters(self) } @@ -971,7 +964,7 @@ impl NodeInner for ClosureParameter { } children } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ClosureParameter(self) } @@ -984,7 +977,7 @@ impl NodeInner for ObjectAccess { NodeRef::ObjectNavigations(self.navigations()), ] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ObjectAccess(self) } @@ -997,7 +990,7 @@ impl NodeInner for ObjectNavigations { .map(|navigation| NodeRef::ObjectNavigation(*navigation)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ObjectNavigations(self) } @@ -1010,7 +1003,7 @@ impl NodeInner for ObjectNavigation { ObjectNavigation::Index(index_expression) => NodeRef::Expression(index_expression), }] } - + fn as_node_ref(&self) -> NodeRef { NodeRef::ObjectNavigation(self) } @@ -1024,7 +1017,7 @@ impl NodeInner for Literal { _ => vec![], } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::Literal(self) } @@ -1037,7 +1030,7 @@ impl NodeInner for DString { .map(|part| NodeRef::DStringPart(*part)) .collect() } - + fn as_node_ref(&self) -> NodeRef { NodeRef::DString(self) } @@ -1050,7 +1043,7 @@ impl NodeInner for DStringPart { _ => vec![], } } - + fn as_node_ref(&self) -> NodeRef { NodeRef::DStringPart(self) } diff --git a/src/ast/node/use_statement.rs b/src/ast/node/use_statement.rs index b018e62..dce4af4 100644 --- a/src/ast/node/use_statement.rs +++ b/src/ast/node/use_statement.rs @@ -1,75 +1,48 @@ use crate::ast::node::named::Named; use crate::ast::node::names::Identifier; -use std::borrow::Cow; use std::range::Range; #[derive(Debug)] -pub struct UseStatement { +pub enum UseStatement { + Concrete(ConcreteUseStatement), + Star(StarUseStatement), +} + +#[derive(Debug)] +pub struct ConcreteUseStatement { + prefixes: Vec, identifiers: Vec>, - last: Box, file_id: usize, range: Range, } -impl UseStatement { +impl ConcreteUseStatement { pub fn new( + prefixes: Vec, identifiers: Vec>, - last: Box, file_id: usize, range: Range, ) -> Self { - UseStatement { + ConcreteUseStatement { + prefixes, identifiers, - last, file_id, range, } } - pub fn base_name(&self) -> Cow<'_, str> { - use UseStatementLast::*; - if self.identifiers.is_empty() { - match self.last.as_ref() { - Identifier(_) => Cow::from(""), - Star | Identifiers(_) => panic!(), // should never get here because of grammar - } - } else if self.identifiers.len() == 1 { - self.identifiers[0].name() - } else { - let mut acc = String::new(); - for (i, identifier) in self.identifiers.iter().enumerate() { - acc.push_str(&identifier.name()); - if i != self.identifiers.len() - 1 { - acc.push_str("::"); - } - } - Cow::from(acc) - } + pub fn prefixes(&self) -> &Vec { + &self.prefixes } - pub fn is_star(&self) -> bool { - match self.last.as_ref() { - UseStatementLast::Star => true, - _ => false, - } + pub fn join_prefixes(&self) -> String { + self.prefixes.join("::") } pub fn identifiers(&self) -> Vec<&Identifier> { self.identifiers.iter().map(Box::as_ref).collect() } - pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> { - self.identifiers.iter_mut().map(Box::as_mut).collect() - } - - pub fn last(&self) -> &UseStatementLast { - &self.last - } - - pub fn last_mut(&mut self) -> &mut UseStatementLast { - &mut self.last - } - pub fn file_id(&self) -> usize { self.file_id } @@ -80,8 +53,34 @@ impl UseStatement { } #[derive(Debug)] -pub enum UseStatementLast { - Identifier(Box), - Identifiers(Vec>), - Star, +pub struct StarUseStatement { + prefixes: Vec, + file_id: usize, + range: Range, +} + +impl StarUseStatement { + pub fn new(prefixes: Vec, file_id: usize, range: Range) -> Self { + Self { + prefixes, + file_id, + range, + } + } + + pub fn prefixes(&self) -> &Vec { + &self.prefixes + } + + pub fn join_prefixes(&self) -> String { + self.prefixes.join("::") + } + + pub fn file_id(&self) -> usize { + self.file_id + } + + pub fn range(&self) -> Range { + self.range + } } diff --git a/src/ast/pretty_print.rs b/src/ast/pretty_print.rs index 108e60e..1348123 100644 --- a/src/ast/pretty_print.rs +++ b/src/ast/pretty_print.rs @@ -320,6 +320,28 @@ impl PrettyPrint for CompilationUnit { } } +impl PrettyPrint for UseStatement { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.writeln_indented("UseStatement")?; + writer.increase_indent(); + match self { + UseStatement::Concrete(concrete_use_statement) => { + writer.writeln_indented(&format!("ConcreteUseStatement(prefixes = {})", concrete_use_statement.join_prefixes()))?; + writer.increase_indent(); + for identifier in concrete_use_statement.identifiers() { + identifier.pretty_print(writer)?; + } + writer.decrease_indent(); + } + UseStatement::Star(star_use_statement) => { + writer.writeln_indented(&format!("StarUseStatement(prefixes = {})", star_use_statement.join_prefixes()))?; + } + } + writer.decrease_indent(); + Ok(()) + } +} + impl PrettyPrint for ModuleLevelDeclaration { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use crate::ast::node::level::ModuleLevelDeclaration::*; @@ -618,39 +640,6 @@ impl PrettyPrint for FieldDeclaration { } } -impl PrettyPrint for UseStatement { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - writer.writeln_indented("UseStatement")?; - writer.increase_indent(); - for identifier in self.identifiers() { - identifier.pretty_print(writer)?; - } - self.last().pretty_print(writer)?; - writer.decrease_indent(); - Ok(()) - } -} - -impl PrettyPrint for UseStatementLast { - fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - writer.writeln_indented("UseStatementLast")?; - writer.increase_indent(); - match self { - UseStatementLast::Identifier(i) => i.pretty_print(writer)?, - UseStatementLast::Identifiers(is) => { - for i in is { - i.pretty_print(writer)?; - } - } - UseStatementLast::Star => { - writer.writeln_indented("Star")?; - } - } - writer.decrease_indent(); - Ok(()) - } -} - impl PrettyPrint for BlockStatement { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("BlockStatement")?; diff --git a/src/ast/unparse.rs b/src/ast/unparse.rs index 58102b8..f3bfa13 100644 --- a/src/ast/unparse.rs +++ b/src/ast/unparse.rs @@ -410,35 +410,28 @@ impl Unparse for CompilationUnit { impl Unparse for UseStatement { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("use ")?; - for (i, identifier) in self.identifiers().iter().enumerate() { - identifier.unparse(writer)?; - if i != self.identifiers().len() - 2 { - // 2 because of use - writer.write("::")?; - } - } - self.last().unparse(writer)?; - Ok(()) - } -} - -impl Unparse for UseStatementLast { - fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { match self { - UseStatementLast::Star => writer.write("*"), - UseStatementLast::Identifiers(identifiers) => { - writer.write("{")?; - for (i, identifier) in identifiers.iter().enumerate() { - identifier.unparse(writer)?; - if i != identifiers.len() - 1 { - writer.write(", ")?; + UseStatement::Concrete(concrete_use_statement) => { + writer.write(&format!("{}::", concrete_use_statement.join_prefixes()))?; + let identifiers = concrete_use_statement.identifiers(); + if identifiers.len() == 1 { + identifiers[0].unparse(writer)?; + } else { + writer.write("{")?; + for (i, identifier) in identifiers.iter().enumerate() { + identifier.unparse(writer)?; + if i != identifiers.len() - 1 { + writer.write(", ")?; + } } + writer.write("}")?; } - writer.write("}")?; - Ok(()) + }, + UseStatement::Star(star_use_statement) => { + writer.write(&format!("{}::*", star_use_statement.join_prefixes()))?; } - UseStatementLast::Identifier(i) => i.unparse(writer), } + Ok(()) } } diff --git a/src/name_analysis/gather.rs b/src/name_analysis/gather.rs index 8de7215..9a6e391 100644 --- a/src/name_analysis/gather.rs +++ b/src/name_analysis/gather.rs @@ -364,21 +364,7 @@ fn gather_use_statement( fqn_context: &mut FqnContext, diagnostics: &mut Vec, ) { - if use_statement.is_star() { - todo!() - } - let base_name = use_statement.base_name().to_string(); - match use_statement.last_mut() { - UseStatementLast::Identifier(identifier) => { - handle_use_statement_import(symbol_table, &base_name, identifier, diagnostics) - } - UseStatementLast::Identifiers(identifiers) => { - for identifier in identifiers { - handle_use_statement_import(symbol_table, &base_name, identifier, diagnostics) - } - } - UseStatementLast::Star => panic!(), - } + todo!() } /* Declarations allowed in each level */ diff --git a/src/name_analysis/mod.rs b/src/name_analysis/mod.rs index 1c34b98..a7ac246 100644 --- a/src/name_analysis/mod.rs +++ b/src/name_analysis/mod.rs @@ -56,7 +56,6 @@ mod tests { use super::*; use crate::ast::build::build_ast; use crate::ast::children::NodeRef; - use crate::ast::node::use_statement::UseStatementLast; use crate::ast::walk::walk_depth_first; use crate::parser::{DeimosParser, Rule}; use crate::std_core::add_std_core_symbols; @@ -126,25 +125,7 @@ mod tests { panic!("{:?} does not have a saved symbol.", fqn) } } - NodeRef::UseStatement(use_statement) => match use_statement.last() { - UseStatementLast::Identifier(identifier) => { - if identifier.saved_symbol().is_none() { - panic!( - "UseStatement {:?} does not have a saved symbol.", - identifier - ) - } - } - UseStatementLast::Identifiers(identifiers) => { - for identifier in identifiers { - if identifier.saved_symbol().is_none() { - panic!( - "UseStatement {:?} does not have a saved symbol.", - identifier - ) - } - } - } + NodeRef::UseStatement(use_statement) => match use_statement { _ => todo!(), }, _ => {} @@ -153,35 +134,7 @@ mod tests { fn assert_resolved_symbols(compilation_unit: &CompilationUnit) { walk_depth_first(compilation_unit, &mut |node_ref| match node_ref { - NodeRef::UseStatement(use_statement) => match use_statement.last() { - UseStatementLast::Identifier(identifier) => { - let use_statement_symbol = identifier - .saved_symbol() - .unwrap() - .unwrap_use_statement_symbol(); - let borrowed = use_statement_symbol.borrow(); - if borrowed.referenced_symbol().is_none() { - panic!( - "{:?} does not have a referenced symbol.", - use_statement_symbol - ) - } - } - UseStatementLast::Identifiers(identifiers) => { - for identifier in identifiers { - let use_statement_symbol = identifier - .saved_symbol() - .unwrap() - .unwrap_use_statement_symbol(); - let borrowed = use_statement_symbol.borrow(); - if borrowed.referenced_symbol().is_none() { - panic!( - "{:?} does not have a referenced symbol.", - use_statement_symbol - ) - } - } - } + NodeRef::UseStatement(use_statement) => match use_statement { _ => todo!(), }, _ => {} diff --git a/src/name_analysis/resolve.rs b/src/name_analysis/resolve.rs index f6c0757..98c6689 100644 --- a/src/name_analysis/resolve.rs +++ b/src/name_analysis/resolve.rs @@ -260,36 +260,7 @@ fn resolve_use_statement( symbol_table: &mut SymbolTable, diagnostics: &mut Vec, ) { - let file_id = use_statement.file_id(); - let use_statement_range = use_statement.range(); - let base_name = use_statement.base_name().to_string(); - - match use_statement.last_mut() { - UseStatementLast::Identifier(identifier) => { - handle_use_statement_identifier( - identifier.deref_mut(), - &base_name, - symbol_table, - diagnostics, - file_id, - use_statement_range, - ); - } - UseStatementLast::Identifiers(identifiers) => { - for identifier in identifiers { - let identifier_range = identifier.range(); - handle_use_statement_identifier( - identifier.deref_mut(), - &base_name, - symbol_table, - diagnostics, - file_id, - identifier_range, - ) - } - } - UseStatementLast::Star => todo!("star imports"), - } + todo!() } /* Declarations allowed in each level */ diff --git a/src/name_analysis/symbol.rs b/src/name_analysis/symbol.rs index dcf3fd0..6b71d05 100644 --- a/src/name_analysis/symbol.rs +++ b/src/name_analysis/symbol.rs @@ -28,15 +28,7 @@ impl SourceDefinition { range: borrowed.range(), } } - - #[deprecated(note = "Use identifier instead.")] - pub fn from_use_statement(use_statement: &UseStatement) -> Self { - SourceDefinition { - file_id: use_statement.file_id(), - range: use_statement.range(), - } - } - + pub fn file_id(&self) -> usize { self.file_id } diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index 5af558a..bbcc876 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -333,6 +333,20 @@ Namespace = { ~ FullyQualifiedName } +UseStatement = { + Use + ~ Identifier + ~ ( "::" ~ Identifier )* + ~ ( "::" ~ ( Star | UseList ) )? +} + +UseList = { + "{" + ~ Identifier + ~ ( "," ~ Identifier )* + ~ "}" +} + // Organizational declarations ModuleLevelDeclaration = { @@ -523,20 +537,6 @@ Field = { // Statements -UseStatement = { - Use - ~ Identifier - ~ ( "::" ~ Identifier )* - ~ ( "::" ~ ( Star | UseList ) )? -} - -UseList = { - "{" - ~ Identifier - ~ ( "," ~ Identifier )* - ~ "}" -} - BlockStatement = { "{" ~ Statement*