Bunch of work on name analysis. Reintroduce Rc<RefCell<_>> for symbols.
This commit is contained in:
parent
273d197841
commit
b5c0e44eeb
@ -5,6 +5,22 @@ use crate::deserialize::util::{get_as_bool, make_build_fn_name, unwrap_single_me
|
|||||||
use crate::spec::struct_spec::*;
|
use crate::spec::struct_spec::*;
|
||||||
use yaml_rust2::Yaml;
|
use yaml_rust2::Yaml;
|
||||||
|
|
||||||
|
fn deserialize_field(field_yaml: &Yaml) -> StructField {
|
||||||
|
let (name, props) = unwrap_single_member_hash(field_yaml);
|
||||||
|
let kind = props["kind"].as_str().unwrap();
|
||||||
|
let wrap = if let Some(wrap) = props["wrap"].as_str() {
|
||||||
|
match wrap {
|
||||||
|
"rc_ref_cell" => {
|
||||||
|
Some(StructFieldWrap::RcRefCell)
|
||||||
|
}
|
||||||
|
_ => panic!()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
StructField::new(&name, kind, wrap)
|
||||||
|
}
|
||||||
|
|
||||||
fn deserialize_skip_child(props: &Yaml) -> StructChild {
|
fn deserialize_skip_child(props: &Yaml) -> StructChild {
|
||||||
let rule = props["rule"].as_str().unwrap();
|
let rule = props["rule"].as_str().unwrap();
|
||||||
StructChild::SkipChild(SkipChild::new(rule))
|
StructChild::SkipChild(SkipChild::new(rule))
|
||||||
@ -151,6 +167,18 @@ pub fn deserialize_struct_spec(name: &str, struct_yaml: &Yaml) -> StructSpec {
|
|||||||
} else {
|
} else {
|
||||||
deserialize_error!("array", "children", name);
|
deserialize_error!("array", "children", name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let fields = if struct_yaml["fields"].is_array() {
|
||||||
|
struct_yaml["fields"].as_vec()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.map(|field| deserialize_field(field))
|
||||||
|
.map(Box::new)
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
};
|
||||||
|
|
||||||
let derive = if struct_yaml["derive"].is_array() {
|
let derive = if struct_yaml["derive"].is_array() {
|
||||||
struct_yaml["derive"].as_vec()
|
struct_yaml["derive"].as_vec()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -161,5 +189,5 @@ pub fn deserialize_struct_spec(name: &str, struct_yaml: &Yaml) -> StructSpec {
|
|||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
StructSpec::new(name, children, derive)
|
StructSpec::new(name, children, fields, derive)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -114,6 +114,9 @@ fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let combined = quote! {
|
let combined = quote! {
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use crate::name_analysis::symbol::use_symbol::UseSymbol;
|
||||||
|
|
||||||
#(#types)*
|
#(#types)*
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
pub struct StructSpec {
|
pub struct StructSpec {
|
||||||
build: String,
|
build: String,
|
||||||
children: Vec<Box<StructChild>>,
|
children: Vec<Box<StructChild>>,
|
||||||
|
fields: Vec<Box<StructField>>,
|
||||||
derive: Vec<String>,
|
derive: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StructSpec {
|
impl StructSpec {
|
||||||
pub fn new(build: &str, children: Vec<Box<StructChild>>, derive: Vec<String>) -> Self {
|
pub fn new(build: &str, children: Vec<Box<StructChild>>, fields: Vec<Box<StructField>>, derive: Vec<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
build: build.to_string(),
|
build: build.to_string(),
|
||||||
children,
|
children,
|
||||||
|
fields,
|
||||||
derive,
|
derive,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,6 +25,10 @@ impl StructSpec {
|
|||||||
self.children.iter().map(Box::as_ref)
|
self.children.iter().map(Box::as_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fields(&self) -> impl Iterator<Item = &StructField> {
|
||||||
|
self.fields.iter().map(Box::as_ref)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn derive(&self) -> &[String] {
|
pub fn derive(&self) -> &[String] {
|
||||||
&self.derive
|
&self.derive
|
||||||
}
|
}
|
||||||
@ -266,3 +272,37 @@ pub enum SpecialChildKind {
|
|||||||
FileId,
|
FileId,
|
||||||
Range,
|
Range,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StructField {
|
||||||
|
name: String,
|
||||||
|
kind: String,
|
||||||
|
wrap: Option<StructFieldWrap>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StructField {
|
||||||
|
pub fn new(name: &str, kind: &str, wrap: Option<StructFieldWrap>) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.to_string(),
|
||||||
|
kind: kind.to_string(),
|
||||||
|
wrap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kind(&self) -> &str {
|
||||||
|
&self.kind
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wrap(&self) -> Option<&StructFieldWrap> {
|
||||||
|
self.wrap.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum StructFieldWrap {
|
||||||
|
RcRefCell
|
||||||
|
}
|
||||||
|
|||||||
@ -1,10 +1,66 @@
|
|||||||
use crate::spec::struct_spec::{
|
use crate::spec::struct_spec::{
|
||||||
MemberChild, MemberChildBuild, SpecialChild, SpecialChildKind, StructChild, StructSpec,
|
MemberChild, MemberChildBuild, SpecialChild, SpecialChildKind, StructChild, StructField,
|
||||||
VecChild, VecChildBuild,
|
StructFieldWrap, StructSpec, VecChild, VecChildBuild,
|
||||||
};
|
};
|
||||||
use proc_macro2::{Ident, TokenStream};
|
use proc_macro2::{Ident, TokenStream};
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
|
|
||||||
|
fn make_field_accessors(field: &StructField) -> TokenStream {
|
||||||
|
let field_ident = format_ident!("{}", field.name());
|
||||||
|
let field_type = {
|
||||||
|
let inner = format_ident!("{}", field.kind());
|
||||||
|
if let Some(wrap) = field.wrap() {
|
||||||
|
match wrap {
|
||||||
|
StructFieldWrap::RcRefCell => {
|
||||||
|
quote! { Rc<RefCell<#inner>> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! { #inner }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let set_field_ident = format_ident!("set_{}", field.name());
|
||||||
|
let field_ident_mut = format_ident!("{}_mut", field.name());
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
pub fn #field_ident(&self) -> Option<&#field_type> {
|
||||||
|
self.#field_ident.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn #field_ident_mut(&mut self) -> Option<&mut #field_type> {
|
||||||
|
self.#field_ident.as_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn #set_field_ident(&mut self, #field_ident: #field_type) {
|
||||||
|
self.#field_ident = Some(#field_ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_field_initializer(field: &StructField) -> TokenStream {
|
||||||
|
let field_ident = format_ident!("{}", field.name());
|
||||||
|
quote! { #field_ident: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_annotated_field(field: &StructField) -> TokenStream {
|
||||||
|
let field_ident = format_ident!("{}", field.name());
|
||||||
|
let field_type = if let Some(wrap) = field.wrap() {
|
||||||
|
match wrap {
|
||||||
|
StructFieldWrap::RcRefCell => {
|
||||||
|
let inner = format_ident!("{}", field.kind());
|
||||||
|
quote! { Rc<RefCell<#inner>> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let inner = format_ident!("{}", field.kind());
|
||||||
|
quote! { #inner }
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#field_ident: Option<#field_type>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn make_vec_child_accessors(vec_child: &VecChild) -> TokenStream {
|
fn make_vec_child_accessors(vec_child: &VecChild) -> TokenStream {
|
||||||
let child_ident = format_ident!("{}", vec_child.name());
|
let child_ident = format_ident!("{}", vec_child.name());
|
||||||
match vec_child.build() {
|
match vec_child.build() {
|
||||||
@ -184,13 +240,18 @@ fn make_annotated_member(child: &StructChild) -> Option<TokenStream> {
|
|||||||
|
|
||||||
pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream {
|
pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream {
|
||||||
let type_ident = format_ident!("{}", build_spec.build());
|
let type_ident = format_ident!("{}", build_spec.build());
|
||||||
let annotated_members = build_spec
|
let annotated_children_members = build_spec
|
||||||
.children()
|
.children()
|
||||||
.map(|child| make_annotated_member(child))
|
.map(|child| make_annotated_member(child))
|
||||||
.filter(Option::is_some)
|
.filter(Option::is_some)
|
||||||
.map(Option::unwrap)
|
.map(Option::unwrap)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let annotated_fields = build_spec
|
||||||
|
.fields()
|
||||||
|
.map(|field| make_annotated_field(field))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let member_names = build_spec
|
let member_names = build_spec
|
||||||
.children()
|
.children()
|
||||||
.map(|child| make_member_ident(child))
|
.map(|child| make_member_ident(child))
|
||||||
@ -198,17 +259,28 @@ pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream {
|
|||||||
.map(Option::unwrap)
|
.map(Option::unwrap)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let accessors = build_spec
|
let field_initializers = build_spec
|
||||||
|
.fields()
|
||||||
|
.map(|field| make_field_initializer(field))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let child_accessors = build_spec
|
||||||
.children()
|
.children()
|
||||||
.map(|child| make_accessors(child))
|
.map(|child| make_accessors(child))
|
||||||
.filter(Option::is_some)
|
.filter(Option::is_some)
|
||||||
.map(Option::unwrap)
|
.map(Option::unwrap)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let field_accessors = build_spec
|
||||||
|
.fields()
|
||||||
|
.map(|field| make_field_accessors(field))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let struct_stream = {
|
let struct_stream = {
|
||||||
let base = quote! {
|
let base = quote! {
|
||||||
pub struct #type_ident {
|
pub struct #type_ident {
|
||||||
#(#annotated_members),*
|
#(#annotated_children_members,)*
|
||||||
|
#(#annotated_fields,)*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if !build_spec.derive().is_empty() {
|
if !build_spec.derive().is_empty() {
|
||||||
@ -231,13 +303,15 @@ pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream {
|
|||||||
#struct_stream
|
#struct_stream
|
||||||
|
|
||||||
impl #type_ident {
|
impl #type_ident {
|
||||||
pub fn new(#(#annotated_members),*) -> Self {
|
pub fn new(#(#annotated_children_members),*) -> Self {
|
||||||
Self {
|
Self {
|
||||||
#(#member_names),*
|
#(#member_names,)*
|
||||||
|
#(#field_initializers,)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#(#accessors)*
|
#(#child_accessors)*
|
||||||
|
#(#field_accessors)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
use crate::ast::node::{CompilationUnit, UseStatement, UseStatementSuffix};
|
use std::cell::RefCell;
|
||||||
|
use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::fqn_context::FqnContext;
|
use crate::name_analysis::fqn_context::FqnContext;
|
||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol, UseSymbol};
|
||||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use crate::name_analysis::util::use_statement_base_fqn;
|
use crate::name_analysis::util::use_statement_base_fqn;
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
fn handle_insert_error(
|
fn handle_insert_error(
|
||||||
err: SymbolInsertError,
|
err: SymbolInsertError,
|
||||||
@ -69,7 +71,7 @@ macro_rules! insert_concrete_use_symbol {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn np1_compilation_unit(
|
pub fn nap1_compilation_unit(
|
||||||
file_name: &str,
|
file_name: &str,
|
||||||
compilation_unit: &mut CompilationUnit,
|
compilation_unit: &mut CompilationUnit,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -85,13 +87,42 @@ pub fn np1_compilation_unit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for use_statement in compilation_unit.use_statements_mut() {
|
for use_statement in compilation_unit.use_statements_mut() {
|
||||||
np1_use_statement(use_statement, symbol_table, diagnostics);
|
nap1_use_statement(use_statement, symbol_table, diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol_table.pop_scope();
|
symbol_table.pop_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn np1_use_statement(
|
fn handle_concrete_use_statement(
|
||||||
|
use_statement: &mut UseStatement,
|
||||||
|
identifier: &Identifier,
|
||||||
|
symbol_table: &mut SymbolTable,
|
||||||
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
) {
|
||||||
|
let base_fqn = use_statement_base_fqn(use_statement);
|
||||||
|
let to_insert = ConcreteUseSymbol::new(
|
||||||
|
&base_fqn,
|
||||||
|
identifier.name(),
|
||||||
|
Some(SourceDefinition::from_identifier(identifier))
|
||||||
|
);
|
||||||
|
match symbol_table.insert_concrete_use_symbol(to_insert) {
|
||||||
|
Ok(inserted) => {
|
||||||
|
use_statement.set_use_symbol(Rc::new(RefCell::new(UseSymbol::Concrete(inserted))));
|
||||||
|
}
|
||||||
|
Err(insert_error) => {
|
||||||
|
handle_insert_error(
|
||||||
|
insert_error,
|
||||||
|
identifier.name(),
|
||||||
|
identifier.file_id(),
|
||||||
|
identifier.range(),
|
||||||
|
"Use Symbol",
|
||||||
|
diagnostics
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nap1_use_statement(
|
||||||
use_statement: &mut UseStatement,
|
use_statement: &mut UseStatement,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
|
|||||||
@ -23,14 +23,13 @@ The resolve phase has one main responsibility: resolve all references based on t
|
|||||||
use crate::ast::ast_node::AstNode;
|
use crate::ast::ast_node::AstNode;
|
||||||
use crate::ast::node::CompilationUnit;
|
use crate::ast::node::CompilationUnit;
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::first_pass::np1_compilation_unit;
|
use crate::name_analysis::first_pass::nap1_compilation_unit;
|
||||||
|
use crate::name_analysis::second_pass::nap2_compilation_unit;
|
||||||
use crate::name_analysis::symbol_table::SymbolTable;
|
use crate::name_analysis::symbol_table::SymbolTable;
|
||||||
use codespan_reporting::files::Files;
|
use codespan_reporting::files::Files;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use crate::name_analysis::second_pass::nap2_compilation_unit;
|
|
||||||
|
|
||||||
pub(self) mod fqn_context;
|
pub(self) mod fqn_context;
|
||||||
mod gather;
|
|
||||||
// mod resolve;
|
// mod resolve;
|
||||||
mod first_pass;
|
mod first_pass;
|
||||||
mod scope_table;
|
mod scope_table;
|
||||||
@ -49,7 +48,7 @@ pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
|||||||
// gather symbols
|
// gather symbols
|
||||||
for compilation_unit in compilation_units.iter_mut() {
|
for compilation_unit in compilation_units.iter_mut() {
|
||||||
let file_name = files.name(compilation_unit.file_id()).unwrap();
|
let file_name = files.name(compilation_unit.file_id()).unwrap();
|
||||||
np1_compilation_unit(&file_name, compilation_unit, symbol_table, &mut diagnostics);
|
nap1_compilation_unit(&file_name, compilation_unit, symbol_table, &mut diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve symbols
|
// resolve symbols
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix};
|
use crate::ast::node::{CompilationUnit, Identifier, UseStatement, UseStatementSuffix};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
|
use crate::name_analysis::symbol::use_symbol::UseSymbol;
|
||||||
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
|
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
|
||||||
use crate::name_analysis::util::use_statement_base_fqn;
|
use crate::name_analysis::util::use_statement_base_fqn;
|
||||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||||
@ -47,18 +48,28 @@ fn nap2_use_statement(
|
|||||||
diagnostics: &mut Vec<DmDiagnostic>,
|
diagnostics: &mut Vec<DmDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let base_fqn = use_statement_base_fqn(use_statement);
|
let base_fqn = use_statement_base_fqn(use_statement);
|
||||||
|
|
||||||
let mut handle_concrete_use_symbol = |identifier: &Identifier| {
|
let mut handle_concrete_use_symbol = |identifier: &Identifier| {
|
||||||
let fqn = format!("{}::{}", base_fqn, identifier.name());
|
let fqn = format!("{}::{}", base_fqn, identifier.name());
|
||||||
if let Err(error) = symbol_table.resolve_usable_by_fqn(&fqn) {
|
match symbol_table.resolve_concrete_usable_by_fqn(&fqn) {
|
||||||
handle_lookup_error(
|
Ok(resolved_symbol) => match *use_statement.use_symbol().unwrap().borrow() {
|
||||||
error,
|
UseSymbol::Concrete(ref concrete_use_symbol) => {
|
||||||
&fqn,
|
concrete_use_symbol
|
||||||
use_statement.file_id(),
|
.borrow_mut()
|
||||||
use_statement.range(),
|
.set_resolved_symbol(resolved_symbol);
|
||||||
"Usable Symbol",
|
}
|
||||||
diagnostics,
|
_ => panic!("Unexpected symbol type"),
|
||||||
);
|
},
|
||||||
|
Err(lookup_error) => {
|
||||||
|
handle_lookup_error(
|
||||||
|
lookup_error,
|
||||||
|
&fqn,
|
||||||
|
use_statement.file_id(),
|
||||||
|
use_statement.range(),
|
||||||
|
"Usable Symbol",
|
||||||
|
diagnostics,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -4,26 +4,30 @@ pub(crate) mod module_symbol;
|
|||||||
pub(crate) mod parameter_symbol;
|
pub(crate) mod parameter_symbol;
|
||||||
pub(crate) mod source_definition;
|
pub(crate) mod source_definition;
|
||||||
pub(crate) mod type_symbol;
|
pub(crate) mod type_symbol;
|
||||||
|
pub(crate) mod usable_symbol;
|
||||||
pub(crate) mod use_symbol;
|
pub(crate) mod use_symbol;
|
||||||
pub(crate) mod variable_symbol;
|
pub(crate) mod variable_symbol;
|
||||||
|
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::type_symbol::ConcreteTypeSymbol;
|
||||||
|
use crate::name_analysis::symbol::use_symbol::UseSymbol;
|
||||||
use class_member_symbol::ClassMemberSymbol;
|
use class_member_symbol::ClassMemberSymbol;
|
||||||
use function_symbol::FunctionSymbol;
|
use function_symbol::FunctionSymbol;
|
||||||
use module_symbol::ModuleSymbol;
|
use module_symbol::ModuleSymbol;
|
||||||
use parameter_symbol::ParameterSymbol;
|
use parameter_symbol::ParameterSymbol;
|
||||||
use source_definition::SourceDefinition;
|
use source_definition::SourceDefinition;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::rc::Rc;
|
||||||
use type_symbol::TypeSymbol;
|
use type_symbol::TypeSymbol;
|
||||||
use variable_symbol::VariableSymbol;
|
use variable_symbol::VariableSymbol;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Symbol {
|
pub enum Symbol {
|
||||||
ConcreteUse(ConcreteUseSymbol),
|
Use(UseSymbol),
|
||||||
StarUse(StarUseSymbol),
|
|
||||||
Module(ModuleSymbol),
|
Module(ModuleSymbol),
|
||||||
Type(TypeSymbol),
|
Type(TypeSymbol),
|
||||||
|
ConcreteType(Rc<RefCell<ConcreteTypeSymbol>>),
|
||||||
Function(FunctionSymbol),
|
Function(FunctionSymbol),
|
||||||
Parameter(ParameterSymbol),
|
Parameter(ParameterSymbol),
|
||||||
Variable(VariableSymbol),
|
Variable(VariableSymbol),
|
||||||
@ -31,16 +35,18 @@ pub enum Symbol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Symbol {
|
impl Symbol {
|
||||||
pub fn definition(&self) -> Option<&SourceDefinition> {
|
pub fn definition(&self) -> Option<SourceDefinition> {
|
||||||
match self {
|
match self {
|
||||||
Symbol::ConcreteUse(concrete) => concrete.source_definition(),
|
Symbol::Use(use_symbol) => use_symbol.source_definition(),
|
||||||
Symbol::StarUse(star) => star.source_definition(),
|
Symbol::Module(module) => module.source_definition().cloned(),
|
||||||
Symbol::Module(module) => module.source_definition(),
|
Symbol::Type(type_symbol) => type_symbol.source_definition().cloned(),
|
||||||
Symbol::Type(type_symbol) => type_symbol.source_definition(),
|
Symbol::ConcreteType(concrete_type_symbol) => concrete_type_symbol.borrow().source_definition().cloned(),
|
||||||
Symbol::Function(function_symbol) => function_symbol.source_definition(),
|
Symbol::Function(function_symbol) => function_symbol.source_definition().cloned(),
|
||||||
Symbol::Parameter(parameter_symbol) => parameter_symbol.source_definition(),
|
Symbol::Parameter(parameter_symbol) => parameter_symbol.source_definition().cloned(),
|
||||||
Symbol::Variable(variable_symbol) => variable_symbol.source_definition(),
|
Symbol::Variable(variable_symbol) => variable_symbol.source_definition().cloned(),
|
||||||
Symbol::ClassMember(class_member_symbol) => class_member_symbol.source_definition(),
|
Symbol::ClassMember(class_member_symbol) => {
|
||||||
|
class_member_symbol.source_definition().cloned()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/name_analysis/symbol/usable_symbol.rs
Normal file
10
src/name_analysis/symbol/usable_symbol.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::name_analysis::symbol::type_symbol::{ConcreteTypeSymbol, TypeSymbol};
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum ConcreteUsableSymbol {
|
||||||
|
Type(Rc<RefCell<ConcreteTypeSymbol>>),
|
||||||
|
Function(Rc<RefCell<FunctionSymbol>>),
|
||||||
|
}
|
||||||
@ -1,11 +1,30 @@
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
|
use crate::name_analysis::symbol::usable_symbol::ConcreteUsableSymbol;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum UseSymbol {
|
||||||
|
Concrete(Rc<RefCell<ConcreteUseSymbol>>),
|
||||||
|
Star(StarUseSymbol),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UseSymbol {
|
||||||
|
pub fn source_definition(&self) -> Option<SourceDefinition> {
|
||||||
|
match self {
|
||||||
|
UseSymbol::Concrete(concrete) => concrete.borrow().source_definition().cloned(),
|
||||||
|
UseSymbol::Star(star) => star.source_definition().cloned(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ConcreteUseSymbol {
|
pub struct ConcreteUseSymbol {
|
||||||
base_fqn: String,
|
base_fqn: String,
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
source_definition: Option<SourceDefinition>,
|
source_definition: Option<SourceDefinition>,
|
||||||
|
resolved_symbol: Option<ConcreteUsableSymbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConcreteUseSymbol {
|
impl ConcreteUseSymbol {
|
||||||
@ -18,6 +37,7 @@ impl ConcreteUseSymbol {
|
|||||||
base_fqn: base_fqn.to_string(),
|
base_fqn: base_fqn.to_string(),
|
||||||
declared_name: declared_name.to_string(),
|
declared_name: declared_name.to_string(),
|
||||||
source_definition,
|
source_definition,
|
||||||
|
resolved_symbol: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +52,14 @@ impl ConcreteUseSymbol {
|
|||||||
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
pub fn source_definition(&self) -> Option<&SourceDefinition> {
|
||||||
self.source_definition.as_ref()
|
self.source_definition.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolved_symbol(&self) -> Option<&ConcreteUsableSymbol> {
|
||||||
|
self.resolved_symbol.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_resolved_symbol(&mut self, symbol: ConcreteUsableSymbol) {
|
||||||
|
self.resolved_symbol = Some(symbol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ConcreteUseSymbol {
|
impl Debug for ConcreteUseSymbol {
|
||||||
|
|||||||
@ -2,15 +2,19 @@ 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::parameter_symbol::ParameterSymbol;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::ConcreteTypeSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::usable_symbol::ConcreteUsableSymbol;
|
||||||
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol, UseSymbol};
|
||||||
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
use crate::name_analysis::symbol::variable_symbol::VariableSymbol;
|
||||||
use crate::name_analysis::symbol::*;
|
use crate::name_analysis::symbol::*;
|
||||||
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 crate::name_analysis::symbol_table::SymbolLookupError::NoDefinition;
|
||||||
use scope::Scope;
|
use scope::Scope;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
mod scope;
|
mod scope;
|
||||||
|
|
||||||
@ -44,13 +48,14 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_scope(&mut self, debug_name: &str) {
|
pub fn push_scope(&mut self, debug_name: &str) {
|
||||||
let id = self.scopes.len();
|
let id_to_push = self.scopes.len();
|
||||||
self.scopes.push(Scope::new(
|
self.scopes.push(Scope::new(
|
||||||
Some(self.current_scope_id),
|
Some(self.current_scope_id),
|
||||||
id,
|
id_to_push,
|
||||||
debug_name.to_string(),
|
debug_name.to_string(),
|
||||||
));
|
));
|
||||||
self.current_scope_id = id;
|
self.current_scope_mut().add_child(id_to_push);
|
||||||
|
self.current_scope_id = id_to_push;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop_scope(&mut self) {
|
pub fn pop_scope(&mut self) {
|
||||||
@ -70,20 +75,17 @@ impl SymbolTable {
|
|||||||
fn find_current_scope_concrete_use_symbol(
|
fn find_current_scope_concrete_use_symbol(
|
||||||
&self,
|
&self,
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
) -> Option<&ConcreteUseSymbol> {
|
) -> Option<Rc<RefCell<ConcreteUseSymbol>>> {
|
||||||
self.current_scope()
|
self.current_scope()
|
||||||
.concrete_use_symbols()
|
.concrete_use_symbols()
|
||||||
.get(declared_name)
|
.get(declared_name)
|
||||||
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_current_scope_star_use_symbol(&self, base_fqn: &str) -> Option<&StarUseSymbol> {
|
fn find_current_scope_star_use_symbol(&self, base_fqn: &str) -> Option<&StarUseSymbol> {
|
||||||
self.current_scope().star_use_symbols().get(base_fqn)
|
self.current_scope().star_use_symbols().get(base_fqn)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_current_scope_type_symbol(&self, declared_name: &str) -> Option<&TypeSymbol> {
|
|
||||||
self.current_scope().type_symbols().get(declared_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_current_scope_module_symbol(&self, declared_name: &str) -> Option<&ModuleSymbol> {
|
fn find_current_scope_module_symbol(&self, declared_name: &str) -> Option<&ModuleSymbol> {
|
||||||
self.current_scope().module_symbols().get(declared_name)
|
self.current_scope().module_symbols().get(declared_name)
|
||||||
}
|
}
|
||||||
@ -119,11 +121,13 @@ impl SymbolTable {
|
|||||||
|
|
||||||
fn find_current_scope_usable_symbol(&self, declared_name: &str) -> Option<Symbol> {
|
fn find_current_scope_usable_symbol(&self, declared_name: &str) -> Option<Symbol> {
|
||||||
self.find_current_scope_concrete_use_symbol(declared_name)
|
self.find_current_scope_concrete_use_symbol(declared_name)
|
||||||
.map(|concrete_use_symbol| Symbol::ConcreteUse(concrete_use_symbol.clone()))
|
.map(|concrete_use_symbol| {
|
||||||
.or_else(|| {
|
Symbol::Use(UseSymbol::Concrete(concrete_use_symbol.clone()))
|
||||||
self.find_current_scope_type_symbol(declared_name)
|
|
||||||
.map(|type_symbol| Symbol::Type(type_symbol.clone()))
|
|
||||||
})
|
})
|
||||||
|
// .or_else(|| {
|
||||||
|
// self.find_current_scope_type_symbol(declared_name)
|
||||||
|
// .map(|type_symbol| Symbol::Type(type_symbol.clone()))
|
||||||
|
// })
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.find_current_scope_module_symbol(declared_name)
|
self.find_current_scope_module_symbol(declared_name)
|
||||||
.map(|module_symbol| Symbol::Module(module_symbol.clone()))
|
.map(|module_symbol| Symbol::Module(module_symbol.clone()))
|
||||||
@ -133,17 +137,22 @@ impl SymbolTable {
|
|||||||
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<(), SymbolInsertError> {
|
) -> Result<Rc<RefCell<ConcreteUseSymbol>>, SymbolInsertError> {
|
||||||
if let Some(defined_symbol) =
|
if let Some(defined_symbol) =
|
||||||
self.find_current_scope_usable_symbol(concrete_use_symbol.declared_name())
|
self.find_current_scope_usable_symbol(concrete_use_symbol.declared_name())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
Err(SymbolAlreadyDefined(defined_symbol))
|
||||||
} else {
|
} else {
|
||||||
self.current_scope_mut().concrete_use_symbols_mut().insert(
|
let name = concrete_use_symbol.declared_name().to_string();
|
||||||
concrete_use_symbol.declared_name().to_string(),
|
self.current_scope_mut()
|
||||||
concrete_use_symbol,
|
.concrete_use_symbols_mut()
|
||||||
);
|
.insert(name.clone(), Rc::new(RefCell::new(concrete_use_symbol)));
|
||||||
Ok(())
|
Ok(self
|
||||||
|
.current_scope()
|
||||||
|
.concrete_use_symbols()
|
||||||
|
.get(&name)
|
||||||
|
.cloned()
|
||||||
|
.unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,9 +163,9 @@ impl SymbolTable {
|
|||||||
if let Some(defined_symbol) =
|
if let Some(defined_symbol) =
|
||||||
self.find_current_scope_star_use_symbol(star_use_symbol.base_fqn())
|
self.find_current_scope_star_use_symbol(star_use_symbol.base_fqn())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(Symbol::StarUse(
|
Err(SymbolAlreadyDefined(Symbol::Use(UseSymbol::Star(
|
||||||
defined_symbol.clone(),
|
defined_symbol.clone(),
|
||||||
)))
|
))))
|
||||||
} else {
|
} else {
|
||||||
self.current_scope_mut()
|
self.current_scope_mut()
|
||||||
.star_use_symbols_mut()
|
.star_use_symbols_mut()
|
||||||
@ -181,15 +190,23 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_type_symbol(&mut self, type_symbol: TypeSymbol) -> Result<(), SymbolInsertError> {
|
fn find_current_scope_concrete_type_symbol(
|
||||||
if let Some(defined_symbol) =
|
&self,
|
||||||
self.find_current_scope_usable_symbol(type_symbol.declared_name())
|
declared_name: &str,
|
||||||
|
) -> Option<Rc<RefCell<ConcreteTypeSymbol>>> {
|
||||||
|
self.current_scope().get_concrete_type_symbol(declared_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_concrete_type_symbol(
|
||||||
|
&mut self,
|
||||||
|
symbol: ConcreteTypeSymbol,
|
||||||
|
) -> Result<(), SymbolInsertError> {
|
||||||
|
if let Some(defined_type) =
|
||||||
|
self.find_current_scope_concrete_type_symbol(symbol.declared_name())
|
||||||
{
|
{
|
||||||
Err(SymbolAlreadyDefined(defined_symbol))
|
Err(SymbolAlreadyDefined(Symbol::ConcreteType(defined_type)))
|
||||||
} else {
|
} else {
|
||||||
self.current_scope_mut()
|
self.current_scope_mut().insert_concrete_type_symbol(symbol);
|
||||||
.type_symbols_mut()
|
|
||||||
.insert(type_symbol.declared_name().to_string(), type_symbol);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,66 +281,6 @@ impl SymbolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_type_in_scope_by_declared_name<'a>(
|
|
||||||
scope: &'a Scope,
|
|
||||||
declared_name: &str,
|
|
||||||
) -> Option<&'a TypeSymbol> {
|
|
||||||
scope.type_symbols().get(declared_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_type_by_declared_name(
|
|
||||||
&self,
|
|
||||||
declared_name: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<&TypeSymbol, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(symbol) = Self::lookup_type_in_scope_by_declared_name(scope, declared_name)
|
|
||||||
{
|
|
||||||
return Ok(symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent() {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lookup_type_in_scope_by_fqn<'a>(scope: &'a Scope, fqn: &str) -> Option<&'a TypeSymbol> {
|
|
||||||
for type_symbol in scope.type_symbols().values() {
|
|
||||||
match type_symbol {
|
|
||||||
TypeSymbol::Concrete(concrete_type_symbol) => {
|
|
||||||
if concrete_type_symbol.fqn() == fqn {
|
|
||||||
return Some(type_symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TypeSymbol::Generic(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lookup_type_by_fqn(
|
|
||||||
&self,
|
|
||||||
fqn: &str,
|
|
||||||
scope_id: usize,
|
|
||||||
) -> Result<&TypeSymbol, SymbolLookupError> {
|
|
||||||
let mut scope_opt = Some(&self.scopes[scope_id]);
|
|
||||||
while let Some(scope) = scope_opt {
|
|
||||||
if let Some(type_symbol) = Self::lookup_type_in_scope_by_fqn(scope, fqn) {
|
|
||||||
return Ok(type_symbol);
|
|
||||||
}
|
|
||||||
scope_opt = if let Some(parent_id) = scope.parent() {
|
|
||||||
Some(&self.scopes[parent_id])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Err(NoDefinition)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lookup_addressable_in_scope_by_identifier(
|
fn lookup_addressable_in_scope_by_identifier(
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
identifier: &str,
|
identifier: &str,
|
||||||
@ -350,12 +307,12 @@ impl SymbolTable {
|
|||||||
.get(identifier)
|
.get(identifier)
|
||||||
.map(|function_symbol| Symbol::Function(function_symbol.clone()))
|
.map(|function_symbol| Symbol::Function(function_symbol.clone()))
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
// .or_else(|| {
|
||||||
scope
|
// scope
|
||||||
.type_symbols()
|
// .type_symbols()
|
||||||
.get(identifier)
|
// .get(identifier)
|
||||||
.map(|type_symbol| Symbol::Type(type_symbol.clone()))
|
// .map(|type_symbol| Symbol::Type(type_symbol.clone()))
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lookup_addressable_by_identifier(
|
pub fn lookup_addressable_by_identifier(
|
||||||
@ -378,17 +335,36 @@ impl SymbolTable {
|
|||||||
Err(NoDefinition)
|
Err(NoDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_usable_by_fqn(
|
pub fn resolve_concrete_usable_by_fqn(
|
||||||
&self,
|
&self,
|
||||||
fqn: &str
|
fqn: &str,
|
||||||
) -> Result<Symbol, SymbolLookupError> {
|
) -> Result<ConcreteUsableSymbol, SymbolLookupError> {
|
||||||
todo!()
|
// breadth-first search, use a queue
|
||||||
|
let mut search_stack: VecDeque<usize> = VecDeque::new();
|
||||||
|
search_stack.push_back(0); // global scope
|
||||||
|
|
||||||
|
while let Some(scope_id) = search_stack.pop_front() {
|
||||||
|
let scope = &self.scopes[scope_id];
|
||||||
|
for child_id in scope.children() {
|
||||||
|
search_stack.push_back(child_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(concrete_type_symbol) = scope.get_concrete_type_symbol_by_fqn(fqn) {
|
||||||
|
return Ok(ConcreteUsableSymbol::Type(concrete_type_symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: this is inefficient. Use a (cached) hash table of Fqn => Rc<RefCell<symbol>>
|
||||||
|
for function_symbol in scope.function_symbols().values() {
|
||||||
|
if function_symbol.fqn() == fqn {
|
||||||
|
return Ok(ConcreteUsableSymbol::Function(todo!()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(NoDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_usable_star(
|
pub fn resolve_usable_star(&self, base_fqn: &str) -> Result<(), SymbolLookupError> {
|
||||||
&self,
|
|
||||||
base_fqn: &str,
|
|
||||||
) -> Result<(), SymbolLookupError> {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,20 +2,24 @@ 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::parameter_symbol::ParameterSymbol;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::{ConcreteTypeSymbol, 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::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Scope {
|
pub struct Scope {
|
||||||
parent: Option<usize>,
|
parent: Option<usize>,
|
||||||
id: usize,
|
id: usize,
|
||||||
concrete_use_symbols: HashMap<String, ConcreteUseSymbol>,
|
children: Vec<usize>,
|
||||||
|
concrete_use_symbols: HashMap<String, Rc<RefCell<ConcreteUseSymbol>>>,
|
||||||
star_use_symbols: HashMap<String, StarUseSymbol>,
|
star_use_symbols: HashMap<String, StarUseSymbol>,
|
||||||
module_symbols: HashMap<String, ModuleSymbol>,
|
module_symbols: HashMap<String, ModuleSymbol>,
|
||||||
type_symbols: HashMap<String, TypeSymbol>,
|
concrete_type_symbols: HashMap<String, Rc<RefCell<ConcreteTypeSymbol>>>,
|
||||||
|
concrete_type_symbols_by_fqn: HashMap<String, Rc<RefCell<ConcreteTypeSymbol>>>,
|
||||||
function_symbols: HashMap<String, FunctionSymbol>,
|
function_symbols: HashMap<String, FunctionSymbol>,
|
||||||
parameter_symbols: HashMap<String, ParameterSymbol>,
|
parameter_symbols: HashMap<String, ParameterSymbol>,
|
||||||
variable_symbols: HashMap<String, VariableSymbol>,
|
variable_symbols: HashMap<String, VariableSymbol>,
|
||||||
@ -28,10 +32,12 @@ impl Scope {
|
|||||||
Self {
|
Self {
|
||||||
parent,
|
parent,
|
||||||
id,
|
id,
|
||||||
|
children: vec![],
|
||||||
concrete_use_symbols: HashMap::new(),
|
concrete_use_symbols: HashMap::new(),
|
||||||
star_use_symbols: HashMap::new(),
|
star_use_symbols: HashMap::new(),
|
||||||
module_symbols: HashMap::new(),
|
module_symbols: HashMap::new(),
|
||||||
type_symbols: HashMap::new(),
|
concrete_type_symbols: HashMap::new(),
|
||||||
|
concrete_type_symbols_by_fqn: 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(),
|
||||||
@ -48,11 +54,21 @@ impl Scope {
|
|||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn concrete_use_symbols(&self) -> &HashMap<String, ConcreteUseSymbol> {
|
pub fn add_child(&mut self, child_id: usize) {
|
||||||
|
self.children.push(child_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn children(&self) -> Vec<usize> {
|
||||||
|
self.children.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn concrete_use_symbols(&self) -> &HashMap<String, Rc<RefCell<ConcreteUseSymbol>>> {
|
||||||
&self.concrete_use_symbols
|
&self.concrete_use_symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn concrete_use_symbols_mut(&mut self) -> &mut HashMap<String, ConcreteUseSymbol> {
|
pub fn concrete_use_symbols_mut(
|
||||||
|
&mut self,
|
||||||
|
) -> &mut HashMap<String, Rc<RefCell<ConcreteUseSymbol>>> {
|
||||||
&mut self.concrete_use_symbols
|
&mut self.concrete_use_symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,12 +88,24 @@ impl Scope {
|
|||||||
&mut self.module_symbols
|
&mut self.module_symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_symbols(&self) -> &HashMap<String, TypeSymbol> {
|
pub fn insert_concrete_type_symbol(&mut self, symbol: ConcreteTypeSymbol) {
|
||||||
&self.type_symbols
|
let as_rc = Rc::new(RefCell::new(symbol));
|
||||||
|
self.concrete_type_symbols.insert(
|
||||||
|
as_rc.borrow().declared_name().to_string(),
|
||||||
|
as_rc.clone(),
|
||||||
|
);
|
||||||
|
self.concrete_type_symbols_by_fqn.insert(
|
||||||
|
as_rc.borrow().fqn().to_string(),
|
||||||
|
as_rc.clone(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_symbols_mut(&mut self) -> &mut HashMap<String, TypeSymbol> {
|
pub fn get_concrete_type_symbol(&self, declared_name: &str) -> Option<Rc<RefCell<ConcreteTypeSymbol>>> {
|
||||||
&mut self.type_symbols
|
self.concrete_type_symbols.get(declared_name).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_concrete_type_symbol_by_fqn(&self, fqn: &str) -> Option<Rc<RefCell<ConcreteTypeSymbol>>> {
|
||||||
|
self.concrete_type_symbols_by_fqn.get(fqn).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn function_symbols(&self) -> &HashMap<String, FunctionSymbol> {
|
pub fn function_symbols(&self) -> &HashMap<String, FunctionSymbol> {
|
||||||
@ -131,13 +159,15 @@ impl Display for Scope {
|
|||||||
f,
|
f,
|
||||||
"----Scope {} (p: {}) {}----",
|
"----Scope {} (p: {}) {}----",
|
||||||
self.id(),
|
self.id(),
|
||||||
self.parent().map(|parent_id| format!("{}", parent_id)).unwrap_or_else(|| "None".to_string()),
|
self.parent()
|
||||||
|
.map(|parent_id| format!("{}", parent_id))
|
||||||
|
.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());
|
||||||
write_symbols!(f, self.star_use_symbols());
|
write_symbols!(f, self.star_use_symbols());
|
||||||
write_symbols!(f, self.module_symbols());
|
write_symbols!(f, self.module_symbols());
|
||||||
write_symbols!(f, self.type_symbols());
|
todo!("self.concrete_type_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());
|
||||||
|
|||||||
@ -248,6 +248,10 @@ UseStatement:
|
|||||||
- range:
|
- range:
|
||||||
special:
|
special:
|
||||||
kind: range
|
kind: range
|
||||||
|
fields:
|
||||||
|
- use_symbol:
|
||||||
|
kind: UseSymbol
|
||||||
|
wrap: rc_ref_cell
|
||||||
UseStatementPrefix:
|
UseStatementPrefix:
|
||||||
struct:
|
struct:
|
||||||
children:
|
children:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user