mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-11 07:34:22 +00:00
internal: Collapse completion ctx path qualifier and is_absolute_path into enum
This commit is contained in:
parent
85363d18e8
commit
531060f103
14 changed files with 141 additions and 151 deletions
|
@ -18,7 +18,9 @@ use syntax::{
|
|||
|
||||
use crate::{
|
||||
completions::module_or_attr,
|
||||
context::{CompletionContext, IdentContext, PathCompletionCtx, PathKind, PathQualifierCtx},
|
||||
context::{
|
||||
CompletionContext, IdentContext, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified,
|
||||
},
|
||||
item::CompletionItem,
|
||||
Completions,
|
||||
};
|
||||
|
@ -72,18 +74,17 @@ pub(crate) fn complete_known_attribute_input(
|
|||
}
|
||||
|
||||
pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let (is_absolute_path, qualifier, is_inner, annotated_item_kind) = match ctx.path_context() {
|
||||
let (qualified, is_inner, annotated_item_kind) = match ctx.path_context() {
|
||||
Some(&PathCompletionCtx {
|
||||
kind: PathKind::Attr { kind, annotated_item_kind },
|
||||
is_absolute_path,
|
||||
ref qualifier,
|
||||
ref qualified,
|
||||
..
|
||||
}) => (is_absolute_path, qualifier, kind == AttrKind::Inner, annotated_item_kind),
|
||||
}) => (qualified, kind == AttrKind::Inner, annotated_item_kind),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
match qualifier {
|
||||
Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
match qualified {
|
||||
Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
if *is_super_chain {
|
||||
acc.add_keyword(ctx, "super::");
|
||||
}
|
||||
|
@ -101,9 +102,9 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext)
|
|||
return;
|
||||
}
|
||||
// fresh use tree with leading colon2, only show crate roots
|
||||
None if is_absolute_path => acc.add_crate_roots(ctx),
|
||||
Qualified::Absolute => acc.add_crate_roots(ctx),
|
||||
// only show modules in a fresh UseTree
|
||||
None => {
|
||||
Qualified::No => {
|
||||
ctx.process_all_names(&mut |name, def| {
|
||||
if let Some(def) = module_or_attr(ctx.db, def) {
|
||||
acc.add_resolution(ctx, name, def);
|
||||
|
|
|
@ -5,26 +5,21 @@ use itertools::Itertools;
|
|||
use syntax::SmolStr;
|
||||
|
||||
use crate::{
|
||||
context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx},
|
||||
context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified},
|
||||
item::CompletionItem,
|
||||
Completions,
|
||||
};
|
||||
|
||||
pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let (qualifier, is_absolute_path) = match ctx.path_context() {
|
||||
Some(&PathCompletionCtx {
|
||||
kind: PathKind::Derive,
|
||||
ref qualifier,
|
||||
is_absolute_path,
|
||||
..
|
||||
}) => (qualifier, is_absolute_path),
|
||||
let qualified = match ctx.path_context() {
|
||||
Some(&PathCompletionCtx { kind: PathKind::Derive, ref qualified, .. }) => qualified,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let core = ctx.famous_defs().core();
|
||||
|
||||
match qualifier {
|
||||
Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
match qualified {
|
||||
Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
if *is_super_chain {
|
||||
acc.add_keyword(ctx, "super::");
|
||||
}
|
||||
|
@ -47,9 +42,9 @@ pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
|
|||
}
|
||||
}
|
||||
}
|
||||
None if is_absolute_path => acc.add_crate_roots(ctx),
|
||||
Qualified::Absolute => acc.add_crate_roots(ctx),
|
||||
// only show modules in a fresh UseTree
|
||||
None => {
|
||||
Qualified::No => {
|
||||
ctx.process_all_names(&mut |name, def| {
|
||||
let mac = match def {
|
||||
ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac))
|
||||
|
@ -65,7 +60,7 @@ pub(crate) fn complete_derive(acc: &mut Completions, ctx: &CompletionContext) {
|
|||
|
||||
match (core, mac.module(ctx.db).krate()) {
|
||||
// show derive dependencies for `core`/`std` derives
|
||||
(Some(core), mac_krate) if core == mac_krate && qualifier.is_none() => {}
|
||||
(Some(core), mac_krate) if core == mac_krate => {}
|
||||
_ => return acc.add_resolution(ctx, name, def),
|
||||
};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use ide_db::FxHashSet;
|
|||
use crate::{
|
||||
context::{
|
||||
CompletionContext, DotAccess, DotAccessKind, NameRefContext, NameRefKind,
|
||||
PathCompletionCtx, PathKind,
|
||||
PathCompletionCtx, PathKind, Qualified,
|
||||
},
|
||||
CompletionItem, CompletionItemKind, Completions,
|
||||
};
|
||||
|
@ -50,8 +50,7 @@ fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
|
|||
match ctx.path_context() {
|
||||
Some(
|
||||
path_ctx @ PathCompletionCtx {
|
||||
is_absolute_path: false,
|
||||
qualifier: None,
|
||||
qualified: Qualified::No,
|
||||
kind: PathKind::Expr { .. },
|
||||
..
|
||||
},
|
||||
|
|
|
@ -4,7 +4,9 @@ use hir::ScopeDef;
|
|||
use ide_db::FxHashSet;
|
||||
|
||||
use crate::{
|
||||
context::{NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PathQualifierCtx},
|
||||
context::{
|
||||
NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified,
|
||||
},
|
||||
CompletionContext, Completions,
|
||||
};
|
||||
|
||||
|
@ -12,8 +14,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
|
|||
let _p = profile::span("complete_expr_path");
|
||||
|
||||
let (
|
||||
is_absolute_path,
|
||||
qualifier,
|
||||
qualified,
|
||||
in_block_expr,
|
||||
in_loop_body,
|
||||
is_func_update,
|
||||
|
@ -33,14 +34,12 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
|
|||
ref ref_expr_parent,
|
||||
ref is_func_update,
|
||||
},
|
||||
is_absolute_path,
|
||||
ref qualifier,
|
||||
ref qualified,
|
||||
..
|
||||
})),
|
||||
..
|
||||
}) if ctx.qualifier_ctx.none() => (
|
||||
is_absolute_path,
|
||||
qualifier,
|
||||
qualified,
|
||||
in_block_expr,
|
||||
in_loop_body,
|
||||
is_func_update.is_some(),
|
||||
|
@ -61,8 +60,8 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
|
|||
}
|
||||
};
|
||||
|
||||
match qualifier {
|
||||
Some(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
|
||||
match qualified {
|
||||
Qualified::With(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
|
||||
if *is_infer_qualifier {
|
||||
ctx.traits_in_scope()
|
||||
.0
|
||||
|
@ -174,8 +173,8 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
|
|||
_ => (),
|
||||
}
|
||||
}
|
||||
None if is_absolute_path => acc.add_crate_roots(ctx),
|
||||
None => {
|
||||
Qualified::Absolute => acc.add_crate_roots(ctx),
|
||||
Qualified::No => {
|
||||
acc.add_nameref_keywords_with_colon(ctx);
|
||||
if let Some(adt) =
|
||||
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
|
||||
|
@ -237,7 +236,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
|
|||
add_keyword("true", "true");
|
||||
add_keyword("false", "false");
|
||||
|
||||
if (in_condition && !is_absolute_path) || in_block_expr {
|
||||
if in_condition || in_block_expr {
|
||||
add_keyword("let", "let");
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use crate::{
|
||||
context::{
|
||||
IdentContext, NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx,
|
||||
PathKind, TypeLocation,
|
||||
PathKind, Qualified, TypeLocation,
|
||||
},
|
||||
CompletionContext, Completions,
|
||||
};
|
||||
|
@ -15,8 +15,7 @@ pub(crate) fn complete_field_list(acc: &mut Completions, ctx: &CompletionContext
|
|||
kind:
|
||||
Some(NameRefKind::Path(PathCompletionCtx {
|
||||
has_macro_bang: false,
|
||||
is_absolute_path: false,
|
||||
qualifier: None,
|
||||
qualified: Qualified::No,
|
||||
parent: None,
|
||||
kind: PathKind::Type { location: TypeLocation::TupleField },
|
||||
has_type_args: false,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use crate::{
|
||||
completions::module_or_fn_macro,
|
||||
context::{ItemListKind, PathCompletionCtx, PathKind, PathQualifierCtx},
|
||||
context::{ItemListKind, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified},
|
||||
CompletionContext, Completions,
|
||||
};
|
||||
|
||||
|
@ -16,23 +16,17 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
|
|||
return;
|
||||
}
|
||||
|
||||
let (&is_absolute_path, path_qualifier, kind, is_trivial_path) = match ctx.path_context() {
|
||||
Some(
|
||||
ctx @ PathCompletionCtx {
|
||||
kind: PathKind::Item { kind },
|
||||
is_absolute_path,
|
||||
qualifier,
|
||||
..
|
||||
},
|
||||
) => (is_absolute_path, qualifier, Some(kind), ctx.is_trivial_path()),
|
||||
let (qualified, kind, is_trivial_path) = match ctx.path_context() {
|
||||
Some(ctx @ PathCompletionCtx { kind: PathKind::Item { kind }, qualified, .. }) => {
|
||||
(qualified, Some(kind), ctx.is_trivial_path())
|
||||
}
|
||||
Some(
|
||||
ctx @ PathCompletionCtx {
|
||||
kind: PathKind::Expr { in_block_expr: true, .. },
|
||||
is_absolute_path,
|
||||
qualifier,
|
||||
qualified,
|
||||
..
|
||||
},
|
||||
) => (is_absolute_path, qualifier, None, ctx.is_trivial_path()),
|
||||
) => (qualified, None, ctx.is_trivial_path()),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
|
@ -49,8 +43,8 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
|
|||
return;
|
||||
}
|
||||
|
||||
match path_qualifier {
|
||||
Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
match qualified {
|
||||
Qualified::With(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) {
|
||||
|
@ -63,8 +57,8 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
|
|||
acc.add_keyword(ctx, "super::");
|
||||
}
|
||||
}
|
||||
None if is_absolute_path => acc.add_crate_roots(ctx),
|
||||
None if ctx.qualifier_ctx.none() => {
|
||||
Qualified::Absolute => acc.add_crate_roots(ctx),
|
||||
Qualified::No if ctx.qualifier_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);
|
||||
|
@ -72,7 +66,7 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
|
|||
});
|
||||
acc.add_nameref_keywords_with_colon(ctx);
|
||||
}
|
||||
None => {}
|
||||
Qualified::No => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use ide_db::FxHashSet;
|
|||
use syntax::ast::Pat;
|
||||
|
||||
use crate::{
|
||||
context::{PathCompletionCtx, PathQualifierCtx, PatternRefutability},
|
||||
context::{PathCompletionCtx, PathQualifierCtx, PatternRefutability, Qualified},
|
||||
CompletionContext, Completions,
|
||||
};
|
||||
|
||||
|
@ -111,10 +111,10 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
|
|||
fn pattern_path_completion(
|
||||
acc: &mut Completions,
|
||||
ctx: &CompletionContext,
|
||||
PathCompletionCtx { qualifier, is_absolute_path, .. }: &PathCompletionCtx,
|
||||
PathCompletionCtx { qualified, .. }: &PathCompletionCtx,
|
||||
) {
|
||||
match qualifier {
|
||||
Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
match qualified {
|
||||
Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
if *is_super_chain {
|
||||
acc.add_keyword(ctx, "super::");
|
||||
}
|
||||
|
@ -197,8 +197,8 @@ 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 => {
|
||||
Qualified::Absolute => acc.add_crate_roots(ctx),
|
||||
Qualified::No => {
|
||||
ctx.process_all_names(&mut |name, res| {
|
||||
// FIXME: properly filter here
|
||||
if let ScopeDef::ModuleDef(_) = res {
|
||||
|
|
|
@ -3,7 +3,9 @@ use ide_db::SymbolKind;
|
|||
use syntax::{ast::Expr, T};
|
||||
|
||||
use crate::{
|
||||
context::{NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PatternContext},
|
||||
context::{
|
||||
NameRefContext, NameRefKind, PathCompletionCtx, PathKind, PatternContext, Qualified,
|
||||
},
|
||||
CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
|
||||
CompletionRelevancePostfixMatch, Completions,
|
||||
};
|
||||
|
@ -19,7 +21,7 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
|
|||
NameRefKind::RecordExpr(record_expr)
|
||||
| NameRefKind::Path(PathCompletionCtx {
|
||||
kind: PathKind::Expr { is_func_update: Some(record_expr), .. },
|
||||
qualifier: None,
|
||||
qualified: Qualified::No,
|
||||
..
|
||||
}),
|
||||
),
|
||||
|
|
|
@ -4,7 +4,7 @@ use hir::Documentation;
|
|||
use ide_db::{imports::insert_use::ImportScope, SnippetCap};
|
||||
|
||||
use crate::{
|
||||
context::{ItemListKind, PathCompletionCtx, PathKind},
|
||||
context::{ItemListKind, PathCompletionCtx, PathKind, Qualified},
|
||||
item::Builder,
|
||||
CompletionContext, CompletionItem, CompletionItemKind, Completions, SnippetScope,
|
||||
};
|
||||
|
@ -18,8 +18,7 @@ fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str)
|
|||
pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let &can_be_stmt = match ctx.path_context() {
|
||||
Some(PathCompletionCtx {
|
||||
is_absolute_path: false,
|
||||
qualifier: None,
|
||||
qualified: Qualified::No,
|
||||
kind: PathKind::Expr { in_block_expr, .. },
|
||||
..
|
||||
}) => in_block_expr,
|
||||
|
@ -44,8 +43,7 @@ pub(crate) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionConte
|
|||
pub(crate) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let path_kind = match ctx.path_context() {
|
||||
Some(PathCompletionCtx {
|
||||
is_absolute_path: false,
|
||||
qualifier: None,
|
||||
qualified: Qualified::No,
|
||||
kind: kind @ (PathKind::Item { .. } | PathKind::Expr { in_block_expr: true, .. }),
|
||||
..
|
||||
}) => kind,
|
||||
|
|
|
@ -5,7 +5,10 @@ use ide_db::FxHashSet;
|
|||
use syntax::{ast, AstNode};
|
||||
|
||||
use crate::{
|
||||
context::{PathCompletionCtx, PathKind, PathQualifierCtx, TypeAscriptionTarget, TypeLocation},
|
||||
context::{
|
||||
PathCompletionCtx, PathKind, PathQualifierCtx, Qualified, TypeAscriptionTarget,
|
||||
TypeLocation,
|
||||
},
|
||||
render::render_type_inference,
|
||||
CompletionContext, Completions,
|
||||
};
|
||||
|
@ -13,13 +16,10 @@ use crate::{
|
|||
pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let _p = profile::span("complete_type_path");
|
||||
|
||||
let (&is_absolute_path, location, qualifier) = match ctx.path_context() {
|
||||
Some(PathCompletionCtx {
|
||||
kind: PathKind::Type { location },
|
||||
is_absolute_path,
|
||||
qualifier,
|
||||
..
|
||||
}) => (is_absolute_path, location, qualifier),
|
||||
let (location, qualified) = match ctx.path_context() {
|
||||
Some(PathCompletionCtx { kind: PathKind::Type { location }, qualified, .. }) => {
|
||||
(location, qualified)
|
||||
}
|
||||
_ => return,
|
||||
};
|
||||
|
||||
|
@ -54,8 +54,8 @@ pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext)
|
|||
hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
|
||||
};
|
||||
|
||||
match qualifier {
|
||||
Some(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
|
||||
match qualified {
|
||||
Qualified::With(PathQualifierCtx { is_infer_qualifier, resolution, .. }) => {
|
||||
if *is_infer_qualifier {
|
||||
ctx.traits_in_scope()
|
||||
.0
|
||||
|
@ -151,8 +151,8 @@ pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext)
|
|||
_ => (),
|
||||
}
|
||||
}
|
||||
None if is_absolute_path => acc.add_crate_roots(ctx),
|
||||
None => {
|
||||
Qualified::Absolute => acc.add_crate_roots(ctx),
|
||||
Qualified::No => {
|
||||
acc.add_nameref_keywords_with_colon(ctx);
|
||||
if let TypeLocation::TypeBound = location {
|
||||
ctx.process_all_names(&mut |name, res| {
|
||||
|
|
|
@ -7,30 +7,30 @@ use syntax::{ast, AstNode};
|
|||
use crate::{
|
||||
context::{
|
||||
CompletionContext, NameRefContext, NameRefKind, PathCompletionCtx, PathKind,
|
||||
PathQualifierCtx,
|
||||
PathQualifierCtx, Qualified,
|
||||
},
|
||||
item::Builder,
|
||||
CompletionItem, CompletionItemKind, CompletionRelevance, Completions,
|
||||
};
|
||||
|
||||
pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let (&is_absolute_path, qualifier, name_ref) = match ctx.nameref_ctx() {
|
||||
let (qualified, name_ref) = match ctx.nameref_ctx() {
|
||||
Some(NameRefContext {
|
||||
kind:
|
||||
Some(NameRefKind::Path(PathCompletionCtx {
|
||||
kind: PathKind::Use,
|
||||
is_absolute_path,
|
||||
qualifier,
|
||||
..
|
||||
})),
|
||||
kind: Some(NameRefKind::Path(PathCompletionCtx { kind: PathKind::Use, qualified, .. })),
|
||||
nameref,
|
||||
..
|
||||
}) => (is_absolute_path, qualifier, nameref),
|
||||
}) => (qualified, nameref),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
match qualifier {
|
||||
Some(PathQualifierCtx { path, resolution, is_super_chain, use_tree_parent, .. }) => {
|
||||
match qualified {
|
||||
Qualified::With(PathQualifierCtx {
|
||||
path,
|
||||
resolution,
|
||||
is_super_chain,
|
||||
use_tree_parent,
|
||||
..
|
||||
}) => {
|
||||
if *is_super_chain {
|
||||
acc.add_keyword(ctx, "super::");
|
||||
}
|
||||
|
@ -105,12 +105,12 @@ pub(crate) fn complete_use_tree(acc: &mut Completions, ctx: &CompletionContext)
|
|||
}
|
||||
}
|
||||
// fresh use tree with leading colon2, only show crate roots
|
||||
None if is_absolute_path => {
|
||||
Qualified::Absolute => {
|
||||
cov_mark::hit!(use_tree_crate_roots_only);
|
||||
acc.add_crate_roots(ctx);
|
||||
}
|
||||
// only show modules and non-std enum in a fresh UseTree
|
||||
None => {
|
||||
Qualified::No => {
|
||||
cov_mark::hit!(unqualified_path_selected_only);
|
||||
ctx.process_all_names(&mut |name, res| {
|
||||
match res {
|
||||
|
|
|
@ -3,23 +3,20 @@
|
|||
use hir::ScopeDef;
|
||||
|
||||
use crate::{
|
||||
context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx},
|
||||
context::{CompletionContext, PathCompletionCtx, PathKind, PathQualifierCtx, Qualified},
|
||||
Completions,
|
||||
};
|
||||
|
||||
pub(crate) fn complete_vis_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let (&is_absolute_path, qualifier, &has_in_token) = match ctx.path_context() {
|
||||
Some(PathCompletionCtx {
|
||||
kind: PathKind::Vis { has_in_token },
|
||||
is_absolute_path,
|
||||
qualifier,
|
||||
..
|
||||
}) => (is_absolute_path, qualifier, has_in_token),
|
||||
let (qualified, &has_in_token) = match ctx.path_context() {
|
||||
Some(PathCompletionCtx { kind: PathKind::Vis { has_in_token }, qualified, .. }) => {
|
||||
(qualified, has_in_token)
|
||||
}
|
||||
_ => return,
|
||||
};
|
||||
|
||||
match qualifier {
|
||||
Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
match qualified {
|
||||
Qualified::With(PathQualifierCtx { resolution, is_super_chain, .. }) => {
|
||||
// Try completing next child module of the path that is still a parent of the current module
|
||||
if let Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))) = resolution {
|
||||
let next_towards_current = ctx
|
||||
|
@ -40,13 +37,13 @@ pub(crate) fn complete_vis_path(acc: &mut Completions, ctx: &CompletionContext)
|
|||
acc.add_keyword(ctx, "super::");
|
||||
}
|
||||
}
|
||||
None if !is_absolute_path => {
|
||||
Qualified::Absolute => {}
|
||||
Qualified::No => {
|
||||
if !has_in_token {
|
||||
cov_mark::hit!(kw_completion_in);
|
||||
acc.add_keyword(ctx, "in");
|
||||
}
|
||||
acc.add_nameref_keywords(ctx);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,10 +57,8 @@ pub(crate) struct PathCompletionCtx {
|
|||
pub(super) has_call_parens: bool,
|
||||
/// If this has a macro call bang !
|
||||
pub(super) has_macro_bang: bool,
|
||||
/// Whether this path stars with a `::`.
|
||||
pub(super) is_absolute_path: bool,
|
||||
/// The qualifier of the current path if it exists.
|
||||
pub(super) qualifier: Option<PathQualifierCtx>,
|
||||
/// The qualifier of the current path.
|
||||
pub(super) qualified: Qualified,
|
||||
/// The parent of the path we are completing.
|
||||
pub(super) parent: Option<ast::Path>,
|
||||
pub(super) kind: PathKind,
|
||||
|
@ -75,8 +73,7 @@ impl PathCompletionCtx {
|
|||
PathCompletionCtx {
|
||||
has_call_parens: false,
|
||||
has_macro_bang: false,
|
||||
is_absolute_path: false,
|
||||
qualifier: None,
|
||||
qualified: Qualified::No,
|
||||
parent: None,
|
||||
has_type_args: false,
|
||||
..
|
||||
|
@ -147,6 +144,14 @@ pub(super) enum ItemListKind {
|
|||
ExternBlock,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum Qualified {
|
||||
No,
|
||||
With(PathQualifierCtx),
|
||||
/// Whether the path is an absolute path
|
||||
Absolute,
|
||||
}
|
||||
|
||||
/// The path qualifier state of the path we are completing.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PathQualifierCtx {
|
||||
|
@ -400,7 +405,10 @@ impl<'a> CompletionContext<'a> {
|
|||
}
|
||||
|
||||
pub(crate) fn path_qual(&self) -> Option<&ast::Path> {
|
||||
self.path_context().and_then(|it| it.qualifier.as_ref().map(|it| &it.path))
|
||||
self.path_context().and_then(|it| match &it.qualified {
|
||||
Qualified::With(it) => Some(&it.path),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Checks if an item is visible and not `doc(hidden)` at the completion site.
|
||||
|
|
|
@ -13,7 +13,7 @@ use syntax::{
|
|||
use crate::context::{
|
||||
CompletionContext, DotAccess, DotAccessKind, IdentContext, ItemListKind, LifetimeContext,
|
||||
LifetimeKind, NameContext, NameKind, NameRefContext, NameRefKind, ParamKind, PathCompletionCtx,
|
||||
PathKind, PathQualifierCtx, PatternContext, PatternRefutability, QualifierCtx,
|
||||
PathKind, PathQualifierCtx, PatternContext, PatternRefutability, Qualified, QualifierCtx,
|
||||
TypeAscriptionTarget, TypeLocation, COMPLETION_MARKER,
|
||||
};
|
||||
|
||||
|
@ -585,8 +585,7 @@ impl<'a> CompletionContext<'a> {
|
|||
let mut path_ctx = PathCompletionCtx {
|
||||
has_call_parens: false,
|
||||
has_macro_bang: false,
|
||||
is_absolute_path: false,
|
||||
qualifier: None,
|
||||
qualified: Qualified::No,
|
||||
parent: path.parent_path(),
|
||||
kind: PathKind::Item { kind: ItemListKind::SourceFile },
|
||||
has_type_args: false,
|
||||
|
@ -854,41 +853,40 @@ impl<'a> CompletionContext<'a> {
|
|||
|
||||
// calculate the qualifier context
|
||||
if let Some((path, use_tree_parent)) = path_or_use_tree_qualifier(&path) {
|
||||
if !use_tree_parent {
|
||||
path_ctx.is_absolute_path =
|
||||
path.top_path().segment().map_or(false, |it| it.coloncolon_token().is_some());
|
||||
if !use_tree_parent && segment.coloncolon_token().is_some() {
|
||||
path_ctx.qualified = Qualified::Absolute;
|
||||
} else {
|
||||
let path = path
|
||||
.segment()
|
||||
.and_then(|it| find_node_in_file(original_file, &it))
|
||||
.map(|it| it.parent_path());
|
||||
if let Some(path) = path {
|
||||
let res = sema.resolve_path(&path);
|
||||
let is_super_chain = iter::successors(Some(path.clone()), |p| p.qualifier())
|
||||
.all(|p| p.segment().and_then(|s| s.super_token()).is_some());
|
||||
|
||||
// `<_>::$0`
|
||||
let is_infer_qualifier = path.qualifier().is_none()
|
||||
&& matches!(
|
||||
path.segment().and_then(|it| it.kind()),
|
||||
Some(ast::PathSegmentKind::Type {
|
||||
type_ref: Some(ast::Type::InferType(_)),
|
||||
trait_ref: None,
|
||||
})
|
||||
);
|
||||
|
||||
path_ctx.qualified = Qualified::With(PathQualifierCtx {
|
||||
path,
|
||||
resolution: res,
|
||||
is_super_chain,
|
||||
use_tree_parent,
|
||||
is_infer_qualifier,
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
let path = path
|
||||
.segment()
|
||||
.and_then(|it| find_node_in_file(original_file, &it))
|
||||
.map(|it| it.parent_path());
|
||||
path_ctx.qualifier = path.map(|path| {
|
||||
let res = sema.resolve_path(&path);
|
||||
let is_super_chain = iter::successors(Some(path.clone()), |p| p.qualifier())
|
||||
.all(|p| p.segment().and_then(|s| s.super_token()).is_some());
|
||||
|
||||
// `<_>::$0`
|
||||
let is_infer_qualifier = path.qualifier().is_none()
|
||||
&& matches!(
|
||||
path.segment().and_then(|it| it.kind()),
|
||||
Some(ast::PathSegmentKind::Type {
|
||||
type_ref: Some(ast::Type::InferType(_)),
|
||||
trait_ref: None,
|
||||
})
|
||||
);
|
||||
|
||||
PathQualifierCtx {
|
||||
path,
|
||||
resolution: res,
|
||||
is_super_chain,
|
||||
use_tree_parent,
|
||||
is_infer_qualifier,
|
||||
}
|
||||
});
|
||||
} else if let Some(segment) = path.segment() {
|
||||
if segment.coloncolon_token().is_some() {
|
||||
path_ctx.is_absolute_path = true;
|
||||
path_ctx.qualified = Qualified::Absolute;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue