]> git.lizzy.rs Git - rust.git/commitdiff
fix regression in self-referential completion
authorAleksey Kladov <aleksey.kladov@gmail.com>
Mon, 11 Feb 2019 20:40:08 +0000 (23:40 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Mon, 11 Feb 2019 20:43:24 +0000 (23:43 +0300)
crates/ra_ide_api/src/completion/complete_path.rs
crates/ra_ide_api/src/completion/completion_item.rs
crates/ra_ide_api/src/marks.rs

index 39aefdb13c92c7a9145f20b74ac693fd0520a96f..91ca7525e7384c9ae2f57a34ba7b5c9989cd59b6 100644 (file)
@@ -1,10 +1,9 @@
 use join_to_string::join;
-
 use hir::{Docs, Resolution};
+use ra_syntax::AstNode;
+use test_utils::tested_by;
 
-use crate::{
-    completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext},
-};
+use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
 
 pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
     let path = match &ctx.path_prefix {
@@ -19,6 +18,17 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
         hir::ModuleDef::Module(module) => {
             let module_scope = module.scope(ctx.db);
             for (name, res) in module_scope.entries() {
+                if Some(module) == ctx.module {
+                    if let Some(import) = res.import {
+                        let path = module.import_source(ctx.db, import);
+                        if path.syntax().range().contains_inclusive(ctx.offset) {
+                            // for `use self::foo<|>`, don't suggest `foo` as a completion
+                            tested_by!(dont_complete_current_use);
+                            continue;
+                        }
+                    }
+                }
+
                 CompletionItem::new(
                     CompletionKind::Reference,
                     ctx.source_range(),
@@ -54,22 +64,22 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
 
 #[cfg(test)]
 mod tests {
-    use crate::completion::CompletionKind;
-    use crate::completion::completion_item::check_completion;
+    use crate::completion::{
+        CompletionKind,
+        completion_item::{check_completion, do_completion},
+};
+
+    use test_utils::covers;
 
     fn check_reference_completion(code: &str, expected_completions: &str) {
         check_completion(code, expected_completions, CompletionKind::Reference);
     }
 
     #[test]
-    #[ignore] // should not complete foo, which currently doesn't work
     fn dont_complete_current_use() {
-        check_reference_completion(
-            "dont_complete_current_use",
-            r"
-            use self::foo<|>;
-            ",
-        );
+        covers!(dont_complete_current_use);
+        let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference);
+        assert!(completions.is_empty());
     }
 
     #[test]
index 7b8972af0e66313b3a1119b83856d811d80a1dfb..22ff08a23040c1562f4666e08ef0202f71f06a75 100644 (file)
@@ -306,10 +306,9 @@ fn function_item_label(ctx: &CompletionContext, function: hir::Function) -> Opti
 }
 
 #[cfg(test)]
-pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind) {
+pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
     use crate::mock_analysis::{single_file_with_position, analysis_and_position};
     use crate::completion::completions;
-    use insta::assert_debug_snapshot_matches;
     let (analysis, position) = if code.contains("//-") {
         analysis_and_position(code)
     } else {
@@ -320,6 +319,13 @@ pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind
     let mut kind_completions: Vec<CompletionItem> =
         completion_items.into_iter().filter(|c| c.completion_kind == kind).collect();
     kind_completions.sort_by_key(|c| c.label.clone());
+    kind_completions
+}
+
+#[cfg(test)]
+pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind) {
+    use insta::assert_debug_snapshot_matches;
+    let kind_completions = do_completion(code, kind);
     assert_debug_snapshot_matches!(test_name, kind_completions);
 }
 
index 21ce7289db8f80e0443b5465d62d0279edcdc5d8..44d8fdf829700a00279b890c3ac2e87065dcbd93 100644 (file)
@@ -3,4 +3,5 @@
     goto_definition_works_for_methods
     goto_definition_works_for_fields
     call_info_bad_offset
+    dont_complete_current_use
 );