Skip to content

Commit 4cbde4e

Browse files
committed
fix(completion): super:: completion at crate root and module depth
aware
1 parent 5342f47 commit 4cbde4e

19 files changed

+140
-112
lines changed

crates/ide-completion/src/completions.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,31 @@ impl Completions {
9191
}
9292

9393
pub(crate) fn add_nameref_keywords_with_colon(&mut self, ctx: &CompletionContext) {
94-
["self::", "super::", "crate::"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
94+
["self::", "crate::"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
95+
96+
if ctx.depth_from_crate_root > 0 {
97+
self.add_keyword(ctx, "super::");
98+
}
9599
}
96100

97101
pub(crate) fn add_nameref_keywords(&mut self, ctx: &CompletionContext) {
98-
["self", "super", "crate"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
102+
["self", "crate"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
103+
104+
if ctx.depth_from_crate_root > 0 {
105+
self.add_keyword(ctx, "super");
106+
}
107+
}
108+
109+
pub(crate) fn add_super_keyword(
110+
&mut self,
111+
ctx: &CompletionContext,
112+
super_chain_len: Option<usize>,
113+
) {
114+
if let Some(len) = super_chain_len {
115+
if len > 0 && len < ctx.depth_from_crate_root {
116+
self.add_keyword(ctx, "super::");
117+
}
118+
}
99119
}
100120

101121
pub(crate) fn add_keyword_snippet_expr(

crates/ide-completion/src/completions/attribute.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,10 @@ pub(crate) fn complete_attribute_path(
8282
match qualified {
8383
Qualified::With {
8484
resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
85-
is_super_chain,
85+
super_chain_len,
8686
..
8787
} => {
88-
if *is_super_chain {
89-
acc.add_keyword(ctx, "super::");
90-
}
88+
acc.add_super_keyword(ctx, *super_chain_len);
9189

9290
for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
9391
match def {

crates/ide-completion/src/completions/attribute/derive.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@ pub(crate) fn complete_derive_path(
2121
match qualified {
2222
Qualified::With {
2323
resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
24-
is_super_chain,
24+
super_chain_len,
2525
..
2626
} => {
27-
if *is_super_chain {
28-
acc.add_keyword(ctx, "super::");
29-
}
27+
acc.add_super_keyword(ctx, *super_chain_len);
3028

3129
for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
3230
match def {

crates/ide-completion/src/completions/item_list.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub(crate) fn complete_item_list(
3636
match qualified {
3737
Qualified::With {
3838
resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
39-
is_super_chain,
39+
super_chain_len,
4040
..
4141
} => {
4242
for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
@@ -51,9 +51,7 @@ pub(crate) fn complete_item_list(
5151
}
5252
}
5353

54-
if *is_super_chain {
55-
acc.add_keyword(ctx, "super::");
56-
}
54+
acc.add_super_keyword(ctx, *super_chain_len);
5755
}
5856
Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
5957
Qualified::No if ctx.qualifier_ctx.none() => {

crates/ide-completion/src/completions/pattern.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,8 @@ pub(crate) fn complete_pattern_path(
111111
path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx,
112112
) {
113113
match qualified {
114-
Qualified::With { resolution: Some(resolution), is_super_chain, .. } => {
115-
if *is_super_chain {
116-
acc.add_keyword(ctx, "super::");
117-
}
114+
Qualified::With { resolution: Some(resolution), super_chain_len, .. } => {
115+
acc.add_super_keyword(ctx, *super_chain_len);
118116

119117
match resolution {
120118
hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {

crates/ide-completion/src/completions/use_.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ pub(crate) fn complete_use_path(
1717
name_ref: &Option<ast::NameRef>,
1818
) {
1919
match qualified {
20-
Qualified::With { path, resolution: Some(resolution), is_super_chain } => {
21-
if *is_super_chain {
22-
acc.add_keyword(ctx, "super::");
23-
}
20+
Qualified::With { path, resolution: Some(resolution), super_chain_len } => {
21+
acc.add_super_keyword(ctx, *super_chain_len);
22+
2423
// only show `self` in a new use-tree when the qualifier doesn't end in self
2524
let not_preceded_by_self = *use_tree_parent
2625
&& !matches!(

crates/ide-completion/src/completions/vis.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub(crate) fn complete_vis_path(
1414
match qualified {
1515
Qualified::With {
1616
resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
17-
is_super_chain,
17+
super_chain_len,
1818
..
1919
} => {
2020
// Try completing next child module of the path that is still a parent of the current module
@@ -27,9 +27,7 @@ pub(crate) fn complete_vis_path(
2727
}
2828
}
2929

30-
if *is_super_chain {
31-
acc.add_keyword(ctx, "super::");
32-
}
30+
acc.add_super_keyword(ctx, *super_chain_len);
3331
}
3432
Qualified::Absolute | Qualified::Infer | Qualified::With { .. } => {}
3533
Qualified::No => {

crates/ide-completion/src/context.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ mod analysis;
44
#[cfg(test)]
55
mod tests;
66

7+
use std::iter;
8+
79
use base_db::SourceDatabaseExt;
810
use hir::{
911
HasAttrs, Local, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo,
@@ -174,8 +176,17 @@ pub(super) enum Qualified {
174176
With {
175177
path: ast::Path,
176178
resolution: Option<PathResolution>,
177-
/// Whether this path consists solely of `super` segments
178-
is_super_chain: bool,
179+
/// How many `super` segments are present in the path
180+
///
181+
/// This would be None, if path is not solely made of
182+
/// `super` segments, e.g.
183+
///
184+
/// ```rust
185+
/// use super::foo;
186+
/// ```
187+
///
188+
/// Otherwise it should be Some(count of `super`)
189+
super_chain_len: Option<usize>,
179190
},
180191
/// <_>::
181192
Infer,
@@ -343,6 +354,12 @@ pub(crate) struct CompletionContext<'a> {
343354
pub(super) qualifier_ctx: QualifierCtx,
344355

345356
pub(super) locals: FxHashMap<Name, Local>,
357+
358+
/// - crate-root
359+
/// - mod foo
360+
/// - mod bar
361+
/// Here depth will be 2: {[bar<->foo], [foo<->crate-root]}
362+
pub(super) depth_from_crate_root: usize,
346363
}
347364

348365
impl<'a> CompletionContext<'a> {
@@ -521,6 +538,8 @@ impl<'a> CompletionContext<'a> {
521538
}
522539
});
523540

541+
let depth_from_crate_root = iter::successors(module.parent(db), |m| m.parent(db)).count();
542+
524543
let mut ctx = CompletionContext {
525544
sema,
526545
scope,
@@ -535,6 +554,7 @@ impl<'a> CompletionContext<'a> {
535554
expected_type: None,
536555
qualifier_ctx: Default::default(),
537556
locals,
557+
depth_from_crate_root,
538558
};
539559
let ident_ctx = ctx.expand_and_analyze(
540560
original_file.syntax().clone(),

crates/ide-completion/src/context/analysis.rs

+19-4
Original file line numberDiff line numberDiff line change
@@ -899,10 +899,25 @@ impl<'a> CompletionContext<'a> {
899899
Qualified::Infer
900900
} else {
901901
let res = sema.resolve_path(&path);
902-
let is_super_chain =
903-
iter::successors(Some(path.clone()), |p| p.qualifier())
904-
.all(|p| p.segment().and_then(|s| s.super_token()).is_some());
905-
Qualified::With { path, resolution: res, is_super_chain }
902+
903+
// For understanding how and why super_chain_len is calculated the way it
904+
// is check the documentation at it's definition
905+
let mut segment_count = 0;
906+
let super_count = iter::successors(Some(path.clone()), |p| p.qualifier())
907+
.take_while(|p| {
908+
p.segment()
909+
.and_then(|s| {
910+
segment_count += 1;
911+
s.super_token()
912+
})
913+
.is_some()
914+
})
915+
.count();
916+
917+
let super_chain_len =
918+
if segment_count > super_count { None } else { Some(super_count) };
919+
920+
Qualified::With { path, resolution: res, super_chain_len }
906921
}
907922
};
908923
}

0 commit comments

Comments
 (0)