aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/patterns.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-06-02 14:21:18 +0100
committerLukas Wirth <[email protected]>2021-06-02 14:21:18 +0100
commit9271941a950026836511bd1c85e15e26a480b824 (patch)
tree972b83f69c876003df59596cb8d109dc1b28c5d4 /crates/ide_completion/src/patterns.rs
parentdbdfeeeff91b5e42d8687df09dda1d29f99b34f8 (diff)
Add MethodCall and FieldAccess variants to ImmediateLocation
Diffstat (limited to 'crates/ide_completion/src/patterns.rs')
-rw-r--r--crates/ide_completion/src/patterns.rs45
1 files changed, 42 insertions, 3 deletions
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::{
7 ast::{self, LoopBodyOwner}, 7 ast::{self, LoopBodyOwner},
8 match_ast, AstNode, Direction, SyntaxElement, 8 match_ast, AstNode, Direction, SyntaxElement,
9 SyntaxKind::*, 9 SyntaxKind::*,
10 SyntaxNode, SyntaxToken, TextSize, T, 10 SyntaxNode, SyntaxToken, TextRange, TextSize, T,
11}; 11};
12 12
13#[cfg(test)] 13#[cfg(test)]
@@ -37,6 +37,15 @@ pub(crate) enum ImmediateLocation {
37 // Fake file ast node 37 // Fake file ast node
38 ModDeclaration(ast::Module), 38 ModDeclaration(ast::Module),
39 // Original file ast node 39 // Original file ast node
40 MethodCall {
41 receiver: Option<ast::Expr>,
42 },
43 // Original file ast node
44 FieldAccess {
45 receiver: Option<ast::Expr>,
46 receiver_is_ambiguous_float_literal: bool,
47 },
48 // Original file ast node
40 /// The record expr of the field name we are completing 49 /// The record expr of the field name we are completing
41 RecordExpr(ast::RecordExpr), 50 RecordExpr(ast::RecordExpr),
42 // Original file ast node 51 // Original file ast node
@@ -164,12 +173,38 @@ pub(crate) fn determine_location(
164 Some(TRAIT) => ImmediateLocation::Trait, 173 Some(TRAIT) => ImmediateLocation::Trait,
165 _ => return None, 174 _ => return None,
166 }, 175 },
167 ast::Module(it) => if it.item_list().is_none() { 176 ast::Module(it) => {
177 if it.item_list().is_none() {
168 ImmediateLocation::ModDeclaration(it) 178 ImmediateLocation::ModDeclaration(it)
169 } else { 179 } else {
170 return None 180 return None;
181 }
171 }, 182 },
172 ast::Attr(it) => ImmediateLocation::Attribute(it), 183 ast::Attr(it) => ImmediateLocation::Attribute(it),
184 ast::FieldExpr(it) => {
185 let receiver = it
186 .expr()
187 .map(|e| e.syntax().text_range())
188 .and_then(|r| find_node_with_range(original_file, r));
189 let receiver_is_ambiguous_float_literal = if let Some(ast::Expr::Literal(l)) = &receiver {
190 match l.kind() {
191 ast::LiteralKind::FloatNumber { .. } => l.token().text().ends_with('.'),
192 _ => false,
193 }
194 } else {
195 false
196 };
197 ImmediateLocation::FieldAccess {
198 receiver,
199 receiver_is_ambiguous_float_literal,
200 }
201 },
202 ast::MethodCallExpr(it) => ImmediateLocation::MethodCall {
203 receiver: it
204 .receiver()
205 .map(|e| e.syntax().text_range())
206 .and_then(|r| find_node_with_range(original_file, r)),
207 },
173 _ => return None, 208 _ => return None,
174 } 209 }
175 }; 210 };
@@ -194,6 +229,10 @@ fn maximize_name_ref(name_ref: &ast::NameRef) -> SyntaxNode {
194 name_ref.syntax().clone() 229 name_ref.syntax().clone()
195} 230}
196 231
232fn find_node_with_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> {
233 syntax.covering_element(range).ancestors().find_map(N::cast)
234}
235
197pub(crate) fn inside_impl_trait_block(element: SyntaxElement) -> bool { 236pub(crate) fn inside_impl_trait_block(element: SyntaxElement) -> bool {
198 // Here we search `impl` keyword up through the all ancestors, unlike in `has_impl_parent`, 237 // Here we search `impl` keyword up through the all ancestors, unlike in `has_impl_parent`,
199 // where we only check the first parent with different text range. 238 // where we only check the first parent with different text range.