76 lines
2.5 KiB
Rust
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<_>>()
|
|
}
|