Properly resolve completion edits for empty input

This commit is contained in:
Kirill Bulatov 2021-01-17 02:52:36 +02:00
parent 09c11054a1
commit d1ac3293f4
2 changed files with 46 additions and 35 deletions

View file

@ -85,7 +85,7 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
let user_input_lowercased = potential_import_name.to_lowercase();
let import_assets = import_assets(ctx, potential_import_name)?;
let import_scope = ImportScope::find_insert_use_container(
position_for_import(ctx, import_assets.import_candidate())?,
position_for_import(ctx, Some(import_assets.import_candidate()))?,
&ctx.sema,
)?;
let mut all_mod_paths = import_assets
@ -122,14 +122,20 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
Some(())
}
fn position_for_import<'a>(
pub(crate) fn position_for_import<'a>(
ctx: &'a CompletionContext,
import_candidate: &ImportCandidate,
import_candidate: Option<&ImportCandidate>,
) -> Option<&'a SyntaxNode> {
Some(match import_candidate {
ImportCandidate::Path(_) => ctx.name_ref_syntax.as_ref()?.syntax(),
ImportCandidate::TraitAssocItem(_) => ctx.path_qual.as_ref()?.syntax(),
ImportCandidate::TraitMethod(_) => ctx.dot_receiver.as_ref()?.syntax(),
Some(ImportCandidate::Path(_)) => ctx.name_ref_syntax.as_ref()?.syntax(),
Some(ImportCandidate::TraitAssocItem(_)) => ctx.path_qual.as_ref()?.syntax(),
Some(ImportCandidate::TraitMethod(_)) => ctx.dot_receiver.as_ref()?.syntax(),
None => ctx
.name_ref_syntax
.as_ref()
.map(|name_ref| name_ref.syntax())
.or_else(|| ctx.path_qual.as_ref().map(|path| path.syntax()))
.or_else(|| ctx.dot_receiver.as_ref().map(|expr| expr.syntax()))?,
})
}
@ -565,7 +571,8 @@ fn main() {
#[test]
fn blanket_trait_impl_import() {
check(
check_edit(
"another_function",
r#"
//- /lib.rs crate:dep
pub mod test_mod {
@ -583,9 +590,13 @@ fn main() {
dep::test_mod::TestStruct::ano$0
}
"#,
expect![[r#"
fn another_function() (dep::test_mod::TestTrait) fn another_function()
"#]],
r#"
use dep::test_mod::TestTrait;
fn main() {
dep::test_mod::TestStruct::another_function()$0
}
"#,
);
}
@ -593,28 +604,28 @@ fn main() {
fn zero_input_assoc_item_completion() {
check(
r#"
//- /lib.rs crate:dep
pub mod test_mod {
pub trait TestTrait {
const SPECIAL_CONST: u8;
type HumbleType;
fn weird_function();
fn random_method(&self);
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
const SPECIAL_CONST: u8 = 42;
type HumbleType = ();
fn weird_function() {}
fn random_method(&self) {}
}
}
//- /lib.rs crate:dep
pub mod test_mod {
pub trait TestTrait {
const SPECIAL_CONST: u8;
type HumbleType;
fn weird_function();
fn random_method(&self);
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
const SPECIAL_CONST: u8 = 42;
type HumbleType = ();
fn weird_function() {}
fn random_method(&self) {}
}
}
//- /main.rs crate:main deps:dep
fn main() {
let test_struct = dep::test_mod::TestStruct {};
test_struct.$0
}
//- /main.rs crate:main deps:dep
fn main() {
let test_struct = dep::test_mod::TestStruct {};
test_struct.$0
}
"#,
expect![[r#"
me random_method() (dep::test_mod::TestTrait) fn random_method(&self)

View file

@ -11,10 +11,10 @@ mod render;
mod completions;
use completions::flyimport::position_for_import;
use ide_db::{
base_db::FilePosition, helpers::insert_use::ImportScope, imports_locator, RootDatabase,
};
use syntax::AstNode;
use text_edit::TextEdit;
use crate::{completions::Completions, context::CompletionContext, item::CompletionKind};
@ -142,10 +142,10 @@ pub fn resolve_completion_edits(
import_for_trait_assoc_item: bool,
) -> Option<Vec<TextEdit>> {
let ctx = CompletionContext::new(db, position, config)?;
let anchor = ctx.name_ref_syntax.as_ref()?;
let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
let position_for_import = position_for_import(&ctx, None)?;
let import_scope = ImportScope::find_insert_use_container(position_for_import, &ctx.sema)?;
let current_module = ctx.sema.scope(anchor.syntax()).module()?;
let current_module = ctx.sema.scope(position_for_import).module()?;
let current_crate = current_module.krate();
let import_path = imports_locator::find_exact_imports(&ctx.sema, current_crate, imported_name)