mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Move autoimport completion into the unqialified_path module
This commit is contained in:
parent
3b0fc4d7f2
commit
ee99620754
5 changed files with 139 additions and 156 deletions
|
@ -22,7 +22,6 @@ text_edit = { path = "../text_edit", version = "0.0.0" }
|
|||
base_db = { path = "../base_db", version = "0.0.0" }
|
||||
ide_db = { path = "../ide_db", version = "0.0.0" }
|
||||
profile = { path = "../profile", version = "0.0.0" }
|
||||
assists = { path = "../assists", version = "0.0.0" }
|
||||
test_utils = { path = "../test_utils", version = "0.0.0" }
|
||||
|
||||
# completions crate should depend only on the top-level `hir` package. if you need
|
||||
|
|
|
@ -13,7 +13,6 @@ pub(crate) mod postfix;
|
|||
pub(crate) mod macro_in_item_position;
|
||||
pub(crate) mod trait_impl;
|
||||
pub(crate) mod mod_;
|
||||
pub(crate) mod magic;
|
||||
|
||||
use hir::{ModPath, ScopeDef, Type};
|
||||
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
//! TODO kb move this into the complete_unqualified_path when starts to work properly
|
||||
|
||||
use assists::utils::{insert_use, mod_path_to_ast, ImportScope};
|
||||
use either::Either;
|
||||
use hir::{ModuleDef, ScopeDef};
|
||||
use ide_db::imports_locator;
|
||||
use syntax::{algo, AstNode};
|
||||
|
||||
use crate::{
|
||||
context::CompletionContext,
|
||||
render::{render_resolution, RenderContext},
|
||||
};
|
||||
|
||||
use super::Completions;
|
||||
|
||||
// TODO kb add a setting toggle for this feature?
|
||||
pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
||||
if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) {
|
||||
return None;
|
||||
}
|
||||
let _p = profile::span("complete_magic");
|
||||
let current_module = ctx.scope.module()?;
|
||||
let anchor = ctx.name_ref_syntax.as_ref()?;
|
||||
let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
|
||||
|
||||
let potential_import_name = ctx.token.to_string();
|
||||
|
||||
let possible_imports =
|
||||
imports_locator::find_similar_imports(&ctx.sema, ctx.krate?, &potential_import_name, 400)
|
||||
.filter_map(|import_candidate| match import_candidate {
|
||||
// when completing outside the use declaration, modules are pretty useless
|
||||
// and tend to bloat the completion suggestions a lot
|
||||
Either::Left(ModuleDef::Module(_)) => None,
|
||||
Either::Left(module_def) => Some((
|
||||
current_module.find_use_path(ctx.db, module_def)?,
|
||||
ScopeDef::ModuleDef(module_def),
|
||||
)),
|
||||
Either::Right(macro_def) => Some((
|
||||
current_module.find_use_path(ctx.db, macro_def)?,
|
||||
ScopeDef::MacroDef(macro_def),
|
||||
)),
|
||||
})
|
||||
.filter_map(|(mod_path, definition)| {
|
||||
let mut resolution_with_missing_import = render_resolution(
|
||||
RenderContext::new(ctx),
|
||||
mod_path.segments.last()?.to_string(),
|
||||
&definition,
|
||||
)?;
|
||||
|
||||
let mut text_edits =
|
||||
resolution_with_missing_import.text_edit().to_owned().into_builder();
|
||||
|
||||
let rewriter =
|
||||
insert_use(&import_scope, mod_path_to_ast(&mod_path), ctx.config.merge);
|
||||
let old_ast = rewriter.rewrite_root()?;
|
||||
algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits);
|
||||
|
||||
resolution_with_missing_import.update_text_edit(text_edits.finish());
|
||||
|
||||
Some(resolution_with_missing_import)
|
||||
});
|
||||
|
||||
acc.add_all(possible_imports);
|
||||
Some(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::test_utils::check_edit;
|
||||
|
||||
#[test]
|
||||
fn function_magic_completion() {
|
||||
check_edit(
|
||||
"stdin",
|
||||
r#"
|
||||
//- /lib.rs crate:dep
|
||||
pub mod io {
|
||||
pub fn stdin() {}
|
||||
};
|
||||
|
||||
//- /main.rs crate:main deps:dep
|
||||
fn main() {
|
||||
stdi<|>
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
use dep::io::stdin;
|
||||
|
||||
fn main() {
|
||||
stdin()$0
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macro_magic_completion() {
|
||||
check_edit(
|
||||
"macro_with_curlies!",
|
||||
r#"
|
||||
//- /lib.rs crate:dep
|
||||
/// Please call me as macro_with_curlies! {}
|
||||
#[macro_export]
|
||||
macro_rules! macro_with_curlies {
|
||||
() => {}
|
||||
}
|
||||
|
||||
//- /main.rs crate:main deps:dep
|
||||
fn main() {
|
||||
curli<|>
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
use dep::macro_with_curlies;
|
||||
|
||||
fn main() {
|
||||
macro_with_curlies! {$0}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_insensitive_magic_completion_works() {
|
||||
check_edit(
|
||||
"ThirdStruct",
|
||||
r#"
|
||||
//- /lib.rs crate:dep
|
||||
pub struct FirstStruct;
|
||||
pub mod some_module {
|
||||
pub struct SecondStruct;
|
||||
pub struct ThirdStruct;
|
||||
}
|
||||
|
||||
//- /main.rs crate:main deps:dep
|
||||
use dep::{FirstStruct, some_module::SecondStruct};
|
||||
|
||||
fn main() {
|
||||
this<|>
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
|
||||
|
||||
fn main() {
|
||||
ThirdStruct
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,16 @@
|
|||
//! Completion of names from the current scope, e.g. locals and imported items.
|
||||
|
||||
use assists::utils::{insert_use, mod_path_to_ast, ImportScope};
|
||||
use either::Either;
|
||||
use hir::{Adt, ModuleDef, ScopeDef, Type};
|
||||
use syntax::AstNode;
|
||||
use ide_db::imports_locator;
|
||||
use syntax::{algo, AstNode};
|
||||
use test_utils::mark;
|
||||
|
||||
use crate::{CompletionContext, Completions};
|
||||
use crate::{
|
||||
render::{render_resolution, RenderContext},
|
||||
CompletionContext, Completions,
|
||||
};
|
||||
|
||||
pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) {
|
||||
|
@ -37,6 +43,56 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
|
|||
}
|
||||
acc.add_resolution(ctx, name.to_string(), &res)
|
||||
});
|
||||
|
||||
fuzzy_completion(acc, ctx).unwrap_or_default()
|
||||
}
|
||||
|
||||
// TODO kb add a setting toggle for this feature?
|
||||
fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
||||
let _p = profile::span("fuzzy_completion®");
|
||||
let current_module = ctx.scope.module()?;
|
||||
let anchor = ctx.name_ref_syntax.as_ref()?;
|
||||
let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
|
||||
|
||||
let potential_import_name = ctx.token.to_string();
|
||||
|
||||
let possible_imports =
|
||||
imports_locator::find_similar_imports(&ctx.sema, ctx.krate?, &potential_import_name, 400)
|
||||
.filter_map(|import_candidate| match import_candidate {
|
||||
// when completing outside the use declaration, modules are pretty useless
|
||||
// and tend to bloat the completion suggestions a lot
|
||||
Either::Left(ModuleDef::Module(_)) => None,
|
||||
Either::Left(module_def) => Some((
|
||||
current_module.find_use_path(ctx.db, module_def)?,
|
||||
ScopeDef::ModuleDef(module_def),
|
||||
)),
|
||||
Either::Right(macro_def) => Some((
|
||||
current_module.find_use_path(ctx.db, macro_def)?,
|
||||
ScopeDef::MacroDef(macro_def),
|
||||
)),
|
||||
})
|
||||
.filter_map(|(mod_path, definition)| {
|
||||
let mut resolution_with_missing_import = render_resolution(
|
||||
RenderContext::new(ctx),
|
||||
mod_path.segments.last()?.to_string(),
|
||||
&definition,
|
||||
)?;
|
||||
|
||||
let mut text_edits =
|
||||
resolution_with_missing_import.text_edit().to_owned().into_builder();
|
||||
|
||||
let rewriter =
|
||||
insert_use(&import_scope, mod_path_to_ast(&mod_path), ctx.config.merge);
|
||||
let old_ast = rewriter.rewrite_root()?;
|
||||
algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut text_edits);
|
||||
|
||||
resolution_with_missing_import.update_text_edit(text_edits.finish());
|
||||
|
||||
Some(resolution_with_missing_import)
|
||||
});
|
||||
|
||||
acc.add_all(possible_imports);
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &Type) {
|
||||
|
@ -676,4 +732,85 @@ impl My<|>
|
|||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_magic_completion() {
|
||||
check_edit(
|
||||
"stdin",
|
||||
r#"
|
||||
//- /lib.rs crate:dep
|
||||
pub mod io {
|
||||
pub fn stdin() {}
|
||||
};
|
||||
|
||||
//- /main.rs crate:main deps:dep
|
||||
fn main() {
|
||||
stdi<|>
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
use dep::io::stdin;
|
||||
|
||||
fn main() {
|
||||
stdin()$0
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macro_magic_completion() {
|
||||
check_edit(
|
||||
"macro_with_curlies!",
|
||||
r#"
|
||||
//- /lib.rs crate:dep
|
||||
/// Please call me as macro_with_curlies! {}
|
||||
#[macro_export]
|
||||
macro_rules! macro_with_curlies {
|
||||
() => {}
|
||||
}
|
||||
|
||||
//- /main.rs crate:main deps:dep
|
||||
fn main() {
|
||||
curli<|>
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
use dep::macro_with_curlies;
|
||||
|
||||
fn main() {
|
||||
macro_with_curlies! {$0}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_insensitive_magic_completion_works() {
|
||||
check_edit(
|
||||
"ThirdStruct",
|
||||
r#"
|
||||
//- /lib.rs crate:dep
|
||||
pub struct FirstStruct;
|
||||
pub mod some_module {
|
||||
pub struct SecondStruct;
|
||||
pub struct ThirdStruct;
|
||||
}
|
||||
|
||||
//- /main.rs crate:main deps:dep
|
||||
use dep::{FirstStruct, some_module::SecondStruct};
|
||||
|
||||
fn main() {
|
||||
this<|>
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
|
||||
|
||||
fn main() {
|
||||
ThirdStruct
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,6 @@ pub fn completions(
|
|||
completions::macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx);
|
||||
completions::trait_impl::complete_trait_impl(&mut acc, &ctx);
|
||||
completions::mod_::complete_mod(&mut acc, &ctx);
|
||||
completions::magic::complete_magic(&mut acc, &ctx);
|
||||
|
||||
Some(acc)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue