internal: Lift out item list path completions from (un)qualified_path

This commit is contained in:
Lukas Wirth 2022-05-05 12:08:40 +02:00
parent 52a58f672e
commit 25d133e3b8
13 changed files with 97 additions and 68 deletions

View file

@ -6,6 +6,7 @@ pub(crate) mod extern_abi;
pub(crate) mod flyimport;
pub(crate) mod fn_param;
pub(crate) mod format_string;
pub(crate) mod item_list;
pub(crate) mod keyword;
pub(crate) mod lifetime;
pub(crate) mod mod_;

View file

@ -0,0 +1,48 @@
//! Completion of paths and keywords at item list position.
use crate::{
completions::module_or_fn_macro,
context::{PathCompletionCtx, PathKind, PathQualifierCtx},
CompletionContext, Completions,
};
pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext) {
let _p = profile::span("complete_unqualified_path");
if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
return;
}
let (&is_absolute_path, qualifier) = match &ctx.path_context {
Some(PathCompletionCtx {
kind: Some(PathKind::Item), is_absolute_path, qualifier, ..
}) => (is_absolute_path, qualifier),
_ => return,
};
match qualifier {
Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
if let Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))) = resolution {
for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
if let Some(def) = module_or_fn_macro(ctx.db, def) {
acc.add_resolution(ctx, name, def);
}
}
}
if *is_super_chain {
acc.add_keyword(ctx, "super::");
}
}
None if is_absolute_path => {
acc.add_crate_roots(ctx);
}
None => {
ctx.process_all_names(&mut |name, def| {
if let Some(def) = module_or_fn_macro(ctx.db, def) {
acc.add_resolution(ctx, name, def);
}
});
acc.add_nameref_keywords_with_colon(ctx);
}
}
}

View file

