94 lines
2.9 KiB
Rust
94 lines
2.9 KiB
Rust
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<str>,
|
|
declared_name_source_range: SourceRange,
|
|
type_use: TypeUse,
|
|
parameter_symbol: Option<Rc<RefCell<ParameterSymbol>>>,
|
|
}
|
|
|
|
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<Rc<RefCell<ParameterSymbol>>, Vec<Diagnostic>> {
|
|
// 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<RefCell<ClassSymbol>>>,
|
|
) -> Result<(), Vec<Diagnostic>> {
|
|
// 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<Diagnostic>> {
|
|
Ok(()) // no-op for now
|
|
}
|
|
|
|
pub fn parameter_symbol(&self) -> &Rc<RefCell<ParameterSymbol>> {
|
|
self.parameter_symbol
|
|
.as_ref()
|
|
.expect("parameter symbol not initialized")
|
|
}
|
|
}
|