summaryrefslogtreecommitdiff
path: root/src/ide/analyze.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ide/analyze.rs')
-rw-r--r--src/ide/analyze.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/ide/analyze.rs b/src/ide/analyze.rs
new file mode 100644
index 00000000..d8925cfc
--- /dev/null
+++ b/src/ide/analyze.rs
@@ -0,0 +1,38 @@
+use comemo::Track;
+
+use crate::model::{eval, Route, Tracer, Value};
+use crate::syntax::{ast, LinkedNode, SyntaxKind};
+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> {
+ match node.cast::<ast::Expr>() {
+ Some(ast::Expr::Ident(_) | ast::Expr::MathIdent(_)) => {
+ if let Some(parent) = node.parent() {
+ if parent.kind() == SyntaxKind::FieldAccess && node.index() > 0 {
+ return analyze(world, parent);
+ }
+ }
+
+ let span = node.span();
+ let source = world.source(span.source());
+ let route = Route::default();
+ let mut tracer = Tracer::new(Some(span));
+ eval(world.track(), route.track(), tracer.track_mut(), source).ok();
+ return tracer.finish();
+ }
+
+ Some(ast::Expr::FieldAccess(access)) => {
+ if let Some(child) = node.children().next() {
+ return analyze(world, &child)
+ .into_iter()
+ .filter_map(|target| target.field(&access.field()).ok())
+ .collect();
+ }
+ }
+
+ _ => {}
+ }
+
+ vec![]
+}