diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-01-28 23:36:27 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-01-28 23:38:03 +0100 |
| commit | 1e97d5c8cbeb96d35e5a34a8340c4ec1860fa1b6 (patch) | |
| tree | aa4a341af10dc0729132a42cdb1cacb1e1d21518 /src/ide | |
| parent | 76048a8ef45ac5892235f2e69cb7cb6c35a037e4 (diff) | |
Better analysis for literals
Diffstat (limited to 'src/ide')
| -rw-r--r-- | src/ide/analyze.rs | 33 | ||||
| -rw-r--r-- | src/ide/tooltip.rs | 30 |
2 files changed, 44 insertions, 19 deletions
diff --git a/src/ide/analyze.rs b/src/ide/analyze.rs index 65d9ded8..12576e53 100644 --- a/src/ide/analyze.rs +++ b/src/ide/analyze.rs @@ -7,6 +7,22 @@ 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::None(_)) => vec![Value::None], + Some(ast::Expr::Auto(_)) => vec![Value::Auto], + Some(ast::Expr::Bool(v)) => vec![Value::Bool(v.get())], + Some(ast::Expr::Int(v)) => vec![Value::Int(v.get())], + Some(ast::Expr::Float(v)) => vec![Value::Float(v.get())], + Some(ast::Expr::Numeric(v)) => vec![Value::numeric(v.get())], + Some(ast::Expr::Str(v)) => vec![Value::Str(v.get().into())], + + Some(ast::Expr::FieldAccess(access)) => { + let Some(child) = node.children().next() else { return vec![] }; + analyze(world, &child) + .into_iter() + .filter_map(|target| target.field(&access.field()).ok()) + .collect() + } + Some(ast::Expr::Ident(_) | ast::Expr::MathIdent(_) | ast::Expr::FuncCall(_)) => { if let Some(parent) = node.parent() { if parent.kind() == SyntaxKind::FieldAccess && node.index() > 0 { @@ -19,22 +35,9 @@ pub fn analyze(world: &(dyn World + 'static), node: &LinkedNode) -> Vec<Value> { 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::Str(s)) => return vec![Value::Str(s.get().into())], - - 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(); - } + tracer.finish() } - _ => {} + _ => vec![], } - - vec![] } diff --git a/src/ide/tooltip.rs b/src/ide/tooltip.rs index 202efd8e..701c5622 100644 --- a/src/ide/tooltip.rs +++ b/src/ide/tooltip.rs @@ -2,6 +2,7 @@ use if_chain::if_chain; use unicode_segmentation::UnicodeSegmentation; use super::{analyze, plain_docs_sentence, summarize_font_family}; +use crate::geom::{round_2, Length, Numeric}; use crate::model::{CastInfo, Tracer, Value}; use crate::syntax::ast; use crate::syntax::{LinkedNode, Source, SyntaxKind}; @@ -22,15 +23,23 @@ pub fn tooltip( /// Tooltip for a hovered expression. fn expr_tooltip(world: &(dyn World + 'static), leaf: &LinkedNode) -> Option<String> { - if !leaf.is::<ast::Expr>() { - return None; - } - + let expr = leaf.cast::<ast::Expr>()?; let values = analyze(world, leaf); + if let [value] = values.as_slice() { if let Some(docs) = value.docs() { return Some(plain_docs_sentence(docs)); } + + if let &Value::Length(length) = value { + if let Some(tooltip) = length_tooltip(length) { + return Some(tooltip); + } + } + } + + if expr.is_literal() { + return None; } let mut tooltip = String::new(); @@ -61,6 +70,19 @@ fn expr_tooltip(world: &(dyn World + 'static), leaf: &LinkedNode) -> Option<Stri (!tooltip.is_empty()).then(|| tooltip) } +/// Tooltip text for a hovered length. +fn length_tooltip(length: Length) -> Option<String> { + length.em.is_zero().then(|| { + format!( + "{}pt = {}mm = {}cm = {}in", + round_2(length.abs.to_pt()), + round_2(length.abs.to_mm()), + round_2(length.abs.to_cm()), + round_2(length.abs.to_inches()) + ) + }) +} + /// Tooltips for components of a named parameter. fn named_param_tooltip( world: &(dyn World + 'static), |
