use crate::ast::node::named::Named; use crate::ast::node::names::Identifier; use crate::ast::node::use_statement::UseStatement; use std::cell::RefCell; use std::fmt::{Debug, Display, Formatter}; use std::ops::Deref; use std::range::Range; use std::rc::Rc; #[derive(Clone, Debug)] pub struct SourceDefinition { file_id: usize, range: Range, } impl SourceDefinition { pub fn from_identifier(identifier: &Identifier) -> Self { SourceDefinition { file_id: identifier.file_id(), range: identifier.range(), } } pub fn from_identifier_rc(identifier: Rc>) -> Self { let borrowed = identifier.borrow(); SourceDefinition { file_id: borrowed.file_id(), 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 } pub fn range(&self) -> Range { self.range.clone() } } pub trait SymbolInner { fn declared_name(&self) -> &str; fn definition(&self) -> Option; } /* Symbol */ #[derive(Debug, Clone)] pub enum Symbol { UseStatement(Rc>), Module(Rc), Type(Rc), Function(Rc>), Parameter(Rc), Variable(Rc), ClassMember(Rc), } impl Symbol { pub fn definition(&self) -> Option { match self { Symbol::UseStatement(s) => s.borrow().definition(), Symbol::Module(s) => s.definition(), Symbol::Type(s) => match s.deref() { TypeSymbol::Concrete(cts) => cts.definition(), TypeSymbol::Generic(gts) => gts.definition(), }, Symbol::Function(s) => s.borrow().definition(), Symbol::Parameter(s) => s.definition(), Symbol::Variable(s) => s.definition(), Symbol::ClassMember(s) => s.definition(), } } pub fn unwrap_use_statement_symbol(&self) -> Rc> { match self { Symbol::UseStatement(s) => s.clone(), _ => panic!("unwrap_use_statement_symbol called on non-use statement symbol"), } } } /* Use-statement */ pub struct UseStatementSymbol { pub fqn: String, pub declared_name: String, definition: Option, referenced_symbol: Option>, } impl UseStatementSymbol { pub fn new(fqn: &str, declared_name: &str, identifier: Option<&Identifier>) -> Self { UseStatementSymbol { fqn: fqn.to_string(), declared_name: declared_name.to_string(), definition: identifier.map(SourceDefinition::from_identifier), referenced_symbol: None, } } pub fn set_referenced_symbol(&mut self, referenced_symbol: Symbol) { self.referenced_symbol = Some(Box::new(referenced_symbol)); } pub fn referenced_symbol(&self) -> Option> { self.referenced_symbol.clone() } } impl SymbolInner for UseStatementSymbol { fn declared_name(&self) -> &str { &self.declared_name } fn definition(&self) -> Option { self.definition.clone() } } impl Debug for UseStatementSymbol { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("UseStatementSymbol") .field("fqn", &self.fqn) .field("declared_name", &self.declared_name) .field("referenced_symbol", &self.referenced_symbol) .finish() } } /* Module */ pub struct ModuleSymbol { fqn: String, declared_name: String, is_public: bool, definition: Option, } impl ModuleSymbol { pub fn new( fqn: &str, declared_name: &str, is_public: bool, identifier: Option<&Identifier>, ) -> ModuleSymbol { ModuleSymbol { fqn: fqn.to_string(), declared_name: declared_name.to_string(), is_public, definition: identifier.map(SourceDefinition::from_identifier), } } } impl SymbolInner for ModuleSymbol { fn declared_name(&self) -> &str { self.declared_name.as_str() } fn definition(&self) -> Option { self.definition.clone() } } impl Debug for ModuleSymbol { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("ModuleSymbol") .field("fqn", &self.fqn) .field("declared_name", &self.declared_name) .field("is_public", &self.is_public) .finish() } } /* TypeSymbol */ #[derive(Debug)] pub enum TypeSymbol { Concrete(ConcreteTypeSymbol), Generic(GenericTypeSymbol), } impl TypeSymbol { pub fn declared_name(&self) -> &str { match self { TypeSymbol::Concrete(t) => t.declared_name(), TypeSymbol::Generic(t) => t.declared_name(), } } } pub struct ConcreteTypeSymbol { fqn: String, declared_name: String, is_public: bool, definition: Option, } impl ConcreteTypeSymbol { pub fn new( fqn: &str, declared_name: &str, is_public: bool, identifier: Option<&Identifier>, ) -> Self { ConcreteTypeSymbol { fqn: fqn.to_string(), declared_name: declared_name.to_string(), is_public, definition: identifier.map(SourceDefinition::from_identifier), } } pub fn fqn(&self) -> &str { &self.fqn } pub fn is_public(&self) -> bool { self.is_public } } impl SymbolInner for ConcreteTypeSymbol { fn declared_name(&self) -> &str { &self.declared_name } fn definition(&self) -> Option { self.definition.clone() } } impl Debug for ConcreteTypeSymbol { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("TypeSymbol") .field("fqn", &self.fqn) .field("declared_name", &self.declared_name) .field("is_public", &self.is_public) .finish() } } pub struct GenericTypeSymbol { declared_name: String, source_definition: SourceDefinition, } impl GenericTypeSymbol { pub fn new(declared_name: &str, source_definition: SourceDefinition) -> Self { GenericTypeSymbol { declared_name: declared_name.to_string(), source_definition, } } } impl SymbolInner for GenericTypeSymbol { fn declared_name(&self) -> &str { self.declared_name.as_str() } fn definition(&self) -> Option { Some(self.source_definition.clone()) } } impl Debug for GenericTypeSymbol { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("GenericTypeSymbol") .field("declared_name", &self.declared_name) .finish() } } /* Function */ pub struct FunctionSymbol { fqn: String, declared_name: String, is_public: bool, is_platform: bool, definition: Option, parameters: Vec>, return_type: Option>, } impl FunctionSymbol { pub fn new( fqn: &str, declared_name: &str, is_public: bool, is_platform: bool, identifier: Option<&Identifier>, ) -> FunctionSymbol { FunctionSymbol { fqn: fqn.to_string(), declared_name: declared_name.to_string(), is_public, is_platform, definition: identifier.map(SourceDefinition::from_identifier), parameters: Vec::new(), return_type: None, } } pub fn with_parameters(self, parameters: Vec) -> Self { Self { fqn: self.fqn, declared_name: self.declared_name, is_public: self.is_public, is_platform: self.is_platform, definition: self.definition, parameters: parameters .into_iter() .map(|parameter| Rc::new(parameter)) .collect(), return_type: self.return_type, } } pub fn with_return_type(self, return_type: ConcreteTypeSymbol) -> Self { Self { fqn: self.fqn, declared_name: self.declared_name, is_public: self.is_public, is_platform: self.is_platform, definition: self.definition, parameters: self.parameters, return_type: Some(Rc::new(return_type)), } } pub fn fqn(&self) -> &str { &self.fqn } pub fn set_parameters(&mut self, parameters: Vec>) { self.parameters = parameters; } pub fn set_return_type(&mut self, return_type: Rc) { self.return_type = Some(return_type); } } impl SymbolInner for FunctionSymbol { fn declared_name(&self) -> &str { self.declared_name.as_str() } fn definition(&self) -> Option { self.definition.clone() } } impl Debug for FunctionSymbol { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("FunctionSymbol") .field("fqn", &self.fqn) .field("declared_name", &self.declared_name) .field("is_public", &self.is_public) .field("is_platform", &self.is_platform) .field("parameters", &self.parameters) .field("return_type", &self.return_type) .finish() } } /* Parameter */ pub struct ParameterSymbol { declared_name: String, definition: Option, } impl ParameterSymbol { pub fn new(declared_name: &str, identifier: Option<&Identifier>) -> Self { ParameterSymbol { declared_name: declared_name.to_string(), definition: identifier.map(SourceDefinition::from_identifier), } } } impl SymbolInner for ParameterSymbol { fn declared_name(&self) -> &str { &self.declared_name } fn definition(&self) -> Option { self.definition.clone() } } impl Debug for ParameterSymbol { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("ParameterSymbol") .field("declared_name", &self.declared_name) .finish() } } /* Variable */ pub struct VariableSymbol { declared_name: String, is_mutable: bool, definition: Option, } impl VariableSymbol { pub fn new(declared_name: &str, is_mutable: bool, identifier: Option<&Identifier>) -> Self { VariableSymbol { declared_name: declared_name.to_string(), is_mutable, definition: identifier.map(SourceDefinition::from_identifier), } } } impl SymbolInner for VariableSymbol { fn declared_name(&self) -> &str { self.declared_name.as_str() } fn definition(&self) -> Option { self.definition.clone() } } impl Debug for VariableSymbol { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("VariableSymbol") .field("declared_name", &self.declared_name) .field("is_mutable", &self.is_mutable) .finish() } } /* Class Member */ pub struct ClassMemberSymbol { declared_name: String, is_field: bool, definition: Option, } impl ClassMemberSymbol { pub fn new(declared_name: &str, is_field: bool, definition: Option) -> Self { ClassMemberSymbol { declared_name: declared_name.to_string(), is_field, definition, } } } impl SymbolInner for ClassMemberSymbol { fn declared_name(&self) -> &str { self.declared_name.as_str() } fn definition(&self) -> Option { self.definition.clone() } } impl Debug for ClassMemberSymbol { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("ClassMemberSymbol") .field("declared_name", &self.declared_name) .finish() } }