From a09c068d1d07f5bfbb84c0c25dad8013a105d47d Mon Sep 17 00:00:00 2001 From: Myriad-Dreamin <35292584+Myriad-Dreamin@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:03:01 +0800 Subject: [PATCH] dev: prefer less uses of `analzer_expr` during definition analysis (#192) * dev: prefer less uses of `analzer_expr` during definition analysis * dev: improve pipeline of resolving syntactic definition --- .../tinymist-query/src/analysis/linked_def.rs | 78 +++++++------------ crates/tinymist-query/src/inlay_hint.rs | 5 +- 2 files changed, 30 insertions(+), 53 deletions(-) diff --git a/crates/tinymist-query/src/analysis/linked_def.rs b/crates/tinymist-query/src/analysis/linked_def.rs index 8ea44772..ecf3e46f 100644 --- a/crates/tinymist-query/src/analysis/linked_def.rs +++ b/crates/tinymist-query/src/analysis/linked_def.rs @@ -74,62 +74,40 @@ pub fn find_definition( } }; - // syntactic definition - let def_use = ctx.def_use(source)?; + // Lexical reference let ident_ref = match use_site.cast::()? { - ast::Expr::Ident(e) => IdentRef { + ast::Expr::Ident(e) => Some(IdentRef { name: e.get().to_string(), range: use_site.range(), - }, - ast::Expr::MathIdent(e) => IdentRef { + }), + ast::Expr::MathIdent(e) => Some(IdentRef { name: e.get().to_string(), range: use_site.range(), - }, + }), ast::Expr::FieldAccess(..) => { debug!("find field access"); - return None; + + None } _ => { debug!("unsupported kind {kind:?}", kind = use_site.kind()); - return None; + None } }; - let def_id = def_use.get_ref(&ident_ref); - let def_id = def_id.or_else(|| Some(def_use.get_def(source_id, &ident_ref)?.0)); - let def_info = def_id.and_then(|def_id| def_use.get_def_by_id(def_id)); - let values = analyze_expr(ctx.world(), &use_site); - for v in values { - // mostly builtin functions - if let Value::Func(f) = v.0 { - use typst::foundations::func::Repr; - match f.inner() { - // The with function should be resolved as the with position - Repr::Closure(..) | Repr::With(..) => continue, - Repr::Native(..) | Repr::Element(..) => {} - } + // Syntactic definition + let def_use = ctx.def_use(source); + let def_info = ident_ref + .as_ref() + .zip(def_use.as_ref()) + .and_then(|(ident_ref, def_use)| { + let def_id = def_use.get_ref(ident_ref); + let def_id = def_id.or_else(|| Some(def_use.get_def(source_id, ident_ref)?.0))?; - let name = f - .name() - .or_else(|| def_info.as_ref().map(|(_, r)| r.name.as_str())); - - if let Some(name) = name { - let span = f.span(); - let fid = span.id()?; - let source = ctx.source_by_id(fid).ok()?; - - return Some(DefinitionLink { - kind: LexicalKind::Var(LexicalVarKind::Function), - name: name.to_owned(), - value: Some(Value::Func(f.clone())), - // value: None, - def_at: Some((fid, source.find(span)?.range())), - name_range: def_info.map(|(_, r)| r.range.clone()), - }); - } - } - } + def_use.get_def_by_id(def_id) + }); + // Global definition let Some((def_fid, def)) = def_info else { return resolve_global_value(ctx, use_site.clone(), false).and_then(move |f| { value_to_def( @@ -191,14 +169,6 @@ pub fn find_definition( /// Resolve a callee expression to a function. pub fn resolve_callee(ctx: &mut AnalysisContext, callee: LinkedNode) -> Option { { - let values = analyze_expr(ctx.world(), &callee); - - values.into_iter().find_map(|v| match v.0 { - Value::Func(f) => Some(f), - _ => None, - }) - } - .or_else(|| { let source = ctx.source_by_id(callee.span().id()?).ok()?; let node = source.find(callee.span())?; let cursor = node.offset(); @@ -211,9 +181,17 @@ pub fn resolve_callee(ctx: &mut AnalysisContext, callee: LinkedNode) -> Option None, } + } + .or_else(|| { + resolve_global_value(ctx, callee.clone(), false).and_then(|v| match v { + Value::Func(f) => Some(f), + _ => None, + }) }) .or_else(|| { - resolve_global_value(ctx, callee, false).and_then(|v| match v { + let values = analyze_expr(ctx.world(), &callee); + + values.into_iter().find_map(|v| match v.0 { Value::Func(f) => Some(f), _ => None, }) diff --git a/crates/tinymist-query/src/inlay_hint.rs b/crates/tinymist-query/src/inlay_hint.rs index bd0d5541..133bd4a2 100644 --- a/crates/tinymist-query/src/inlay_hint.rs +++ b/crates/tinymist-query/src/inlay_hint.rs @@ -1,6 +1,5 @@ use std::ops::Range; -use log::debug; use lsp_types::{InlayHintKind, InlayHintLabel}; use crate::{ @@ -69,14 +68,14 @@ impl SemanticRequest for InlayHintRequest { let range = ctx.to_typst_range(self.range, &source)?; let hints = inlay_hint(ctx, &source, range, ctx.position_encoding()).ok()?; - debug!( + log::debug!( "got inlay hints on {source:?} => {hints:?}", source = source.id(), hints = hints.len() ); if hints.is_empty() { let root = LinkedNode::new(source.root()); - debug!("debug root {root:#?}"); + log::debug!("debug root {root:#?}"); } Some(hints)