use crate::ir::SourceLocation;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Severity {
Error,
Warning,
Info,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Diagnostic {
pub file: String,
pub line: u32,
pub column: u32,
#[serde(default)]
pub length: Option<u32>,
pub severity: Severity,
pub code: String,
pub message: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub targets: Vec<String>,
}
impl Diagnostic {
pub fn error(source: &SourceLocation, code: &str, message: String) -> Self {
Self {
file: source.file.clone(),
line: source.line,
column: source.column,
length: source.length,
severity: Severity::Error,
code: code.to_string(),
message,
targets: vec![],
}
}
pub fn warning(source: &SourceLocation, code: &str, message: String) -> Self {
Self {
file: source.file.clone(),
line: source.line,
column: source.column,
length: source.length,
severity: Severity::Warning,
code: code.to_string(),
message,
targets: vec![],
}
}
pub fn info(source: &SourceLocation, code: &str, message: String) -> Self {
Self {
file: source.file.clone(),
line: source.line,
column: source.column,
length: source.length,
severity: Severity::Info,
code: code.to_string(),
message,
targets: vec![],
}
}
pub fn with_targets(mut self, targets: Vec<String>) -> Self {
self.targets = targets;
self
}
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Diagnostics {
pub diagnostics: Vec<Diagnostic>,
}
impl Diagnostics {
pub fn new() -> Self {
Self::default()
}
pub fn add(&mut self, diagnostic: Diagnostic) {
self.diagnostics.push(diagnostic);
}
pub fn has_errors(&self) -> bool {
self.diagnostics
.iter()
.any(|d| d.severity == Severity::Error)
}
pub fn for_target(&self, target: &str) -> Vec<&Diagnostic> {
self.diagnostics
.iter()
.filter(|d| d.targets.is_empty() || d.targets.contains(&target.to_string()))
.collect()
}
}
pub const ERR_UNKNOWN_TYPE: &str = "unknown-type";
pub const ERR_PARSE_FAILURE: &str = "parse-failure";
pub const ERR_DUPLICATE_NAME: &str = "duplicate-name";
pub const ERR_INVALID_IDENTIFIER: &str = "invalid-identifier";
pub const ERR_TYPE_MISMATCH: &str = "type-mismatch";
pub const ERR_NAMING_CONVENTION: &str = "naming-convention";
pub const ERR_INVALID_ENUM_VARIANT: &str = "invalid-enum-variant";
pub const ERR_OVERFLOW: &str = "overflow";
pub const ERR_BYTE_OVERFLOW: &str = "byte-overflow";
pub const ERR_CIRCULAR_NAMESPACE: &str = "circular-namespace";
pub const WARN_UNSAFE_INTEGER: &str = "js-unsafe-integer";
pub const WARN_DURATION_PRECISION: &str = "duration-precision";
pub const WARN_KEYWORD_COLLISION: &str = "keyword-collision";
pub const WARN_UNUSED_NAMESPACE: &str = "unused-namespace";
pub const INFO_DEPRECATED: &str = "deprecated";
pub const INFO_STYLE: &str = "style";