Struct DiagnosticEngine

Source
pub struct DiagnosticEngine<'a> {
    diagnostics: Vec<Diagnostic>,
    error_count: usize,
    warning_count: usize,
    max_errors: usize,
    recovery_mode: bool,
    file_name: Option<String>,
    source_text: Option<&'a str>,
}
Expand description

A diagnostic collection and reporting engine for compiler errors, warnings, and notes

The DiagnosticEngine serves as the central hub for collecting, managing, and reporting all kinds of diagnostic messages during compilation. It supports error recovery mode, rich formatting with source code context, and can emit diagnostics in various formats.

§Features

  • Collects errors, warnings, and notes with source location information
  • Supports error recovery mode for collecting multiple errors in one pass
  • Rich formatting with colored output and source code context
  • Configurable error limits to prevent overwhelming output
  • Integration with CompilerError for unified error handling

§Example

use slang_shared::DiagnosticEngine;
use slang_error::ErrorCode;
use slang_ir::location::Location;

let mut engine = DiagnosticEngine::new();
engine.set_file_name("example.sl".to_string());
engine.emit_error(
    ErrorCode::ExpectedSemicolon,
    "Missing semicolon".to_string(),
    Location::new(42, 5, 10, 1)
);

if engine.has_errors() {
    engine.report_all(&source_code);
}

Fields§

§diagnostics: Vec<Diagnostic>§error_count: usize§warning_count: usize§max_errors: usize§recovery_mode: bool§file_name: Option<String>§source_text: Option<&'a str>

Implementations§

Source§

impl<'a> DiagnosticEngine<'a>

Source

pub fn new() -> Self

Creates a new diagnostic engine with default settings

§Returns

A new DiagnosticEngine instance ready for collecting diagnostics

§Example
use slang_shared::DiagnosticEngine;

let engine = DiagnosticEngine::new();
Source

pub fn emit(&mut self, diagnostic: Diagnostic)

Emits a diagnostic message to the engine

This is the core method for adding diagnostics. It handles error counting, enforces error limits, and manages the diagnostic collection.

§Arguments
  • diagnostic - The diagnostic to emit
§Example
use slang_shared::{DiagnosticEngine, Diagnostic, ErrorSeverity};
use slang_error::ErrorCode;
use slang_ir::location::Location;

let mut engine = DiagnosticEngine::new();
let diagnostic = Diagnostic {
    severity: ErrorSeverity::Error,
    error_code: ErrorCode::ExpectedSemicolon,
    message: "Missing semicolon".to_string(),
    location: Location::new(42, 5, 10, 1),
    suggestions: Vec::new(),
    related: Vec::new(),
};
engine.emit(diagnostic);
Source

pub fn emit_error( &mut self, error_code: ErrorCode, message: String, location: Location, )

Emits an error diagnostic with the specified details

This is a convenience method for creating and emitting error diagnostics.

§Arguments
  • error_code - The structured error code
  • message - The error message
  • location - The source location where the error occurred
§Example
use slang_shared::DiagnosticEngine;
use slang_error::ErrorCode;
use slang_ir::location::Location;

let mut engine = DiagnosticEngine::new();
engine.emit_error(
    ErrorCode::ExpectedSemicolon,
    "Missing semicolon after statement".to_string(),
    Location::new(42, 5, 10, 1)
);
Source

pub fn emit_warning( &mut self, error_code: ErrorCode, message: String, location: Location, )

Emits a warning diagnostic with the specified details

This is a convenience method for creating and emitting warning diagnostics.

§Arguments
  • error_code - The structured error code
  • message - The warning message
  • location - The source location where the warning occurred
§Example
use slang_shared::DiagnosticEngine;
use slang_error::ErrorCode;
use slang_ir::location::Location;

let mut engine = DiagnosticEngine::new();
engine.emit_warning(
    ErrorCode::UnusedVariable,
    "Variable 'x' is declared but never used".to_string(),
    Location::new(15, 3, 5, 1)
);
Source

pub fn emit_with_suggestion( &mut self, error_code: ErrorCode, message: String, location: Location, suggestion: Suggestion, )

Emits an error diagnostic with a suggestion for fixing the issue

This is useful for providing actionable feedback to users about how to fix errors.

§Arguments
  • error_code - The structured error code
  • message - The error message
  • location - The source location where the error occurred
  • suggestion - A suggestion for fixing the error
§Example
use slang_shared::{DiagnosticEngine, Suggestion};
use slang_error::ErrorCode;
use slang_ir::location::Location;

let mut engine = DiagnosticEngine::new();
let suggestion = Suggestion {
    message: "Add a semicolon".to_string(),
    replacement: Some(";".to_string()),
    location: Some(Location::new(42, 5, 10, 0)),
};
engine.emit_with_suggestion(
    ErrorCode::ExpectedSemicolon,
    "Missing semicolon".to_string(),
    Location::new(42, 5, 10, 1),
    suggestion
);
Source

pub fn emit_compiler_error(&mut self, error: CompilerError)

Directly emits a CompilerError as a diagnostic

