feat: fledge diagnostic hint patterns by updating 2 refiners (#1544)

* feat: support more diagnostic hint patterns about typst v0.13 deprecation

* feat: add out of root hint diagnostic refiner

* optimize multi-pattern search with `RegexSet`

* add "cannot spread content"

* fix test

* Revert "add "cannot spread content""

This reverts commit 7d6c981413.
This commit is contained in:
7mile 2025-03-20 14:30:35 +08:00 committed by GitHub
parent 766a41f4d5
commit 8d9a8f8bed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 103 additions and 8 deletions

View file

@ -5,6 +5,9 @@ use typst::syntax::Span;
use crate::{prelude::*, LspWorldExt};
use once_cell::sync::Lazy;
use regex::RegexSet;
/// Stores diagnostics for files.
pub type DiagnosticsMap = HashMap<Url, EcoVec<Diagnostic>>;
@ -64,7 +67,8 @@ fn convert_diagnostic(
let mut diag = Cow::Borrowed(typst_diagnostic);
// Extend more refiners here by adding their instances.
let refiners = &[&DeprecationRefiner::<13> {}];
let refiners: &[&dyn DiagnosticRefiner] =
&[&DeprecationRefiner::<13> {}, &OutOfRootHintRefiner {}];
// NOTE: It would be nice to have caching here.
for refiner in refiners {
@ -195,9 +199,19 @@ trait DiagnosticRefiner {
struct DeprecationRefiner<const MINOR: usize>();
static DEPRECATION_PATTERNS: Lazy<RegexSet> = Lazy::new(|| {
RegexSet::new([
r"unknown variable: style",
r"unexpected argument: fill",
r"type state has no method `display`",
r"only element functions can be used as selectors",
])
.expect("Invalid regular expressions")
});
impl DiagnosticRefiner for DeprecationRefiner<13> {
fn matches(&self, raw: &TypstDiagnostic) -> bool {
raw.message.contains("unknown variable: style")
DEPRECATION_PATTERNS.is_match(&raw.message)
}
fn refine(&self, raw: TypstDiagnostic) -> TypstDiagnostic {
@ -209,3 +223,20 @@ impl DiagnosticRefiner for DeprecationRefiner<13> {
))
}
}
struct OutOfRootHintRefiner();
impl DiagnosticRefiner for OutOfRootHintRefiner {
fn matches(&self, raw: &TypstDiagnostic) -> bool {
raw.message.contains("failed to load file (access denied)")
&& raw
.hints
.iter()
.any(|hint| hint.contains("cannot read file outside of project root"))
}
fn refine(&self, mut raw: TypstDiagnostic) -> TypstDiagnostic {
raw.hints.clear();
raw.with_hint("Cannot read file outside of project root.")
}
}