use picostr for identifiers

This commit is contained in:
PgBiel 2024-07-22 11:57:39 -03:00
parent c4c7cfc714
commit 5d60e48057
5 changed files with 28 additions and 61 deletions

View File

@ -9,6 +9,7 @@ use std::string::FromUtf8Error;
use comemo::Tracked; use comemo::Tracked;
use ecow::{eco_vec, EcoVec}; use ecow::{eco_vec, EcoVec};
use typst_utils::PicoStr;
use crate::syntax::package::{PackageSpec, PackageVersion}; use crate::syntax::package::{PackageSpec, PackageVersion};
use crate::syntax::{ast, Span, Spanned, SyntaxError}; use crate::syntax::{ast, Span, Spanned, SyntaxError};
@ -116,14 +117,14 @@ macro_rules! __error {
macro_rules! __warning { macro_rules! __warning {
( (
$span:expr, $span:expr,
$id:ident, id: $id:expr,
$fmt:literal $(, $arg:expr)* message: $fmt:literal $(, $arg:expr)*
$(; hint: $hint:literal $(, $hint_arg:expr)*)* $(; hint: $hint:literal $(, $hint_arg:expr)*)*
$(,)? $(,)?
) => { ) => {
$crate::diag::SourceDiagnostic::warning( $crate::diag::SourceDiagnostic::warning(
$span, $span,
::std::option::Option::Some($crate::diag::CompilerWarning::$id), $id,
$crate::diag::eco_format!($fmt, $($arg),*), $crate::diag::eco_format!($fmt, $($arg),*),
) $(.with_hint($crate::diag::eco_format!($hint, $($hint_arg),*)))* ) $(.with_hint($crate::diag::eco_format!($hint, $($hint_arg),*)))*
}; };
@ -161,7 +162,9 @@ pub struct SourceDiagnostic {
/// The span of the relevant node in the source code. /// The span of the relevant node in the source code.
pub span: Span, pub span: Span,
/// The identifier for this diagnostic. /// The identifier for this diagnostic.
pub identifier: Option<Identifier>, ///
/// Currently, this field is only used by warnings.
pub identifier: Option<PicoStr>,
/// A diagnostic message describing the problem. /// A diagnostic message describing the problem.
pub message: EcoString, pub message: EcoString,
/// The trace of function calls leading to the problem. /// The trace of function calls leading to the problem.
@ -196,13 +199,13 @@ impl SourceDiagnostic {
/// Create a new, bare warning. /// Create a new, bare warning.
pub fn warning( pub fn warning(
span: Span, span: Span,
identifier: Option<CompilerWarning>, identifier: impl Into<PicoStr>,
message: impl Into<EcoString>, message: impl Into<EcoString>,
) -> Self { ) -> Self {
Self { Self {
severity: Severity::Warning, severity: Severity::Warning,
span, span,
identifier: identifier.map(Identifier::Warn), identifier: Some(identifier.into()),
trace: eco_vec![], trace: eco_vec![],
message: message.into(), message: message.into(),
hints: eco_vec![], hints: eco_vec![],
@ -240,49 +243,6 @@ impl From<SyntaxError> for SourceDiagnostic {
} }
} }
/// The identifier of a [`SourceDiagnostic`].
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum Identifier {
/// Identifier for a built-in compiler warning.
Warn(CompilerWarning),
/// Identifier for a warning raised by a package.
User(EcoString),
}
/// Built-in compiler warnings.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum CompilerWarning {
UnnecessaryImportRenaming,
UnnecessaryStars,
UnnecessaryUnderscores,
NonConvergingLayout,
UnknownFontFamilies,
}
impl CompilerWarning {
/// The name of the warning as a string, following the format of diagnostic
/// identifiers.
pub const fn name(&self) -> &'static str {
match self {
CompilerWarning::UnnecessaryImportRenaming => "unnecessary-import-renaming",
CompilerWarning::UnnecessaryStars => "unnecessary-stars",
CompilerWarning::UnnecessaryUnderscores => "unnecessary-underscores",
CompilerWarning::NonConvergingLayout => "non-converging-layout",
CompilerWarning::UnknownFontFamilies => "unknown-font-families",
}
}
}
impl Identifier {
/// The identifier's name, e.g. 'unnecessary-stars'.
pub fn name(&self) -> &str {
match self {
Self::Warn(warning_identifier) => warning_identifier.name(),
Self::User(user_identifier) => user_identifier,
}
}
}
/// A part of a diagnostic's [trace](SourceDiagnostic::trace). /// A part of a diagnostic's [trace](SourceDiagnostic::trace).
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Tracepoint { pub enum Tracepoint {
@ -529,6 +489,7 @@ pub fn deduplicate_and_suppress_warnings(
return true; return true;
}; };
let identifier = identifier.resolve();
let should_raise = !is_warning_suppressed(diag.span, world, identifier) let should_raise = !is_warning_suppressed(diag.span, world, identifier)
&& !diag.trace.iter().any(|tracepoint| { && !diag.trace.iter().any(|tracepoint| {
is_warning_suppressed(tracepoint.span, world, identifier) is_warning_suppressed(tracepoint.span, world, identifier)
@ -544,7 +505,7 @@ pub fn deduplicate_and_suppress_warnings(
/// in. If one of the ancestors of the node where the warning occurred has a /// in. If one of the ancestors of the node where the warning occurred has a
/// warning suppression annotation sibling right before it suppressing this /// warning suppression annotation sibling right before it suppressing this
/// particular warning, the warning is considered suppressed. /// particular warning, the warning is considered suppressed.
fn is_warning_suppressed(span: Span, world: &dyn World, warning: &Identifier) -> bool { fn is_warning_suppressed(span: Span, world: &dyn World, warning: &str) -> bool {
// Don't suppress detached warnings. // Don't suppress detached warnings.
let Some(source) = span.id().and_then(|file| world.source(file).ok()) else { let Some(source) = span.id().and_then(|file| world.source(file).ok()) else {
return false; return false;
@ -574,14 +535,14 @@ fn is_warning_suppressed(span: Span, world: &dyn World, warning: &Identifier) ->
/// identifier to be suppressed. /// identifier to be suppressed.
fn check_annotation_suppresses_warning( fn check_annotation_suppresses_warning(
annotation: ast::Annotation, annotation: ast::Annotation,
warning: &Identifier, warning: &str,
) -> bool { ) -> bool {
if annotation.name().as_str() != "allow" { if annotation.name().as_str() != "allow" {
return false; return false;
} }
for argument in annotation.arguments() { for argument in annotation.arguments() {
if warning.name() == argument.get() { if warning == argument.get() {
return true; return true;
} }
} }

View File

@ -37,8 +37,8 @@ impl Eval for ast::ModuleImport<'_> {
// Warn on `import x as x` // Warn on `import x as x`
vm.engine.sink.warn(warning!( vm.engine.sink.warn(warning!(
new_name.span(), new_name.span(),
UnnecessaryImportRenaming, id: "unnecessary-import-renaming",
"unnecessary import rename to same name", message: "unnecessary import rename to same name",
)); ));
} }
} }
@ -113,8 +113,8 @@ impl Eval for ast::ModuleImport<'_> {
{ {
vm.engine.sink.warn(warning!( vm.engine.sink.warn(warning!(
renamed_item.new_name().span(), renamed_item.new_name().span(),
UnnecessaryImportRenaming, id: "unnecessary-import-renaming",
"unnecessary import rename to same name", message: "unnecessary import rename to same name",
)); ));
} }
} }

View File

@ -136,7 +136,9 @@ impl Eval for ast::Strong<'_> {
vm.engine vm.engine
.sink .sink
.warn(warning!( .warn(warning!(
self.span(), UnnecessaryStars, "no text within stars"; self.span(),
id: "unnecessary-stars",
message: "no text within stars";
hint: "using multiple consecutive stars (e.g. **) has no additional effect", hint: "using multiple consecutive stars (e.g. **) has no additional effect",
)); ));
} }
@ -154,7 +156,9 @@ impl Eval for ast::Emph<'_> {
vm.engine vm.engine
.sink .sink
.warn(warning!( .warn(warning!(
self.span(), UnnecessaryUnderscores, "no text within underscores"; self.span(),
id: "unnecessary-underscores",
message: "no text within underscores";
hint: "using multiple consecutive underscores (e.g. __) has no additional effect" hint: "using multiple consecutive underscores (e.g. __) has no additional effect"
)); ));
} }

View File

@ -161,7 +161,9 @@ fn compile_inner(
if iter >= 5 { if iter >= 5 {
sink.warn(warning!( sink.warn(warning!(
Span::detached(), NonConvergingLayout, "layout did not converge within 5 attempts"; Span::detached(),
id: "non-converging-layout",
message: "layout did not converge within 5 attempts";
hint: "check if any states or queries are updating themselves" hint: "check if any states or queries are updating themselves"
)); ));
break; break;

View File

@ -134,8 +134,8 @@ pub struct TextElem {
if !book.contains_family(family.as_str()) { if !book.contains_family(family.as_str()) {
engine.sink.warn(warning!( engine.sink.warn(warning!(
font_list.span, font_list.span,
UnknownFontFamilies, id: "unknown-font-families",
"unknown font family: {}", message: "unknown font family: {}",
family.as_str(), family.as_str(),
)); ));
} }