This method provides seamless integration with the existing CompilerError type, allowing for unified error handling across the compiler pipeline.

§Arguments
  • error - The CompilerError to emit as a diagnostic
§Example
use slang_shared::DiagnosticEngine;
use slang_error::{CompilerError, ErrorCode};

let mut engine = DiagnosticEngine::new();
let error = CompilerError::new(
    ErrorCode::ExpectedSemicolon,
    "Missing semicolon".to_string(),
    5, 10, 42, Some(1)
);
engine.emit_compiler_error(error);
Source

pub fn get_compiler_errors(&self) -> Vec<CompilerError>

Retrieves all error diagnostics as CompilerError instances

This method converts all error-level diagnostics back to CompilerError format, useful for interfacing with code that expects the traditional CompilerError type.

§Returns

A vector of CompilerError instances representing all errors collected

§Example
use slang_shared::DiagnosticEngine;
use slang_error::ErrorCode;
use slang_ir::location::Location;

let mut engine = DiagnosticEngine::new();
engine.emit_error(
    ErrorCode::ExpectedSemicolon,
    "Missing semicolon".to_string(),
    Location::new(42, 5, 10, 1)
);

let errors = engine.get_compiler_errors();
assert_eq!(errors.len(), 1);
Source

pub fn has_errors(&self) -> bool

Checks if any errors have been collected

§Returns

true if there are any error-level diagnostics, false otherwise

§Example
use slang_shared::DiagnosticEngine;

let mut engine = DiagnosticEngine::new();
assert!(!engine.has_errors());

// After emitting an error...
// assert!(engine.has_errors());
Source

pub fn error_count(&self) -> usize

Returns the total number of errors collected

§Returns

The count of error-level diagnostics

Source

pub fn warning_count(&self) -> usize

Returns the total number of warnings collected

§Returns

The count of warning-level diagnostics

Source

pub fn finish(self) -> Result<(), Vec<Diagnostic>>

Finishes diagnostic collection and returns the result

§Returns

Ok(()) if no errors were collected, otherwise Err with all diagnostics

Source

pub fn set_recovery_mode(&mut self, enabled: bool)

Enables or disables error recovery mode

In recovery mode, the compilation pipeline continues processing even after encountering errors, allowing multiple errors to be collected in a single pass.

§Arguments
  • enabled - Whether to enable recovery mode
Source

pub fn is_recovery_mode(&self) -> bool

Checks if error recovery mode is enabled

§Returns

true if recovery mode is enabled, false otherwise

Source

pub fn set_file_name(&mut self, file_name: String)

Sets the file name for better error reporting

§Arguments
  • file_name - The name of the file being compiled
Source

pub fn set_source_text(&mut self, source_text: &'a str)

Sets the source text for better error reporting

§Arguments
  • source_text - The source code being compiled
Source

pub fn set_max_errors(&mut self, max_errors: usize)

Sets the maximum number of errors before stopping compilation

§Arguments
  • max_errors - The maximum number of errors to collect
Source

pub fn into_errors(self) -> Vec<Diagnostic>

Consumes the engine and returns all collected diagnostics

§Returns

A vector containing all diagnostics that were collected

Source

pub fn report_all(&self, source: &str)

Reports all diagnostics to stderr with rich formatting

This method provides comprehensive error reporting with colored output, source code context, line numbers, and helpful suggestions.

§Arguments
  • source - The source code to display in error context
§Example
use slang_shared::DiagnosticEngine;

let engine = DiagnosticEngine::new();
// ... collect some diagnostics ...
engine.report_all(&source_code);
Source

fn emit_too_many_errors(&mut self)

Emits a “too many errors” diagnostic when the error limit is reached

This private method is called automatically when the error count reaches the configured maximum, helping to prevent overwhelming output in cases of cascading errors.

Source

fn report_diagnostic(&self, diagnostic: &Diagnostic, line_info: &LineInfo<'_>)

Formats and prints a single diagnostic with rich formatting

This private method handles the detailed formatting of individual diagnostics, including colored output, source code context, line markers, and suggestions.

§Arguments
  • diagnostic - The diagnostic to format and display
  • line_info - Line information for displaying source context
Source

fn report_summary(&self)

Prints a summary of all collected diagnostics

This private method displays a final summary showing the total count of errors and warnings encountered during compilation.

Source

pub fn take_diagnostics(&mut self) -> Vec<Diagnostic>

Removes and returns all collected diagnostics, resetting counters

This method provides a way to extract all diagnostics while clearing the internal state. Useful for batch processing or transferring diagnostics to another system.

§Returns

A vector containing all previously collected diagnostics

Trait Implementations§

Source§

impl Default for DiagnosticEngine<'_>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for DiagnosticEngine<'a>

§

impl<'a> RefUnwindSafe for DiagnosticEngine<'a>

§

impl<'a> Send for DiagnosticEngine<'a>

§

impl<'a> Sync for DiagnosticEngine<'a>

§

impl<'a> Unpin for DiagnosticEngine<'a>

§

impl<'a> UnwindSafe for DiagnosticEngine<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.