diff options
Diffstat (limited to 'src/ide/analyze.rs')
| -rw-r--r-- | src/ide/analyze.rs | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/src/ide/analyze.rs b/src/ide/analyze.rs index cfc77f38..357e98f8 100644 --- a/src/ide/analyze.rs +++ b/src/ide/analyze.rs @@ -1,11 +1,14 @@ +use std::path::PathBuf; + use comemo::Track; -use crate::model::{eval, Route, Tracer, Value}; -use crate::syntax::{ast, LinkedNode, SyntaxKind}; +use crate::model::{eval, Module, Route, Tracer, Value}; +use crate::syntax::{ast, LinkedNode, Source, SyntaxKind}; +use crate::util::PathExt; use crate::World; /// Try to determine a set of possible values for an expression. -pub fn analyze(world: &(dyn World + 'static), node: &LinkedNode) -> Vec<Value> { +pub fn analyze_expr(world: &(dyn World + 'static), node: &LinkedNode) -> Vec<Value> { match node.cast::<ast::Expr>() { Some(ast::Expr::None(_)) => vec![Value::None], Some(ast::Expr::Auto(_)) => vec![Value::Auto], @@ -17,7 +20,7 @@ pub fn analyze(world: &(dyn World + 'static), node: &LinkedNode) -> Vec<Value> { Some(ast::Expr::FieldAccess(access)) => { let Some(child) = node.children().next() else { return vec![] }; - analyze(world, &child) + analyze_expr(world, &child) .into_iter() .filter_map(|target| target.field(&access.field()).ok()) .collect() @@ -26,7 +29,7 @@ pub fn analyze(world: &(dyn World + 'static), node: &LinkedNode) -> Vec<Value> { Some(_) => { if let Some(parent) = node.parent() { if parent.kind() == SyntaxKind::FieldAccess && node.index() > 0 { - return analyze(world, parent); + return analyze_expr(world, parent); } } @@ -41,3 +44,23 @@ pub fn analyze(world: &(dyn World + 'static), node: &LinkedNode) -> Vec<Value> { _ => vec![], } } + +/// Try to load a module from the current source file. +pub fn analyze_import( + world: &(dyn World + 'static), + source: &Source, + path: &str, +) -> Option<Module> { + let full: PathBuf = if let Some(path) = path.strip_prefix('/') { + world.root().join(path).normalize() + } else if let Some(dir) = source.path().parent() { + dir.join(path).normalize() + } else { + path.into() + }; + let route = Route::default(); + let mut tracer = Tracer::default(); + let id = world.resolve(&full).ok()?; + let source = world.source(id); + eval(world.track(), route.track(), tracer.track_mut(), source).ok() +} |
