deimos-lang/src/name_analysis/util.rs
2025-11-01 21:38:52 -05:00

76 lines
2.5 KiB
Rust

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<usize>,
diagnostics: &mut Vec<DmDiagnostic>,
) {
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<usize>,
diagnostics: &mut Vec<DmDiagnostic>,
) {
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<str>]) -> String {
format_fqn(&parts.iter().map(|part| part.as_ref()).collect::<Vec<_>>())
}
pub fn str_slice_to_rcs(str_slice: &[&str]) -> Vec<Rc<str>> {
str_slice.iter().map(|s| Rc::from(*s)).collect::<Vec<_>>()
}