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, declared_name_source_range: SourceRange, extends: Vec, scope_id: Option, generic_parameter_symbol: Option>>, } impl GenericParameter { pub fn new( declared_name: &str, declared_name_source_range: SourceRange, extends: Vec, ) -> 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 { 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> { // 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> { let mut diagnostics: Vec = 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) } }