fix regression in self-referential completion

This commit is contained in:
Aleksey Kladov 2019-02-11 23:40:08 +03:00
parent db6d214411
commit 8ef80086a0
3 changed files with 32 additions and 15 deletions

View file

@ -1,10 +1,9 @@
use join_to_string::join; use join_to_string::join;
use hir::{Docs, Resolution}; use hir::{Docs, Resolution};
use ra_syntax::AstNode;
use test_utils::tested_by;
use crate::{ use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext},
};
pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
let path = match &ctx.path_prefix { let path = match &ctx.path_prefix {
@ -19,6 +18,17 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
hir::ModuleDef::Module(module) => { hir::ModuleDef::Module(module) => {
let module_scope = module.scope(ctx.db); let module_scope = module.scope(ctx.db);
for (name, res) in module_scope.entries() { 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( CompletionItem::new(
CompletionKind::Reference, CompletionKind::Reference,
ctx.source_range(), ctx.source_range(),
@ -54,22 +64,22 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::completion::CompletionKind; use crate::completion::{
use crate::completion::completion_item::check_completion; CompletionKind,
completion_item::{check_completion, do_completion},
};
use test_utils::covers;
fn check_reference_completion(code: &str, expected_completions: &str) { fn check_reference_completion(code: &str, expected_completions: &str) {
check_completion(code, expected_completions, CompletionKind::Reference); check_completion(code, expected_completions, CompletionKind::Reference);
} }
#[test] #[test]
#[ignore] // should not complete foo, which currently doesn't work
fn dont_complete_current_use() { fn dont_complete_current_use() {
check_reference_completion( covers!(dont_complete_current_use);
"dont_complete_current_use", let completions = do_completion(r"use self::foo<|>;", CompletionKind::Reference);
r" assert!(completions.is_empty());
use self::foo<|>;
",
);
} }
#[test] #[test]

View file

@ -306,10 +306,9 @@ fn function_item_label(ctx: &CompletionContext, function: hir::Function) -> Opti
} }
#[cfg(test)] #[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::mock_analysis::{single_file_with_position, analysis_and_position};
use crate::completion::completions; use crate::completion::completions;
use insta::assert_debug_snapshot_matches;
let (analysis, position) = if code.contains("//-") { let (analysis, position) = if code.contains("//-") {
analysis_and_position(code) analysis_and_position(code)
} else { } else {
@ -320,6 +319,13 @@ pub(crate) fn check_completion(test_name: &str, code: &str, kind: CompletionKind
let mut kind_completions: Vec<CompletionItem> = let mut kind_completions: Vec<CompletionItem> =
completion_items.into_iter().filter(|c| c.completion_kind == kind).collect(); completion_items.into_iter().filter(|c| c.completion_kind == kind).collect();
kind_completions.sort_by_key(|c| c.label.clone()); 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); assert_debug_snapshot_matches!(test_name, kind_completions);
} }

View file

@ -3,4 +3,5 @@ test_utils::marks!(
goto_definition_works_for_methods goto_definition_works_for_methods
goto_definition_works_for_fields goto_definition_works_for_fields
call_info_bad_offset call_info_bad_offset
dont_complete_current_use
); );