aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-02-11 20:40:08 +0000
committerAleksey Kladov <[email protected]>2019-02-11 20:43:24 +0000
commit8ef80086a0ee81b4dedab6d37a9a2e7fe5bce38a (patch)
tree6be1668b8cf61d4d67054581a10424be0aaeaa0e
parentdb6d214411505de6534fce183e9bea8109bc5283 (diff)
fix regression in self-referential completion
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs36
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs10
-rw-r--r--crates/ra_ide_api/src/marks.rs1
3 files changed, 32 insertions, 15 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 39aefdb13..91ca7525e 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -1,10 +1,9 @@
1use join_to_string::join; 1use join_to_string::join;
2
3use hir::{Docs, Resolution}; 2use hir::{Docs, Resolution};
3use ra_syntax::AstNode;
4use test_utils::tested_by;
4 5
5use crate::{ 6use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
6 completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext},
7};
8 7
9pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { 8pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
10 let path = match &ctx.path_prefix { 9 let path = match &ctx.path_prefix {
@@ -19,6 +18,17 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
19 hir::ModuleDef::Module(module) => { 18 hir::ModuleDef::Module(module) => {
20 let module_scope = module.scope(ctx.db); 19 let module_scope = module.scope(ctx.db);
21 for (name, res) in module_scope.entries() { 20 for (name, res) in module_scope.entries() {
21 if Some(module) == ctx.module {
22 if let Some(import) = res.import {
23 let path = module.import_source(ctx.db, import);
24 if path.syntax().range().contains_inclusive(ctx.offset) {
25 // for `use self::foo<|>`, don't suggest `foo` as a completion
26 tested_by!(dont_complete_current_use);
27 continue;
28 }
29 }
30 }
31
22 CompletionItem::new( 32 CompletionItem::new(
23 CompletionKind::Reference, 33 CompletionKind::Reference,
24 ctx.source_range(), 34 ctx.source_range(),
@@ -54,22 +64,22 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
54 64
55#[cfg(test)] 65#[cfg(test)]
56mod tests { 66mod tests {
57 use crate::completion::CompletionKind; 67 use crate::completion::{
58 use crate::completion::completion_item::check_completion; 68 CompletionKind,
69 completion_item::{check_completion, do_completion},
70};
71
72 use test_utils::covers;
59 73
60 fn check_reference_completion(code: &str, expected_completions: &str) { 74 fn check_reference_completion(code: &str, expected_completions: &str) {
61 check_completion(code, expected_completions, CompletionKind::Reference); 75 check_completion(code, expected_completions, CompletionKind::Reference);
62 } 76 }
63 77
64 #[test] 78 #[test]
65 #[ignore] // should not complete foo, which currently doesn't work
66 fn dont_complete_current_use() { 79 fn dont_complete_current_use() {
67 check_reference_completion( 80 covers!(dont_complete_current_use);
68 "dont_complete_current_use", 81 let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference);
69 r" 82 assert!(completions.is_empty());
70 use self::foo<|>;
71 ",
72 );
73 } 83 }
74 84
75 #[test] 85 #[test]
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index 7b8972af0..22ff08a23 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -306,10 +306,9 @@ fn function_item_label(ctx: &CompletionContext, function: hir::Function) -> Opti
306} 306}
307 307
308#[cfg(test)] 308#[cfg(test)]
309pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind) { 309pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
310 use crate::mock_analysis::{single_file_with_position, analysis_and_position}; 310 use crate::mock_analysis::{single_file_with_position, analysis_and_position};
311 use crate::completion::completions; 311 use crate::completion::completions;
312 use insta::assert_debug_snapshot_matches;
313 let (analysis, position) = if code.contains("//-") { 312 let (analysis, position) = if code.contains("//-") {
314 analysis_and_position(code) 313 analysis_and_position(code)
315 } else { 314 } else {
@@ -320,6 +319,13 @@ pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind
320 let mut kind_completions: Vec<CompletionItem> = 319 let mut kind_completions: Vec<CompletionItem> =
321 completion_items.into_iter().filter(|c| c.completion_kind == kind).collect(); 320 completion_items.into_iter().filter(|c| c.completion_kind == kind).collect();
322 kind_completions.sort_by_key(|c| c.label.clone()); 321 kind_completions.sort_by_key(|c| c.label.clone());
322 kind_completions
323}
324
325#[cfg(test)]
326pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind) {
327 use insta::assert_debug_snapshot_matches;
328 let kind_completions = do_completion(code, kind);
323 assert_debug_snapshot_matches!(test_name, kind_completions); 329 assert_debug_snapshot_matches!(test_name, kind_completions);
324} 330}
325 331
diff --git a/crates/ra_ide_api/src/marks.rs b/crates/ra_ide_api/src/marks.rs
index 21ce7289d..44d8fdf82 100644
--- a/crates/ra_ide_api/src/marks.rs
+++ b/crates/ra_ide_api/src/marks.rs
@@ -3,4 +3,5 @@ test_utils::marks!(
3 goto_definition_works_for_methods 3 goto_definition_works_for_methods
4 goto_definition_works_for_fields 4 goto_definition_works_for_fields
5 call_info_bad_offset 5 call_info_bad_offset
6 dont_complete_current_use
6); 7);