From 406de22ee5cd74dc6f67743bad4710415bb50c41 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sat, 28 Jan 2023 18:32:58 +0100 Subject: Remove method call syntax kind --- src/ide/analyze.rs | 4 +- src/ide/complete.rs | 6 +-- src/ide/highlight.rs | 117 ++++++++++++++++++++++++--------------------------- 3 files changed, 59 insertions(+), 68 deletions(-) (limited to 'src/ide') diff --git a/src/ide/analyze.rs b/src/ide/analyze.rs index c170186f..65d9ded8 100644 --- a/src/ide/analyze.rs +++ b/src/ide/analyze.rs @@ -7,9 +7,7 @@ use crate::World; /// Try to determine a set of possible values for an expression. pub fn analyze(world: &(dyn World + 'static), node: &LinkedNode) -> Vec { match node.cast::() { - Some( - ast::Expr::Ident(_) | ast::Expr::MathIdent(_) | ast::Expr::MethodCall(_), - ) => { + Some(ast::Expr::Ident(_) | ast::Expr::MathIdent(_) | ast::Expr::FuncCall(_)) => { if let Some(parent) = node.parent() { if parent.kind() == SyntaxKind::FieldAccess && node.index() > 0 { return analyze(world, parent); diff --git a/src/ide/complete.rs b/src/ide/complete.rs index 83202e30..143e22b9 100644 --- a/src/ide/complete.rs +++ b/src/ide/complete.rs @@ -4,7 +4,7 @@ use if_chain::if_chain; use super::{analyze, plain_docs_sentence, summarize_font_family}; use crate::model::{methods_on, CastInfo, Scope, Value}; -use crate::syntax::{ast, LinkedNode, Source, SyntaxKind, SyntaxNode}; +use crate::syntax::{ast, LinkedNode, Source, SyntaxKind}; use crate::util::{format_eco, EcoString}; use crate::World; @@ -936,9 +936,7 @@ impl<'a> CompletionContext<'a> { if let Some(parent) = node.parent() { if let Some(v) = parent.cast::() { - if node.prev_sibling().as_deref().map(SyntaxNode::kind) - != Some(SyntaxKind::In) - { + if node.prev_sibling_kind() != Some(SyntaxKind::In) { let pattern = v.pattern(); if let Some(key) = pattern.key() { defined.insert(key.take()); diff --git a/src/ide/highlight.rs b/src/ide/highlight.rs index d8f15f00..ede13d7f 100644 --- a/src/ide/highlight.rs +++ b/src/ide/highlight.rs @@ -85,8 +85,7 @@ pub fn highlight(node: &LinkedNode) -> Option { match node.kind() { SyntaxKind::Markup if node.parent_kind() == Some(SyntaxKind::TermItem) - && node.next_sibling().as_ref().map(|v| v.kind()) - == Some(SyntaxKind::Colon) => + && node.next_sibling_kind() == Some(SyntaxKind::Colon) => { Some(Category::ListTerm) } @@ -116,17 +115,12 @@ pub fn highlight(node: &LinkedNode) -> Option { SyntaxKind::Math => None, SyntaxKind::MathIdent => highlight_ident(node), + SyntaxKind::MathAlignPoint => Some(Category::MathOperator), SyntaxKind::MathDelimited => None, SyntaxKind::MathAttach => None, SyntaxKind::MathFrac => None, - SyntaxKind::MathAlignPoint => Some(Category::MathOperator), - - SyntaxKind::Hashtag => node - .next_sibling() - .filter(|node| node.cast::().map_or(false, |e| e.hashtag())) - .and_then(|node| node.leftmost_leaf()) - .and_then(|node| highlight(&node)), + SyntaxKind::Hashtag => highlight_hashtag(node), SyntaxKind::LeftBrace => Some(Category::Punctuation), SyntaxKind::RightBrace => Some(Category::Punctuation), SyntaxKind::LeftBracket => Some(Category::Punctuation), @@ -206,18 +200,8 @@ pub fn highlight(node: &LinkedNode) -> Option { SyntaxKind::Keyed => None, SyntaxKind::Unary => None, SyntaxKind::Binary => None, - SyntaxKind::FieldAccess => match node.parent_kind() { - Some( - SyntaxKind::Markup - | SyntaxKind::Math - | SyntaxKind::MathFrac - | SyntaxKind::MathAttach, - ) => Some(Category::Interpolated), - Some(SyntaxKind::FieldAccess) => node.parent().and_then(highlight), - _ => None, - }, + SyntaxKind::FieldAccess => None, SyntaxKind::FuncCall => None, - SyntaxKind::MethodCall => None, SyntaxKind::Args => None, SyntaxKind::Spread => None, SyntaxKind::Closure => None, @@ -245,49 +229,60 @@ pub fn highlight(node: &LinkedNode) -> Option { /// Highlight an identifier based on context. fn highlight_ident(node: &LinkedNode) -> Option { - match node.parent_kind() { - Some(SyntaxKind::FuncCall) => Some(Category::Function), - Some(SyntaxKind::FieldAccess) - if node.parent().and_then(|p| p.parent_kind()) - == Some(SyntaxKind::SetRule) - && node.next_sibling().is_none() => - { - Some(Category::Function) - } - Some(SyntaxKind::FieldAccess) - if node - .parent() - .and_then(|p| p.parent()) - .filter(|gp| gp.kind() == SyntaxKind::Parenthesized) - .and_then(|gp| gp.parent()) - .map_or(false, |ggp| ggp.kind() == SyntaxKind::FuncCall) - && node.next_sibling().is_none() => - { - Some(Category::Function) - } - Some(SyntaxKind::FieldAccess) => node.parent().and_then(highlight), - Some(SyntaxKind::MethodCall) if node.prev_sibling().is_some() => { - Some(Category::Function) - } - Some(SyntaxKind::Closure) if node.prev_sibling().is_none() => { - Some(Category::Function) - } - Some(SyntaxKind::SetRule) => Some(Category::Function), - Some(SyntaxKind::ShowRule) - if node.prev_sibling().as_ref().map(|v| v.kind()) - == Some(SyntaxKind::Show) => - { - Some(Category::Function) + // Are we directly before an argument list? + let next_leaf_kind = node.next_leaf().map(|leaf| leaf.kind()); + if matches!(next_leaf_kind, Some(SyntaxKind::LeftParen | SyntaxKind::LeftBracket)) { + return Some(Category::Function); + } + + // Are we in math? + if node.kind() == SyntaxKind::MathIdent { + return Some(Category::Interpolated); + } + + // Find the first non-field access ancestor. + let mut ancestor = node; + while ancestor.parent_kind() == Some(SyntaxKind::FieldAccess) { + ancestor = ancestor.parent()?; + } + + // Are we directly before a show rule colon? + if next_leaf_kind == Some(SyntaxKind::Colon) + && ancestor.parent_kind() == Some(SyntaxKind::ShowRule) + { + return Some(Category::Function); + } + + // Are we (or an ancestor field access) directly after a hashtag. + if ancestor.prev_leaf().map(|leaf| leaf.kind()) == Some(SyntaxKind::Hashtag) { + return Some(Category::Interpolated); + } + + // Are we behind a dot, that is behind another identifier? + let prev = node.prev_leaf()?; + if prev.kind() == SyntaxKind::Dot { + let prev_prev = prev.prev_leaf()?; + if is_ident(&prev_prev) { + return highlight_ident(&prev_prev); } - Some( - SyntaxKind::Markup - | SyntaxKind::Math - | SyntaxKind::MathFrac - | SyntaxKind::MathAttach, - ) => Some(Category::Interpolated), - _ if node.kind() == SyntaxKind::MathIdent => Some(Category::Interpolated), - _ => None, } + + None +} + +/// Highlight a hashtag based on context. +fn highlight_hashtag(node: &LinkedNode) -> Option { + let next = node.next_sibling()?; + let expr = next.cast::()?; + if !expr.hashtag() { + return None; + } + highlight(&next.leftmost_leaf()?) +} + +/// Whether the node is one of the two identifier nodes. +fn is_ident(node: &LinkedNode) -> bool { + matches!(node.kind(), SyntaxKind::Ident | SyntaxKind::MathIdent) } #[cfg(test)] -- cgit v1.2.3