mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-24 05:05:00 +00:00
fix: cyclic loop detection in cross-module def-use relation checking (#396)
This commit is contained in:
parent
1e424eca8a
commit
653789c1e6
2 changed files with 11 additions and 10 deletions
|
@ -123,7 +123,7 @@ impl DefUseInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_def_use_inner(
|
pub(super) fn get_def_use_inner(
|
||||||
ctx: &mut AnalysisContext,
|
ctx: &mut SearchCtx,
|
||||||
source: Source,
|
source: Source,
|
||||||
e: EcoVec<LexicalHierarchy>,
|
e: EcoVec<LexicalHierarchy>,
|
||||||
import: Arc<ImportInfo>,
|
import: Arc<ImportInfo>,
|
||||||
|
@ -154,8 +154,8 @@ pub(super) fn get_def_use_inner(
|
||||||
Some(Arc::new(collector.info))
|
Some(Arc::new(collector.info))
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DefUseCollector<'a, 'w> {
|
struct DefUseCollector<'a, 'b, 'w> {
|
||||||
ctx: &'a mut AnalysisContext<'w>,
|
ctx: &'a mut SearchCtx<'b, 'w>,
|
||||||
info: DefUseInfo,
|
info: DefUseInfo,
|
||||||
label_scope: SnapshotMap<String, DefId>,
|
label_scope: SnapshotMap<String, DefId>,
|
||||||
id_scope: SnapshotMap<String, DefId>,
|
id_scope: SnapshotMap<String, DefId>,
|
||||||
|
@ -165,7 +165,7 @@ struct DefUseCollector<'a, 'w> {
|
||||||
ext_src: Option<Source>,
|
ext_src: Option<Source>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'w> DefUseCollector<'a, 'w> {
|
impl<'a, 'b, 'w> DefUseCollector<'a, 'b, 'w> {
|
||||||
fn enter<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
|
fn enter<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||||
let id_snap = self.id_scope.snapshot();
|
let id_snap = self.id_scope.snapshot();
|
||||||
let res = f(self);
|
let res = f(self);
|
||||||
|
@ -186,7 +186,8 @@ impl<'a, 'w> DefUseCollector<'a, 'w> {
|
||||||
let source = self.ext_src.as_ref()?;
|
let source = self.ext_src.as_ref()?;
|
||||||
|
|
||||||
log::debug!("import for def use: {:?}, name: {name}", source.id());
|
log::debug!("import for def use: {:?}, name: {name}", source.id());
|
||||||
let (_, external_info) = Some(source.id()).zip(self.ctx.def_use(source.clone()))?;
|
let (_, external_info) =
|
||||||
|
Some(source.id()).zip(AnalysisContext::def_use_(self.ctx, source.clone()))?;
|
||||||
|
|
||||||
let ext_id = external_info.exports_defs.get(name)?;
|
let ext_id = external_info.exports_defs.get(name)?;
|
||||||
self.import_from(&external_info, *ext_id);
|
self.import_from(&external_info, *ext_id);
|
||||||
|
@ -252,8 +253,8 @@ impl<'a, 'w> DefUseCollector<'a, 'w> {
|
||||||
LexicalKind::Mod(LexicalModKind::Star) => {
|
LexicalKind::Mod(LexicalModKind::Star) => {
|
||||||
if let Some(source) = &self.ext_src {
|
if let Some(source) = &self.ext_src {
|
||||||
log::debug!("diving source for def use: {:?}", source.id());
|
log::debug!("diving source for def use: {:?}", source.id());
|
||||||
let (_, external_info) =
|
let (_, external_info) = Some(source.id())
|
||||||
Some(source.id()).zip(self.ctx.def_use(source.clone()))?;
|
.zip(AnalysisContext::def_use_(self.ctx, source.clone()))?;
|
||||||
|
|
||||||
for ext_id in &external_info.exports_refs {
|
for ext_id in &external_info.exports_refs {
|
||||||
self.import_from(&external_info, *ext_id);
|
self.import_from(&external_info, *ext_id);
|
||||||
|
|
|
@ -527,20 +527,20 @@ impl<'w> AnalysisContext<'w> {
|
||||||
|
|
||||||
let l = def_use_lexical_hierarchy(source.clone())?;
|
let l = def_use_lexical_hierarchy(source.clone())?;
|
||||||
let m = ctx.ctx.import_info(source.clone())?;
|
let m = ctx.ctx.import_info(source.clone())?;
|
||||||
let dep_hash = m
|
let deps = m
|
||||||
.imports
|
.imports
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|e| e.1)
|
.flat_map(|e| e.1)
|
||||||
.map(|e| Self::def_use_(ctx, e.clone()))
|
.map(|e| Self::def_use_(ctx, e.clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let key = (&source, &l, &m, dep_hash);
|
let key = (&source, &l, &m, deps);
|
||||||
let h = hash128(&key);
|
let h = hash128(&key);
|
||||||
|
|
||||||
let res = if let Some(res) = ctx.ctx.analysis.caches.def_use.get(&h) {
|
let res = if let Some(res) = ctx.ctx.analysis.caches.def_use.get(&h) {
|
||||||
res.1.clone()
|
res.1.clone()
|
||||||
} else {
|
} else {
|
||||||
let res = crate::analysis::get_def_use_inner(ctx.ctx, source, l, m);
|
let res = crate::analysis::get_def_use_inner(ctx, source, l, m);
|
||||||
ctx.ctx
|
ctx.ctx
|
||||||
.analysis
|
.analysis
|
||||||
.caches
|
.caches
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue