mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-03 17:58:17 +00:00
feat: pass world to linter (#1650)
This commit is contained in:
parent
9c98876dfb
commit
3d6c712565
6 changed files with 77 additions and 53 deletions
|
@ -669,10 +669,8 @@ mod lint_tests {
|
|||
fn test() {
|
||||
snapshot_testing("lint", &|ctx, path| {
|
||||
let source = ctx.source_by_path(&path).unwrap();
|
||||
let expr = ctx.expr_stage(&source);
|
||||
let ti = ctx.type_check(&source);
|
||||
|
||||
let result = tinymist_lint::lint_file(&expr, ti);
|
||||
let result = ctx.lint(&source);
|
||||
let result = crate::diagnostics::DiagWorker::new(ctx).convert_all(result.iter());
|
||||
let result = result
|
||||
.into_iter()
|
||||
|
|
|
@ -11,13 +11,16 @@ use rustc_hash::FxHashMap;
|
|||
use tinymist_analysis::stats::AllocStats;
|
||||
use tinymist_analysis::ty::term_value;
|
||||
use tinymist_analysis::{analyze_expr_, analyze_import_};
|
||||
use tinymist_lint::LintInfo;
|
||||
use tinymist_project::{LspComputeGraph, LspWorld};
|
||||
use tinymist_std::hash::{hash128, FxDashMap};
|
||||
use tinymist_std::typst::TypstDocument;
|
||||
use tinymist_world::debug_loc::DataSource;
|
||||
use tinymist_world::vfs::{PathResolution, WorkspaceResolver};
|
||||
use tinymist_world::{EntryReader, DETACHED_ENTRY};
|
||||
use typst::diag::{eco_format, At, FileError, FileResult, SourceResult, StrResult};
|
||||
use typst::diag::{
|
||||
eco_format, At, FileError, FileResult, SourceDiagnostic, SourceResult, StrResult,
|
||||
};
|
||||
use typst::foundations::{Bytes, IntoValue, Module, StyleChain, Styles};
|
||||
use typst::introspection::Introspector;
|
||||
use typst::layout::Position;
|
||||
|
@ -463,6 +466,10 @@ impl LocalContext {
|
|||
cache.get_or_init(|| self.shared.type_check(source)).clone()
|
||||
}
|
||||
|
||||
pub(crate) fn lint(&mut self, source: &Source) -> EcoVec<SourceDiagnostic> {
|
||||
self.shared.lint(source).diagnostics
|
||||
}
|
||||
|
||||
/// Get the type check information of a source file.
|
||||
pub(crate) fn type_check_by_id(&mut self, id: TypstFileId) -> Arc<TypeInfo> {
|
||||
let cache = &self.caches.modules.entry(id).or_default().type_check;
|
||||
|
@ -759,17 +766,9 @@ impl SharedContext {
|
|||
let ei = self.expr_stage(source);
|
||||
let guard = self.query_stat(source.id(), "type_check");
|
||||
self.slot.type_check.compute(hash128(&ei), |prev| {
|
||||
let cache_hit = prev.and_then(|prev| {
|
||||
// todo: recursively check changed scheme type
|
||||
if prev.revision != ei.revision {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(prev)
|
||||
});
|
||||
|
||||
if let Some(prev) = cache_hit {
|
||||
return prev.clone();
|
||||
// todo: recursively check changed scheme type
|
||||
if let Some(cache_hint) = prev.filter(|prev| prev.revision == ei.revision) {
|
||||
return cache_hint;
|
||||
}
|
||||
|
||||
guard.miss();
|
||||
|
@ -777,6 +776,17 @@ impl SharedContext {
|
|||
})
|
||||
}
|
||||
|
||||
/// Get the lint result of a source file.
|
||||
pub(crate) fn lint(self: &Arc<Self>, source: &Source) -> LintInfo {
|
||||
let ei = self.expr_stage(source);
|
||||
let ti = self.type_check(source);
|
||||
let guard = self.query_stat(source.id(), "lint");
|
||||
self.slot.lint.compute(hash128(&(&ei, &ti)), |_prev| {
|
||||
guard.miss();
|
||||
tinymist_lint::lint_file(&self.world, &ei, ti)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn type_of_func(self: &Arc<Self>, func: Func) -> Signature {
|
||||
crate::log_debug_ct!("convert runtime func {func:?}");
|
||||
analyze_signature(self, SignatureTarget::Convert(func)).unwrap()
|
||||
|
@ -1180,6 +1190,7 @@ impl RevisionManagerLike for AnalysisRevCache {
|
|||
fn gc(&mut self, rev: usize) {
|
||||
self.manager.gc(rev);
|
||||
|
||||
// todo: the following code are time consuming.
|
||||
{
|
||||
let mut max_ei = FxHashMap::default();
|
||||
let es = self.default_slot.expr_stage.global.lock();
|
||||
|
@ -1199,6 +1210,16 @@ impl RevisionManagerLike for AnalysisRevCache {
|
|||
}
|
||||
ts.retain(|_, r| r.1.revision == *max_ti.get(&r.1.fid).unwrap_or(&0));
|
||||
}
|
||||
|
||||
{
|
||||
let mut max_li = FxHashMap::default();
|
||||
let ts = self.default_slot.lint.global.lock();
|
||||
for r in ts.iter() {
|
||||
let rev: &mut usize = max_li.entry(r.1.fid).or_default();
|
||||
*rev = (*rev).max(r.1.revision);
|
||||
}
|
||||
ts.retain(|_, r| r.1.revision == *max_li.get(&r.1.fid).unwrap_or(&0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1222,6 +1243,7 @@ impl AnalysisRevCache {
|
|||
revision: slot.revision,
|
||||
expr_stage: slot.data.expr_stage.crawl(revision.get()),
|
||||
type_check: slot.data.type_check.crawl(revision.get()),
|
||||
lint: slot.data.lint.crawl(revision.get()),
|
||||
})
|
||||
.unwrap_or_else(|| self.default_slot.clone())
|
||||
})
|
||||
|
@ -1254,6 +1276,7 @@ struct AnalysisRevSlot {
|
|||
revision: usize,
|
||||
expr_stage: IncrCacheMap<u128, ExprInfo>,
|
||||
type_check: IncrCacheMap<u128, Arc<TypeInfo>>,
|
||||
lint: IncrCacheMap<u128, LintInfo>,
|
||||
}
|
||||
|
||||
impl Drop for AnalysisRevSlot {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use tinymist_analysis::ty::TypeInfo;
|
||||
use tinymist_project::LspWorld;
|
||||
use tinymist_world::vfs::WorkspaceResolver;
|
||||
use typst::{diag::SourceDiagnostic, syntax::Span};
|
||||
use typst::syntax::Span;
|
||||
|
||||
use crate::{analysis::Analysis, prelude::*, syntax::ExprInfo, LspWorldExt};
|
||||
use crate::{analysis::Analysis, prelude::*, LspWorldExt};
|
||||
|
||||
use regex::RegexSet;
|
||||
|
||||
|
@ -57,13 +56,9 @@ impl<'w> DiagWorker<'w> {
|
|||
let Ok(source) = self.ctx.world.source(dep) else {
|
||||
continue;
|
||||
};
|
||||
let expr = self.ctx.expr_stage(&source);
|
||||
let ti = self.ctx.type_check(&source);
|
||||
let res = lint_file(&expr, ti);
|
||||
if !res.is_empty() {
|
||||
for diag in res {
|
||||
self.handle(&diag);
|
||||
}
|
||||
|
||||
for diag in self.ctx.lint(&source) {
|
||||
self.handle(&diag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,8 +241,3 @@ impl DiagnosticRefiner for OutOfRootHintRefiner {
|
|||
raw.with_hint("Cannot read file outside of project root.")
|
||||
}
|
||||
}
|
||||
|
||||
#[comemo::memoize]
|
||||
fn lint_file(source: &ExprInfo, ti: Arc<TypeInfo>) -> EcoVec<SourceDiagnostic> {
|
||||
tinymist_lint::lint_file(source, ti)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue