WIP variety of name-analysis things.
This commit is contained in:
parent
8b374e1066
commit
5721bd1e83
@ -116,6 +116,7 @@ fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
|||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use crate::name_analysis::symbol::type_symbol::*;
|
||||||
use crate::name_analysis::symbol::use_symbol::*;
|
use crate::name_analysis::symbol::use_symbol::*;
|
||||||
|
|
||||||
#(#types)*
|
#(#types)*
|
||||||
|
|||||||
@ -1,18 +1,21 @@
|
|||||||
use crate::ast::node::{
|
use crate::ast::node::{
|
||||||
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
|
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
|
||||||
Identifier, Module, ModuleLevelDeclaration, Parameters, ReturnType, TypeUse, UseStatement,
|
GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters,
|
||||||
UseStatementIdentifier, UseStatementPrefix,
|
PrimitiveType, ReturnType, TypeUse, TypedArray, UseStatement, UseStatementIdentifier,
|
||||||
|
UseStatementPrefix,
|
||||||
};
|
};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
||||||
use crate::name_analysis::symbol::module_level_symbol::ModuleLevelSymbol;
|
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::primitive_type_symbol::PrimitiveTypeSymbol;
|
||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
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::{format_fqn, handle_insert_error, handle_lookup_error};
|
||||||
use crate::name_analysis::util::handle_insert_error;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -23,13 +26,15 @@ pub fn na_p1_compilation_unit(
|
|||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
if let Some(namespace) = compilation_unit.namespace() {
|
if let Some(namespace) = compilation_unit.namespace() {
|
||||||
symbol_table.set_current_fqn(
|
match namespace.identifier_or_fqn() {
|
||||||
&namespace
|
IdentifierOrFqn::Identifier(identifier) => {
|
||||||
.fqn()
|
symbol_table.set_current_fqn(&[identifier.name()])
|
||||||
.identifiers()
|
}
|
||||||
.map(Identifier::name)
|
IdentifierOrFqn::FullyQualifiedName(fqn) => {
|
||||||
.collect::<Vec<_>>(),
|
symbol_table
|
||||||
);
|
.set_current_fqn(&fqn.identifiers().map(Identifier::name).collect::<Vec<_>>());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol_table.push_scope(&format!("FileScope {}", file_name));
|
symbol_table.push_scope(&format!("FileScope {}", file_name));
|
||||||
@ -214,16 +219,22 @@ fn na_p1_function(
|
|||||||
Ok(function_symbol) => {
|
Ok(function_symbol) => {
|
||||||
{
|
{
|
||||||
let mut as_ref_mut = function_symbol.borrow_mut();
|
let mut as_ref_mut = function_symbol.borrow_mut();
|
||||||
|
// generics
|
||||||
|
na_p1_generic_parameters(function.generics_mut(), symbol_table, diagnostics);
|
||||||
|
|
||||||
|
// parameters
|
||||||
as_ref_mut.set_parameter_symbols(na_p1_parameters(
|
as_ref_mut.set_parameter_symbols(na_p1_parameters(
|
||||||
function.parameters_mut(),
|
function.parameters_mut(),
|
||||||
symbol_table,
|
symbol_table,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
));
|
));
|
||||||
as_ref_mut.set_return_type(na_p1_return_type(
|
|
||||||
function.return_type_mut(),
|
// return type
|
||||||
symbol_table,
|
let return_type =
|
||||||
diagnostics,
|
na_p1_return_type(function.return_type_mut(), symbol_table, diagnostics);
|
||||||
))
|
if let Some(type_symbol) = return_type {
|
||||||
|
as_ref_mut.set_return_type(type_symbol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(function_symbol)
|
Some(function_symbol)
|
||||||
}
|
}
|
||||||
@ -256,7 +267,7 @@ fn na_p1_return_type(
|
|||||||
return_type: &mut ReturnType,
|
return_type: &mut ReturnType,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) -> Rc<RefCell<TypeUseContainer>> {
|
) -> Option<TypeSymbol> {
|
||||||
na_p1_type_use(return_type.type_use_mut(), symbol_table, diagnostics)
|
na_p1_type_use(return_type.type_use_mut(), symbol_table, diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,13 +275,68 @@ fn na_p1_type_use(
|
|||||||
type_use: &mut TypeUse,
|
type_use: &mut TypeUse,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) -> Rc<RefCell<TypeUseContainer>> {
|
) -> Option<TypeSymbol> {
|
||||||
match type_use {
|
match type_use {
|
||||||
TypeUse::PrimitiveType(primitive_type) => {
|
TypeUse::PrimitiveType(primitive_type) => {
|
||||||
todo!()
|
Some(TypeSymbol::Primitive(match primitive_type {
|
||||||
|
PrimitiveType::Byte => PrimitiveTypeSymbol::Byte,
|
||||||
|
PrimitiveType::Short => PrimitiveTypeSymbol::Short,
|
||||||
|
PrimitiveType::Char => PrimitiveTypeSymbol::Char,
|
||||||
|
PrimitiveType::Int => PrimitiveTypeSymbol::Int,
|
||||||
|
PrimitiveType::Long => PrimitiveTypeSymbol::Long,
|
||||||
|
PrimitiveType::Double => PrimitiveTypeSymbol::Double,
|
||||||
|
PrimitiveType::Bool => PrimitiveTypeSymbol::Boolean,
|
||||||
|
PrimitiveType::String => PrimitiveTypeSymbol::String,
|
||||||
|
PrimitiveType::TypedArray(typed_array) => {
|
||||||
|
na_p1_typed_array(typed_array, symbol_table, diagnostics)
|
||||||
|
}
|
||||||
|
PrimitiveType::Any => PrimitiveTypeSymbol::Any,
|
||||||
|
PrimitiveType::Void => PrimitiveTypeSymbol::Void,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
TypeUse::InterfaceOrClassTypeUse(interface_or_class_type) => {
|
TypeUse::InterfaceOrClassTypeUse(interface_or_class_type) => {
|
||||||
todo!()
|
match interface_or_class_type.identifier_or_fqn() {
|
||||||
|
IdentifierOrFqn::Identifier(identifier) => {
|
||||||
|
match symbol_table.lookup_type(identifier.name()) {
|
||||||
|
Ok(type_symbol) => {
|
||||||
|
interface_or_class_type.set_type_symbol(type_symbol.clone());
|
||||||
|
Some(type_symbol)
|
||||||
|
}
|
||||||
|
Err(symbol_lookup_error) => {
|
||||||
|
handle_lookup_error(
|
||||||
|
symbol_lookup_error,
|
||||||
|
identifier.name(),
|
||||||
|
identifier.file_id(),
|
||||||
|
identifier.range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IdentifierOrFqn::FullyQualifiedName(fqn) => {
|
||||||
|
let fqn_parts = fqn
|
||||||
|
.identifiers()
|
||||||
|
.map(Identifier::name)
|
||||||
|
.collect::<Vec<&str>>();
|
||||||
|
match symbol_table.lookup_type_by_fqn(&fqn_parts) {
|
||||||
|
Ok(type_symbol) => {
|
||||||
|
interface_or_class_type.set_type_symbol(type_symbol.clone());
|
||||||
|
Some(type_symbol)
|
||||||
|
}
|
||||||
|
Err(symbol_lookup_error) => {
|
||||||
|
handle_lookup_error(
|
||||||
|
symbol_lookup_error,
|
||||||
|
&format_fqn(&fqn_parts),
|
||||||
|
fqn.file_id(),
|
||||||
|
fqn.range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TypeUse::TupleTypeUse(tuple_type) => {
|
TypeUse::TupleTypeUse(tuple_type) => {
|
||||||
todo!()
|
todo!()
|
||||||
@ -281,6 +347,48 @@ fn na_p1_type_use(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn na_p1_typed_array(
|
||||||
|
typed_array: &mut TypedArray,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) -> PrimitiveTypeSymbol {
|
||||||
|
let inner_type_use = typed_array
|
||||||
|
.generic_arguments_mut()
|
||||||
|
.type_use_list_mut()
|
||||||
|
.type_uses_mut()
|
||||||
|
.next()
|
||||||
|
.unwrap();
|
||||||
|
let inner_type_symbol = na_p1_type_use(inner_type_use, symbol_table, diagnostics);
|
||||||
|
PrimitiveTypeSymbol::TypedArray {
|
||||||
|
inner_type: inner_type_symbol.map(Box::from),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn na_p1_generic_parameters(
|
||||||
|
generic_parameters: &mut GenericParameters,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
for identifier in generic_parameters.identifier_list().identifiers() {
|
||||||
|
let generic_type_symbol = GenericTypeSymbol::new(
|
||||||
|
identifier.name(),
|
||||||
|
Some(SourceDefinition::from_identifier(identifier)),
|
||||||
|
);
|
||||||
|
match symbol_table.insert_generic_type_symbol(generic_type_symbol) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(symbol_insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
symbol_insert_error,
|
||||||
|
identifier.name(),
|
||||||
|
identifier.file_id(),
|
||||||
|
identifier.range(),
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn na_p1_function_body(
|
fn na_p1_function_body(
|
||||||
function_body: &mut FunctionBody,
|
function_body: &mut FunctionBody,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
|
|||||||
@ -31,11 +31,9 @@ use std::hash::Hash;
|
|||||||
|
|
||||||
// mod resolve;
|
// mod resolve;
|
||||||
mod first_pass;
|
mod first_pass;
|
||||||
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>>(
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
use crate::ast::node::{FullyQualifiedName, VariableUse};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
pub struct ScopeTable<'a> {
|
|
||||||
variable_use_scopes: HashMap<&'a VariableUse, usize>,
|
|
||||||
fqn_scopes: HashMap<&'a FullyQualifiedName, usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> ScopeTable<'a> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
variable_use_scopes: HashMap::new(),
|
|
||||||
fqn_scopes: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_variable_use_scope(&mut self, variable_use: &'a VariableUse, scope_id: usize) {
|
|
||||||
self.variable_use_scopes.insert(variable_use, scope_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_fqn_scope(&mut self, fqn: &'a FullyQualifiedName, scope_id: usize) {
|
|
||||||
self.fqn_scopes.insert(fqn, scope_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn variable_use_scope(&self, variable_use: &'a VariableUse) -> Option<usize> {
|
|
||||||
self.variable_use_scopes.get(&variable_use).copied()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fqn_scope(&self, fqn: &'a FullyQualifiedName) -> Option<usize> {
|
|
||||||
self.fqn_scopes.get(&fqn).copied()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
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::TypeSymbol;
|
||||||
use crate::name_analysis::symbol::Symbol;
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use crate::name_analysis::type_use_container::TypeUseContainer;
|
|
||||||
use crate::name_analysis::util::join_fqn_parts;
|
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};
|
||||||
@ -13,7 +13,7 @@ pub struct FunctionSymbol {
|
|||||||
is_platform: bool,
|
is_platform: bool,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
parameters: Vec<Rc<RefCell<ParameterSymbol>>>,
|
parameters: Vec<Rc<RefCell<ParameterSymbol>>>,
|
||||||
return_type: Option<Rc<RefCell<TypeUseContainer>>>, // todo: can we use TypeSymbol?
|
return_type: Option<TypeSymbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FunctionSymbol {
|
impl FunctionSymbol {
|
||||||
@ -39,7 +39,7 @@ impl FunctionSymbol {
|
|||||||
is_platform: bool,
|
is_platform: bool,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
parameters: &[Rc<RefCell<ParameterSymbol>>],
|
parameters: &[Rc<RefCell<ParameterSymbol>>],
|
||||||
return_type: Option<Rc<RefCell<TypeUseContainer>>>,
|
return_type: Option<TypeSymbol>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fqn_parts: fqn_parts.to_vec(),
|
fqn_parts: fqn_parts.to_vec(),
|
||||||
@ -79,8 +79,8 @@ impl FunctionSymbol {
|
|||||||
self.parameters = parameter_symbols;
|
self.parameters = parameter_symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_return_type(&mut self, type_use_container: Rc<RefCell<TypeUseContainer>>) {
|
pub fn set_return_type(&mut self, type_symbol: TypeSymbol) {
|
||||||
self.return_type = Some(type_use_container);
|
self.return_type = Some(type_symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GenericTypeSymbol {
|
pub struct GenericTypeSymbol {
|
||||||
declared_name: String,
|
declared_name: Rc<str>,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenericTypeSymbol {
|
impl GenericTypeSymbol {
|
||||||
pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self {
|
pub fn new(declared_name: &str, source_definition: Option<SourceDefinition>) -> Self {
|
||||||
GenericTypeSymbol {
|
GenericTypeSymbol {
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: Rc::from(declared_name),
|
||||||
source_definition,
|
source_definition,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,12 +20,22 @@ impl GenericTypeSymbol {
|
|||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||||
|
self.declared_name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Symbol for GenericTypeSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
self.source_definition.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Debug for GenericTypeSymbol {
|
impl Debug for GenericTypeSymbol {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("GenericTypeSymbol")
|
f.debug_struct("GenericTypeSymbol")
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
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 crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
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>,
|
type_symbol: Option<TypeSymbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParameterSymbol {
|
impl ParameterSymbol {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
type_use_symbol: Option<TypeUseContainer>,
|
type_symbol: Option<TypeSymbol>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ParameterSymbol {
|
ParameterSymbol {
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
source_definition,
|
source_definition,
|
||||||
type_use_symbol,
|
type_symbol,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
#[derive(Debug)]
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub enum PrimitiveTypeSymbol {
|
pub enum PrimitiveTypeSymbol {
|
||||||
Byte,
|
Byte,
|
||||||
Char,
|
Char,
|
||||||
@ -9,4 +13,13 @@ pub enum PrimitiveTypeSymbol {
|
|||||||
Double,
|
Double,
|
||||||
Boolean,
|
Boolean,
|
||||||
String,
|
String,
|
||||||
|
TypedArray { inner_type: Option<Box<TypeSymbol>> },
|
||||||
|
Any,
|
||||||
|
Void,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Symbol for PrimitiveTypeSymbol {
|
||||||
|
fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,35 @@
|
|||||||
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::generic_type_symbol::GenericTypeSymbol;
|
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
||||||
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
use crate::name_analysis::symbol::interface_symbol::InterfaceSymbol;
|
||||||
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
|
use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use crate::name_analysis::symbol::Symbol;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TypeSymbol {
|
pub enum TypeSymbol {
|
||||||
Primitive(PrimitiveTypeSymbol),
|
Primitive(PrimitiveTypeSymbol),
|
||||||
Class(Rc<RefCell<ClassSymbol>>),
|
Class(Rc<RefCell<ClassSymbol>>),
|
||||||
Interface(Rc<RefCell<InterfaceSymbol>>),
|
Interface(Rc<RefCell<InterfaceSymbol>>),
|
||||||
Generic(Rc<RefCell<GenericTypeSymbol>>),
|
Generic(Rc<RefCell<GenericTypeSymbol>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TypeSymbol {
|
||||||
|
pub fn to_symbol(self) -> Rc<RefCell<dyn Symbol>> {
|
||||||
|
match self {
|
||||||
|
TypeSymbol::Primitive(primitive_type_symbol) => {
|
||||||
|
Rc::new(RefCell::new(primitive_type_symbol))
|
||||||
|
}
|
||||||
|
TypeSymbol::Class(class_symbol) => {
|
||||||
|
class_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
TypeSymbol::Interface(interface_symbol) => {
|
||||||
|
interface_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
TypeSymbol::Generic(generic_symbol) => {
|
||||||
|
generic_symbol as Rc<RefCell<dyn Symbol>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
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::type_symbol::TypeSymbol;
|
||||||
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
use crate::name_analysis::symbol::usable_symbol::UsableSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol::Symbol;
|
use crate::name_analysis::symbol::Symbol;
|
||||||
@ -11,6 +12,7 @@ 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::generic_type_symbol::GenericTypeSymbol;
|
||||||
|
|
||||||
pub(self) mod fqn_context;
|
pub(self) mod fqn_context;
|
||||||
mod scope;
|
mod scope;
|
||||||
@ -55,7 +57,6 @@ impl SymbolTable {
|
|||||||
id_to_push,
|
id_to_push,
|
||||||
debug_name.to_string(),
|
debug_name.to_string(),
|
||||||
));
|
));
|
||||||
self.current_scope_mut().add_child(id_to_push);
|
|
||||||
self.current_scope_id = id_to_push;
|
self.current_scope_id = id_to_push;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,6 +179,36 @@ impl SymbolTable {
|
|||||||
Ok(inserted)
|
Ok(inserted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_generic_type_symbol(
|
||||||
|
&mut self,
|
||||||
|
generic_type_symbol: GenericTypeSymbol,
|
||||||
|
) -> Result<Rc<RefCell<GenericTypeSymbol>>, SymbolInsertError> {
|
||||||
|
if let Some(defined_symbol) = self.current_scope().find_type_symbol(generic_type_symbol.declared_name()) {
|
||||||
|
Err(SymbolAlreadyDefined(defined_symbol.to_symbol()))
|
||||||
|
} else {
|
||||||
|
let inserted = self.current_scope_mut().insert_generic_type_symbol(generic_type_symbol);
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lookup_type(&self, declared_name: &str) -> Result<TypeSymbol, SymbolLookupError> {
|
||||||
|
let mut current_scope: Option<&Scope> = Some(self.current_scope());
|
||||||
|
while let Some(scope) = current_scope.take() {
|
||||||
|
if let Some(type_symbol) = scope.find_type_symbol(declared_name) {
|
||||||
|
return Ok(type_symbol);
|
||||||
|
} else {
|
||||||
|
current_scope = scope
|
||||||
|
.parent()
|
||||||
|
.and_then(|parent_id| self.scopes.get(parent_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(SymbolLookupError::NoDefinition)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lookup_type_by_fqn(&self, fqn_parts: &[&str]) -> Result<TypeSymbol, SymbolLookupError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SymbolTable {
|
impl Display for SymbolTable {
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
use crate::name_analysis::symbol::class_member_symbol::ClassMemberSymbol;
|
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::generic_type_symbol::GenericTypeSymbol;
|
||||||
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_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::type_symbol::TypeSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -22,6 +24,7 @@ pub struct Scope {
|
|||||||
module_symbols: HashMap<Rc<str>, Rc<RefCell<ModuleSymbol>>>,
|
module_symbols: HashMap<Rc<str>, Rc<RefCell<ModuleSymbol>>>,
|
||||||
interface_symbols: HashMap<Rc<str>, Rc<RefCell<InterfaceSymbol>>>,
|
interface_symbols: HashMap<Rc<str>, Rc<RefCell<InterfaceSymbol>>>,
|
||||||
class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>,
|
class_symbols: HashMap<Rc<str>, Rc<RefCell<ClassSymbol>>>,
|
||||||
|
generic_symbols: HashMap<Rc<str>, Rc<RefCell<GenericTypeSymbol>>>,
|
||||||
function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
function_symbols: HashMap<Rc<str>, Rc<RefCell<FunctionSymbol>>>,
|
||||||
parameter_symbols: HashMap<Rc<str>, ParameterSymbol>,
|
parameter_symbols: HashMap<Rc<str>, ParameterSymbol>,
|
||||||
variable_symbols: HashMap<Rc<str>, VariableSymbol>,
|
variable_symbols: HashMap<Rc<str>, VariableSymbol>,
|
||||||
@ -48,6 +51,7 @@ impl Scope {
|
|||||||
module_symbols: HashMap::new(),
|
module_symbols: HashMap::new(),
|
||||||
interface_symbols: HashMap::new(),
|
interface_symbols: HashMap::new(),
|
||||||
class_symbols: HashMap::new(),
|
class_symbols: HashMap::new(),
|
||||||
|
generic_symbols: HashMap::new(),
|
||||||
function_symbols: HashMap::new(),
|
function_symbols: HashMap::new(),
|
||||||
parameter_symbols: HashMap::new(),
|
parameter_symbols: HashMap::new(),
|
||||||
variable_symbols: HashMap::new(),
|
variable_symbols: HashMap::new(),
|
||||||
@ -64,15 +68,10 @@ impl Scope {
|
|||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_child(&mut self, child_id: usize) {
|
pub fn insert_concrete_use_symbol(
|
||||||
self.children.push(child_id);
|
&mut self,
|
||||||
}
|
symbol: ConcreteUseSymbol,
|
||||||
|
) -> Rc<RefCell<ConcreteUseSymbol>> {
|
||||||
pub fn children(&self) -> Vec<usize> {
|
|
||||||
self.children.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_concrete_use_symbol(&mut self, symbol: ConcreteUseSymbol) -> Rc<RefCell<ConcreteUseSymbol>> {
|
|
||||||
let key = symbol.declared_name_owned();
|
let key = symbol.declared_name_owned();
|
||||||
insert_symbol!(self.concrete_use_symbols, symbol, key)
|
insert_symbol!(self.concrete_use_symbols, symbol, key)
|
||||||
}
|
}
|
||||||
@ -126,6 +125,11 @@ impl Scope {
|
|||||||
pub fn get_class_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<ClassSymbol>>> {
|
pub fn get_class_symbol(&self, declared_name: &str) -> Option<&Rc<RefCell<ClassSymbol>>> {
|
||||||
self.class_symbols.get(declared_name)
|
self.class_symbols.get(declared_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn insert_generic_type_symbol(&mut self, symbol: GenericTypeSymbol) -> Rc<RefCell<GenericTypeSymbol>> {
|
||||||
|
let key = symbol.declared_name_owned();
|
||||||
|
insert_symbol!(self.generic_symbols, symbol, key)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> {
|
pub fn find_module_level_symbol(&self, declared_name: &str) -> Option<ModuleLevelSymbol> {
|
||||||
self.module_symbols
|
self.module_symbols
|
||||||
@ -148,6 +152,22 @@ impl Scope {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_type_symbol(&self, declared_name: &str) -> Option<TypeSymbol> {
|
||||||
|
self.interface_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|interface_symbol| TypeSymbol::Interface(interface_symbol.clone()))
|
||||||
|
.or_else(|| {
|
||||||
|
self.class_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|class_symbol| TypeSymbol::Class(class_symbol.clone()))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.generic_symbols
|
||||||
|
.get(declared_name)
|
||||||
|
.map(|generic_symbol| TypeSymbol::Generic(generic_symbol.clone()))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn debug_name(&self) -> &str {
|
pub fn debug_name(&self) -> &str {
|
||||||
&self.debug_name
|
&self.debug_name
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -62,6 +62,11 @@ $defs:
|
|||||||
description: Traits to derive.
|
description: Traits to derive.
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
|
fields:
|
||||||
|
type: array
|
||||||
|
description: Fields to add to the struct node.
|
||||||
|
items:
|
||||||
|
$ref: "#/$defs/StructField"
|
||||||
required:
|
required:
|
||||||
- children
|
- children
|
||||||
StructChild:
|
StructChild:
|
||||||
@ -209,6 +214,24 @@ $defs:
|
|||||||
- kind
|
- kind
|
||||||
required:
|
required:
|
||||||
- special
|
- special
|
||||||
|
StructField:
|
||||||
|
type: object
|
||||||
|
description: Single-key object mapping the field name to its advanced definition.
|
||||||
|
minProperties: 1
|
||||||
|
maxProperties: 1
|
||||||
|
additionalProperties: false
|
||||||
|
patternProperties:
|
||||||
|
"^[a-z][a-z0-9_]*$":
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
kind:
|
||||||
|
type: string
|
||||||
|
wrap:
|
||||||
|
enum:
|
||||||
|
- rc_ref_cell
|
||||||
|
required:
|
||||||
|
- kind
|
||||||
|
|
||||||
# Leaf Struct Node
|
# Leaf Struct Node
|
||||||
LeafStructNodeDefinition:
|
LeafStructNodeDefinition:
|
||||||
|
|||||||
@ -59,10 +59,21 @@ FullyQualifiedName:
|
|||||||
- identifiers:
|
- identifiers:
|
||||||
vec:
|
vec:
|
||||||
rule: Identifier
|
rule: Identifier
|
||||||
|
- file_id:
|
||||||
|
special:
|
||||||
|
kind: file_id
|
||||||
|
- range:
|
||||||
|
special:
|
||||||
|
kind: range
|
||||||
derive:
|
derive:
|
||||||
- PartialEq
|
- PartialEq
|
||||||
- Eq
|
- Eq
|
||||||
- Hash
|
- Hash
|
||||||
|
IdentifierOrFqn:
|
||||||
|
tree_enum:
|
||||||
|
rules:
|
||||||
|
- Identifier
|
||||||
|
- FullyQualifiedName
|
||||||
|
|
||||||
# Lists
|
# Lists
|
||||||
TypeUseList:
|
TypeUseList:
|
||||||
@ -126,13 +137,14 @@ TypedArray:
|
|||||||
InterfaceOrClassTypeUse:
|
InterfaceOrClassTypeUse:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
- fully_qualified_name
|
- identifier_or_fqn
|
||||||
- generic_arguments:
|
- generic_arguments:
|
||||||
member:
|
member:
|
||||||
rule: GenericArguments
|
rule: GenericArguments
|
||||||
build:
|
optional: true
|
||||||
node:
|
fields:
|
||||||
or_else_default: true
|
- type_symbol:
|
||||||
|
kind: TypeSymbol
|
||||||
TupleTypeUse:
|
TupleTypeUse:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
@ -227,9 +239,7 @@ Namespace:
|
|||||||
- ns_kw:
|
- ns_kw:
|
||||||
skip:
|
skip:
|
||||||
rule: Ns
|
rule: Ns
|
||||||
- fqn:
|
- identifier_or_fqn
|
||||||
member:
|
|
||||||
rule: FullyQualifiedName
|
|
||||||
UseStatement:
|
UseStatement:
|
||||||
tree_enum:
|
tree_enum:
|
||||||
rules:
|
rules:
|
||||||
|
|||||||
@ -184,7 +184,12 @@ IdentifierChar = {
|
|||||||
|
|
||||||
FullyQualifiedName = {
|
FullyQualifiedName = {
|
||||||
Identifier
|
Identifier
|
||||||
~ ( "::" ~ Identifier )*
|
~ ( "::" ~ Identifier )+
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentifierOrFqn = {
|
||||||
|
Identifier
|
||||||
|
| FullyQualifiedName
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common lists
|
// Common lists
|
||||||
@ -238,7 +243,7 @@ TypedArray = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InterfaceOrClassTypeUse = {
|
InterfaceOrClassTypeUse = {
|
||||||
FullyQualifiedName
|
IdentifierOrFqn
|
||||||
~ GenericArguments?
|
~ GenericArguments?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +323,7 @@ CompilationUnit = {
|
|||||||
|
|
||||||
Namespace = {
|
Namespace = {
|
||||||
Ns
|
Ns
|
||||||
~ FullyQualifiedName
|
~ IdentifierOrFqn
|
||||||
}
|
}
|
||||||
|
|
||||||
UseStatement = {
|
UseStatement = {
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
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::primitive_type_symbol::PrimitiveTypeSymbol;
|
||||||
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
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::cell::RefCell;
|
||||||
use std::rc::Rc;
|
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.set_current_fqn(&vec!["std", "core"]);
|
symbol_table.set_current_fqn(&vec!["std", "core"]);
|
||||||
|
|
||||||
let mut println_msg_symbol_type_use = TypeUseContainer::new();
|
let println_msg_symbol = ParameterSymbol::new("msg", None, Some(
|
||||||
println_msg_symbol_type_use.set_resolved_type(todo!());
|
TypeSymbol::Primitive(PrimitiveTypeSymbol::Any)
|
||||||
|
));
|
||||||
let println_msg_symbol = ParameterSymbol::new("msg", None, Some(TypeUseContainer::new()));
|
|
||||||
|
|
||||||
let println_symbol = FunctionSymbol::with_parameters_and_return_type(
|
let println_symbol = FunctionSymbol::with_parameters_and_return_type(
|
||||||
&symbol_table.resolve_fqn(Rc::from("println")),
|
&symbol_table.resolve_fqn(Rc::from("println")),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user