From 51e2d76b9839410020c75ac02ad602675b0a5aa9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Sep 2019 23:35:53 +0300 Subject: Specify desirable namespace when calling resolve That way, we are able to get rid of a number of unreachable statements --- .../completion/complete_macro_in_item_position.rs | 8 +- crates/ra_ide_api/src/completion/complete_path.rs | 10 +-- .../ra_ide_api/src/completion/complete_pattern.rs | 14 ++-- crates/ra_ide_api/src/completion/complete_scope.rs | 5 +- crates/ra_ide_api/src/completion/presentation.rs | 95 +++++++++++++--------- 5 files changed, 76 insertions(+), 56 deletions(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs index 6fcef4a72..0cbe4abf7 100644 --- a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs +++ b/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs @@ -3,11 +3,11 @@ use crate::completion::{CompletionContext, Completions}; pub(super) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { // Show only macros in top level. if ctx.is_new_item { - for (name, res) in ctx.analyzer.all_names(ctx.db) { - if res.get_macros().is_some() { - acc.add_resolution(ctx, name.to_string(), &res.only_macros()); + ctx.analyzer.process_all_names(ctx.db, &mut |name, res| { + if let hir::ScopeDef::MacroDef(mac) = res { + acc.add_macro(ctx, Some(name.to_string()), mac); } - } + }) } } diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index 4d3414f33..5ee2864dc 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs @@ -1,4 +1,4 @@ -use hir::{Adt, Either, Resolution}; +use hir::{Adt, Either, PathResolution}; use ra_syntax::AstNode; use test_utils::tested_by; @@ -9,15 +9,15 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { Some(path) => path.clone(), _ => return, }; - let def = match ctx.analyzer.resolve_hir_path(ctx.db, &path).take_types() { - Some(Resolution::Def(def)) => def, + let def = match dbg!(ctx.analyzer.resolve_hir_path(ctx.db, &path)) { + Some(PathResolution::Def(def)) => def, _ => return, }; match def { hir::ModuleDef::Module(module) => { let module_scope = module.scope(ctx.db); for (name, res) in module_scope.entries() { - if let Some(hir::ModuleDef::BuiltinType(..)) = res.def.as_ref().take_types() { + if let Some(hir::ModuleDef::BuiltinType(..)) = res.def.take_types() { if ctx.use_item_syntax.is_some() { tested_by!(dont_complete_primitive_in_use); continue; @@ -34,7 +34,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { } } } - acc.add_resolution(ctx, name.to_string(), &res.def.map(hir::Resolution::Def)); + acc.add_resolution(ctx, name.to_string(), &res.def.into()); } } hir::ModuleDef::Adt(_) | hir::ModuleDef::TypeAlias(_) => { diff --git a/crates/ra_ide_api/src/completion/complete_pattern.rs b/crates/ra_ide_api/src/completion/complete_pattern.rs index fb7f9feb8..c17b5b7ee 100644 --- a/crates/ra_ide_api/src/completion/complete_pattern.rs +++ b/crates/ra_ide_api/src/completion/complete_pattern.rs @@ -7,22 +7,20 @@ pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { } // FIXME: ideally, we should look at the type we are matching against and // suggest variants + auto-imports - let names = ctx.analyzer.all_names(ctx.db); - for (name, res) in names.into_iter() { - let r = res.as_ref(); - let def = match r.take_types().or_else(|| r.take_values()) { - Some(hir::Resolution::Def(def)) => def, - _ => continue, + ctx.analyzer.process_all_names(ctx.db, &mut |name, res| { + let def = match &res { + hir::ScopeDef::ModuleDef(def) => def, + _ => return, }; match def { hir::ModuleDef::Adt(hir::Adt::Enum(..)) | hir::ModuleDef::EnumVariant(..) | hir::ModuleDef::Const(..) | hir::ModuleDef::Module(..) => (), - _ => continue, + _ => return, } acc.add_resolution(ctx, name.to_string(), &res) - } + }); } #[cfg(test)] diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 2ea22876f..c1f48b026 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs @@ -10,8 +10,9 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { return; } - let names = ctx.analyzer.all_names(ctx.db); - names.into_iter().for_each(|(name, res)| acc.add_resolution(ctx, name.to_string(), &res)); + ctx.analyzer.process_all_names(ctx.db, &mut |name, res| { + acc.add_resolution(ctx, name.to_string(), &res) + }); // auto-import // We fetch ident from the original file, because we need to pre-filter auto-imports diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 95bbd34b7..31b887492 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -1,5 +1,5 @@ -//! This modules takes care of rendering various defenitions as completion items. -use hir::{Docs, HasSource, HirDisplay, PerNs, Resolution, Ty, TypeWalk}; +//! This modules takes care of rendering various definitions as completion items. +use hir::{Docs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; use join_to_string::join; use ra_syntax::ast::NameOwner; use test_utils::tested_by; @@ -39,61 +39,77 @@ impl Completions { &mut self, ctx: &CompletionContext, local_name: String, - resolution: &PerNs, + resolution: &ScopeDef, ) { use hir::ModuleDef::*; - if let Some(macro_) = resolution.get_macros() { - self.add_macro(ctx, Some(local_name.clone()), macro_); - } + // if let Some(macro_) = resolution.get_macros() { + // self.add_macro(ctx, Some(local_name.clone()), macro_); + // } - let def = resolution.as_ref().take_types().or_else(|| resolution.as_ref().take_values()); - let def = match def { - // Only insert once if it is just a macro name - None if resolution.get_macros().is_some() => return, - None => { - self.add(CompletionItem::new( - CompletionKind::Reference, - ctx.source_range(), - local_name, - )); - return; - } - Some(it) => it, - }; + // let def = resolution.as_ref().take_types().or_else(|| resolution.as_ref().take_values()); + // let def = match def { + // // Only insert once if it is just a macro name + // None if resolution.get_macros().is_some() => return, + // None => { + // self.add(CompletionItem::new( + // CompletionKind::Reference, + // ctx.source_range(), + // local_name, + // )); + // return; + // } + // Some(it) => it, + // }; let mut completion_kind = CompletionKind::Reference; - let (kind, docs) = match def { - Resolution::Def(Module(it)) => (CompletionItemKind::Module, it.docs(ctx.db)), - Resolution::Def(Function(func)) => { + let (kind, docs) = match resolution { + ScopeDef::ModuleDef(Module(it)) => (CompletionItemKind::Module, it.docs(ctx.db)), + ScopeDef::ModuleDef(Function(func)) => { return self.add_function_with_name(ctx, Some(local_name), *func); } - Resolution::Def(Adt(hir::Adt::Struct(it))) => { + ScopeDef::ModuleDef(Adt(hir::Adt::Struct(it))) => { (CompletionItemKind::Struct, it.docs(ctx.db)) } - Resolution::Def(Adt(hir::Adt::Union(it))) => { + ScopeDef::ModuleDef(Adt(hir::Adt::Union(it))) => { (CompletionItemKind::Struct, it.docs(ctx.db)) } - Resolution::Def(Adt(hir::Adt::Enum(it))) => (CompletionItemKind::Enum, it.docs(ctx.db)), - Resolution::Def(EnumVariant(it)) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)), - Resolution::Def(Const(it)) => (CompletionItemKind::Const, it.docs(ctx.db)), - Resolution::Def(Static(it)) => (CompletionItemKind::Static, it.docs(ctx.db)), - Resolution::Def(Trait(it)) => (CompletionItemKind::Trait, it.docs(ctx.db)), - Resolution::Def(TypeAlias(it)) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), - Resolution::Def(BuiltinType(..)) => { + ScopeDef::ModuleDef(Adt(hir::Adt::Enum(it))) => { + (CompletionItemKind::Enum, it.docs(ctx.db)) + } + ScopeDef::ModuleDef(EnumVariant(it)) => { + (CompletionItemKind::EnumVariant, it.docs(ctx.db)) + } + ScopeDef::ModuleDef(Const(it)) => (CompletionItemKind::Const, it.docs(ctx.db)), + ScopeDef::ModuleDef(Static(it)) => (CompletionItemKind::Static, it.docs(ctx.db)), + ScopeDef::ModuleDef(Trait(it)) => (CompletionItemKind::Trait, it.docs(ctx.db)), + ScopeDef::ModuleDef(TypeAlias(it)) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), + ScopeDef::ModuleDef(BuiltinType(..)) => { completion_kind = CompletionKind::BuiltinType; (CompletionItemKind::BuiltinType, None) } - Resolution::GenericParam(..) => (CompletionItemKind::TypeParam, None), - Resolution::LocalBinding(..) => (CompletionItemKind::Binding, None), - Resolution::SelfType(..) => ( + ScopeDef::GenericParam(..) => (CompletionItemKind::TypeParam, None), + ScopeDef::LocalBinding(..) => (CompletionItemKind::Binding, None), + ScopeDef::SelfType(..) => ( CompletionItemKind::TypeParam, // (does this need its own kind?) None, ), + ScopeDef::MacroDef(mac) => { + self.add_macro(ctx, Some(local_name.clone()), *mac); + return; + } + ScopeDef::Unknown => { + self.add(CompletionItem::new( + CompletionKind::Reference, + ctx.source_range(), + local_name, + )); + return; + } }; let mut completion_item = CompletionItem::new(completion_kind, ctx.source_range(), local_name); - if let Resolution::LocalBinding(pat_id) = def { + if let ScopeDef::LocalBinding(pat_id) = resolution { let ty = ctx .analyzer .type_of_pat_by_id(ctx.db, pat_id.clone()) @@ -108,7 +124,12 @@ impl Completions { self.add_function_with_name(ctx, None, func) } - fn add_macro(&mut self, ctx: &CompletionContext, name: Option, macro_: hir::MacroDef) { + pub(crate) fn add_macro( + &mut self, + ctx: &CompletionContext, + name: Option, + macro_: hir::MacroDef, + ) { let ast_node = macro_.source(ctx.db).ast; if let Some(name) = name { let detail = macro_label(&ast_node); -- cgit v1.2.3