|
1 | 1 | use hir::{db::HirDatabase, HirDisplay}; |
2 | 2 | use ra_syntax::{ |
3 | 3 | ast::{self, AstNode, LetStmt, NameOwner}, |
4 | | - T, |
| 4 | + SyntaxKind::EQ, |
| 5 | + TextRange, T, |
5 | 6 | }; |
6 | 7 |
|
7 | 8 | use crate::{Assist, AssistCtx, AssistId}; |
@@ -34,6 +35,14 @@ pub(crate) fn add_explicit_type(ctx: AssistCtx<impl HirDatabase>) -> Option<Assi |
34 | 35 | // The binding must have a name |
35 | 36 | let name = pat.name()?; |
36 | 37 | let name_range = name.syntax().text_range(); |
| 38 | + // Assist should only be applicable if cursor is between 'let' and '=' |
| 39 | + let stmt_range = stmt.syntax().text_range(); |
| 40 | + let eq_range = stmt.syntax().descendants_with_tokens().find(|t| t.kind() == EQ)?.text_range(); |
| 41 | + let let_range = TextRange::from_to(stmt_range.start(), eq_range.start()); |
| 42 | + let cursor_in_range = ctx.frange.range.is_subrange(&let_range); |
| 43 | + if !cursor_in_range { |
| 44 | + return None; |
| 45 | + } |
37 | 46 | // Assist not applicable if the type has already been specified |
38 | 47 | if stmt.syntax().children_with_tokens().any(|child| child.kind() == T![:]) { |
39 | 48 | return None; |
@@ -109,4 +118,20 @@ mod tests { |
109 | 118 | fn add_explicit_type_not_applicable_if_specified_ty_is_tuple() { |
110 | 119 | check_assist_not_applicable(add_explicit_type, "fn f() { let a<|>: (i32, i32) = (3, 4); }"); |
111 | 120 | } |
| 121 | + |
| 122 | + #[test] |
| 123 | + fn add_explicit_type_not_applicable_if_cursor_after_equals() { |
| 124 | + check_assist_not_applicable( |
| 125 | + add_explicit_type, |
| 126 | + "fn f() {let a =<|> match 1 {2 => 3, 3 => 5};}", |
| 127 | + ) |
| 128 | + } |
| 129 | + |
| 130 | + #[test] |
| 131 | + fn add_explicit_type_not_applicable_if_cursor_before_let() { |
| 132 | + check_assist_not_applicable( |
| 133 | + add_explicit_type, |
| 134 | + "fn f() <|>{let a = match 1 {2 => 3, 3 => 5};}", |
| 135 | + ) |
| 136 | + } |
112 | 137 | } |
0 commit comments