aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r--crates/ra_analysis/src/completion/complete_keyword.rs55
-rw-r--r--crates/ra_analysis/src/completion/completion_context.rs32
2 files changed, 67 insertions, 20 deletions
diff --git a/crates/ra_analysis/src/completion/complete_keyword.rs b/crates/ra_analysis/src/completion/complete_keyword.rs
index 2869e67e0..d70fdaada 100644
--- a/crates/ra_analysis/src/completion/complete_keyword.rs
+++ b/crates/ra_analysis/src/completion/complete_keyword.rs
@@ -32,8 +32,13 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
32 acc.add(keyword("else if", "else if $0 {}")); 32 acc.add(keyword("else if", "else if $0 {}"));
33 } 33 }
34 if is_in_loop_body(ctx.leaf) { 34 if is_in_loop_body(ctx.leaf) {
35 acc.add(keyword("continue", "continue")); 35 if ctx.can_be_stmt {
36 acc.add(keyword("break", "break")); 36 acc.add(keyword("continue", "continue;"));
37 acc.add(keyword("break", "break;"));
38 } else {
39 acc.add(keyword("continue", "continue"));
40 acc.add(keyword("break", "break"));
41 }
37 } 42 }
38 acc.add_all(complete_return(fn_def, ctx.can_be_stmt)); 43 acc.add_all(complete_return(fn_def, ctx.can_be_stmt));
39} 44}
@@ -186,6 +191,24 @@ mod tests {
186 return "return $0;" 191 return "return $0;"
187 "#, 192 "#,
188 ); 193 );
194 check_keyword_completion(
195 r"
196 fn quux() -> i32 {
197 if condition {
198 <|>
199 }
200 let x = 92;
201 x
202 }
203 ",
204 r#"
205 if "if $0 {}"
206 match "match $0 {}"
207 while "while $0 {}"
208 loop "loop {$0}"
209 return "return $0;"
210 "#,
211 );
189 } 212 }
190 213
191 #[test] 214 #[test]
@@ -201,8 +224,8 @@ mod tests {
201 match "match $0 {}" 224 match "match $0 {}"
202 while "while $0 {}" 225 while "while $0 {}"
203 loop "loop {$0}" 226 loop "loop {$0}"
204 continue "continue" 227 continue "continue;"
205 break "break" 228 break "break;"
206 return "return $0;" 229 return "return $0;"
207 "#, 230 "#,
208 ); 231 );
@@ -222,4 +245,28 @@ mod tests {
222 "#, 245 "#,
223 ); 246 );
224 } 247 }
248
249 #[test]
250 fn no_semi_after_break_continue_in_expr() {
251 check_keyword_completion(
252 r"
253 fn f() {
254 loop {
255 match () {
256 () => br<|>
257 }
258 }
259 }
260 ",
261 r#"
262 if "if $0 {}"
263 match "match $0 {}"
264 while "while $0 {}"
265 loop "loop {$0}"
266 continue "continue"
267 break "break"
268 return "return"
269 "#,
270 )
271 }
225} 272}
diff --git a/crates/ra_analysis/src/completion/completion_context.rs b/crates/ra_analysis/src/completion/completion_context.rs
index 4685c9328..4584f355d 100644
--- a/crates/ra_analysis/src/completion/completion_context.rs
+++ b/crates/ra_analysis/src/completion/completion_context.rs
@@ -148,24 +148,24 @@ impl<'a> CompletionContext<'a> {
148 if path.qualifier().is_none() { 148 if path.qualifier().is_none() {
149 self.is_trivial_path = true; 149 self.is_trivial_path = true;
150 150
151 self.can_be_stmt = match name_ref 151 // Find either enclosing expr statement (thing with `;`) or a
152 // block. If block, check that we are the last expr.
153 self.can_be_stmt = name_ref
152 .syntax() 154 .syntax()
153 .ancestors() 155 .ancestors()
154 .filter_map(ast::ExprStmt::cast) 156 .find_map(|node| {
155 .next() 157 if let Some(stmt) = ast::ExprStmt::cast(node) {
156 { 158 return Some(stmt.syntax().range() == name_ref.syntax().range());
157 None => { 159 }
158 name_ref 160 if let Some(block) = ast::Block::cast(node) {
159 .syntax() 161 return Some(
160 .ancestors() 162 block.expr().map(|e| e.syntax().range())
161 .filter_map(ast::Block::cast) 163 == Some(name_ref.syntax().range()),
162 .next() 164 );
163 .and_then(|block| block.expr()) 165 }
164 .map(|e| e.syntax().range()) 166 None
165 == Some(name_ref.syntax().range()) 167 })
166 } 168 .unwrap_or(false);
167 Some(expr_stmt) => expr_stmt.syntax().range() == name_ref.syntax().range(),
168 };
169 169
170 if let Some(off) = name_ref.syntax().range().start().checked_sub(2.into()) { 170 if let Some(off) = name_ref.syntax().range().start().checked_sub(2.into()) {
171 if let Some(if_expr) = 171 if let Some(if_expr) =