diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/auto_import.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/name.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 59 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 15 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_scope.rs | 55 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/completion_context.rs | 12 |
7 files changed, 68 insertions, 92 deletions
diff --git a/crates/ra_assists/src/auto_import.rs b/crates/ra_assists/src/auto_import.rs index b002d0e4d..7c856c19b 100644 --- a/crates/ra_assists/src/auto_import.rs +++ b/crates/ra_assists/src/auto_import.rs | |||
@@ -492,7 +492,6 @@ fn apply_auto_import( | |||
492 | } | 492 | } |
493 | } | 493 | } |
494 | 494 | ||
495 | #[allow(unused)] | ||
496 | pub fn collect_hir_path_segments(path: &hir::Path) -> Vec<SmolStr> { | 495 | pub fn collect_hir_path_segments(path: &hir::Path) -> Vec<SmolStr> { |
497 | let mut ps = Vec::<SmolStr>::with_capacity(10); | 496 | let mut ps = Vec::<SmolStr>::with_capacity(10); |
498 | match path.kind { | 497 | match path.kind { |
@@ -503,7 +502,7 @@ pub fn collect_hir_path_segments(path: &hir::Path) -> Vec<SmolStr> { | |||
503 | hir::PathKind::Super => ps.push("super".into()), | 502 | hir::PathKind::Super => ps.push("super".into()), |
504 | } | 503 | } |
505 | for s in path.segments.iter() { | 504 | for s in path.segments.iter() { |
506 | ps.push(s.name.to_smolstr()); | 505 | ps.push(s.name.to_string().into()); |
507 | } | 506 | } |
508 | ps | 507 | ps |
509 | } | 508 | } |
@@ -511,7 +510,6 @@ pub fn collect_hir_path_segments(path: &hir::Path) -> Vec<SmolStr> { | |||
511 | // This function produces sequence of text edits into edit | 510 | // This function produces sequence of text edits into edit |
512 | // to import the target path in the most appropriate scope given | 511 | // to import the target path in the most appropriate scope given |
513 | // the cursor position | 512 | // the cursor position |
514 | #[allow(unused)] | ||
515 | pub fn auto_import_text_edit( | 513 | pub fn auto_import_text_edit( |
516 | // Ideally the position of the cursor, used to | 514 | // Ideally the position of the cursor, used to |
517 | position: &SyntaxNode, | 515 | position: &SyntaxNode, |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index f156e3f07..4411715de 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -52,7 +52,7 @@ use crate::{ | |||
52 | db::{HirDatabase, DefDatabase}, | 52 | db::{HirDatabase, DefDatabase}, |
53 | name::{AsName, KnownName}, | 53 | name::{AsName, KnownName}, |
54 | source_id::{FileAstId, AstId}, | 54 | source_id::{FileAstId, AstId}, |
55 | resolve::Resolver, resolve::ImportResolver, | 55 | resolve::Resolver, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | pub use self::{ | 58 | pub use self::{ |
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs index 331da6027..9a999e66c 100644 --- a/crates/ra_hir/src/name.rs +++ b/crates/ra_hir/src/name.rs | |||
@@ -46,8 +46,17 @@ impl Name { | |||
46 | Name::new(idx.to_string().into()) | 46 | Name::new(idx.to_string().into()) |
47 | } | 47 | } |
48 | 48 | ||
49 | pub fn to_smolstr(&self) -> SmolStr { | 49 | // There's should be no way to extract a string out of `Name`: `Name` in the |
50 | self.text.clone() | 50 | // future, `Name` will include hygiene information, and you can't encode |
51 | // hygiene into a String. | ||
52 | // | ||
53 | // If you need to compare something with `Name`, compare `Name`s directly. | ||
54 | // | ||
55 | // If you need to render `Name` for the user, use the `Display` impl, but be | ||
56 | // aware that it strips hygiene info. | ||
57 | #[deprecated(note = "use to_string instead")] | ||
58 | pub fn as_smolstr(&self) -> &SmolStr { | ||
59 | &self.text | ||
51 | } | 60 | } |
52 | 61 | ||
53 | pub(crate) fn as_known_name(&self) -> Option<KnownName> { | 62 | pub(crate) fn as_known_name(&self) -> Option<KnownName> { |
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index ce80be17f..bd0f074c1 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs | |||
@@ -23,12 +23,6 @@ pub(crate) struct Resolver { | |||
23 | scopes: Vec<Scope>, | 23 | scopes: Vec<Scope>, |
24 | } | 24 | } |
25 | 25 | ||
26 | #[derive(Debug, Clone, Default)] | ||
27 | pub(crate) struct ImportResolver { | ||
28 | // todo: use fst crate or something like that | ||
29 | dummy_names: Vec<(SmolStr, Vec<SmolStr>)>, | ||
30 | } | ||
31 | |||
32 | // FIXME how to store these best | 26 | // FIXME how to store these best |
33 | #[derive(Debug, Clone)] | 27 | #[derive(Debug, Clone)] |
34 | pub(crate) struct ModuleItemMap { | 28 | pub(crate) struct ModuleItemMap { |
@@ -317,56 +311,3 @@ impl Scope { | |||
317 | } | 311 | } |
318 | } | 312 | } |
319 | } | 313 | } |
320 | |||
321 | impl ImportResolver { | ||
322 | pub(crate) fn new() -> Self { | ||
323 | let dummy_names = vec![ | ||
324 | (SmolStr::new("fmt"), vec![SmolStr::new("std"), SmolStr::new("fmt")]), | ||
325 | (SmolStr::new("io"), vec![SmolStr::new("std"), SmolStr::new("io")]), | ||
326 | (SmolStr::new("iter"), vec![SmolStr::new("std"), SmolStr::new("iter")]), | ||
327 | (SmolStr::new("hash"), vec![SmolStr::new("std"), SmolStr::new("hash")]), | ||
328 | ( | ||
329 | SmolStr::new("Debug"), | ||
330 | vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Debug")], | ||
331 | ), | ||
332 | ( | ||
333 | SmolStr::new("Display"), | ||
334 | vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Display")], | ||
335 | ), | ||
336 | ( | ||
337 | SmolStr::new("Hash"), | ||
338 | vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hash")], | ||
339 | ), | ||
340 | ( | ||
341 | SmolStr::new("Hasher"), | ||
342 | vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hasher")], | ||
343 | ), | ||
344 | ( | ||
345 | SmolStr::new("Iterator"), | ||
346 | vec![SmolStr::new("std"), SmolStr::new("iter"), SmolStr::new("Iterator")], | ||
347 | ), | ||
348 | ]; | ||
349 | |||
350 | ImportResolver { dummy_names } | ||
351 | } | ||
352 | |||
353 | // Returns a map of importable items filtered by name. | ||
354 | // The map associates item name with its full path. | ||
355 | // todo: should return Resolutions | ||
356 | pub(crate) fn all_names( | ||
357 | &self, | ||
358 | _db: &impl HirDatabase, | ||
359 | name: &Name, | ||
360 | ) -> FxHashMap<SmolStr, Vec<SmolStr>> { | ||
361 | let name = name.to_smolstr(); | ||
362 | if name.len() > 1 { | ||
363 | self.dummy_names | ||
364 | .iter() | ||
365 | .filter(|(n, _)| n.as_str().contains(name.as_str())) | ||
366 | .cloned() | ||
367 | .collect() | ||
368 | } else { | ||
369 | FxHashMap::default() | ||
370 | } | ||
371 | } | ||
372 | } | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 42399622a..2959e3eca 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -14,12 +14,11 @@ use ra_syntax::{ | |||
14 | ast::{self, AstNode, NameOwner}, | 14 | ast::{self, AstNode, NameOwner}, |
15 | algo::find_node_at_offset, | 15 | algo::find_node_at_offset, |
16 | SyntaxKind::*, | 16 | SyntaxKind::*, |
17 | SmolStr, | ||
18 | }; | 17 | }; |
19 | 18 | ||
20 | use crate::{ | 19 | use crate::{ |
21 | HirDatabase, Function, Struct, Enum, Const, Static, Either, DefWithBody, PerNs, Name, | 20 | HirDatabase, Function, Struct, Enum, Const, Static, Either, DefWithBody, PerNs, Name, |
22 | AsName, Module, HirFileId, Crate, Trait, Resolver, Ty, ImportResolver, | 21 | AsName, Module, HirFileId, Crate, Trait, Resolver, Ty, |
23 | expr::{BodySourceMap, scope::{ScopeId, ExprScopes}}, | 22 | expr::{BodySourceMap, scope::{ScopeId, ExprScopes}}, |
24 | ids::LocationCtx, | 23 | ids::LocationCtx, |
25 | expr, AstId, | 24 | expr, AstId, |
@@ -171,7 +170,6 @@ fn def_with_body_from_child_node( | |||
171 | #[derive(Debug)] | 170 | #[derive(Debug)] |
172 | pub struct SourceAnalyzer { | 171 | pub struct SourceAnalyzer { |
173 | resolver: Resolver, | 172 | resolver: Resolver, |
174 | import_resolver: ImportResolver, | ||
175 | body_source_map: Option<Arc<BodySourceMap>>, | 173 | body_source_map: Option<Arc<BodySourceMap>>, |
176 | infer: Option<Arc<crate::ty::InferenceResult>>, | 174 | infer: Option<Arc<crate::ty::InferenceResult>>, |
177 | scopes: Option<Arc<crate::expr::ExprScopes>>, | 175 | scopes: Option<Arc<crate::expr::ExprScopes>>, |
@@ -219,7 +217,6 @@ impl SourceAnalyzer { | |||
219 | offset: Option<TextUnit>, | 217 | offset: Option<TextUnit>, |
220 | ) -> SourceAnalyzer { | 218 | ) -> SourceAnalyzer { |
221 | let def_with_body = def_with_body_from_child_node(db, file_id, node); | 219 | let def_with_body = def_with_body_from_child_node(db, file_id, node); |
222 | let import_resolver = ImportResolver::new(); | ||
223 | if let Some(def) = def_with_body { | 220 | if let Some(def) = def_with_body { |
224 | let source_map = def.body_source_map(db); | 221 | let source_map = def.body_source_map(db); |
225 | let scopes = db.expr_scopes(def); | 222 | let scopes = db.expr_scopes(def); |
@@ -230,7 +227,6 @@ impl SourceAnalyzer { | |||
230 | let resolver = expr::resolver_for_scope(def.body(db), db, scope); | 227 | let resolver = expr::resolver_for_scope(def.body(db), db, scope); |
231 | SourceAnalyzer { | 228 | SourceAnalyzer { |
232 | resolver, | 229 | resolver, |
233 | import_resolver, | ||
234 | body_source_map: Some(source_map), | 230 | body_source_map: Some(source_map), |
235 | infer: Some(def.infer(db)), | 231 | infer: Some(def.infer(db)), |
236 | scopes: Some(scopes), | 232 | scopes: Some(scopes), |
@@ -241,7 +237,6 @@ impl SourceAnalyzer { | |||
241 | .ancestors() | 237 | .ancestors() |
242 | .find_map(|node| try_get_resolver_for_node(db, file_id, node)) | 238 | .find_map(|node| try_get_resolver_for_node(db, file_id, node)) |
243 | .unwrap_or_default(), | 239 | .unwrap_or_default(), |
244 | import_resolver, | ||
245 | body_source_map: None, | 240 | body_source_map: None, |
246 | infer: None, | 241 | infer: None, |
247 | scopes: None, | 242 | scopes: None, |
@@ -328,14 +323,6 @@ impl SourceAnalyzer { | |||
328 | self.resolver.all_names(db) | 323 | self.resolver.all_names(db) |
329 | } | 324 | } |
330 | 325 | ||
331 | pub fn all_import_names( | ||
332 | &self, | ||
333 | db: &impl HirDatabase, | ||
334 | name: &Name, | ||
335 | ) -> FxHashMap<SmolStr, Vec<SmolStr>> { | ||
336 | self.import_resolver.all_names(db, name) | ||
337 | } | ||
338 | |||
339 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | 326 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { |
340 | // FIXME: at least, this should work with any DefWithBody, but ideally | 327 | // FIXME: at least, this should work with any DefWithBody, but ideally |
341 | // this should be hir-based altogether | 328 | // this should be hir-based altogether |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 5bd5376c9..a2523c5ef 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -1,6 +1,8 @@ | |||
1 | use rustc_hash::FxHashMap; | ||
1 | use ra_text_edit::TextEditBuilder; | 2 | use ra_text_edit::TextEditBuilder; |
2 | use ra_syntax::SmolStr; | 3 | use ra_syntax::SmolStr; |
3 | use ra_assists::auto_import; | 4 | use ra_assists::auto_import; |
5 | |||
4 | use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionContext}; | 6 | use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionContext}; |
5 | 7 | ||
6 | pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | 8 | pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { |
@@ -10,7 +12,8 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
10 | } | 12 | } |
11 | 13 | ||
12 | if let Some(name) = ctx.path_ident.as_ref() { | 14 | if let Some(name) = ctx.path_ident.as_ref() { |
13 | let import_names = ctx.analyzer.all_import_names(ctx.db, name); | 15 | let import_resolver = ImportResolver::new(); |
16 | let import_names = import_resolver.all_names(&name.to_string()); | ||
14 | import_names.into_iter().for_each(|(name, path)| { | 17 | import_names.into_iter().for_each(|(name, path)| { |
15 | let edit = { | 18 | let edit = { |
16 | let mut builder = TextEditBuilder::default(); | 19 | let mut builder = TextEditBuilder::default(); |
@@ -64,6 +67,56 @@ fn fmt_import_path(path: &Vec<SmolStr>, buf: &mut String) { | |||
64 | } | 67 | } |
65 | } | 68 | } |
66 | 69 | ||
70 | #[derive(Debug, Clone, Default)] | ||
71 | pub(crate) struct ImportResolver { | ||
72 | // todo: use fst crate or something like that | ||
73 | dummy_names: Vec<(SmolStr, Vec<SmolStr>)>, | ||
74 | } | ||
75 | |||
76 | impl ImportResolver { | ||
77 | pub(crate) fn new() -> Self { | ||
78 | let dummy_names = vec![ | ||
79 | (SmolStr::new("fmt"), vec![SmolStr::new("std"), SmolStr::new("fmt")]), | ||
80 | (SmolStr::new("io"), vec![SmolStr::new("std"), SmolStr::new("io")]), | ||
81 | (SmolStr::new("iter"), vec![SmolStr::new("std"), SmolStr::new("iter")]), | ||
82 | (SmolStr::new("hash"), vec![SmolStr::new("std"), SmolStr::new("hash")]), | ||
83 | ( | ||
84 | SmolStr::new("Debug"), | ||
85 | vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Debug")], | ||
86 | ), | ||
87 | ( | ||
88 | SmolStr::new("Display"), | ||
89 | vec![SmolStr::new("std"), SmolStr::new("fmt"), SmolStr::new("Display")], | ||
90 | ), | ||
91 | ( | ||
92 | SmolStr::new("Hash"), | ||
93 | vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hash")], | ||
94 | ), | ||
95 | ( | ||
96 | SmolStr::new("Hasher"), | ||
97 | vec![SmolStr::new("std"), SmolStr::new("hash"), SmolStr::new("Hasher")], | ||
98 | ), | ||
99 | ( | ||
100 | SmolStr::new("Iterator"), | ||
101 | vec![SmolStr::new("std"), SmolStr::new("iter"), SmolStr::new("Iterator")], | ||
102 | ), | ||
103 | ]; | ||
104 | |||
105 | ImportResolver { dummy_names } | ||
106 | } | ||
107 | |||
108 | // Returns a map of importable items filtered by name. | ||
109 | // The map associates item name with its full path. | ||
110 | // todo: should return Resolutions | ||
111 | pub(crate) fn all_names(&self, name: &str) -> FxHashMap<SmolStr, Vec<SmolStr>> { | ||
112 | if name.len() > 1 { | ||
113 | self.dummy_names.iter().filter(|(n, _)| n.contains(name)).cloned().collect() | ||
114 | } else { | ||
115 | FxHashMap::default() | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
67 | #[cfg(test)] | 120 | #[cfg(test)] |
68 | mod tests { | 121 | mod tests { |
69 | use crate::completion::{CompletionKind, check_completion}; | 122 | use crate::completion::{CompletionKind, check_completion}; |
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index ca8f7900d..0d630fdf6 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs | |||
@@ -86,18 +86,6 @@ impl<'a> CompletionContext<'a> { | |||
86 | } | 86 | } |
87 | 87 | ||
88 | fn fill(&mut self, original_file: &'a SourceFile, offset: TextUnit) { | 88 | fn fill(&mut self, original_file: &'a SourceFile, offset: TextUnit) { |
89 | // We heed the original NameRef before the "intellijRulezz" hack | ||
90 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(original_file.syntax(), offset) | ||
91 | { | ||
92 | if let Some(path) = name_ref.syntax().ancestors().find_map(ast::Path::cast) { | ||
93 | if let Some(path) = hir::Path::from_ast(path) { | ||
94 | if let Some(ident) = path.as_ident() { | ||
95 | self.path_ident = Some(ident.clone()); | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | |||
101 | // Insert a fake ident to get a valid parse tree. We will use this file | 89 | // Insert a fake ident to get a valid parse tree. We will use this file |
102 | // to determine context, though the original_file will be used for | 90 | // to determine context, though the original_file will be used for |
103 | // actual completion. | 91 | // actual completion. |