WIP seemingly endless name analysis refactoring.
This commit is contained in:
parent
93c6a71185
commit
8b374e1066
@ -1,12 +1,20 @@
|
|||||||
use crate::ast::node::{
|
use crate::ast::node::{
|
||||||
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Identifier, UseStatement,
|
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
|
||||||
|
Identifier, Module, ModuleLevelDeclaration, Parameters, ReturnType, TypeUse, UseStatement,
|
||||||
UseStatementIdentifier, UseStatementPrefix,
|
UseStatementIdentifier, UseStatementPrefix,
|
||||||
};
|
};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
|
||||||
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::use_symbol::ConcreteUseSymbol;
|
use crate::name_analysis::symbol::use_symbol::ConcreteUseSymbol;
|
||||||
use crate::name_analysis::symbol_table::SymbolTable;
|
use crate::name_analysis::symbol_table::SymbolTable;
|
||||||
|
use crate::name_analysis::type_use_container::TypeUseContainer;
|
||||||
use crate::name_analysis::util::handle_insert_error;
|
use crate::name_analysis::util::handle_insert_error;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn na_p1_compilation_unit(
|
pub fn na_p1_compilation_unit(
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
@ -30,6 +38,10 @@ pub fn na_p1_compilation_unit(
|
|||||||
na_p1_use_statement(use_statement, symbol_table, diagnostics);
|
na_p1_use_statement(use_statement, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for module_level_declaration in compilation_unit.module_level_declarations_mut() {
|
||||||
|
na_p1_module_level_declaration(module_level_declaration, symbol_table, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
symbol_table.pop_scope();
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,12 +65,12 @@ fn na_p1_concrete_use_statement(
|
|||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let prefixes: Vec<String> = concrete_use_statement
|
let prefixes: Vec<Rc<str>> = concrete_use_statement
|
||||||
.prefixes()
|
.prefixes()
|
||||||
.map(UseStatementPrefix::identifier)
|
.map(UseStatementPrefix::identifier)
|
||||||
.map(Identifier::name)
|
.map(Identifier::name)
|
||||||
.map(ToString::to_string)
|
.map(Rc::from)
|
||||||
.collect::<Vec<_>>();
|
.collect();
|
||||||
|
|
||||||
match concrete_use_statement.suffix_mut() {
|
match concrete_use_statement.suffix_mut() {
|
||||||
ConcreteUseStatementSuffix::UseStatementIdentifier(use_statement_identifier) => {
|
ConcreteUseStatementSuffix::UseStatementIdentifier(use_statement_identifier) => {
|
||||||
@ -83,16 +95,16 @@ fn na_p1_concrete_use_statement(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_concrete_use_statement_identifier(
|
fn handle_concrete_use_statement_identifier(
|
||||||
prefixes: &Vec<String>,
|
prefixes: &Vec<Rc<str>>,
|
||||||
use_statement_identifier: &mut UseStatementIdentifier,
|
use_statement_identifier: &mut UseStatementIdentifier,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let mut fqn_parts: Vec<&str> = vec![];
|
let mut fqn_parts: Vec<Rc<str>> = vec![];
|
||||||
for prefix in prefixes {
|
for prefix in prefixes {
|
||||||
fqn_parts.push(prefix);
|
fqn_parts.push(prefix.clone());
|
||||||
}
|
}
|
||||||
fqn_parts.push(use_statement_identifier.identifier().name());
|
fqn_parts.push(Rc::from(use_statement_identifier.identifier().name()));
|
||||||
|
|
||||||
let to_insert = ConcreteUseSymbol::new(
|
let to_insert = ConcreteUseSymbol::new(
|
||||||
&fqn_parts,
|
&fqn_parts,
|
||||||
@ -111,9 +123,168 @@ fn handle_concrete_use_statement_identifier(
|
|||||||
use_statement_identifier.identifier().name(),
|
use_statement_identifier.identifier().name(),
|
||||||
use_statement_identifier.identifier().file_id(),
|
use_statement_identifier.identifier().file_id(),
|
||||||
use_statement_identifier.identifier().range(),
|
use_statement_identifier.identifier().range(),
|
||||||
"Use Symbol",
|
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn na_p1_module_level_declaration(
|
||||||
|
module_level_declaration: &mut ModuleLevelDeclaration,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Option<ModuleLevelSymbol> {
|
||||||
|
match module_level_declaration {
|
||||||
|
ModuleLevelDeclaration::Module(module) => na_p1_module(module, symbol_table, diagnostics)
|
||||||
|
.map(|module_symbol| ModuleLevelSymbol::Module(module_symbol)),
|
||||||
|
ModuleLevelDeclaration::Interface(interface) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
ModuleLevelDeclaration::Class(class) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
ModuleLevelDeclaration::Function(function) => {
|
||||||
|
na_p1_function(function, symbol_table, diagnostics)
|
||||||
|
.map(|function_symbol| ModuleLevelSymbol::Function(function_symbol))
|
||||||
|
}
|
||||||
|
ModuleLevelDeclaration::PlatformFunction(platform_function) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_module(
|
||||||
|
module: &mut Module,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Option<Rc<RefCell<ModuleSymbol>>> {
|
||||||
|
symbol_table.push_fqn_part(module.identifier().name());
|
||||||
|
symbol_table.push_scope(&format!("ModuleScope {}", module.identifier().name()));
|
||||||
|
|
||||||
|
let to_insert = ModuleSymbol::new(
|
||||||
|
symbol_table.current_fqn_owned(),
|
||||||
|
module.is_public(),
|
||||||
|
Some(SourceDefinition::from_identifier(module.identifier())),
|
||||||
|
);
|
||||||
|
let module_symbol = match symbol_table.insert_module_symbol(to_insert) {
|
||||||
|
Ok(module_symbol) => {
|
||||||
|
for declaration in module.declarations_mut() {
|
||||||
|
let declaration_result =
|
||||||
|
na_p1_module_level_declaration(declaration, symbol_table, diagnostics);
|
||||||
|
if let Some(module_level_symbol) = declaration_result {
|
||||||
|
module_symbol
|
||||||
|
.borrow_mut()
|
||||||
|
.add_inner_symbol(module_level_symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(module_symbol)
|
||||||
|
}
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
module.identifier().name(),
|
||||||
|
module.identifier().file_id(),
|
||||||
|
module.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
symbol_table.pop_fqn_part();
|
||||||
|
|
||||||
|
module_symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_function(
|
||||||
|
function: &mut Function,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
||||||
|
symbol_table.push_scope(&format!("FunctionScope {}", function.identifier().name()));
|
||||||
|
|
||||||
|
let to_insert = FunctionSymbol::new(
|
||||||
|
&symbol_table.resolve_fqn(Rc::from(function.identifier().name())),
|
||||||
|
function.is_public(),
|
||||||
|
false,
|
||||||
|
Some(SourceDefinition::from_identifier(function.identifier())),
|
||||||
|
);
|
||||||
|
let function_symbol = match symbol_table.insert_function_symbol(to_insert) {
|
||||||
|
Ok(function_symbol) => {
|
||||||
|
{
|
||||||
|
let mut as_ref_mut = function_symbol.borrow_mut();
|
||||||
|
as_ref_mut.set_parameter_symbols(na_p1_parameters(
|
||||||
|
function.parameters_mut(),
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
));
|
||||||
|
as_ref_mut.set_return_type(na_p1_return_type(
|
||||||
|
function.return_type_mut(),
|
||||||
|
symbol_table,
|
||||||
|
diagnostics,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Some(function_symbol)
|
||||||
|
}
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
function.identifier().name(),
|
||||||
|
function.identifier().file_id(),
|
||||||
|
function.identifier().range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
symbol_table.pop_scope();
|
||||||
|
|
||||||
|
function_symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_parameters(
|
||||||
|
parameters: &mut Parameters,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Vec<Rc<RefCell<ParameterSymbol>>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_return_type(
|
||||||
|
return_type: &mut ReturnType,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Rc<RefCell<TypeUseContainer>> {
|
||||||
|
na_p1_type_use(return_type.type_use_mut(), symbol_table, diagnostics)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_type_use(
|
||||||
|
type_use: &mut TypeUse,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> Rc<RefCell<TypeUseContainer>> {
|
||||||
|
match type_use {
|
||||||
|
TypeUse::PrimitiveType(primitive_type) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
TypeUse::InterfaceOrClassTypeUse(interface_or_class_type) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
TypeUse::TupleTypeUse(tuple_type) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
TypeUse::FunctionTypeUse(function_type) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_function_body(
|
||||||
|
function_body: &mut FunctionBody,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|||||||
@ -35,6 +35,7 @@ mod scope_table;
|
|||||||
mod second_pass;
|
mod second_pass;
|
||||||
pub mod symbol;
|
pub mod symbol;
|
||||||
pub mod symbol_table;
|
pub mod symbol_table;
|
||||||
|
pub mod type_use_container;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
||||||
|
|||||||
@ -96,7 +96,6 @@ fn handle_concrete_use_statement_identifier(
|
|||||||
&fqn_parts.join("::"),
|
&fqn_parts.join("::"),
|
||||||
use_statement_identifier.identifier().file_id(),
|
use_statement_identifier.identifier().file_id(),
|
||||||
use_statement_identifier.identifier().range(),
|
use_statement_identifier.identifier().range(),
|
||||||
"Usable Symbol",
|
|
||||||
diagnostics,
|
diagnostics,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,40 +1,40 @@
|
|||||||
|
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
||||||
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ClassSymbol {
|
pub struct ClassSymbol {
|
||||||
declared_name: Rc<String>,
|
fqn_parts: Vec<Rc<str>>,
|
||||||
fqn: Rc<String>,
|
members: HashMap<Rc<str>, Rc<RefCell<ClassMemberSymbol>>>,
|
||||||
members: HashMap<Rc<String>, Rc<RefCell<ClassMemberSymbol>>>,
|
functions: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
||||||
functions: HashMap<Rc<String>, Rc<RefCell<FunctionSymbol>>>
|
source_definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClassSymbol {
|
impl ClassSymbol {
|
||||||
pub fn new(declared_name: &str, fqn: &str) -> Self {
|
pub fn new(fqn_parts: &[Rc<str>], source_definition: Option<SourceDefinition>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
declared_name: Rc::new(declared_name.to_string()),
|
fqn_parts: fqn_parts.to_vec(),
|
||||||
fqn: Rc::new(fqn.to_string()),
|
|
||||||
members: HashMap::new(),
|
members: HashMap::new(),
|
||||||
functions: HashMap::new(),
|
functions: HashMap::new(),
|
||||||
|
source_definition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
self.fqn_parts.last().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name_owned(&self) -> Rc<String> {
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
self.declared_name.clone()
|
self.fqn_parts.last().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn fqn(&self) -> &str {
|
|
||||||
&self.fqn
|
impl Symbol for ClassSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn fqn_owned(&self) -> Rc<String> {
|
|
||||||
self.fqn.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,30 +1,30 @@
|
|||||||
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::type_symbol::ConcreteTypeSymbol;
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
use crate::name_analysis::type_use_container::TypeUseContainer;
|
||||||
|
use crate::name_analysis::util::join_fqn_parts;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct FunctionSymbol {
|
pub struct FunctionSymbol {
|
||||||
fqn: String,
|
fqn_parts: Vec<Rc<str>>,
|
||||||
declared_name: String,
|
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
is_platform: bool,
|
is_platform: bool,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
parameters: Vec<ParameterSymbol>,
|
parameters: Vec<Rc<RefCell<ParameterSymbol>>>,
|
||||||
return_type: Option<ConcreteTypeSymbol>, // todo: can we use TypeSymbol?
|
return_type: Option<Rc<RefCell<TypeUseContainer>>>, // todo: can we use TypeSymbol?
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionSymbol {
|
impl FunctionSymbol {
|
||||||
pub fn without_parameters_or_return_type(
|
pub fn new(
|
||||||
fqn: &str,
|
fqn_parts: &[Rc<str>],
|
||||||
declared_name: &str,
|
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
is_platform: bool,
|
is_platform: bool,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
) -> FunctionSymbol {
|
) -> FunctionSymbol {
|
||||||
FunctionSymbol {
|
FunctionSymbol {
|
||||||
fqn: fqn.to_string(),
|
fqn_parts: fqn_parts.to_vec(),
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
is_public,
|
is_public,
|
||||||
is_platform,
|
is_platform,
|
||||||
source_definition,
|
source_definition,
|
||||||
@ -33,36 +33,34 @@ impl FunctionSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_parameters(self, parameters: Vec<ParameterSymbol>) -> Self {
|
pub fn with_parameters_and_return_type(
|
||||||
|
fqn_parts: &[Rc<str>],
|
||||||
|
is_public: bool,
|
||||||
|
is_platform: bool,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
parameters: &[Rc<RefCell<ParameterSymbol>>],
|
||||||
|
return_type: Option<Rc<RefCell<TypeUseContainer>>>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fqn: self.fqn,
|
fqn_parts: fqn_parts.to_vec(),
|
||||||
declared_name: self.declared_name,
|
is_public,
|
||||||
is_public: self.is_public,
|
is_platform,
|
||||||
is_platform: self.is_platform,
|
source_definition,
|
||||||
source_definition: self.source_definition,
|
parameters: parameters.to_vec(),
|
||||||
parameters,
|
return_type,
|
||||||
return_type: self.return_type,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_return_type(self, return_type: ConcreteTypeSymbol) -> Self {
|
pub fn fqn_parts_owned(&self) -> Vec<Rc<str>> {
|
||||||
Self {
|
self.fqn_parts.to_vec()
|
||||||
fqn: self.fqn,
|
|
||||||
declared_name: self.declared_name,
|
|
||||||
is_public: self.is_public,
|
|
||||||
is_platform: self.is_platform,
|
|
||||||
source_definition: self.source_definition,
|
|
||||||
parameters: self.parameters,
|
|
||||||
return_type: Some(return_type),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fqn(&self) -> &str {
|
|
||||||
&self.fqn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
self.fqn_parts.last().unwrap().as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
|
self.fqn_parts.last().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_public(&self) -> bool {
|
pub fn is_public(&self) -> bool {
|
||||||
@ -73,24 +71,30 @@ impl FunctionSymbol {
|
|||||||
self.is_platform
|
self.is_platform
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
pub fn parameter_symbols(&self) -> &[Rc<RefCell<ParameterSymbol>>] {
|
||||||
self.source_definition.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parameters(&self) -> &[ParameterSymbol] {
|
|
||||||
&self.parameters
|
&self.parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn return_type(&self) -> Option<&ConcreteTypeSymbol> {
|
pub fn set_parameter_symbols(&mut self, parameter_symbols: Vec<Rc<RefCell<ParameterSymbol>>>) {
|
||||||
self.return_type.as_ref()
|
self.parameters = parameter_symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_return_type(&mut self, type_use_container: Rc<RefCell<TypeUseContainer>>) {
|
||||||
|
self.return_type = Some(type_use_container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Symbol for FunctionSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for FunctionSymbol {
|
impl Debug for FunctionSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("FunctionSymbol")
|
f.debug_struct("FunctionSymbol")
|
||||||
.field("fqn", &self.fqn)
|
.field("fqn", &join_fqn_parts(&self.fqn_parts))
|
||||||
.field("declared_name", &self.declared_name)
|
.field("declared_name", &self.declared_name())
|
||||||
.field("is_public", &self.is_public)
|
.field("is_public", &self.is_public)
|
||||||
.field("is_platform", &self.is_platform)
|
.field("is_platform", &self.is_platform)
|
||||||
.field("parameters", &self.parameters)
|
.field("parameters", &self.parameters)
|
||||||
|
|||||||
34
src/name_analysis/symbol/generic_type_symbol.rs
Normal file
34
src/name_analysis/symbol/generic_type_symbol.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct GenericTypeSymbol {
|
||||||
|
declared_name: String,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericTypeSymbol {
|
||||||
|
pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self {
|
||||||
|
GenericTypeSymbol {
|
||||||
|
declared_name: declared_name.to_string(),
|
||||||
|
source_definition,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name(&self) -> &str {
|
||||||
|
&self.declared_name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for GenericTypeSymbol {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("GenericTypeSymbol")
|
||||||
|
.field("declared_name", &self.declared_name)
|
||||||
|
.field("source_definition", &self.source_definition)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,36 +1,37 @@
|
|||||||
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InterfaceSymbol {
|
pub struct InterfaceSymbol {
|
||||||
declared_name: Rc<String>,
|
fqn_parts: Vec<Rc<str>>,
|
||||||
fqn: Rc<String>,
|
functions: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
||||||
functions: HashMap<String, FunctionSymbol>,
|
source_definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InterfaceSymbol {
|
impl InterfaceSymbol {
|
||||||
pub fn new(declared_name: &str, fqn: &str) -> Self {
|
pub fn new(fqn_parts: &[Rc<str>], source_definition: Option<SourceDefinition>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
declared_name: Rc::new(declared_name.to_string()),
|
fqn_parts: fqn_parts.to_vec(),
|
||||||
fqn: Rc::new(fqn.to_string()),
|
|
||||||
functions: HashMap::new(),
|
functions: HashMap::new(),
|
||||||
|
source_definition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
self.fqn_parts.last().unwrap().as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name_owned(&self) -> Rc<String> {
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
self.declared_name.clone()
|
self.fqn_parts.last().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn fqn(&self) -> &str {
|
|
||||||
&self.fqn
|
impl Symbol for InterfaceSymbol {
|
||||||
}
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
pub fn fqn_owned(&self) -> Rc<String> {
|
|
||||||
self.fqn.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,56 +1,21 @@
|
|||||||
pub mod class_member_symbol;
|
pub mod class_member_symbol;
|
||||||
pub mod class_symbol;
|
pub mod class_symbol;
|
||||||
pub mod function_symbol;
|
pub mod function_symbol;
|
||||||
|
pub mod generic_type_symbol;
|
||||||
pub mod interface_symbol;
|
pub mod interface_symbol;
|
||||||
|
pub mod module_level_symbol;
|
||||||
pub mod module_symbol;
|
pub mod module_symbol;
|
||||||
pub mod parameter_symbol;
|
pub mod parameter_symbol;
|
||||||
|
pub mod primitive_type_symbol;
|
||||||
pub mod source_definition;
|
pub mod source_definition;
|
||||||
pub mod type_symbol;
|
pub mod type_symbol;
|
||||||
pub mod usable_symbol;
|
pub mod usable_symbol;
|
||||||
pub mod use_symbol;
|
pub mod use_symbol;
|
||||||
pub mod variable_symbol;
|
pub mod variable_symbol;
|
||||||
|
|
||||||
use crate::name_analysis::symbol::type_symbol::ConcreteTypeSymbol;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::use_symbol::UseSymbol;
|
use std::fmt::Debug;
|
||||||
use class_member_symbol::ClassMemberSymbol;
|
|
||||||
use function_symbol::FunctionSymbol;
|
|
||||||
use module_symbol::ModuleSymbol;
|
|
||||||
use parameter_symbol::ParameterSymbol;
|
|
||||||
use source_definition::SourceDefinition;
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::fmt::{Debug, Display};
|
|
||||||
use std::ops::Deref;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use type_symbol::TypeSymbol;
|
|
||||||
use variable_symbol::VariableSymbol;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
pub trait Symbol: Debug {
|
||||||
pub enum Symbol {
|
fn source_definition(&self) -> Option<&SourceDefinition>;
|
||||||
Use(UseSymbol),
|
|
||||||
Module(ModuleSymbol),
|
|
||||||
Type(TypeSymbol),
|
|
||||||
ConcreteType(Rc<RefCell<ConcreteTypeSymbol>>),
|
|
||||||
Function(FunctionSymbol),
|
|
||||||
Parameter(ParameterSymbol),
|
|
||||||
Variable(VariableSymbol),
|
|
||||||
ClassMember(ClassMemberSymbol),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Symbol {
|
|
||||||
pub fn definition(&self) -> Option<SourceDefinition> {
|
|
||||||
match self {
|
|
||||||
Symbol::Use(use_symbol) => use_symbol.source_definition(),
|
|
||||||
Symbol::Module(module) => module.source_definition().cloned(),
|
|
||||||
Symbol::Type(type_symbol) => type_symbol.source_definition().cloned(),
|
|
||||||
Symbol::ConcreteType(concrete_type_symbol) => {
|
|
||||||
concrete_type_symbol.borrow().source_definition().cloned()
|
|
||||||
}
|
|
||||||
Symbol::Function(function_symbol) => function_symbol.source_definition().cloned(),
|
|
||||||
Symbol::Parameter(parameter_symbol) => parameter_symbol.source_definition().cloned(),
|
|
||||||
Symbol::Variable(variable_symbol) => variable_symbol.source_definition().cloned(),
|
|
||||||
Symbol::ClassMember(class_member_symbol) => {
|
|
||||||
class_member_symbol.source_definition().cloned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/name_analysis/symbol/module_level_symbol.rs
Normal file
30
src/name_analysis/symbol/module_level_symbol.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
||||||
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ModuleLevelSymbol {
|
||||||
|
Module(Rc<RefCell<ModuleSymbol>>),
|
||||||
|
Interface(Rc<RefCell<InterfaceSymbol>>),
|
||||||
|
Class(Rc<RefCell<ClassSymbol>>),
|
||||||
|
Function(Rc<RefCell<FunctionSymbol>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleLevelSymbol {
|
||||||
|
pub fn to_symbol(self) -> Rc<RefCell<dyn Symbol>> {
|
||||||
|
match self {
|
||||||
|
ModuleLevelSymbol::Module(module_symbol) => module_symbol as Rc<RefCell<dyn Symbol>>,
|
||||||
|
ModuleLevelSymbol::Interface(interface_symbol) => {
|
||||||
|
interface_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
ModuleLevelSymbol::Class(class_symbol) => class_symbol as Rc<RefCell<dyn Symbol>>,
|
||||||
|
ModuleLevelSymbol::Function(function_symbol) => {
|
||||||
|
function_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,42 +1,54 @@
|
|||||||
|
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
|
||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
use crate::name_analysis::util::join_fqn_parts;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ModuleSymbol {
|
pub struct ModuleSymbol {
|
||||||
fqn: String,
|
fqn_parts: Vec<Rc<str>>,
|
||||||
declared_name: String,
|
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
|
inner_symbols: Vec<ModuleLevelSymbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleSymbol {
|
impl ModuleSymbol {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
fqn: &str,
|
fqn_parts: Vec<Rc<str>>,
|
||||||
declared_name: &str,
|
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fqn: fqn.to_string(),
|
fqn_parts,
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
is_public,
|
is_public,
|
||||||
source_definition,
|
source_definition,
|
||||||
|
inner_symbols: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fqn(&self) -> &str {
|
pub fn fqn_parts(&self) -> &[Rc<str>] {
|
||||||
&self.fqn
|
&self.fqn_parts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
self.fqn_parts.last().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
|
self.fqn_parts.last().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_public(&self) -> bool {
|
pub fn is_public(&self) -> bool {
|
||||||
self.is_public
|
self.is_public
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
pub fn add_inner_symbol(&mut self, module_level_symbol: ModuleLevelSymbol) {
|
||||||
|
self.inner_symbols.push(module_level_symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Symbol for ModuleSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,10 +56,10 @@ impl ModuleSymbol {
|
|||||||
impl Debug for ModuleSymbol {
|
impl Debug for ModuleSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("ModuleSymbol")
|
f.debug_struct("ModuleSymbol")
|
||||||
.field("fqn", &self.fqn)
|
.field("fqn", &join_fqn_parts(&self.fqn_parts))
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.field("is_public", &self.is_public)
|
.field("is_public", &self.is_public)
|
||||||
.field("source_definition", &self.source_definition)
|
.field("source_definition", &self.source_definition)
|
||||||
|
.field("inner_symbols", &self.inner_symbols)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,30 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::type_use_container::TypeUseContainer;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ParameterSymbol {
|
pub struct ParameterSymbol {
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
|
type_use_symbol: Option<TypeUseContainer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParameterSymbol {
|
impl ParameterSymbol {
|
||||||
pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self {
|
pub fn new(
|
||||||
|
declared_name: &str,
|
||||||
|
source_definition: Option<SourceDefinition>,
|
||||||
|
type_use_symbol: Option<TypeUseContainer>,
|
||||||
|
) -> Self {
|
||||||
ParameterSymbol {
|
ParameterSymbol {
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
source_definition,
|
source_definition,
|
||||||
|
type_use_symbol,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/name_analysis/symbol/primitive_type_symbol.rs
Normal file
12
src/name_analysis/symbol/primitive_type_symbol.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub enum PrimitiveTypeSymbol {
|
||||||
|
Byte,
|
||||||
|
Char,
|
||||||
|
Short,
|
||||||
|
Int,
|
||||||
|
Long,
|
||||||
|
Float,
|
||||||
|
Double,
|
||||||
|
Boolean,
|
||||||
|
String,
|
||||||
|
}
|
||||||
@ -1,121 +1,15 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Formatter};
|
use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
||||||
|
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
||||||
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
|
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TypeSymbol {
|
pub enum TypeSymbol {
|
||||||
Concrete(ConcreteTypeSymbol),
|
Primitive(PrimitiveTypeSymbol),
|
||||||
Generic(GenericTypeSymbol),
|
Class(Rc<RefCell<ClassSymbol>>),
|
||||||
}
|
Interface(Rc<RefCell<InterfaceSymbol>>),
|
||||||
|
Generic(Rc<RefCell<GenericTypeSymbol>>),
|
||||||
impl TypeSymbol {
|
|
||||||
pub fn declared_name(&self) -> &str {
|
|
||||||
match self {
|
|
||||||
TypeSymbol::Concrete(t) => t.declared_name(),
|
|
||||||
TypeSymbol::Generic(t) => t.declared_name(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
|
||||||
match self {
|
|
||||||
TypeSymbol::Concrete(t) => t.source_definition(),
|
|
||||||
TypeSymbol::Generic(t) => t.source_definition(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ConcreteTypeSymbol {
|
|
||||||
fqn: String,
|
|
||||||
declared_name: String,
|
|
||||||
is_public: bool,
|
|
||||||
kind: ConcreteTypeSymbolKind,
|
|
||||||
source_definition: Option<SourceDefinition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConcreteTypeSymbol {
|
|
||||||
pub fn new(
|
|
||||||
fqn: &str,
|
|
||||||
declared_name: &str,
|
|
||||||
is_public: bool,
|
|
||||||
kind: ConcreteTypeSymbolKind,
|
|
||||||
source_definition: Option<SourceDefinition>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
fqn: fqn.to_string(),
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
is_public,
|
|
||||||
kind,
|
|
||||||
source_definition
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fqn(&self) -> &str {
|
|
||||||
&self.fqn
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_public(&self) -> bool {
|
|
||||||
self.is_public
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kind(&self) -> &ConcreteTypeSymbolKind {
|
|
||||||
&self.kind
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
|
||||||
&self.declared_name
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
|
||||||
self.source_definition.as_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
.field("kind", &self.kind)
|
|
||||||
.field("source_definition", &self.source_definition)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum ConcreteTypeSymbolKind {
|
|
||||||
Interface,
|
|
||||||
Class
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct GenericTypeSymbol {
|
|
||||||
declared_name: String,
|
|
||||||
source_definition: Option<SourceDefinition>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GenericTypeSymbol {
|
|
||||||
pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self {
|
|
||||||
GenericTypeSymbol {
|
|
||||||
declared_name: declared_name.to_string(),
|
|
||||||
source_definition,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
|
||||||
&self.declared_name
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
|
||||||
self.source_definition.as_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for GenericTypeSymbol {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("GenericTypeSymbol")
|
|
||||||
.field("declared_name", &self.declared_name)
|
|
||||||
.field("source_definition", &self.source_definition)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,25 @@
|
|||||||
use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub enum UsableSymbol {
|
pub enum UsableSymbol {
|
||||||
Interface(Rc<RefCell<InterfaceSymbol>>),
|
Interface(Rc<RefCell<InterfaceSymbol>>),
|
||||||
Class(Rc<RefCell<ClassSymbol>>),
|
Class(Rc<RefCell<ClassSymbol>>),
|
||||||
Function(Rc<RefCell<FunctionSymbol>>),
|
Function(Rc<RefCell<FunctionSymbol>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UsableSymbol {
|
||||||
|
pub fn to_symbol(self) -> Rc<RefCell<dyn Symbol>> {
|
||||||
|
match self {
|
||||||
|
UsableSymbol::Interface(interface_symbol) => {
|
||||||
|
interface_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
UsableSymbol::Class(class_symbol) => class_symbol as Rc<RefCell<dyn Symbol>>,
|
||||||
|
UsableSymbol::Function(function_symbol) => function_symbol as Rc<RefCell<dyn Symbol>>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
use crate::name_analysis::util::join_fqn_parts;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub enum UseSymbol {
|
pub enum UseSymbol {
|
||||||
Concrete(Rc<RefCell<ConcreteUseSymbol>>),
|
Concrete(Rc<RefCell<ConcreteUseSymbol>>),
|
||||||
Star(StarUseSymbol),
|
Star(StarUseSymbol),
|
||||||
@ -19,35 +21,31 @@ impl UseSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ConcreteUseSymbol {
|
pub struct ConcreteUseSymbol {
|
||||||
fqn_parts: Vec<String>,
|
fqn_parts: Vec<Rc<str>>,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
resolved_symbol: Option<UsableSymbol>,
|
resolved_symbol: Option<UsableSymbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConcreteUseSymbol {
|
impl ConcreteUseSymbol {
|
||||||
pub fn new(
|
pub fn new(fqn_parts: &[Rc<str>], source_definition: Option<SourceDefinition>) -> Self {
|
||||||
fqn_parts: &[&str],
|
|
||||||
source_definition: Option<SourceDefinition>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
fqn_parts: fqn_parts.iter().map(ToString::to_string).collect(),
|
fqn_parts: fqn_parts.to_vec(),
|
||||||
source_definition,
|
source_definition,
|
||||||
resolved_symbol: None,
|
resolved_symbol: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fqn_parts(&self) -> &[String] {
|
pub fn fqn_parts(&self) -> &[Rc<str>] {
|
||||||
self.fqn_parts.as_slice()
|
&self.fqn_parts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
self.fqn_parts.last().unwrap()
|
self.fqn_parts.last().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
self.source_definition.as_ref()
|
self.fqn_parts.last().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolved_symbol(&self) -> Option<&UsableSymbol> {
|
pub fn resolved_symbol(&self) -> Option<&UsableSymbol> {
|
||||||
@ -59,6 +57,12 @@ impl ConcreteUseSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Symbol for ConcreteUseSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Debug for ConcreteUseSymbol {
|
impl Debug for ConcreteUseSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("ConcreteUseStatementSymbol")
|
f.debug_struct("ConcreteUseStatementSymbol")
|
||||||
@ -70,23 +74,25 @@ impl Debug for ConcreteUseSymbol {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct StarUseSymbol {
|
pub struct StarUseSymbol {
|
||||||
base_fqn: String,
|
fqn_parts: Vec<Rc<str>>,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StarUseSymbol {
|
impl StarUseSymbol {
|
||||||
pub fn new(base_fqn: &str, source_definition: Option<SourceDefinition>) -> Self {
|
pub fn new(fqn_parts: &[Rc<str>], source_definition: Option<SourceDefinition>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
base_fqn: base_fqn.to_string(),
|
fqn_parts: fqn_parts.to_vec(),
|
||||||
source_definition,
|
source_definition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn base_fqn(&self) -> &str {
|
pub fn fqn_parts(&self) -> &[Rc<str>] {
|
||||||
&self.base_fqn
|
&self.fqn_parts
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
impl Symbol for StarUseSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +100,7 @@ impl StarUseSymbol {
|
|||||||
impl Debug for StarUseSymbol {
|
impl Debug for StarUseSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("StarUseStatementSymbol")
|
f.debug_struct("StarUseStatementSymbol")
|
||||||
.field("base_fqn", &self.base_fqn)
|
.field("fqn", &join_fqn_parts(&self.fqn_parts))
|
||||||
.field("source_definition", &self.source_definition)
|
.field("source_definition", &self.source_definition)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FqnContext {
|
pub struct FqnContext {
|
||||||
stack: Vec<String>,
|
stack: Vec<Rc<str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FqnContext {
|
impl FqnContext {
|
||||||
@ -9,31 +11,18 @@ impl FqnContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, name: &str) {
|
pub fn push(&mut self, name: &str) {
|
||||||
self.stack.push(name.to_string());
|
self.stack.push(Rc::from(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self) {
|
pub fn pop(&mut self) {
|
||||||
self.stack.pop();
|
self.stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current(&self) -> String {
|
pub fn current_fqn(&self) -> Vec<&str> {
|
||||||
let mut acc = String::new();
|
self.stack.iter().map(|part| part.as_ref()).collect()
|
||||||
for (i, name) in self.stack.iter().enumerate() {
|
|
||||||
acc.push_str(name);
|
|
||||||
if i != self.stack.len() - 1 {
|
|
||||||
acc.push_str("::")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
acc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve(&self, name: &str) -> String {
|
pub fn current_fqn_owned(&self) -> Vec<Rc<str>> {
|
||||||
let mut acc = String::new();
|
self.stack.clone()
|
||||||
if !self.stack.is_empty() {
|
|
||||||
acc.push_str(&self.current());
|
|
||||||
acc.push_str("::");
|
|
||||||
}
|
|
||||||
acc.push_str(name);
|
|
||||||
acc
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,16 @@
|
|||||||
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol, UseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use crate::name_analysis::symbol::*;
|
|
||||||
use crate::name_analysis::symbol_table::fqn_context::FqnContext;
|
use crate::name_analysis::symbol_table::fqn_context::FqnContext;
|
||||||
use crate::name_analysis::symbol_table::symbol_tree::SymbolTree;
|
use crate::name_analysis::symbol_table::symbol_tree::SymbolTree;
|
||||||
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
use crate::name_analysis::symbol_table::SymbolInsertError::SymbolAlreadyDefined;
|
||||||
use crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
|
||||||
use scope::Scope;
|
use scope::Scope;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
|
||||||
|
|
||||||
pub(self) mod fqn_context;
|
pub(self) mod fqn_context;
|
||||||
mod scope;
|
mod scope;
|
||||||
@ -22,10 +18,9 @@ pub mod symbol_tree;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SymbolInsertError {
|
pub enum SymbolInsertError {
|
||||||
SymbolAlreadyDefined(Symbol),
|
SymbolAlreadyDefined(Rc<RefCell<dyn Symbol>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum SymbolLookupError {
|
pub enum SymbolLookupError {
|
||||||
NoDefinition,
|
NoDefinition,
|
||||||
}
|
}
|
||||||
@ -69,26 +64,36 @@ impl SymbolTable {
|
|||||||
self.current_scope_id = parent_id;
|
self.current_scope_id = parent_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_current_fqn(&mut self, names: &[&str]) {
|
pub fn set_current_fqn(&mut self, names: &[&str]) {
|
||||||
self.fqn_context = Box::new(FqnContext::new());
|
self.fqn_context = Box::new(FqnContext::new());
|
||||||
for name in names {
|
for name in names {
|
||||||
self.fqn_context.push(*name);
|
self.fqn_context.push(*name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_fqn_part(&mut self, part: &str) {
|
pub fn push_fqn_part(&mut self, part: &str) {
|
||||||
self.fqn_context.push(part);
|
self.fqn_context.push(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_fqn_part(&mut self) {
|
pub fn pop_fqn_part(&mut self) {
|
||||||
self.fqn_context.pop();
|
self.fqn_context.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn symbol_tree(&self) -> &SymbolTree {
|
pub fn current_fqn(&self) -> Vec<&str> {
|
||||||
&self.symbol_tree
|
self.fqn_context.current_fqn()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn current_fqn_owned(&self) -> Vec<Rc<str>> {
|
||||||
|
self.fqn_context.current_fqn_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_fqn(&self, part: Rc<str>) -> Vec<Rc<str>> {
|
||||||
|
let mut parts = self.current_fqn_owned();
|
||||||
|
parts.push(part);
|
||||||
|
parts
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_usable_symbol(&self, fqn_parts: &[&str]) -> Option<UsableSymbol> {
|
pub fn find_usable_symbol(&self, fqn_parts: &[&str]) -> Option<UsableSymbol> {
|
||||||
self.symbol_tree
|
self.symbol_tree
|
||||||
.find_interface(fqn_parts)
|
.find_interface(fqn_parts)
|
||||||
@ -113,83 +118,20 @@ impl SymbolTable {
|
|||||||
&mut self.scopes[self.current_scope_id]
|
&mut self.scopes[self.current_scope_id]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_current_scope_concrete_use_symbol(
|
|
||||||
&self,
|
|
||||||
declared_name: &str,
|
|
||||||
) -> Option<Rc<RefCell<ConcreteUseSymbol>>> {
|
|
||||||
self.current_scope()
|
|
||||||
.concrete_use_symbols()
|
|
||||||
.get(declared_name)
|
|
||||||
.cloned()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_current_scope_module_symbol(&self, declared_name: &str) -> Option<&ModuleSymbol> {
|
|
||||||
self.current_scope().module_symbols().get(declared_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_current_scope_parameter_symbol(&self, declared_name: &str) -> Option<&ParameterSymbol> {
|
|
||||||
self.current_scope().parameter_symbols().get(declared_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_current_scope_variable_symbol(&self, declared_name: &str) -> Option<&VariableSymbol> {
|
|
||||||
self.current_scope().variable_symbols().get(declared_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_current_scope_class_member_symbol(
|
|
||||||
&self,
|
|
||||||
declared_name: &str,
|
|
||||||
) -> Option<&ClassMemberSymbol> {
|
|
||||||
self.current_scope()
|
|
||||||
.class_member_symbols()
|
|
||||||
.get(declared_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_current_scope_variable_or_parameter_symbol(
|
|
||||||
&self,
|
|
||||||
declared_name: &str,
|
|
||||||
) -> Option<Symbol> {
|
|
||||||
self.find_current_scope_variable_symbol(declared_name)
|
|
||||||
.map(|variable_symbol| Symbol::Variable(variable_symbol.clone()))
|
|
||||||
.or_else(|| {
|
|
||||||
self.find_current_scope_parameter_symbol(declared_name)
|
|
||||||
.map(|parameter_symbol| Symbol::Parameter(parameter_symbol.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_current_scope_usable_symbol(&self, declared_name: &str) -> Option<Symbol> {
|
|
||||||
self.find_current_scope_concrete_use_symbol(declared_name)
|
|
||||||
.map(|concrete_use_symbol| {
|
|
||||||
Symbol::Use(UseSymbol::Concrete(concrete_use_symbol.clone()))
|
|
||||||
})
|
|
||||||
// .or_else(|| {
|
|
||||||
// self.find_current_scope_type_symbol(declared_name)
|
|
||||||
// .map(|type_symbol| Symbol::Type(type_symbol.clone()))
|
|
||||||
// })
|
|
||||||
.or_else(|| {
|
|
||||||
self.find_current_scope_module_symbol(declared_name)
|
|
||||||
.map(|module_symbol| Symbol::Module(module_symbol.clone()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_concrete_use_symbol(
|
pub fn insert_concrete_use_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
concrete_use_symbol: ConcreteUseSymbol,
|
concrete_use_symbol: ConcreteUseSymbol,
|
||||||
) -> Result<Rc<RefCell<ConcreteUseSymbol>>, SymbolInsertError> {
|
) -> Result<Rc<RefCell<ConcreteUseSymbol>>, SymbolInsertError> {
|
||||||
if let Some(defined_symbol) =
|
if let Some(defined_symbol) = self
|
||||||
self.find_current_scope_usable_symbol(concrete_use_symbol.declared_name())
|
.current_scope()
|
||||||
|
.find_module_level_symbol(concrete_use_symbol.declared_name())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
||||||
} else {
|
} else {
|
||||||
let name = concrete_use_symbol.declared_name().to_string();
|
let inserted = self
|
||||||
self.current_scope_mut()
|
.current_scope_mut()
|
||||||
.concrete_use_symbols_mut()
|
.insert_concrete_use_symbol(concrete_use_symbol);
|
||||||
.insert(name.clone(), Rc::new(RefCell::new(concrete_use_symbol)));
|
Ok(inserted)
|
||||||
Ok(self
|
|
||||||
.current_scope()
|
|
||||||
.concrete_use_symbols()
|
|
||||||
.get(&name)
|
|
||||||
.cloned()
|
|
||||||
.unwrap())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,142 +148,36 @@ impl SymbolTable {
|
|||||||
pub fn insert_module_symbol(
|
pub fn insert_module_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
module_symbol: ModuleSymbol,
|
module_symbol: ModuleSymbol,
|
||||||
) -> Result<(), SymbolInsertError> {
|
) -> Result<Rc<RefCell<ModuleSymbol>>, SymbolInsertError> {
|
||||||
if let Some(defined_symbol) =
|
if let Some(defined_symbol) = self
|
||||||
self.find_current_scope_usable_symbol(module_symbol.declared_name())
|
.current_scope()
|
||||||
|
.find_module_level_symbol(module_symbol.declared_name())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
||||||
} else {
|
} else {
|
||||||
self.current_scope_mut()
|
let inserted = self.current_scope_mut().insert_module_symbol(module_symbol);
|
||||||
.module_symbols_mut()
|
self.symbol_tree.register_module(inserted.clone());
|
||||||
.insert(module_symbol.declared_name().to_string(), module_symbol);
|
Ok(inserted)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_function_symbol(
|
pub fn insert_function_symbol(
|
||||||
&mut self,
|
&mut self,
|
||||||
function_symbol: FunctionSymbol,
|
function_symbol: FunctionSymbol,
|
||||||
) -> Result<(), SymbolInsertError> {
|
) -> Result<Rc<RefCell<FunctionSymbol>>, SymbolInsertError> {
|
||||||
if let Some(defined_symbol) =
|
if let Some(defined_symbol) = self
|
||||||
self.find_current_scope_usable_symbol(function_symbol.declared_name())
|
.current_scope()
|
||||||
|
.find_module_level_symbol(function_symbol.declared_name())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
||||||
} else {
|
} else {
|
||||||
self.current_scope_mut()
|
let inserted = self
|
||||||
.function_symbols_mut()
|
.current_scope_mut()
|
||||||
.insert(function_symbol.declared_name().to_string(), function_symbol);
|
.insert_function_symbol(function_symbol);
|
||||||
Ok(())
|
self.symbol_tree.register_function(inserted.clone());
|
||||||
|
Ok(inserted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_parameter_symbol(
|
|
||||||
&mut self,
|
|
||||||
parameter_symbol: ParameterSymbol,
|
|
||||||
) -> Result<(), SymbolInsertError> {
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
self.find_current_scope_parameter_symbol(parameter_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(Symbol::Parameter(
|
|
||||||
defined_symbol.clone(),
|
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
self.current_scope_mut().parameter_symbols_mut().insert(
|
|
||||||
parameter_symbol.declared_name().to_string(),
|
|
||||||
parameter_symbol,
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_variable_symbol(
|
|
||||||
&mut self,
|
|
||||||
variable_symbol: VariableSymbol,
|
|
||||||
) -> Result<(), SymbolInsertError> {
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
self.find_current_scope_variable_or_parameter_symbol(variable_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
|
||||||
} else {
|
|
||||||
self.current_scope_mut()
|
|
||||||
.variable_symbols_mut()
|
|
||||||
.insert(variable_symbol.declared_name().to_string(), variable_symbol);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_class_member_symbol(
|
|
||||||
&mut self,
|
|
||||||
class_member_symbol: ClassMemberSymbol,
|
|
||||||
) -> Result<(), SymbolInsertError> {
|
|
||||||
if let Some(defined_symbol) =
|
|
||||||
self.find_current_scope_class_member_symbol(class_member_symbol.declared_name())
|
|
||||||
{
|
|
||||||
Err(SymbolAlreadyDefined(Symbol::ClassMember(
|
|
||||||
defined_symbol.clone(),
|
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
self.current_scope_mut().class_member_symbols_mut().insert(
|
|
||||||
class_member_symbol.declared_name().to_string(),
|
|
||||||
class_member_symbol,
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lookup_addressable_in_scope_by_identifier(
|
|
||||||
scope: &Scope,
|
|
||||||
identifier: &str,
|
|
||||||
) -> Option<Symbol> {
|
|
||||||
scope
|
|
||||||
.variable_symbols()
|
|
||||||
.get(identifier)
|
|
||||||
.map(|variable_symbol| Symbol::Variable(variable_symbol.clone()))
|
|
||||||
.or_else(|| {
|
|
||||||
scope
|
|
||||||
.parameter_symbols()
|
|
||||||
.get(identifier)
|
|
||||||
.map(|parameter_symbol| Symbol::Parameter(parameter_symbol.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
scope
|
|
||||||
.class_member_symbols()
|
|
||||||
.get(identifier)
|
|
||||||
.map(|class_member_symbol| Symbol::ClassMember(class_member_symbol.clone()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
scope
|
|
||||||
.function_symbols()
|
|
||||||
.get(identifier)
|
|
||||||
.map(|function_symbol| Symbol::Function(function_symbol.clone()))
|
|
||||||
})
|
|
||||||
// .or_else(|| {
|
|
||||||
// scope
|
|
||||||
// .type_symbols()
|
|
||||||
// .get(identifier)
|
|
||||||
// .map(|type_symbol| Symbol::Type(type_symbol.clone()))
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_addressable_by_identifier(
|
|
||||||
&self,
|
|
||||||
identifier: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<Symbol, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = Self::lookup_addressable_in_scope_by_identifier(scope, identifier)
|
|
||||||
{
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent() {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SymbolTable {
|
impl Display for SymbolTable {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
|||||||
use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
|
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
|
||||||
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
@ -16,18 +17,26 @@ pub struct Scope {
|
|||||||
parent: Option<usize>,
|
parent: Option<usize>,
|
||||||
id: usize,
|
id: usize,
|
||||||
children: Vec<usize>,
|
children: Vec<usize>,
|
||||||
concrete_use_symbols: HashMap<String, Rc<RefCell<ConcreteUseSymbol>>>,
|
concrete_use_symbols: HashMap<Rc<str>, Rc<RefCell<ConcreteUseSymbol>>>,
|
||||||
star_use_symbols: HashMap<String, Rc<RefCell<StarUseSymbol>>>,
|
star_use_symbols: HashMap<Vec<Rc<str>>, Rc<RefCell<StarUseSymbol>>>,
|
||||||
module_symbols: HashMap<String, ModuleSymbol>,
|
module_symbols: HashMap<Rc<str>, Rc<RefCell<ModuleSymbol>>>,
|
||||||
interface_symbols: HashMap<Rc<String>, Rc<RefCell<InterfaceSymbol>>>,
|
interface_symbols: HashMap<Rc<str>, Rc<RefCell<InterfaceSymbol>>>,
|
||||||
class_symbols: HashMap<Rc<String>, Rc<RefCell<ClassSymbol>>>,
|
class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>,
|
||||||
function_symbols: HashMap<String, FunctionSymbol>,
|
function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
||||||
parameter_symbols: HashMap<String, ParameterSymbol>,
|
parameter_symbols: HashMap<Rc<str>, ParameterSymbol>,
|
||||||
variable_symbols: HashMap<String, VariableSymbol>,
|
variable_symbols: HashMap<Rc<str>, VariableSymbol>,
|
||||||
class_member_symbols: HashMap<String, ClassMemberSymbol>,
|
class_member_symbols: HashMap<Rc<str>, ClassMemberSymbol>,
|
||||||
debug_name: String,
|
debug_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! insert_symbol {
|
||||||
|
($table:expr, $symbol:expr, $key:expr) => {{
|
||||||
|
let as_rc = Rc::new(RefCell::new($symbol));
|
||||||
|
$table.insert($key, as_rc.clone());
|
||||||
|
as_rc
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
impl Scope {
|
impl Scope {
|
||||||
pub fn new(parent: Option<usize>, id: usize, debug_name: String) -> Self {
|
pub fn new(parent: Option<usize>, id: usize, debug_name: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -62,82 +71,81 @@ impl Scope {
|
|||||||
pub fn children(&self) -> Vec<usize> {
|
pub fn children(&self) -> Vec<usize> {
|
||||||
self.children.clone()
|
self.children.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn concrete_use_symbols(&self) -> &HashMap<String, Rc<RefCell<ConcreteUseSymbol>>> {
|
|
||||||
&self.concrete_use_symbols
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn concrete_use_symbols_mut(
|
|
||||||
&mut self,
|
|
||||||
) -> &mut HashMap<String, Rc<RefCell<ConcreteUseSymbol>>> {
|
|
||||||
&mut self.concrete_use_symbols
|
|
||||||
}
|
|
||||||
|
|
||||||
|
pub fn insert_concrete_use_symbol(&mut self, symbol: ConcreteUseSymbol) -> Rc<RefCell<ConcreteUseSymbol>> {
|
||||||
|
let key = symbol.declared_name_owned();
|
||||||
|
insert_symbol!(self.concrete_use_symbols, symbol, key)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert_star_use_symbol(&mut self, symbol: StarUseSymbol) -> Rc<RefCell<StarUseSymbol>> {
|
pub fn insert_star_use_symbol(&mut self, symbol: StarUseSymbol) -> Rc<RefCell<StarUseSymbol>> {
|
||||||
let as_rc = Rc::new(RefCell::new(symbol));
|
let key = symbol.fqn_parts().to_vec();
|
||||||
self.star_use_symbols.insert(as_rc.borrow().base_fqn().to_string(), as_rc.clone());
|
insert_symbol!(self.star_use_symbols, symbol, key)
|
||||||
as_rc.clone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module_symbols(&self) -> &HashMap<String, ModuleSymbol> {
|
pub fn insert_module_symbol(&mut self, symbol: ModuleSymbol) -> Rc<RefCell<ModuleSymbol>> {
|
||||||
&self.module_symbols
|
let key = symbol.declared_name_owned();
|
||||||
|
insert_symbol!(self.module_symbols, symbol, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module_symbols_mut(&mut self) -> &mut HashMap<String, ModuleSymbol> {
|
pub fn get_module_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<ModuleSymbol>>> {
|
||||||
&mut self.module_symbols
|
self.module_symbols.get(declared_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_interface_symbol(&mut self, symbol: InterfaceSymbol) {
|
pub fn insert_function_symbol(
|
||||||
self.interface_symbols
|
&mut self,
|
||||||
.insert(symbol.declared_name_owned(), Rc::new(RefCell::new(symbol)));
|
symbol: FunctionSymbol,
|
||||||
|
) -> Rc<RefCell<FunctionSymbol>> {
|
||||||
|
let key = symbol.declared_name_owned();
|
||||||
|
insert_symbol!(self.function_symbols, symbol, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_function_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<FunctionSymbol>>> {
|
||||||
|
self.function_symbols.get(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_interface_symbol(
|
||||||
|
&mut self,
|
||||||
|
symbol: InterfaceSymbol,
|
||||||
|
) -> Rc<RefCell<InterfaceSymbol>> {
|
||||||
|
let key = symbol.declared_name_owned();
|
||||||
|
insert_symbol!(self.interface_symbols, symbol, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_interface_symbol(
|
pub fn get_interface_symbol(
|
||||||
&self,
|
&self,
|
||||||
declared_name: Rc<String>,
|
declared_name: &str,
|
||||||
) -> Option<Rc<RefCell<InterfaceSymbol>>> {
|
) -> Option<&Rc<RefCell<InterfaceSymbol>>> {
|
||||||
self.interface_symbols.get(&declared_name).cloned()
|
self.interface_symbols.get(declared_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_class_symbol(&mut self, symbol: ClassSymbol) {
|
pub fn insert_class_symbol(&mut self, symbol: ClassSymbol) -> Rc<RefCell<ClassSymbol>> {
|
||||||
self.class_symbols
|
let key = symbol.declared_name_owned();
|
||||||
.insert(symbol.declared_name_owned(), Rc::new(RefCell::new(symbol)));
|
insert_symbol!(self.class_symbols, symbol, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_class_symbol(&self, declared_name: Rc<String>) -> Option<Rc<RefCell<ClassSymbol>>> {
|
pub fn get_class_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<ClassSymbol>>> {
|
||||||
self.class_symbols.get(&declared_name).cloned()
|
self.class_symbols.get(declared_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn function_symbols(&self) -> &HashMap<String, FunctionSymbol> {
|
pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> {
|
||||||
&self.function_symbols
|
self.module_symbols
|
||||||
}
|
.get(declared_name)
|
||||||
|
.map(|module_symbol| ModuleLevelSymbol::Module(module_symbol.clone()))
|
||||||
pub fn function_symbols_mut(&mut self) -> &mut HashMap<String, FunctionSymbol> {
|
.or_else(|| {
|
||||||
&mut self.function_symbols
|
self.interface_symbols
|
||||||
}
|
.get(declared_name)
|
||||||
|
.map(|interface_symbol| ModuleLevelSymbol::Interface(interface_symbol.clone()))
|
||||||
pub fn parameter_symbols(&self) -> &HashMap<String, ParameterSymbol> {
|
})
|
||||||
&self.parameter_symbols
|
.or_else(|| {
|
||||||
}
|
self.class_symbols
|
||||||
|
.get(declared_name)
|
||||||
pub fn parameter_symbols_mut(&mut self) -> &mut HashMap<String, ParameterSymbol> {
|
.map(|class_symbol| ModuleLevelSymbol::Class(class_symbol.clone()))
|
||||||
&mut self.parameter_symbols
|
})
|
||||||
}
|
.or_else(|| {
|
||||||
|
self.function_symbols
|
||||||
pub fn variable_symbols(&self) -> &HashMap<String, VariableSymbol> {
|
.get(declared_name)
|
||||||
&self.variable_symbols
|
.map(|function_symbol| ModuleLevelSymbol::Function(function_symbol.clone()))
|
||||||
}
|
})
|
||||||
|
|
||||||
pub fn variable_symbols_mut(&mut self) -> &mut HashMap<String, VariableSymbol> {
|
|
||||||
&mut self.variable_symbols
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn class_member_symbols(&self) -> &HashMap<String, ClassMemberSymbol> {
|
|
||||||
&self.class_member_symbols
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn class_member_symbols_mut(&mut self) -> &mut HashMap<String, ClassMemberSymbol> {
|
|
||||||
&mut self.class_member_symbols
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_name(&self) -> &str {
|
pub fn debug_name(&self) -> &str {
|
||||||
@ -164,14 +172,14 @@ impl Display for Scope {
|
|||||||
.unwrap_or_else(|| "None".to_string()),
|
.unwrap_or_else(|| "None".to_string()),
|
||||||
self.debug_name()
|
self.debug_name()
|
||||||
)?;
|
)?;
|
||||||
write_symbols!(f, self.concrete_use_symbols());
|
write_symbols!(f, self.concrete_use_symbols);
|
||||||
todo!("self.star_use_symbols");
|
write_symbols!(f, self.star_use_symbols);
|
||||||
write_symbols!(f, self.module_symbols());
|
write_symbols!(f, self.module_symbols);
|
||||||
todo!("self.concrete_type_symbols");
|
write_symbols!(f, self.interface_symbols);
|
||||||
write_symbols!(f, self.function_symbols());
|
write_symbols!(f, self.function_symbols);
|
||||||
write_symbols!(f, self.parameter_symbols());
|
write_symbols!(f, self.parameter_symbols);
|
||||||
write_symbols!(f, self.variable_symbols());
|
write_symbols!(f, self.variable_symbols);
|
||||||
write_symbols!(f, self.class_member_symbols());
|
write_symbols!(f, self.class_member_symbols);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
use crate::name_analysis::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
|
use crate::name_analysis::symbol::module_symbol::ModuleSymbol;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SymbolTree {
|
pub struct SymbolTree {
|
||||||
children: Box<HashMap<String, SymbolTree>>,
|
children: Box<HashMap<Rc<str>, SymbolTree>>,
|
||||||
classes: Box<HashMap<String, Rc<RefCell<ClassSymbol>>>>,
|
classes: Box<HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>>,
|
||||||
interfaces: Box<HashMap<String, Rc<RefCell<InterfaceSymbol>>>>,
|
interfaces: Box<HashMap<Rc<str>, Rc<RefCell<InterfaceSymbol>>>>,
|
||||||
functions: Box<HashMap<String, Rc<RefCell<FunctionSymbol>>>>,
|
functions: Box<HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SymbolTree {
|
impl SymbolTree {
|
||||||
@ -33,7 +34,7 @@ impl SymbolTree {
|
|||||||
.and_then(|child_tree| child_tree.find_class(&fqn_parts[1..])),
|
.and_then(|child_tree| child_tree.find_class(&fqn_parts[1..])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_interface(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<InterfaceSymbol>>> {
|
pub fn find_interface(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<InterfaceSymbol>>> {
|
||||||
match fqn_parts.len() {
|
match fqn_parts.len() {
|
||||||
0 => None,
|
0 => None,
|
||||||
@ -44,7 +45,7 @@ impl SymbolTree {
|
|||||||
.and_then(|child_tree| child_tree.find_interface(&fqn_parts[1..])),
|
.and_then(|child_tree| child_tree.find_interface(&fqn_parts[1..])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_function(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
pub fn find_function(&self, fqn_parts: &[&str]) -> Option<Rc<RefCell<FunctionSymbol>>> {
|
||||||
match fqn_parts.len() {
|
match fqn_parts.len() {
|
||||||
0 => None,
|
0 => None,
|
||||||
@ -55,4 +56,49 @@ impl SymbolTree {
|
|||||||
.and_then(|child_tree| child_tree.find_function(&fqn_parts[1..])),
|
.and_then(|child_tree| child_tree.find_function(&fqn_parts[1..])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_module(&mut self, module_symbol: Rc<RefCell<ModuleSymbol>>) {
|
||||||
|
self.recurse_register_module(&module_symbol.borrow().fqn_parts());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recurse_register_module(&mut self, fqn_parts: &[Rc<str>]) {
|
||||||
|
if fqn_parts.len() == 0 {
|
||||||
|
panic!("Unable to register module fqn with no parts.")
|
||||||
|
}
|
||||||
|
if fqn_parts.len() == 1 {
|
||||||
|
self.children
|
||||||
|
.insert(fqn_parts[0].clone(), SymbolTree::new());
|
||||||
|
} else {
|
||||||
|
if self.children.contains_key(fqn_parts[0].as_ref()) {
|
||||||
|
let child = self.children.get_mut(fqn_parts[0].as_ref()).unwrap();
|
||||||
|
child.recurse_register_module(&fqn_parts[1..]);
|
||||||
|
} else {
|
||||||
|
let mut child = SymbolTree::new();
|
||||||
|
child.recurse_register_module(&fqn_parts[1..]);
|
||||||
|
self.children.insert(fqn_parts[0].clone(), child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register_function(&mut self, function_symbol: Rc<RefCell<FunctionSymbol>>) {
|
||||||
|
let fqn_parts = function_symbol.borrow().fqn_parts_owned();
|
||||||
|
self.recurse_register_function(function_symbol, &fqn_parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recurse_register_function(&mut self, function_symbol: Rc<RefCell<FunctionSymbol>>, fqn_parts: &[Rc<str>]) {
|
||||||
|
if fqn_parts.len() == 0 {
|
||||||
|
panic!("Unable to register function fqn with no parts.")
|
||||||
|
}
|
||||||
|
if fqn_parts.len() == 1 {
|
||||||
|
self.functions.insert(fqn_parts[0].clone(), function_symbol);
|
||||||
|
} else {
|
||||||
|
if self.children.contains_key(fqn_parts[0].as_ref()) {
|
||||||
|
let child = self.children.get_mut(fqn_parts[0].as_ref()).unwrap();
|
||||||
|
child.recurse_register_function(function_symbol, &fqn_parts[1..]);
|
||||||
|
} else {
|
||||||
|
panic!("No such inner module registered: {}", fqn_parts[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/name_analysis/type_use_container.rs
Normal file
20
src/name_analysis/type_use_container.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TypeUseContainer {
|
||||||
|
resolved_type: Option<Rc<RefCell<TypeSymbol>>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeUseContainer {
|
||||||
|
pub fn new() -> TypeUseContainer {
|
||||||
|
Self {
|
||||||
|
resolved_type: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_resolved_type(&mut self, type_symbol: Rc<RefCell<TypeSymbol>>) {
|
||||||
|
self.resolved_type = Some(type_symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,28 +2,28 @@ use crate::diagnostic::DmDiagnostic;
|
|||||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolLookupError};
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolLookupError};
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn handle_insert_error(
|
pub fn handle_insert_error(
|
||||||
err: SymbolInsertError,
|
err: SymbolInsertError,
|
||||||
error_symbol_name: &str,
|
error_symbol_name: &str,
|
||||||
error_file_id: usize,
|
error_file_id: usize,
|
||||||
error_range: Range<usize>,
|
error_range: Range<usize>,
|
||||||
symbol_types: &str,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
match err {
|
match err {
|
||||||
SymbolInsertError::SymbolAlreadyDefined(s) => {
|
SymbolInsertError::SymbolAlreadyDefined(s) => {
|
||||||
let mut diagnostic = Diagnostic::error()
|
let mut diagnostic = Diagnostic::error()
|
||||||
.with_message(format!(
|
.with_message(format!(
|
||||||
"{} symbol '{}' already defined in the current scope.",
|
"Symbol '{}' already defined in the current scope.",
|
||||||
symbol_types, error_symbol_name,
|
error_symbol_name,
|
||||||
))
|
))
|
||||||
.with_label(
|
.with_label(
|
||||||
Label::primary(error_file_id, error_range)
|
Label::primary(error_file_id, error_range)
|
||||||
.with_message("Symbol duplicated here."),
|
.with_message("Symbol duplicated here."),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(source_definition) = s.definition() {
|
if let Some(source_definition) = s.borrow().source_definition() {
|
||||||
diagnostic = diagnostic.with_label(
|
diagnostic = diagnostic.with_label(
|
||||||
Label::secondary(source_definition.file_id(), source_definition.range())
|
Label::secondary(source_definition.file_id(), source_definition.range())
|
||||||
.with_message("Symbol defined here."),
|
.with_message("Symbol defined here."),
|
||||||
@ -40,16 +40,12 @@ pub fn handle_lookup_error(
|
|||||||
error_symbol_name: &str,
|
error_symbol_name: &str,
|
||||||
error_file_id: usize,
|
error_file_id: usize,
|
||||||
error_range: Range<usize>,
|
error_range: Range<usize>,
|
||||||
symbol_types: &str,
|
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
match err {
|
match err {
|
||||||
SymbolLookupError::NoDefinition => {
|
SymbolLookupError::NoDefinition => {
|
||||||
let diagnostic = Diagnostic::error()
|
let diagnostic = Diagnostic::error()
|
||||||
.with_message(format!(
|
.with_message(format!("No such symbol '{}' in scope.", error_symbol_name,))
|
||||||
"No such {} symbol '{}' in scope.",
|
|
||||||
symbol_types, error_symbol_name,
|
|
||||||
))
|
|
||||||
.with_label(
|
.with_label(
|
||||||
Label::primary(error_file_id, error_range).with_message("Symbol used here."),
|
Label::primary(error_file_id, error_range).with_message("Symbol used here."),
|
||||||
);
|
);
|
||||||
@ -57,3 +53,11 @@ pub fn handle_lookup_error(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format_fqn(parts: &[&str]) -> String {
|
||||||
|
parts.join("::")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn join_fqn_parts(parts: &[Rc<str>]) -> String {
|
||||||
|
format_fqn(&parts.iter().map(|part| part.as_ref()).collect::<Vec<_>>())
|
||||||
|
}
|
||||||
|
|||||||
@ -1,27 +1,27 @@
|
|||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
use crate::name_analysis::symbol::parameter_symbol::ParameterSymbol;
|
||||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
|
use crate::name_analysis::type_use_container::TypeUseContainer;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> {
|
||||||
symbol_table.insert_function_symbol(
|
symbol_table.set_current_fqn(&vec!["std", "core"]);
|
||||||
FunctionSymbol::without_parameters_or_return_type(
|
|
||||||
"std::core::println",
|
let mut println_msg_symbol_type_use = TypeUseContainer::new();
|
||||||
"println",
|
println_msg_symbol_type_use.set_resolved_type(todo!());
|
||||||
true,
|
|
||||||
true,
|
let println_msg_symbol = ParameterSymbol::new("msg", None, Some(TypeUseContainer::new()));
|
||||||
None,
|
|
||||||
)
|
let println_symbol = FunctionSymbol::with_parameters_and_return_type(
|
||||||
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
&symbol_table.resolve_fqn(Rc::from("println")),
|
||||||
)?;
|
true,
|
||||||
symbol_table.insert_function_symbol(
|
true,
|
||||||
FunctionSymbol::without_parameters_or_return_type(
|
None,
|
||||||
"std::core::print",
|
&vec![Rc::new(RefCell::new(println_msg_symbol))],
|
||||||
"print",
|
None,
|
||||||
true,
|
);
|
||||||
true,
|
symbol_table.insert_function_symbol(println_symbol)?;
|
||||||
None,
|
|
||||||
)
|
|
||||||
.with_parameters(vec![ParameterSymbol::new("msg", None)]),
|
|
||||||
)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user