@ -40,7 +40,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
if let Some(PathKind::Vis { .. }) = ctx.path_kind() {
return;
}
if ctx.has_impl_or_trait_prev_sibling() {
if ctx.has_unfinished_impl_or_trait_prev_sibling() {
add_keyword("where", "where");
if ctx.has_impl_prev_sibling() {
add_keyword("for", "for");

View file

@ -196,12 +196,13 @@ fn pattern_path_completion(
// qualifier can only be none here if we are in a TuplePat or RecordPat in which case special characters have to follow the path
None if *is_absolute_path => acc.add_crate_roots(ctx),
None => {
cov_mark::hit!(unqualified_path_only_modules_in_import);
ctx.process_all_names(&mut |name, res| {
if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
// FIXME: properly filter here
if let ScopeDef::ModuleDef(_) = res {
acc.add_resolution(ctx, name, res);
}
});
acc.add_nameref_keywords_with_colon(ctx);
}
}

View file

@ -5,14 +5,12 @@ use ide_db::FxHashSet;
use syntax::ast;
use crate::{
completions::module_or_fn_macro,
context::{PathCompletionCtx, PathKind},
patterns::ImmediateLocation,
CompletionContext, Completions,
};
pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
if ctx.is_path_disallowed() || ctx.has_impl_or_trait_prev_sibling() {
if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
return;
}
if ctx.pattern_ctx.is_some() {
@ -54,26 +52,13 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
None => return,
};
match ctx.completion_location {
Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
if let Some(def) = module_or_fn_macro(ctx.db, def) {
acc.add_resolution(ctx, name, def);
}
}
}
return;
}
_ => (),
}
match kind {
Some(
PathKind::Pat
| PathKind::Attr { .. }
| PathKind::Vis { .. }
| PathKind::Use
| PathKind::Item
| PathKind::Derive,
) => {
return;

View file

@ -46,7 +46,7 @@ pub(crate) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionConte
if !(ctx.expects_item() || ctx.has_block_expr_parent())
|| ctx.previous_token_is(T![unsafe])
|| ctx.path_qual().is_some()
|| ctx.has_impl_or_trait_prev_sibling()
|| ctx.has_unfinished_impl_or_trait_prev_sibling()
{
return;
}

View file

@ -547,12 +547,7 @@ impl Test for T {
type Test = fn $0;
}
",
expect![[r#"
sp Self
st T
tt Test
bt u32
"#]],
expect![[r#""#]],
);
}

View file

@ -4,7 +4,6 @@ use hir::ScopeDef;
use syntax::{ast, AstNode};
use crate::{
completions::module_or_fn_macro,
context::{PathCompletionCtx, PathKind},
patterns::ImmediateLocation,
CompletionContext, Completions,
@ -12,14 +11,15 @@ use crate::{
pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
let _p = profile::span("complete_unqualified_path");
if ctx.is_path_disallowed() || ctx.has_impl_or_trait_prev_sibling() {
if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
return;
}
match ctx.path_context {
match &ctx.path_context {
Some(PathCompletionCtx {
is_absolute_path: false,
qualifier: None,
kind: None | Some(PathKind::Expr | PathKind::Type | PathKind::Item),
kind: None | Some(PathKind::Expr | PathKind::Type),
..
}) => (),
_ => return,
@ -28,15 +28,6 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
acc.add_nameref_keywords(ctx);
match &ctx.completion_location {
Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
// only show macros in {Assoc}ItemList
ctx.process_all_names(&mut |name, def| {
if let Some(def) = module_or_fn_macro(ctx.db, def) {
acc.add_resolution(ctx, name, def);
}
});
return;
}
Some(ImmediateLocation::TypeBound) => {
ctx.process_all_names(&mut |name, res| {
let add_resolution = match res {

View file

@ -270,13 +270,17 @@ impl<'a> CompletionContext<'a> {
|| matches!(self.name_ctx, Some(NameContext::RecordField))
}
pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool {
/// Whether the cursor is right after a trait or impl header.
/// trait Foo ident$0
// FIXME: This probably shouldn't exist
pub(crate) fn has_unfinished_impl_or_trait_prev_sibling(&self) -> bool {
matches!(
self.prev_sibling,
Some(ImmediatePrevSibling::ImplDefType | ImmediatePrevSibling::TraitDefName)
)
}
// FIXME: This probably shouldn't exist
pub(crate) fn has_impl_prev_sibling(&self) -> bool {
matches!(self.prev_sibling, Some(ImmediatePrevSibling::ImplDefType))
}
@ -289,6 +293,7 @@ impl<'a> CompletionContext<'a> {
matches!(self.prev_sibling, Some(ImmediatePrevSibling::IfExpr))
}
// FIXME: This shouldn't exist
pub(crate) fn is_path_disallowed(&self) -> bool {
self.previous_token_is(T![unsafe])
|| matches!(

View file

@ -155,6 +155,7 @@ pub fn completions(
completions::flyimport::import_on_the_fly(&mut acc, &ctx);
completions::fn_param::complete_fn_param(&mut acc, &ctx);
completions::format_string::format_string(&mut acc, &ctx);
completions::item_list::complete_item_list(&mut acc, &ctx);
completions::inferred_type(&mut acc, &ctx);
completions::keyword::complete_expr_keyword(&mut acc, &ctx);
completions::lifetime::complete_label(&mut acc, &ctx);

View file

@ -95,7 +95,7 @@ fn after_struct_name() {
ma makro!() macro_rules! makro
md module
kw const
kw crate
kw crate::
kw enum
kw extern
kw fn
@ -104,10 +104,10 @@ fn after_struct_name() {
kw pub
kw pub(crate)
kw pub(super)
kw self
kw self::
kw static
kw struct
kw super
kw super::
kw trait
kw type
kw union
@ -129,7 +129,7 @@ fn after_fn_name() {
ma makro!() macro_rules! makro
md module
kw const
kw crate
kw crate::
kw enum
kw extern
kw fn
@ -138,10 +138,10 @@ fn after_fn_name() {
kw pub
kw pub(crate)
kw pub(super)
kw self
kw self::
kw static
kw struct
kw super
kw super::
kw trait
kw type
kw union

View file

@ -15,7 +15,7 @@ fn in_mod_item_list() {
expect![[r#"
ma makro!() macro_rules! makro
kw const
kw crate
kw crate::
kw enum
kw extern
kw fn
@ -24,10 +24,10 @@ fn in_mod_item_list() {
kw pub
kw pub(crate)
kw pub(super)
kw self
kw self::
kw static
kw struct
kw super
kw super::
kw trait
kw type
kw union
@ -48,7 +48,7 @@ fn in_source_file_item_list() {
ma makro!() macro_rules! makro
md module
kw const
kw crate
kw crate::
kw enum
kw extern
kw fn
@ -57,10 +57,10 @@ fn in_source_file_item_list() {
kw pub
kw pub(crate)
kw pub(super)
kw self
kw self::
kw static
kw struct
kw super
kw super::
kw trait
kw type
kw union
@ -166,13 +166,13 @@ fn in_impl_assoc_item_list() {
ma makro!() macro_rules! makro
md module
kw const
kw crate
kw crate::
kw fn
kw pub
kw pub(crate)
kw pub(super)
kw self
kw super
kw self::
kw super::
kw type
kw unsafe
"#]],
@ -203,10 +203,10 @@ fn in_trait_assoc_item_list() {
ma makro!() macro_rules! makro
md module
kw const
kw crate
kw crate::
kw fn
kw self
kw super
kw self::
kw super::
kw type
kw unsafe
"#]],
@ -240,13 +240,13 @@ impl Test for () {
md module
ta type Type1 =
kw const
kw crate
kw crate::
kw fn
kw pub
kw pub(crate)
kw pub(super)
kw self
kw super
kw self::
kw super::
kw type
kw unsafe
"#]],

View file

@ -394,6 +394,9 @@ fn foo() {
}
"#,
expect![[r#"
fn foo() fn()
st Bar
bt u32
kw crate::
kw self::
kw super::
@ -403,19 +406,18 @@ fn foo() {
r#"
struct Foo { bar: u32 }
fn foo() {
match Foo { bar: 0 } {
match (Foo { bar: 0 }) {
F$0 { bar } => {}
}
}
"#,
expect![[r#"
fn foo() fn()
fn foo() fn()
st Foo
bt u32
kw crate
kw return
kw self
kw super
kw crate::
kw self::
kw super::
"#]],
);
check_empty(