Skip to content

Working with diagnostics

hydroperfox edited this page Jul 20, 2024 · 1 revision

The parser typically takes a CompilationUnit and produces a program structure. Diagnostics are emitted to that CompilationUnit rather than being returned by the parser. You can obtain them as follows:

// Sorts the diagnostics, including these from files resolved from
// `IncludeDirective`.
compilation_unit.sort_diagnostics();

// diagnostics: Vec<Diagnostic>
// This includes diagnostics from files resolved from
// `IncludeDirective`.
let diagnostics = compilation_unit.nested_diagnostics();

// Formats the diagnostic with default English
for diagnostic in diagnostics {
    println!("{}", diagnostic.format_english());
}

Invalidation

A compilation unit is invalidated when it or any of its IncludeDirective files contain any errors:

// invalidated: bool
let invalidated = compilation_unit.invalidated();

Adding diagnostics

Adding a diagnostic to a CompilationUnit is a simple call, where K is the diagnostic kind:

// Syntax error
compilation_unit.add_diagnostic(Diagnostic::new_syntax_error(&location, DiagnosticKind::K, diagarg![]));

// Verify error
compilation_unit.add_diagnostic(Diagnostic::new_verify_error(&location, DiagnosticKind::K, diagarg![]));

// Warning
compilation_unit.add_diagnostic(Diagnostic::new_warning(&location, DiagnosticKind::K, diagarg![]));

The diagarg![] literal takes elements that implement the DiagnosticArgument trait.

Custom kinds

If you need to support your own messages, set the custom_kind field:

diagnostic.set_custom_kind(Some(Rc::new(kind)));

Where kind is an enumeration's variant. You may then later cast the custom kind from Rc<dyn Any> to your enumeration through .downcast::<MyEnum>().

If you want, for simple debugging purposes, you may finish formatting your own message with location information by using:

diagnostic.format_with_message("My message", Some(custom_id_number))

For real use cases, calling .format_with_message() is not preferred if your application is not solely in English, since it will add categories such as Warning.

Arguments

Diagnostics allow arbitrary argument data as long as it implements the DiagnosticArgument trait. The diagarg! literal autoboxes arguments in Rc::new(...).

To downcast to your data type, first make sure to have this attribute at the top of your crate:

#![feature(trait_upcasting)]

Then, use the following code snippet:

if let Ok(value) = Rc::downcast::<DataType>(arg.clone()) {
    // value: Rc<DataType>
}

Available IDs

The following range of IDs may be already in use by the parser:

  • 1024-1499

Any ID range out of this is safe to use for an application over AS3Parser.

Clone this wiki locally