diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-07-11 00:31:57 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-07-11 00:31:57 +0100 |
commit | 343b9c6e76919c255466fd9b12fc7fd46f59022e (patch) | |
tree | 107769c5884b71e865b7efe44604cfad979e1f72 | |
parent | 349c4fcecaab90a521d4344cf965202ed7a0a54e (diff) | |
parent | a36ff4a100c2c321eec898f2cfee25c0be85ffc6 (diff) |
Merge #5303
5303: Speed up completion r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
8 files changed, 19 insertions, 20 deletions
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 { | |||
568 | node.ancestors().last().unwrap() | 568 | node.ancestors().last().unwrap() |
569 | } | 569 | } |
570 | 570 | ||
571 | #[derive(Debug)] | ||
571 | pub struct SemanticsScope<'a> { | 572 | pub struct SemanticsScope<'a> { |
572 | pub db: &'a dyn HirDatabase, | 573 | pub db: &'a dyn HirDatabase, |
573 | resolver: Resolver, | 574 | 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<FxHashSet<String>, | |||
195 | 195 | ||
196 | fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> { | 196 | fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> { |
197 | let mut result = FxHashSet::default(); | 197 | let mut result = FxHashSet::default(); |
198 | ctx.scope().process_all_names(&mut |name, scope_def| { | 198 | ctx.scope.process_all_names(&mut |name, scope_def| { |
199 | if let hir::ScopeDef::MacroDef(mac) = scope_def { | 199 | if let hir::ScopeDef::MacroDef(mac) = scope_def { |
200 | if mac.is_derive_macro() { | 200 | if mac.is_derive_macro() { |
201 | result.insert(name.to_string()); | 201 | 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) { | |||
29 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { | 29 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { |
30 | for receiver in receiver.autoderef(ctx.db) { | 30 | for receiver in receiver.autoderef(ctx.db) { |
31 | for (field, ty) in receiver.fields(ctx.db) { | 31 | for (field, ty) in receiver.fields(ctx.db) { |
32 | if ctx.scope().module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { | 32 | if ctx.scope.module().map_or(false, |m| !field.is_visible_from(ctx.db, m)) { |
33 | // Skip private field. FIXME: If the definition location of the | 33 | // Skip private field. FIXME: If the definition location of the |
34 | // field is editable, we should show the completion | 34 | // field is editable, we should show the completion |
35 | continue; | 35 | continue; |
@@ -46,10 +46,10 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Ty | |||
46 | fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { | 46 | fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { |
47 | if let Some(krate) = ctx.krate { | 47 | if let Some(krate) = ctx.krate { |
48 | let mut seen_methods = FxHashSet::default(); | 48 | let mut seen_methods = FxHashSet::default(); |
49 | let traits_in_scope = ctx.scope().traits_in_scope(); | 49 | let traits_in_scope = ctx.scope.traits_in_scope(); |
50 | receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| { | 50 | receiver.iterate_method_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, func| { |
51 | if func.has_self_param(ctx.db) | 51 | if func.has_self_param(ctx.db) |
52 | && ctx.scope().module().map_or(true, |m| func.is_visible_from(ctx.db, m)) | 52 | && ctx.scope.module().map_or(true, |m| func.is_visible_from(ctx.db, m)) |
53 | && seen_methods.insert(func.name(ctx.db)) | 53 | && seen_methods.insert(func.name(ctx.db)) |
54 | { | 54 | { |
55 | acc.add_function(ctx, func, None); | 55 | 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}; | |||
5 | pub(super) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { | 5 | pub(super) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { |
6 | // Show only macros in top level. | 6 | // Show only macros in top level. |
7 | if ctx.is_new_item { | 7 | if ctx.is_new_item { |
8 | ctx.scope().process_all_names(&mut |name, res| { | 8 | ctx.scope.process_all_names(&mut |name, res| { |
9 | if let hir::ScopeDef::MacroDef(mac) = res { | 9 | if let hir::ScopeDef::MacroDef(mac) = res { |
10 | acc.add_macro(ctx, Some(name.to_string()), mac); | 10 | acc.add_macro(ctx, Some(name.to_string()), mac); |
11 | } | 11 | } |
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) { | |||
13 | 13 | ||
14 | // FIXME: ideally, we should look at the type we are matching against and | 14 | // FIXME: ideally, we should look at the type we are matching against and |
15 | // suggest variants + auto-imports | 15 | // suggest variants + auto-imports |
16 | ctx.scope().process_all_names(&mut |name, res| { | 16 | ctx.scope.process_all_names(&mut |name, res| { |
17 | match &res { | 17 | match &res { |
18 | hir::ScopeDef::ModuleDef(def) => match def { | 18 | hir::ScopeDef::ModuleDef(def) => match def { |
19 | hir::ModuleDef::Adt(hir::Adt::Enum(..)) | 19 | 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 | |||
17 | return; | 17 | return; |
18 | } | 18 | } |
19 | 19 | ||
20 | let scope = ctx.scope(); | 20 | let context_module = ctx.scope.module(); |
21 | let context_module = scope.module(); | ||
22 | 21 | ||
23 | let res = match scope.resolve_hir_path_qualifier(&path) { | 22 | let resolution = match ctx.scope.resolve_hir_path_qualifier(&path) { |
24 | Some(res) => res, | 23 | Some(res) => res, |
25 | None => return, | 24 | None => return, |
26 | }; | 25 | }; |
27 | 26 | ||
28 | // Add associated types on type parameters and `Self`. | 27 | // Add associated types on type parameters and `Self`. |
29 | res.assoc_type_shorthand_candidates(ctx.db, |alias| { | 28 | resolution.assoc_type_shorthand_candidates(ctx.db, |alias| { |
30 | acc.add_type_alias(ctx, alias); | 29 | acc.add_type_alias(ctx, alias); |
31 | None::<()> | 30 | None::<()> |
32 | }); | 31 | }); |
33 | 32 | ||
34 | match res { | 33 | match resolution { |
35 | PathResolution::Def(hir::ModuleDef::Module(module)) => { | 34 | PathResolution::Def(hir::ModuleDef::Module(module)) => { |
36 | let module_scope = module.scope(ctx.db, context_module); | 35 | let module_scope = module.scope(ctx.db, context_module); |
37 | for (name, def) in module_scope { | 36 | for (name, def) in module_scope { |
@@ -68,7 +67,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
68 | 67 | ||
69 | let krate = ctx.krate; | 68 | let krate = ctx.krate; |
70 | if let Some(krate) = krate { | 69 | if let Some(krate) = krate { |
71 | let traits_in_scope = ctx.scope().traits_in_scope(); | 70 | let traits_in_scope = ctx.scope.traits_in_scope(); |
72 | ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { | 71 | ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { |
73 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { | 72 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { |
74 | return None; | 73 | return None; |
@@ -113,13 +112,13 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
113 | } | 112 | } |
114 | PathResolution::TypeParam(_) | PathResolution::SelfType(_) => { | 113 | PathResolution::TypeParam(_) | PathResolution::SelfType(_) => { |
115 | if let Some(krate) = ctx.krate { | 114 | if let Some(krate) = ctx.krate { |
116 | let ty = match res { | 115 | let ty = match resolution { |
117 | PathResolution::TypeParam(param) => param.ty(ctx.db), | 116 | PathResolution::TypeParam(param) => param.ty(ctx.db), |
118 | PathResolution::SelfType(impl_def) => impl_def.target_ty(ctx.db), | 117 | PathResolution::SelfType(impl_def) => impl_def.target_ty(ctx.db), |
119 | _ => return, | 118 | _ => return, |
120 | }; | 119 | }; |
121 | 120 | ||
122 | let traits_in_scope = ctx.scope().traits_in_scope(); | 121 | let traits_in_scope = ctx.scope.traits_in_scope(); |
123 | let mut seen = FxHashSet::default(); | 122 | let mut seen = FxHashSet::default(); |
124 | ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { | 123 | ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { |
125 | if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { | 124 | 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 | |||
25 | return; | 25 | return; |
26 | } | 26 | } |
27 | 27 | ||
28 | ctx.scope().process_all_names(&mut |name, res| { | 28 | ctx.scope.process_all_names(&mut |name, res| { |
29 | if ctx.use_item_syntax.is_some() { | 29 | if ctx.use_item_syntax.is_some() { |
30 | if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) { | 30 | if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) { |
31 | if name_ref.syntax().text() == name.to_string().as_str() { | 31 | 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 | |||
42 | if let Some(Adt::Enum(enum_data)) = ty.as_adt() { | 42 | if let Some(Adt::Enum(enum_data)) = ty.as_adt() { |
43 | let variants = enum_data.variants(ctx.db); | 43 | let variants = enum_data.variants(ctx.db); |
44 | 44 | ||
45 | let module = if let Some(module) = ctx.scope().module() { | 45 | let module = if let Some(module) = ctx.scope.module() { |
46 | // Compute path from the completion site if available. | 46 | // Compute path from the completion site if available. |
47 | module | 47 | module |
48 | } else { | 48 | } 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; | |||
24 | #[derive(Debug)] | 24 | #[derive(Debug)] |
25 | pub(crate) struct CompletionContext<'a> { | 25 | pub(crate) struct CompletionContext<'a> { |
26 | pub(super) sema: Semantics<'a, RootDatabase>, | 26 | pub(super) sema: Semantics<'a, RootDatabase>, |
27 | pub(super) scope: SemanticsScope<'a>, | ||
27 | pub(super) db: &'a RootDatabase, | 28 | pub(super) db: &'a RootDatabase, |
28 | pub(super) config: &'a CompletionConfig, | 29 | pub(super) config: &'a CompletionConfig, |
29 | pub(super) offset: TextSize, | 30 | pub(super) offset: TextSize, |
@@ -106,8 +107,10 @@ impl<'a> CompletionContext<'a> { | |||
106 | let original_token = | 107 | let original_token = |
107 | original_file.syntax().token_at_offset(position.offset).left_biased()?; | 108 | original_file.syntax().token_at_offset(position.offset).left_biased()?; |
108 | let token = sema.descend_into_macros(original_token.clone()); | 109 | let token = sema.descend_into_macros(original_token.clone()); |
110 | let scope = sema.scope_at_offset(&token.parent(), position.offset); | ||
109 | let mut ctx = CompletionContext { | 111 | let mut ctx = CompletionContext { |
110 | sema, | 112 | sema, |
113 | scope, | ||
111 | db, | 114 | db, |
112 | config, | 115 | config, |
113 | original_token, | 116 | original_token, |
@@ -207,10 +210,6 @@ impl<'a> CompletionContext<'a> { | |||
207 | } | 210 | } |
208 | } | 211 | } |
209 | 212 | ||
210 | pub(crate) fn scope(&self) -> SemanticsScope<'_> { | ||
211 | self.sema.scope_at_offset(&self.token.parent(), self.offset) | ||
212 | } | ||
213 | |||
214 | fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) { | 213 | fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) { |
215 | let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); | 214 | let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); |
216 | let syntax_element = NodeOrToken::Token(fake_ident_token.clone()); | 215 | let syntax_element = NodeOrToken::Token(fake_ident_token.clone()); |