use crate::ast::type_use::TypeUse; use crate::diagnostic::Diagnostic; use crate::source_range::SourceRange; use crate::symbol::ParameterSymbol; use crate::symbol_table::{SymbolInsertError, SymbolTable}; use crate::type_info::TypeInfo; use std::cell::RefCell; use std::rc::Rc; pub struct Parameter { declared_name: String, 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> { let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new( &self.declared_name, TypeInfo::from_declared_name(self.type_use.declared_name()), )); match insert_result { Ok(parameter_symbol) => { self.parameter_symbol = Some(parameter_symbol.clone()); Ok(parameter_symbol) } Err(symbol_insert_error) => match symbol_insert_error { SymbolInsertError::AlreadyDeclared(already_declared) => Err(vec![Diagnostic::new( &format!("Parameter {} already declared.", already_declared.name()), self.declared_name_source_range.start(), self.declared_name_source_range.end(), )]), }, } } pub fn check_name_usages( &mut self, _symbol_table: &SymbolTable, ) -> Result<(), Vec> { Ok(()) // no-op for now } 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") } }