-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce
Diagnostic
type and remove ariadne from public API (#963)
Part of or might close #804 Rather than coming up with perfect API that ties everything together, let's start with the `Diagnostic` and iterate from there.
- Loading branch information
Showing
47 changed files
with
784 additions
and
268 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@nomicfoundation/slang": minor | ||
--- | ||
|
||
Introduce a `Diagnostic` API for compiler errors, warnings etc. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use crate::text_index::TextRange; | ||
|
||
/// The severity of a diagnostic. | ||
/// | ||
/// Explicitly compatible with the [LSP protocol](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticSeverity). | ||
#[repr(u8)] | ||
pub enum Severity { | ||
Error = 1, | ||
Warning = 2, | ||
Information = 3, | ||
Hint = 4, | ||
} | ||
|
||
/// A compiler diagnostic that can be rendered to a user. | ||
pub trait Diagnostic { | ||
/// The character range of the source that this diagnostic applies to. | ||
/// at the moment. | ||
fn text_range(&self) -> TextRange; | ||
/// The severity of this diagnostic. | ||
fn severity(&self) -> Severity; | ||
/// The primary message associated with this diagnostic. | ||
fn message(&self) -> String; | ||
} | ||
|
||
#[cfg(feature = "__private_ariadne")] | ||
pub fn render<D: Diagnostic>(error: &D, source_id: &str, source: &str, with_color: bool) -> String { | ||
use ariadne::{Color, Config, Label, Report, ReportKind, Source}; | ||
|
||
let (kind, color) = match error.severity() { | ||
Severity::Error => (ReportKind::Error, Color::Red), | ||
Severity::Warning => (ReportKind::Warning, Color::Yellow), | ||
Severity::Information => (ReportKind::Advice, Color::Blue), | ||
Severity::Hint => (ReportKind::Advice, Color::Blue), | ||
}; | ||
|
||
let message = error.message(); | ||
|
||
if source.is_empty() { | ||
return format!("{kind}: {message}\n ─[{source_id}:0:0]"); | ||
} | ||
|
||
let color = if with_color { color } else { Color::Unset }; | ||
|
||
let range = { | ||
let start = source[..error.text_range().start.utf8].chars().count(); | ||
let end = source[..error.text_range().end.utf8].chars().count(); | ||
start..end | ||
}; | ||
|
||
let report = Report::build(kind, source_id, range.start) | ||
.with_config(Config::default().with_color(with_color)) | ||
.with_message(message) | ||
.with_label( | ||
Label::new((source_id, range)) | ||
.with_color(color) | ||
.with_message("Error occurred here."), | ||
) | ||
.finish(); | ||
|
||
let mut result = vec![]; | ||
report | ||
.write((source_id, Source::from(&source)), &mut result) | ||
.expect("Failed to write report"); | ||
|
||
return String::from_utf8(result) | ||
.expect("Failed to convert report to utf8") | ||
.trim() | ||
.to_string(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
crates/codegen/runtime/cargo/src/runtime/napi_interface/diagnostic.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
use napi_derive::napi; | ||
|
||
use crate::napi_interface::text_index::TextRange; | ||
|
||
/// Severity of the compiler diagnostic. | ||
/// | ||
/// Explicitly compatible with the LSP protocol. | ||
#[napi(namespace = "diagnostic")] | ||
pub enum Severity { | ||
Error = 1, | ||
Warning = 2, | ||
Information = 3, | ||
Hint = 4, | ||
} | ||
|
||
impl From<crate::diagnostic::Severity> for Severity { | ||
fn from(value: crate::diagnostic::Severity) -> Severity { | ||
match value { | ||
crate::diagnostic::Severity::Error => Self::Error, | ||
crate::diagnostic::Severity::Warning => Self::Warning, | ||
crate::diagnostic::Severity::Information => Self::Information, | ||
crate::diagnostic::Severity::Hint => Self::Hint, | ||
} | ||
} | ||
} | ||
|
||
/// A compiler diagnostic that can be rendered to a user. | ||
#[napi(namespace = "diagnostic")] | ||
pub struct Diagnostic(pub(crate) Box<dyn crate::diagnostic::Diagnostic>); | ||
|
||
#[napi(namespace = "diagnostic")] | ||
impl Diagnostic { | ||
/// The severity of this diagnostic. | ||
#[napi] | ||
pub fn severity(&self) -> Severity { | ||
self.0.severity().into() | ||
} | ||
|
||
/// The character range of the source that this diagnostic applies to. | ||
#[napi(ts_return_type = "text_index.TextRange")] | ||
pub fn text_range(&self) -> TextRange { | ||
self.0.text_range().into() | ||
} | ||
|
||
/// The primary message associated with this diagnostic. | ||
#[napi] | ||
pub fn message(&self) -> String { | ||
self.0.message() | ||
} | ||
} | ||
|
||
/// Exposes the [`Diagnostic`](crate::diagnostic::Diagnostic) methods implemented for a given type | ||
/// as regular N-API functions, satisfying the custom `DiagnosticInterface` interface on the N-API side. | ||
// NOTE(#987): This is required because we can't directly expose the trait using `#[napi]` or expose | ||
// an interface that has only methods defined. | ||
// To not require explicit conversions, we define the interface ourselves and expose the relevant methods to satisfy it. | ||
#[macro_export] | ||
macro_rules! expose_diagnostic_trait_interface { | ||
($namespace:literal, $diagnostic:ty) => { | ||
#[napi(namespace = $namespace)] | ||
impl $diagnostic { | ||
#[napi(ts_return_type = "diagnostic.Severity", catch_unwind)] | ||
pub fn severity(&self) -> $crate::napi_interface::diagnostic::Severity { | ||
$crate::diagnostic::Diagnostic::severity(&self.0).into() | ||
} | ||
|
||
#[napi(ts_return_type = "text_index.TextRange", catch_unwind)] | ||
pub fn text_range(&self) -> $crate::napi_interface::text_index::TextRange { | ||
$crate::diagnostic::Diagnostic::text_range(&self.0).into() | ||
} | ||
|
||
#[napi] | ||
pub fn message(&self) -> String { | ||
$crate::diagnostic::Diagnostic::message(&self.0) | ||
} | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
pub mod cst; | ||
pub mod cursor; | ||
pub mod diagnostic; | ||
pub mod parse_error; | ||
pub mod parse_output; | ||
pub mod query; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.