use crate::Compiler::AST::Position;
use crate::Compiler::Core::SectionEnhancers::{
QualifiedIdentifierKey, QualifiedIdentifierResolution,
};
use std::collections::HashMap;
pub mod enums_section_analyzer;
pub mod dlm_section_analyzer;
pub mod security_section_analyzer;
pub mod data_section_analyzer;
pub mod quickfuncs_section_analyzer;
pub mod imports_section_analyzer;
pub use enums_section_analyzer::EnumsSectionAnalyzer;
pub use dlm_section_analyzer::DlmSectionAnalyzer;
pub use security_section_analyzer::SecuritySectionAnalyzer;
pub use data_section_analyzer::DataSectionAnalyzer;
pub use quickfuncs_section_analyzer::QuickFuncsSectionAnalyzer;
pub use imports_section_analyzer::ImportsSectionAnalyzer;
#[derive(Debug, Clone)]
pub struct SectionAnalysisResult {
pub section_name: String,
pub is_success: bool,
pub errors: Vec<SemanticErrorInfo>,
pub warnings: Vec<SemanticWarningInfo>,
pub qualified_id_resolutions: HashMap<QualifiedIdentifierKey, QualifiedIdentifierResolution>,
}
impl SectionAnalysisResult {
pub fn new(section_name: impl Into<String>) -> Self {
SectionAnalysisResult {
section_name: section_name.into(),
is_success: false,
errors: Vec::new(),
warnings: Vec::new(),
qualified_id_resolutions: HashMap::new(),
}
}
pub fn has_errors(&self) -> bool {
!self.errors.is_empty()
}
pub fn has_warnings(&self) -> bool {
!self.warnings.is_empty()
}
pub fn total_issues(&self) -> usize {
self.errors.len() + self.warnings.len()
}
}
#[derive(Debug, Clone)]
pub struct SemanticErrorInfo {
pub error_id: String,
pub error_type: String,
pub message: String,
pub section_name: String,
pub suggestion: String,
pub position: Option<Position>,
}
impl SemanticErrorInfo {
pub fn new(
error_id: impl Into<String>,
error_type: impl Into<String>,
message: impl Into<String>,
section_name: impl Into<String>,
suggestion: impl Into<String>,
position: Option<Position>,
) -> Self {
SemanticErrorInfo {
error_id: error_id.into(),
error_type: error_type.into(),
message: message.into(),
section_name: section_name.into(),
suggestion: suggestion.into(),
position,
}
}
}
impl std::fmt::Display for SemanticErrorInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"[{}] {} in @{}: {}",
self.error_id, self.error_type, self.section_name, self.message
)?;
if !self.suggestion.is_empty() {
write!(f, "\n Suggestion: {}", self.suggestion)?;
}
if let Some(pos) = self.position {
write!(f, "\n at line {}, column {}", pos.line, pos.column)?;
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct SemanticWarningInfo {
pub warning_id: String,
pub message: String,
pub section_name: String,
pub position: Option<Position>,
}
impl SemanticWarningInfo {
pub fn new(
warning_id: impl Into<String>,
message: impl Into<String>,
section_name: impl Into<String>,
position: Option<Position>,
) -> Self {
SemanticWarningInfo {
warning_id: warning_id.into(),
message: message.into(),
section_name: section_name.into(),
position,
}
}
}
impl std::fmt::Display for SemanticWarningInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"[{}] {} in @{}",
self.warning_id, self.message, self.section_name
)?;
if let Some(pos) = self.position {
write!(f, " at line {}, column {}", pos.line, pos.column)?;
}
Ok(())
}
}
pub fn success_result(section_name: impl Into<String>) -> SectionAnalysisResult {
let mut result = SectionAnalysisResult::new(section_name);
result.is_success = true;
result
}
pub fn failure_result(
section_name: impl Into<String>,
errors: Vec<SemanticErrorInfo>,
) -> SectionAnalysisResult {
let mut result = SectionAnalysisResult::new(section_name);
result.is_success = false;
result.errors = errors;
result
}
pub fn warning_result(
section_name: impl Into<String>,
warnings: Vec<SemanticWarningInfo>,
) -> SectionAnalysisResult {
let mut result = SectionAnalysisResult::new(section_name);
result.is_success = true;
result.warnings = warnings;
result
}
pub trait SectionAnalyzer {
type Section;
fn analyze(
&mut self,
section: &Self::Section,
symbol_table: &mut crate::Compiler::Utilities::SymbolTable,
) -> SectionAnalysisResult;
fn analyzer_name(&self) -> &'static str;
}
pub type AnalyzerResult = SectionAnalysisResult;