mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-11-22 20:35:20 +00:00
feat: resolve definitions with dynamic analysis (#1904)
Some checks failed
tinymist::ci / Duplicate Actions Detection (push) Has been cancelled
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Has been cancelled
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Has been cancelled
tinymist::ci / prepare-build (push) Has been cancelled
tinymist::gh_pages / build-gh-pages (push) Has been cancelled
tinymist::ci / build-vsc-assets (push) Has been cancelled
tinymist::ci / build-vscode (push) Has been cancelled
tinymist::ci / build-vscode-others (push) Has been cancelled
tinymist::ci / publish-vscode (push) Has been cancelled
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-2022) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Has been cancelled
tinymist::ci / build-binary (push) Has been cancelled
Some checks failed
tinymist::ci / Duplicate Actions Detection (push) Has been cancelled
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Has been cancelled
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Has been cancelled
tinymist::ci / prepare-build (push) Has been cancelled
tinymist::gh_pages / build-gh-pages (push) Has been cancelled
tinymist::ci / build-vsc-assets (push) Has been cancelled
tinymist::ci / build-vscode (push) Has been cancelled
tinymist::ci / build-vscode-others (push) Has been cancelled
tinymist::ci / publish-vscode (push) Has been cancelled
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-2022) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Has been cancelled
tinymist::ci / build-binary (push) Has been cancelled
* feat: dyn resolve targets * fix: test cases * feat: static analysis again based on dyn analysis result
This commit is contained in:
parent
35e8f447b0
commit
1359e9975b
11 changed files with 218 additions and 69 deletions
|
|
@ -10,6 +10,7 @@ use parking_lot::Mutex;
|
|||
use rustc_hash::FxHashMap;
|
||||
use tinymist_analysis::docs::DocString;
|
||||
use tinymist_analysis::stats::AllocStats;
|
||||
use tinymist_analysis::syntax::classify_def_loosely;
|
||||
use tinymist_analysis::ty::term_value;
|
||||
use tinymist_analysis::{analyze_expr_, analyze_import_};
|
||||
use tinymist_lint::LintInfo;
|
||||
|
|
@ -861,12 +862,68 @@ impl SharedContext {
|
|||
definition(self, source, doc, syntax)
|
||||
}
|
||||
|
||||
pub(crate) fn type_of_span(self: &Arc<Self>, span: Span) -> Option<Ty> {
|
||||
self.type_of_span_(&self.source_by_id(span.id()?).ok()?, span)
|
||||
pub(crate) fn def_of_syntax_or_dyn(
|
||||
self: &Arc<Self>,
|
||||
source: &Source,
|
||||
doc: Option<&TypstDocument>,
|
||||
syntax: SyntaxClass,
|
||||
) -> Option<Definition> {
|
||||
let def = self.def_of_syntax(source, doc, syntax.clone());
|
||||
match def.as_ref().map(|d| d.decl.kind()) {
|
||||
// todo: DefKind::Function
|
||||
Some(DefKind::Reference | DefKind::Module | DefKind::Function) => return def,
|
||||
Some(DefKind::Struct | DefKind::Constant | DefKind::Variable) | None => {}
|
||||
}
|
||||
|
||||
// Checks that we resolved a high-equality definition.
|
||||
let know_ty_well = def
|
||||
.as_ref()
|
||||
.and_then(|d| self.simplified_type_of_span(d.decl.span()))
|
||||
.filter(|ty| !matches!(ty, Ty::Any))
|
||||
.is_some();
|
||||
if know_ty_well {
|
||||
return def;
|
||||
}
|
||||
|
||||
let def_ref = def.as_ref();
|
||||
let def_name = || Some(def_ref?.name().clone());
|
||||
let dyn_def = self
|
||||
.analyze_expr(syntax.node())
|
||||
.iter()
|
||||
.find_map(|(value, _)| {
|
||||
let def = Definition::from_value(value.clone(), def_name)?;
|
||||
None.or_else(|| {
|
||||
let source = self.source_by_id(def.decl.file_id()?).ok()?;
|
||||
let node = LinkedNode::new(source.root()).find(def.decl.span())?;
|
||||
let def_at_the_span = classify_def_loosely(node)?;
|
||||
self.def_of_span(&source, doc, def_at_the_span.name()?.span())
|
||||
})
|
||||
.or(Some(def))
|
||||
});
|
||||
|
||||
// Uses the dynamic definition or the fallback definition.
|
||||
dyn_def.or(def)
|
||||
}
|
||||
|
||||
pub(crate) fn type_of_span_(self: &Arc<Self>, source: &Source, span: Span) -> Option<Ty> {
|
||||
self.type_check(source).type_of_span(span)
|
||||
pub(crate) fn simplified_type_of_span(self: &Arc<Self>, span: Span) -> Option<Ty> {
|
||||
let source = self.source_by_id(span.id()?).ok()?;
|
||||
let (ti, ty) = self.type_of_span_(&source, span)?;
|
||||
Some(ti.simplify(ty, false))
|
||||
}
|
||||
|
||||
pub(crate) fn type_of_span(self: &Arc<Self>, span: Span) -> Option<Ty> {
|
||||
let source = self.source_by_id(span.id()?).ok()?;
|
||||
Some(self.type_of_span_(&source, span)?.1)
|
||||
}
|
||||
|
||||
pub(crate) fn type_of_span_(
|
||||
self: &Arc<Self>,
|
||||
source: &Source,
|
||||
span: Span,
|
||||
) -> Option<(Arc<TypeInfo>, Ty)> {
|
||||
let ti = self.type_check(source);
|
||||
let ty = ti.type_of_span(span)?;
|
||||
Some((ti, ty))
|
||||
}
|
||||
|
||||
pub(crate) fn post_type_of_node(self: &Arc<Self>, node: LinkedNode) -> Option<Ty> {
|
||||
|
|
@ -889,6 +946,24 @@ impl SharedContext {
|
|||
super::sig_of_type(self, ti, ty)
|
||||
}
|
||||
|
||||
pub(crate) fn sig_of_type_or_dyn(
|
||||
self: &Arc<Self>,
|
||||
ti: &TypeInfo,
|
||||
callee_ty: Ty,
|
||||
callee: &SyntaxNode,
|
||||
) -> Option<Signature> {
|
||||
self.sig_of_type(ti, callee_ty).or_else(|| {
|
||||
self.analyze_expr(callee).iter().find_map(|(value, _)| {
|
||||
let Value::Func(callee) = value else {
|
||||
return None;
|
||||
};
|
||||
|
||||
// Converts with cache
|
||||
analyze_signature(self, SignatureTarget::Runtime(callee.clone()))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Try to find imported target from the current source file.
|
||||
/// This function will try to resolves target statically.
|
||||
///
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue