aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-07-11 00:31:57 +0100
committerGitHub <[email protected]>2020-07-11 00:31:57 +0100
commit343b9c6e76919c255466fd9b12fc7fd46f59022e (patch)
tree107769c5884b71e865b7efe44604cfad979e1f72
parent349c4fcecaab90a521d4344cf965202ed7a0a54e (diff)
parenta36ff4a100c2c321eec898f2cfee25c0be85ffc6 (diff)
Merge #5303
5303: Speed up completion r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/ra_hir/src/semantics.rs1
-rw-r--r--crates/ra_ide/src/completion/complete_attribute.rs2
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs6
-rw-r--r--crates/ra_ide/src/completion/complete_macro_in_item_position.rs2
-rw-r--r--crates/ra_ide/src/completion/complete_pattern.rs2
-rw-r--r--crates/ra_ide/src/completion/complete_qualified_path.rs15
-rw-r--r--crates/ra_ide/src/completion/complete_unqualified_path.rs4
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs7
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)]
571pub struct SemanticsScope<'a> { 572pub 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
196fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> { 196fn 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) {
29fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { 29fn 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
46fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: &Type) { 46fn 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};
5pub(super) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { 5pub(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)]
25pub(crate) struct CompletionContext<'a> { 25pub(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());