111 lines
3.4 KiB
Rust
111 lines
3.4 KiB
Rust
use crate::ast::NodesToSymbols;
|
|
use crate::ast::helpers::insert_resolved_names_into;
|
|
use crate::ast::type_use::TypeUse;
|
|
use crate::diagnostic::{Diagnostic, Diagnostics};
|
|
use crate::source_range::SourceRange;
|
|
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
|
use crate::symbol_table::SymbolTable;
|
|
use crate::type_info::TypeInfo;
|
|
use crate::types_table::TypesTable;
|
|
use crate::{diagnostics_result, handle_diagnostics};
|
|
use std::cell::RefCell;
|
|
use std::rc::Rc;
|
|
|
|
pub struct GenericParameter {
|
|
declared_name: Rc<str>,
|
|
declared_name_source_range: SourceRange,
|
|
extends: Vec<TypeUse>,
|
|
scope_id: Option<usize>,
|
|
generic_parameter_symbol: Option<Rc<RefCell<GenericParameterSymbol>>>,
|
|
}
|
|
|
|
impl GenericParameter {
|
|
pub fn new(
|
|
declared_name: &str,
|
|
declared_name_source_range: SourceRange,
|
|
extends: Vec<TypeUse>,
|
|
) -> Self {
|
|
Self {
|
|
declared_name: declared_name.into(),
|
|
declared_name_source_range,
|
|
extends,
|
|
scope_id: None,
|
|
generic_parameter_symbol: None,
|
|
}
|
|
}
|
|
|
|
pub fn init_scopes(&mut self, symbol_table: &mut SymbolTable, container_scope: usize) {
|
|
self.scope_id = Some(container_scope);
|
|
for type_use in &mut self.extends {
|
|
type_use.init_scopes(symbol_table, container_scope);
|
|
}
|
|
}
|
|
|
|
pub fn make_symbol(&self) -> GenericParameterSymbol {
|
|
GenericParameterSymbol::new(
|
|
&self.declared_name,
|
|
&self.declared_name_source_range,
|
|
self.scope_id.unwrap(),
|
|
)
|
|
}
|
|
|
|
pub fn resolve_names(&self, symbol_table: &SymbolTable) -> (NodesToSymbols, Diagnostics) {
|
|
let mut diagnostics = Diagnostics::new();
|
|
let mut names_table = NodesToSymbols::new();
|
|
|
|
for type_use in &self.extends {
|
|
let (ns, mut ds) = type_use.resolve_names(symbol_table);
|
|
insert_resolved_names_into(ns, &mut names_table);
|
|
diagnostics.append(&mut ds);
|
|
}
|
|
|
|
(names_table, diagnostics)
|
|
}
|
|
|
|
pub fn check_names(&self, symbol_table: &SymbolTable) -> Vec<Diagnostic> {
|
|
self.extends
|
|
.iter()
|
|
.flat_map(|type_use| type_use.check_names(symbol_table))
|
|
.collect()
|
|
}
|
|
|
|
pub fn gather_types(
|
|
&self,
|
|
symbol_table: &SymbolTable,
|
|
types_table: &mut TypesTable,
|
|
) -> Result<(), Vec<Diagnostic>> {
|
|
// self param
|
|
let generic_parameter_symbol = symbol_table
|
|
.get_generic_parameter_symbol_owned(self.scope_id.unwrap(), &self.declared_name)
|
|
.unwrap();
|
|
types_table.generic_parameter_types_mut().insert(
|
|
generic_parameter_symbol.clone(),
|
|
TypeInfo::GenericType(generic_parameter_symbol),
|
|
);
|
|
|
|
let mut diagnostics = Vec::new();
|
|
|
|
for type_use in &self.extends {
|
|
handle_diagnostics!(
|
|
type_use.gather_types(symbol_table, types_table),
|
|
diagnostics
|
|
);
|
|
}
|
|
|
|
diagnostics_result!(diagnostics)
|
|
}
|
|
|
|
pub fn type_check(
|
|
&mut self,
|
|
symbol_table: &SymbolTable,
|
|
types_table: &TypesTable,
|
|
) -> Result<(), Vec<Diagnostic>> {
|
|
let mut diagnostics: Vec<Diagnostic> = vec![];
|
|
// check extends type uses
|
|
for type_use in &mut self.extends {
|
|
handle_diagnostics!(type_use.type_check(symbol_table, types_table), diagnostics);
|
|
}
|
|
diagnostics_result!(diagnostics)
|
|
}
|
|
}
|