use std::borrow::Cow; use crate::name_analysis::symbol::Symbol; use std::range::Range; use crate::ast::node::named::Named; #[derive(Debug)] pub struct Identifier { name: String, file_id: usize, range: Range, scope_id: Option, saved_symbol: Option, } impl Identifier { pub fn new(name: &str, file_id: usize, range: Range) -> Self { Self { name: name.to_string(), file_id, range, scope_id: None, saved_symbol: None, } } } impl Named for Identifier { fn name(&self) -> Cow<'_, str> { Cow::Borrowed(&self.name) } fn file_id(&self) -> usize { self.file_id } fn range(&self) -> Range { self.range } fn set_scope_id(&mut self, id: usize) { self.scope_id = Some(id); } fn scope_id(&self) -> Option { self.scope_id } fn set_saved_symbol(&mut self, saved_symbol: Symbol) { self.saved_symbol = Some(saved_symbol); } fn saved_symbol(&self) -> Option { self.saved_symbol.clone() } } #[derive(Debug)] pub struct FullyQualifiedName { identifiers: Vec>, file_id: usize, range: Range, scope_id: Option, saved_symbol: Option, } impl FullyQualifiedName { pub fn new(identifiers: Vec>, file_id: usize, range: Range) -> Self { Self { identifiers, range, file_id, scope_id: None, saved_symbol: None, } } 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() } #[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")] pub fn last(&self) -> &Identifier { &self.identifiers[self.identifiers.len() - 1] } #[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")] pub fn last_mut(&mut self) -> &mut Identifier { let last_index = self.identifiers.len() - 1; &mut self.identifiers[last_index] } #[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")] pub fn len(&self) -> usize { self.identifiers.len() } #[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")] pub fn is_single_identifier(&self) -> bool { self.identifiers.len() == 1 } } impl Named for FullyQualifiedName { fn name(&self) -> Cow<'_, str> { if self.identifiers.len() == 1 { self.identifiers[0].name() } else { let mut acc = String::new(); for (i, identifier) in self.identifiers.iter().enumerate() { acc += &identifier.name(); if i < self.identifiers.len() - 1 { acc += "::"; } } Cow::Owned(acc) } } fn file_id(&self) -> usize { self.file_id } fn range(&self) -> Range { self.range } fn set_scope_id(&mut self, id: usize) { self.scope_id = Some(id); } fn scope_id(&self) -> Option { self.scope_id } fn set_saved_symbol(&mut self, symbol: Symbol) { self.saved_symbol = Some(symbol); } fn saved_symbol(&self) -> Option { self.saved_symbol.clone() } }