From a36ff4a100c2c321eec898f2cfee25c0be85ffc6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 11 Jul 2020 01:26:24 +0200 Subject: Speed up completion --- crates/ra_hir/src/semantics.rs | 1 + crates/ra_ide/src/completion/complete_attribute.rs | 2 +- crates/ra_ide/src/completion/complete_dot.rs | 6 +++--- .../src/completion/complete_macro_in_item_position.rs | 2 +- crates/ra_ide/src/completion/complete_pattern.rs | 2 +- crates/ra_ide/src/completion/complete_qualified_path.rs | 15 +++++++-------- crates/ra_ide/src/completion/complete_unqualified_path.rs | 4 ++-- crates/ra_ide/src/completion/completion_context.rs | 7 +++---- 8 files changed, 19 insertions(+), 20 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index 0d877e44e..4a16ac566 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -568,6 +568,7 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode { node.ancestors().last().unwrap() } +#[derive(Debug)] pub struct SemanticsScope<'a> { pub db: &'a dyn HirDatabase, resolver: Resolver, diff --git a/crates/ra_ide/src/completion/complete_attribute.rs b/crates/ra_ide/src/completion/complete_attribute.rs index 9db317509..047299de9 100644 --- a/crates/ra_ide/src/completion/complete_attribute.rs +++ b/crates/ra_ide/src/completion/complete_attribute.rs @@ -195,7 +195,7 @@ fn parse_derive_input(derive_input: ast::TokenTree) -> Result, fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet { let mut result = FxHashSet::default(); - ctx.scope().process_all_names(&mut |name, scope_def| { + ctx.scope.process_all_names(&mut |name, scope_def| { if let hir::ScopeDef::MacroDef(mac) = scope_def { if mac.is_derive_macro() { result.insert(name.to_string()); diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs index 3c6c8c81a..532665285 100644 --- a/crates/ra_ide/src/completion/complete_dot.rs +++ b/crates/ra_ide/src/completion/complete_dot.rs @@ -29,7 +29,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { for receiver in receiver.autoderef(ctx.db) { for (field, ty) in receiver.fields(ctx.db) { - if ctx.scope().module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { + if ctx.scope.module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { // Skip private field. FIXME: If the definition location of the // field is editable, we should show the completion continue; @@ -46,10 +46,10 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Ty fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { if let Some(krate) = ctx.krate { let mut seen_methods = FxHashSet::default(); - let traits_in_scope = ctx.scope().traits_in_scope(); + let traits_in_scope = ctx.scope.traits_in_scope(); receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| { if func.has_self_param(ctx.db) - && ctx.scope().module().map_or(true, |m| func.is_visible_from(ctx.db, m)) + && ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m)) && seen_methods.insert(func.name(ctx.db)) { acc.add_function(ctx, func, None); diff --git a/crates/ra_ide/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs index d6613ed7b..0447f0511 100644 --- a/crates/ra_ide/src/completion/complete_macro_in_item_position.rs +++ b/crates/ra_ide/src/completion/complete_macro_in_item_position.rs @@ -5,7 +5,7 @@ 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 { - ctx.scope().process_all_names(&mut |name, res| { + ctx.scope.process_all_names(&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/src/completion/complete_pattern.rs b/crates/ra_ide/src/completion/complete_pattern.rs index 13fa7548d..aceb77cb5 100644 --- a/crates/ra_ide/src/completion/complete_pattern.rs +++ b/crates/ra_ide/src/completion/complete_pattern.rs @@ -13,7 +13,7 @@ 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 - ctx.scope().process_all_names(&mut |name, res| { + ctx.scope.process_all_names(&mut |name, res| { match &res { hir::ScopeDef::ModuleDef(def) => match def { hir::ModuleDef::Adt(hir::Adt::Enum(..)) diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs index e5553e28f..b08f5b9b4 100644 --- a/crates/ra_ide/src/completion/complete_qualified_path.rs +++ b/crates/ra_ide/src/completion/complete_qualified_path.rs @@ -17,21 +17,20 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon return; } - let scope = ctx.scope(); - let context_module = scope.module(); + let context_module = ctx.scope.module(); - let res = match scope.resolve_hir_path_qualifier(&path) { + let resolution = match ctx.scope.resolve_hir_path_qualifier(&path) { Some(res) => res, None => return, }; // Add associated types on type parameters and `Self`. - res.assoc_type_shorthand_candidates(ctx.db, |alias| { + resolution.assoc_type_shorthand_candidates(ctx.db, |alias| { acc.add_type_alias(ctx, alias); None::<()> }); - match res { + match resolution { PathResolution::Def(hir::ModuleDef::Module(module)) => { let module_scope = module.scope(ctx.db, context_module); for (name, def) in module_scope { @@ -68,7 +67,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon let krate = ctx.krate; if let Some(krate) = krate { - let traits_in_scope = ctx.scope().traits_in_scope(); + let traits_in_scope = ctx.scope.traits_in_scope(); ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { return None; @@ -113,13 +112,13 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon } PathResolution::TypeParam(_) | PathResolution::SelfType(_) => { if let Some(krate) = ctx.krate { - let ty = match res { + let ty = match resolution { PathResolution::TypeParam(param) => param.ty(ctx.db), PathResolution::SelfType(impl_def) => impl_def.target_ty(ctx.db), _ => return, }; - let traits_in_scope = ctx.scope().traits_in_scope(); + let traits_in_scope = ctx.scope.traits_in_scope(); let mut seen = FxHashSet::default(); ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs index 18f4488b7..bd9551f35 100644 --- a/crates/ra_ide/src/completion/complete_unqualified_path.rs +++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs @@ -25,7 +25,7 @@ pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC return; } - ctx.scope().process_all_names(&mut |name, res| { + ctx.scope.process_all_names(&mut |name, res| { if ctx.use_item_syntax.is_some() { if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) { if name_ref.syntax().text() == name.to_string().as_str() { @@ -42,7 +42,7 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T if let Some(Adt::Enum(enum_data)) = ty.as_adt() { let variants = enum_data.variants(ctx.db); - let module = if let Some(module) = ctx.scope().module() { + let module = if let Some(module) = ctx.scope.module() { // Compute path from the completion site if available. module } else { diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 02811a91e..3d93f7067 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs @@ -24,6 +24,7 @@ use test_utils::mark; #[derive(Debug)] pub(crate) struct CompletionContext<'a> { pub(super) sema: Semantics<'a, RootDatabase>, + pub(super) scope: SemanticsScope<'a>, pub(super) db: &'a RootDatabase, pub(super) config: &'a CompletionConfig, pub(super) offset: TextSize, @@ -106,8 +107,10 @@ impl<'a> CompletionContext<'a> { let original_token = original_file.syntax().token_at_offset(position.offset).left_biased()?; let token = sema.descend_into_macros(original_token.clone()); + let scope = sema.scope_at_offset(&token.parent(), position.offset); let mut ctx = CompletionContext { sema, + scope, db, config, original_token, @@ -207,10 +210,6 @@ impl<'a> CompletionContext<'a> { } } - pub(crate) fn scope(&self) -> SemanticsScope<'_> { - self.sema.scope_at_offset(&self.token.parent(), self.offset) - } - fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) { let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); let syntax_element = NodeOrToken::Token(fake_ident_token.clone()); -- cgit v1.2.3