From 9271941a950026836511bd1c85e15e26a480b824 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 2 Jun 2021 15:21:18 +0200 Subject: Add MethodCall and FieldAccess variants to ImmediateLocation --- crates/ide_completion/src/patterns.rs | 45 ++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'crates/ide_completion/src/patterns.rs') diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs index 26516046b..bf3a3f61e 100644 --- a/crates/ide_completion/src/patterns.rs +++ b/crates/ide_completion/src/patterns.rs @@ -7,7 +7,7 @@ use syntax::{ ast::{self, LoopBodyOwner}, match_ast, AstNode, Direction, SyntaxElement, SyntaxKind::*, - SyntaxNode, SyntaxToken, TextSize, T, + SyntaxNode, SyntaxToken, TextRange, TextSize, T, }; #[cfg(test)] @@ -37,6 +37,15 @@ pub(crate) enum ImmediateLocation { // Fake file ast node ModDeclaration(ast::Module), // Original file ast node + MethodCall { + receiver: Option, + }, + // Original file ast node + FieldAccess { + receiver: Option, + receiver_is_ambiguous_float_literal: bool, + }, + // Original file ast node /// The record expr of the field name we are completing RecordExpr(ast::RecordExpr), // Original file ast node @@ -164,12 +173,38 @@ pub(crate) fn determine_location( Some(TRAIT) => ImmediateLocation::Trait, _ => return None, }, - ast::Module(it) => if it.item_list().is_none() { + ast::Module(it) => { + if it.item_list().is_none() { ImmediateLocation::ModDeclaration(it) } else { - return None + return None; + } }, ast::Attr(it) => ImmediateLocation::Attribute(it), + ast::FieldExpr(it) => { + let receiver = it + .expr() + .map(|e| e.syntax().text_range()) + .and_then(|r| find_node_with_range(original_file, r)); + let receiver_is_ambiguous_float_literal = if let Some(ast::Expr::Literal(l)) = &receiver { + match l.kind() { + ast::LiteralKind::FloatNumber { .. } => l.token().text().ends_with('.'), + _ => false, + } + } else { + false + }; + ImmediateLocation::FieldAccess { + receiver, + receiver_is_ambiguous_float_literal, + } + }, + ast::MethodCallExpr(it) => ImmediateLocation::MethodCall { + receiver: it + .receiver() + .map(|e| e.syntax().text_range()) + .and_then(|r| find_node_with_range(original_file, r)), + }, _ => return None, } }; @@ -194,6 +229,10 @@ fn maximize_name_ref(name_ref: &ast::NameRef) -> SyntaxNode { name_ref.syntax().clone() } +fn find_node_with_range(syntax: &SyntaxNode, range: TextRange) -> Option { + syntax.covering_element(range).ancestors().find_map(N::cast) +} + pub(crate) fn inside_impl_trait_block(element: SyntaxElement) -> bool { // Here we search `impl` keyword up through the all ancestors, unlike in `has_impl_parent`, // where we only check the first parent with different text range. -- cgit v1.2.3 From 76fd1b316f38b59991316d5b97582c0203728738 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 2 Jun 2021 15:25:02 +0200 Subject: Remove obsolete is_new_item field on CompletionContext --- crates/ide_completion/src/patterns.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ide_completion/src/patterns.rs') diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs index bf3a3f61e..080898aef 100644 --- a/crates/ide_completion/src/patterns.rs +++ b/crates/ide_completion/src/patterns.rs @@ -13,7 +13,7 @@ use syntax::{ #[cfg(test)] use crate::test_utils::{check_pattern_is_applicable, check_pattern_is_not_applicable}; -/// Direct parent container of the cursor position +/// Immediate previous node to what we are completing. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub(crate) enum ImmediatePrevSibling { IfExpr, @@ -21,7 +21,7 @@ pub(crate) enum ImmediatePrevSibling { ImplDefType, } -/// Direct parent container of the cursor position +/// Direct parent "thing" of what we are currently completing. #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum ImmediateLocation { Use, -- cgit v1.2.3