use crate::diagnostic::DmDiagnostic; use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolLookupError}; use codespan_reporting::diagnostic::{Diagnostic, Label}; use std::range::Range; use std::rc::Rc; pub fn handle_insert_error( err: SymbolInsertError, error_symbol_name: &str, error_file_id: usize, error_range: Range, diagnostics: &mut Vec, ) { match err { SymbolInsertError::SymbolAlreadyDefined(s) => { let mut diagnostic = Diagnostic::error() .with_message(format!( "Symbol '{}' already defined in the current scope.", error_symbol_name, )) .with_label( Label::primary(error_file_id, error_range) .with_message("Symbol duplicated here."), ); if let Some(source_definition) = s.borrow().source_definition() { diagnostic = diagnostic.with_label( Label::secondary(source_definition.file_id(), source_definition.range()) .with_message("Symbol defined here."), ); } diagnostics.push(diagnostic); } } } pub fn handle_lookup_error( err: SymbolLookupError, error_symbol_name: &str, error_file_id: usize, error_range: Range, diagnostics: &mut Vec, ) { match err { SymbolLookupError::NoDefinition => { let diagnostic = Diagnostic::error() .with_message(format!("No such symbol '{}' in scope.", error_symbol_name)) .with_label( Label::primary(error_file_id, error_range).with_message("Symbol used here."), ); diagnostics.push(diagnostic); } SymbolLookupError::NoSuchNamespace => { let diagnostic = Diagnostic::error() .with_message(format!("No such namespace '{}' found", error_symbol_name)) .with_label( Label::primary(error_file_id, error_range).with_message("Namespace used here."), ); diagnostics.push(diagnostic); } } } pub fn format_fqn(parts: &[&str]) -> String { parts.join("::") } pub fn join_fqn_parts(parts: &[Rc]) -> String { format_fqn(&parts.iter().map(|part| part.as_ref()).collect::>()) } pub fn str_slice_to_rcs(str_slice: &[&str]) -> Vec> { str_slice.iter().map(|s| Rc::from(*s)).collect::>() }