use crate::ast::type_use::TypeUse; use crate::diagnostic::Diagnostic; use crate::source_range::SourceRange; use crate::symbol::class_symbol::ClassSymbol; use crate::symbol::parameter_symbol::ParameterSymbol; use crate::symbol_table::{SymbolInsertError, SymbolTable}; use std::cell::RefCell; use std::rc::Rc; pub struct Parameter { declared_name: Rc, declared_name_source_range: SourceRange, type_use: TypeUse, parameter_symbol: Option>>, } impl Parameter { pub fn new( declared_name: &str, declared_name_source_range: SourceRange, type_use: TypeUse, ) -> Self { Self { declared_name: declared_name.into(), declared_name_source_range, type_use, parameter_symbol: None, } } pub fn gather_declared_names( &mut self, symbol_table: &mut SymbolTable, ) -> Result>, Vec> { // insert parameter symbol let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new( &self.declared_name, self.declared_name_source_range.clone(), )); match insert_result { Ok(parameter_symbol) => { self.parameter_symbol = Some(parameter_symbol.clone()); } Err(symbol_insert_error) => { return match symbol_insert_error { SymbolInsertError::AlreadyDeclared(already_declared) => { Err(vec![Diagnostic::new( &format!( "Parameter {} already declared.", already_declared.symbol().borrow().declared_name() ), self.declared_name_source_range.start(), self.declared_name_source_range.end(), )]) } }; } } // type use self.type_use.gather_declared_names(symbol_table)?; Ok(self.parameter_symbol.clone().unwrap()) } pub fn check_name_usages( &mut self, symbol_table: &SymbolTable, class_context: Option<&Rc>>, ) -> Result<(), Vec> { // check the type use self.type_use .check_name_usages(symbol_table, class_context)?; // set type on parameter symbol self.parameter_symbol .as_mut() .unwrap() .borrow_mut() .set_type_info(self.type_use.type_info().clone()); Ok(()) } pub fn type_check(&mut self, _symbol_table: &SymbolTable) -> Result<(), Vec> { Ok(()) // no-op for now } pub fn parameter_symbol(&self) -> &Rc> { self.parameter_symbol .as_ref() .expect("parameter symbol not initialized") } }