Adhere to style guidelines in import_assets

This commit is contained in:
Lukas Wirth 2020-10-13 18:52:56 +02:00
parent 256104d78e
commit 02b844e9fb
2 changed files with 45 additions and 43 deletions

View file

@ -1,3 +1,5 @@
use syntax::ast;
use crate::{ use crate::{
utils::import_assets::{ImportAssets, ImportCandidate}, utils::import_assets::{ImportAssets, ImportCandidate},
utils::{insert_use, mod_path_to_ast, ImportScope}, utils::{insert_use, mod_path_to_ast, ImportScope},
@ -24,16 +26,24 @@ use crate::{
// # pub mod std { pub mod collections { pub struct HashMap { } } } // # pub mod std { pub mod collections { pub struct HashMap { } } }
// ``` // ```
pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
let auto_import_assets = ImportAssets::new(&ctx)?; let import_assets =
let proposed_imports = auto_import_assets.search_for_imports(&ctx.sema, &ctx.config.insert_use); if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() {
ImportAssets::for_regular_path(path_under_caret, &ctx.sema)
} else if let Some(method_under_caret) =
ctx.find_node_at_offset_with_descend::<ast::MethodCallExpr>()
{
ImportAssets::for_method_call(method_under_caret, &ctx.sema)
} else {
None
}?;
let proposed_imports = import_assets.search_for_imports(&ctx.sema, &ctx.config.insert_use);
if proposed_imports.is_empty() { if proposed_imports.is_empty() {
return None; return None;
} }
let range = ctx.sema.original_range(auto_import_assets.syntax_under_caret()).range; let range = ctx.sema.original_range(import_assets.syntax_under_caret()).range;
let group = import_group_message(auto_import_assets.import_candidate()); let group = import_group_message(import_assets.import_candidate());
let scope = let scope = ImportScope::find_insert_use_container(import_assets.syntax_under_caret(), ctx)?;
ImportScope::find_insert_use_container(auto_import_assets.syntax_under_caret(), ctx)?;
let syntax = scope.as_syntax_node(); let syntax = scope.as_syntax_node();
for import in proposed_imports { for import in proposed_imports {
acc.add_group( acc.add_group(

View file

@ -9,6 +9,23 @@ use syntax::{ast, AstNode, SyntaxNode};
use crate::assist_config::InsertUseConfig; use crate::assist_config::InsertUseConfig;
#[derive(Debug)]
pub(crate) enum ImportCandidate {
/// Simple name like 'HashMap'
UnqualifiedName(String),
/// First part of the qualified name.
/// For 'std::collections::HashMap', that will be 'std'.
QualifierStart(String),
/// A trait associated function (with no self parameter) or associated constant.
/// For 'test_mod::TestEnum::test_function', `Type` is the `test_mod::TestEnum` expression type
/// and `String` is the `test_function`
TraitAssocItem(hir::Type, String),
/// A trait method with self parameter.
/// For 'test_enum.test_method()', `Type` is the `test_enum` expression type
/// and `String` is the `test_method`
TraitMethod(hir::Type, String),
}
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct ImportAssets { pub(crate) struct ImportAssets {
import_candidate: ImportCandidate, import_candidate: ImportCandidate,
@ -17,23 +34,7 @@ pub(crate) struct ImportAssets {
} }
impl ImportAssets { impl ImportAssets {
pub(crate) fn new(ctx: &crate::assist_context::AssistContext) -> Option<Self> { pub(crate) fn for_method_call(
if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() {
Self::for_regular_path(path_under_caret, &ctx.sema)
} else {
Self::for_method_call(ctx.find_node_at_offset_with_descend()?, &ctx.sema)
}
}
pub(crate) fn syntax_under_caret(&self) -> &SyntaxNode {
&self.syntax_under_caret
}
pub(crate) fn import_candidate(&self) -> &ImportCandidate {
&self.import_candidate
}
fn for_method_call(
method_call: ast::MethodCallExpr, method_call: ast::MethodCallExpr,
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
) -> Option<Self> { ) -> Option<Self> {
@ -46,7 +47,7 @@ impl ImportAssets {
}) })
} }
fn for_regular_path( pub(crate) fn for_regular_path(
path_under_caret: ast::Path, path_under_caret: ast::Path,
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
) -> Option<Self> { ) -> Option<Self> {
@ -63,6 +64,14 @@ impl ImportAssets {
}) })
} }
pub(crate) fn syntax_under_caret(&self) -> &SyntaxNode {
&self.syntax_under_caret
}
pub(crate) fn import_candidate(&self) -> &ImportCandidate {
&self.import_candidate
}
fn get_search_query(&self) -> &str { fn get_search_query(&self) -> &str {
match &self.import_candidate { match &self.import_candidate {
ImportCandidate::UnqualifiedName(name) => name, ImportCandidate::UnqualifiedName(name) => name,
@ -182,25 +191,8 @@ impl ImportAssets {
} }
} }
#[derive(Debug)]
pub(crate) enum ImportCandidate {
/// Simple name like 'HashMap'
UnqualifiedName(String),
/// First part of the qualified name.
/// For 'std::collections::HashMap', that will be 'std'.
QualifierStart(String),
/// A trait associated function (with no self parameter) or associated constant.
/// For 'test_mod::TestEnum::test_function', `Type` is the `test_mod::TestEnum` expression type
/// and `String` is the `test_function`
TraitAssocItem(hir::Type, String),
/// A trait method with self parameter.
/// For 'test_enum.test_method()', `Type` is the `test_enum` expression type
/// and `String` is the `test_method`
TraitMethod(hir::Type, String),
}
impl ImportCandidate { impl ImportCandidate {
pub(crate) fn for_method_call( fn for_method_call(
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
method_call: &ast::MethodCallExpr, method_call: &ast::MethodCallExpr,
) -> Option<Self> { ) -> Option<Self> {
@ -213,7 +205,7 @@ impl ImportCandidate {
)) ))
} }
pub(crate) fn for_regular_path( fn for_regular_path(
sema: &Semantics<RootDatabase>, sema: &Semantics<RootDatabase>,
path_under_caret: &ast::Path, path_under_caret: &ast::Path,
) -> Option<Self> { ) -> Option<Self> {