diff options
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r-- | crates/ide_completion/src/context.rs | 51 |
1 files changed, 19 insertions, 32 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 7c46c815d..eeb4333f8 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs | |||
@@ -80,9 +80,6 @@ pub(crate) struct CompletionContext<'a> { | |||
80 | pub(super) is_expr: bool, | 80 | pub(super) is_expr: bool, |
81 | /// Something is typed at the "top" level, in module or impl/trait. | 81 | /// Something is typed at the "top" level, in module or impl/trait. |
82 | pub(super) is_new_item: bool, | 82 | pub(super) is_new_item: bool, |
83 | /// The receiver if this is a field or method access, i.e. writing something.$0 | ||
84 | pub(super) dot_receiver: Option<ast::Expr>, | ||
85 | pub(super) dot_receiver_is_ambiguous_float_literal: bool, | ||
86 | /// If this is a call (method or function) in particular, i.e. the () are already there. | 83 | /// If this is a call (method or function) in particular, i.e. the () are already there. |
87 | pub(super) is_call: bool, | 84 | pub(super) is_call: bool, |
88 | /// Like `is_call`, but for tuple patterns. | 85 | /// Like `is_call`, but for tuple patterns. |
@@ -159,8 +156,6 @@ impl<'a> CompletionContext<'a> { | |||
159 | can_be_stmt: false, | 156 | can_be_stmt: false, |
160 | is_expr: false, | 157 | is_expr: false, |
161 | is_new_item: false, | 158 | is_new_item: false, |
162 | dot_receiver: None, | ||
163 | dot_receiver_is_ambiguous_float_literal: false, | ||
164 | is_call: false, | 159 | is_call: false, |
165 | is_pattern_call: false, | 160 | is_pattern_call: false, |
166 | is_macro_call: false, | 161 | is_macro_call: false, |
@@ -255,6 +250,22 @@ impl<'a> CompletionContext<'a> { | |||
255 | ) | 250 | ) |
256 | } | 251 | } |
257 | 252 | ||
253 | pub(crate) fn has_dot_receiver(&self) -> bool { | ||
254 | matches!( | ||
255 | &self.completion_location, | ||
256 | Some(ImmediateLocation::FieldAccess { receiver, .. }) | Some(ImmediateLocation::MethodCall { receiver }) | ||
257 | if receiver.is_some() | ||
258 | ) | ||
259 | } | ||
260 | |||
261 | pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> { | ||
262 | match &self.completion_location { | ||
263 | Some(ImmediateLocation::MethodCall { receiver }) | ||
264 | | Some(ImmediateLocation::FieldAccess { receiver, .. }) => receiver.as_ref(), | ||
265 | _ => None, | ||
266 | } | ||
267 | } | ||
268 | |||
258 | pub(crate) fn expects_use_tree(&self) -> bool { | 269 | pub(crate) fn expects_use_tree(&self) -> bool { |
259 | matches!(self.completion_location, Some(ImmediateLocation::Use)) | 270 | matches!(self.completion_location, Some(ImmediateLocation::Use)) |
260 | } | 271 | } |
@@ -267,6 +278,7 @@ impl<'a> CompletionContext<'a> { | |||
267 | matches!(self.completion_location, Some(ImmediateLocation::ItemList)) | 278 | matches!(self.completion_location, Some(ImmediateLocation::ItemList)) |
268 | } | 279 | } |
269 | 280 | ||
281 | // fn expects_value(&self) -> bool { | ||
270 | pub(crate) fn expects_expression(&self) -> bool { | 282 | pub(crate) fn expects_expression(&self) -> bool { |
271 | self.is_expr | 283 | self.is_expr |
272 | } | 284 | } |
@@ -623,33 +635,8 @@ impl<'a> CompletionContext<'a> { | |||
623 | .unwrap_or(false); | 635 | .unwrap_or(false); |
624 | self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some(); | 636 | self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some(); |
625 | } | 637 | } |
626 | 638 | self.is_call |= | |
627 | if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { | 639 | matches!(self.completion_location, Some(ImmediateLocation::MethodCall { .. })); |
628 | // The receiver comes before the point of insertion of the fake | ||
629 | // ident, so it should have the same range in the non-modified file | ||
630 | self.dot_receiver = field_expr | ||
631 | .expr() | ||
632 | .map(|e| e.syntax().text_range()) | ||
633 | .and_then(|r| find_node_with_range(original_file, r)); | ||
634 | self.dot_receiver_is_ambiguous_float_literal = | ||
635 | if let Some(ast::Expr::Literal(l)) = &self.dot_receiver { | ||
636 | match l.kind() { | ||
637 | ast::LiteralKind::FloatNumber { .. } => l.token().text().ends_with('.'), | ||
638 | _ => false, | ||
639 | } | ||
640 | } else { | ||
641 | false | ||
642 | }; | ||
643 | } | ||
644 | |||
645 | if let Some(method_call_expr) = ast::MethodCallExpr::cast(parent) { | ||
646 | // As above | ||
647 | self.dot_receiver = method_call_expr | ||
648 | .receiver() | ||
649 | .map(|e| e.syntax().text_range()) | ||
650 | .and_then(|r| find_node_with_range(original_file, r)); | ||
651 | self.is_call = true; | ||
652 | } | ||
653 | } | 640 | } |
654 | } | 641 | } |
655 | 642 | ||