120 lines
3.8 KiB
Rust
120 lines
3.8 KiB
Rust
use crate::diagnostic::{Diagnostic, SecondaryLabel};
|
|
use crate::error_codes::{
|
|
CLASS_NO_CONSTRUCTOR, FIELD_NO_TYPE_OR_INIT, OUTER_CLASS_FIELD_USED_IN_INIT,
|
|
OUTER_CLASS_METHOD_USED_IN_INIT, SELF_CONSTRUCTOR_USED_IN_INIT, SELF_FIELD_USED_IN_INIT,
|
|
SELF_METHOD_USED_IN_INIT, SYMBOL_ALREADY_DECLARED, SYMBOL_NOT_FOUND,
|
|
};
|
|
use crate::source_range::SourceRange;
|
|
use crate::symbol::Symbol;
|
|
|
|
pub fn symbol_not_found(name: &str, source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
&format!("Symbol {} not found in scope.", name),
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(SYMBOL_NOT_FOUND)
|
|
}
|
|
|
|
pub fn field_has_no_type_or_init(name: &str, source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
&format!("Field {} has no declared type nor initializer.", name),
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(FIELD_NO_TYPE_OR_INIT)
|
|
.with_primary_label_message("Declare a type and/or an initializer.")
|
|
}
|
|
|
|
pub fn cannot_reference_field_in_init(name: &str, source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
&format!("Cannot reference field {} during initialization.", name),
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(SELF_FIELD_USED_IN_INIT)
|
|
}
|
|
|
|
pub fn symbol_already_declared(already_inserted: &Symbol, would_insert: &Symbol) -> Diagnostic {
|
|
let secondary_label = if let Some(source_range) = already_inserted.declared_name_source_range()
|
|
{
|
|
Some(SecondaryLabel::new(
|
|
source_range.start(),
|
|
source_range.end(),
|
|
Some("Symbol already declared here.".to_string()),
|
|
))
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let diagnostic = Diagnostic::new(
|
|
&format!(
|
|
"Symbol {} already declared in current scope.",
|
|
would_insert.declared_name()
|
|
),
|
|
would_insert.declared_name_source_range().unwrap().start(), // unwrap should be okay, since this is user code
|
|
would_insert.declared_name_source_range().unwrap().end(),
|
|
)
|
|
.with_error_code(SYMBOL_ALREADY_DECLARED);
|
|
|
|
if let Some(secondary_label) = secondary_label {
|
|
diagnostic.with_secondary_labels(&[secondary_label])
|
|
} else {
|
|
diagnostic
|
|
}
|
|
}
|
|
|
|
pub fn self_constructor_used_in_init(source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
"Cannot call Self constructor during initialization.",
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(SELF_CONSTRUCTOR_USED_IN_INIT)
|
|
}
|
|
|
|
pub fn self_field_used_in_init(source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
"Cannot reference Self field during initialization.",
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(SELF_FIELD_USED_IN_INIT)
|
|
}
|
|
|
|
pub fn self_method_used_in_init(source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
"Cannot call Self method during initialization.",
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(SELF_METHOD_USED_IN_INIT)
|
|
}
|
|
|
|
pub fn outer_class_field_usage(source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
"Cannot reference an outer class member.",
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(OUTER_CLASS_FIELD_USED_IN_INIT)
|
|
}
|
|
|
|
pub fn outer_class_method_usage(source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
"Cannot call an outer class method.",
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(OUTER_CLASS_METHOD_USED_IN_INIT)
|
|
}
|
|
|
|
pub fn class_has_no_constructor(name: &str, source_range: &SourceRange) -> Diagnostic {
|
|
Diagnostic::new(
|
|
&format!("Class {} has no constructor.", name),
|
|
source_range.start(),
|
|
source_range.end(),
|
|
)
|
|
.with_error_code(CLASS_NO_CONSTRUCTOR)
|
|
}
|