fix: perform correct dynamic analysis on imports (#143)

* dev: perform correct dynamic analysis on imports

* dev: review e2e snapshot
This commit is contained in:
Myriad-Dreamin 2024-04-01 10:35:48 +08:00 committed by GitHub
parent c420b10540
commit d6e58ea961
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 30 deletions

View file

@ -49,6 +49,7 @@ pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec<(Value, Opti
/// Try to load a module from the current source file.
pub fn analyze_import(world: &dyn World, source: &LinkedNode) -> Option<Value> {
let source_span = source.span();
let (source, _) = analyze_expr(world, source).into_iter().next()?;
if source.scope().is_some() {
return Some(source);
@ -72,7 +73,7 @@ pub fn analyze_import(world: &dyn World, source: &LinkedNode) -> Option<Value> {
Scopes::new(Some(world.library())),
Span::detached(),
);
typst::eval::import(&mut vm, source, Span::detached(), true)
typst::eval::import(&mut vm, source, source_span, true)
.ok()
.map(Value::Module)
}

View file

@ -27,36 +27,34 @@ impl<'a> CompletionContext<'a> {
}
}
// todo: cache
if let Some(v) = node.cast::<ast::ModuleImport>() {
let imports = v.imports();
match imports {
None | Some(ast::Imports::Wildcard) => {
if let Some(value) = node
.children()
.find(|child| child.is::<ast::Expr>())
.and_then(|source| analyze_import(self.world, &source))
{
if imports.is_none() {
// todo: correct kind
defined.extend(
value
.name()
.map(Into::into)
.map(|e| (e, CompletionKind::Variable)),
);
} else if let Some(scope) = value.scope() {
for (name, _) in scope.iter() {
defined.insert(name.clone(), CompletionKind::Variable);
}
}
}
}
Some(ast::Imports::Items(items)) => {
for item in items.iter() {
defined.insert(
item.bound_name().get().clone(),
CompletionKind::Variable,
);
let anaylyze = node.children().find(|child| child.is::<ast::Expr>());
let analyzed = anaylyze
.as_ref()
.and_then(|source| analyze_import(self.world, source));
if analyzed.is_none() {
log::info!("failed to analyze import: {:?}", anaylyze);
}
if let Some(value) = analyzed {
if imports.is_none() {
// todo: correct kind
defined.extend(
value
.name()
.map(Into::into)
.map(|e| (e, CompletionKind::Module)),
);
} else if let Some(scope) = value.scope() {
for (name, v) in scope.iter() {
let kind = match v {
Value::Func(..) => CompletionKind::Func,
Value::Module(..) => CompletionKind::Module,
Value::Type(..) => CompletionKind::Type,
_ => CompletionKind::Constant,
};
defined.insert(name.clone(), kind);
}
}
}