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
This commit is contained in:
Myriad-Dreamin 2024-04-16 14:03:01 +08:00 committed by GitHub
parent 68ce4701c6
commit a09c068d1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 53 deletions

View file

@ -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>()? {
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<Func> {
{
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<F
},
_ => 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,
})

View file

@ -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)