484 lines
12 KiB
Rust
484 lines
12 KiB
Rust
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<usize>,
|
|
}
|
|
|
|
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<RefCell<Identifier>>) -> 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<usize> {
|
|
self.range.clone()
|
|
}
|
|
}
|
|
|
|
pub trait SymbolInner {
|
|
fn declared_name(&self) -> &str;
|
|
fn definition(&self) -> Option<SourceDefinition>;
|
|
}
|
|
|
|
/* Symbol */
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum Symbol {
|
|
UseStatement(Rc<RefCell<UseStatementSymbol>>),
|
|
Module(Rc<ModuleSymbol>),
|
|
Type(Rc<TypeSymbol>),
|
|
Function(Rc<RefCell<FunctionSymbol>>),
|
|
Parameter(Rc<ParameterSymbol>),
|
|
Variable(Rc<VariableSymbol>),
|
|
ClassMember(Rc<ClassMemberSymbol>),
|
|
}
|
|
|
|
impl Symbol {
|
|
pub fn definition(&self) -> Option<SourceDefinition> {
|
|
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<RefCell<UseStatementSymbol>> {
|
|
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<SourceDefinition>,
|
|
referenced_symbol: Option<Box<Symbol>>,
|
|
}
|
|
|
|
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<Box<Symbol>> {
|
|
self.referenced_symbol.clone()
|
|
}
|
|
}
|
|
|
|
impl SymbolInner for UseStatementSymbol {
|
|
fn declared_name(&self) -> &str {
|
|
&self.declared_name
|
|
}
|
|
|
|
fn definition(&self) -> Option<SourceDefinition> {
|
|
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<SourceDefinition>,
|
|
}
|
|
|
|
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<SourceDefinition> {
|
|
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<SourceDefinition>,
|
|
}
|
|
|
|
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<SourceDefinition> {
|
|
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<SourceDefinition> {
|
|
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<SourceDefinition>,
|
|
parameters: Vec<Rc<ParameterSymbol>>,
|
|
return_type: Option<Rc<ConcreteTypeSymbol>>,
|
|
}
|
|
|
|
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<ParameterSymbol>) -> 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<Rc<ParameterSymbol>>) {
|
|
self.parameters = parameters;
|
|
}
|
|
|
|
pub fn set_return_type(&mut self, return_type: Rc<ConcreteTypeSymbol>) {
|
|
self.return_type = Some(return_type);
|
|
}
|
|
}
|
|
|
|
impl SymbolInner for FunctionSymbol {
|
|
fn declared_name(&self) -> &str {
|
|
self.declared_name.as_str()
|
|
}
|
|
|
|
fn definition(&self) -> Option<SourceDefinition> {
|
|
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<SourceDefinition>,
|
|
}
|
|
|
|
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<SourceDefinition> {
|
|
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<SourceDefinition>,
|
|
}
|
|
|
|
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<SourceDefinition> {
|
|
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<SourceDefinition>,
|
|
}
|
|
|
|
impl ClassMemberSymbol {
|
|
pub fn new(declared_name: &str, is_field: bool, definition: Option<SourceDefinition>) -> 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<SourceDefinition> {
|
|
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()
|
|
}
|
|
}
|