Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide_completion/src/completions/attribute.rs')
-rw-r--r--crates/ide_completion/src/completions/attribute.rs58
1 files changed, 40 insertions, 18 deletions
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs
index 8950b13d6f..1a1fa533c1 100644
--- a/crates/ide_completion/src/completions/attribute.rs
+++ b/crates/ide_completion/src/completions/attribute.rs
@@ -1,9 +1,10 @@
-//! Completion for attributes
+//! Completion for (built-in) attributes, derives and lints.
//!
-//! This module uses a bit of static metadata to provide completions
-//! for built-in attributes.
-//! Non-built-in attribute (excluding derives attributes) completions are done in [`super::unqualified_path`].
+//! This module uses a bit of static metadata to provide completions for builtin-in attributes and lints.
+use std::iter;
+
+use hir::ScopeDef;
use ide_db::{
helpers::{
generated_lints::{
@@ -85,24 +86,45 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext)
_ => return,
};
- if !is_trivial_path {
- return;
- }
+ match qualifier {
+ Some((path, qualifier)) => {
+ let is_super_chain = iter::successors(Some(path.clone()), |p| p.qualifier())
+ .all(|p| p.segment().and_then(|s| s.super_token()).is_some());
+ if is_super_chain {
+ acc.add_keyword(ctx, "super::");
+ }
- if let Some((_, Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))))) = qualifier {
- for (name, def) in module.scope(ctx.db, ctx.module) {
- if let Some(def) = module_or_attr(def) {
- acc.add_resolution(ctx, name, def);
+ let module = match qualifier {
+ Some(hir::PathResolution::Def(hir::ModuleDef::Module(it))) => it,
+ _ => return,
+ };
+
+ for (name, def) in module.scope(ctx.db, ctx.module) {
+ if let Some(def) = module_or_attr(def) {
+ acc.add_resolution(ctx, name, def);
+ }
}
+ return;
}
- return;
- }
-
- ctx.process_all_names(&mut |name, def| {
- if let Some(def) = module_or_attr(def) {
- acc.add_resolution(ctx, name, def);
+ // fresh use tree with leading colon2, only show crate roots
+ None if !is_trivial_path => {
+ ctx.process_all_names(&mut |name, res| match res {
+ ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => {
+ acc.add_resolution(ctx, name, res);
+ }
+ _ => (),
+ });
}
- });
+ // only show modules in a fresh UseTree
+ None => {
+ ctx.process_all_names(&mut |name, def| {
+ if let Some(def) = module_or_attr(def) {
+ acc.add_resolution(ctx, name, def);
+ }
+ });
+ ["self::", "super::", "crate::"].into_iter().for_each(|kw| acc.add_keyword(ctx, kw));
+ }
+ }
let attributes = annotated_item_kind.and_then(|kind| {
if ast::Expr::can_cast(kind) {