diff options
author | Aleksey Kladov <[email protected]> | 2019-04-22 13:56:28 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-04-22 13:56:28 +0100 |
commit | e01052d1f0b8bf70a418a10538528923c5f400d5 (patch) | |
tree | 18ed1c151e7782b791214df4c4a2966c617ae1c6 /crates/ra_ide_api/src/completion | |
parent | 200032852be0c66b978c875a8edf0eca1f08b901 (diff) |
move auto-imoprter into IDE
auto-import is purely an IDE concern, so it should be done outside of
HIR
Diffstat (limited to 'crates/ra_ide_api/src/completion')
-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 |
2 files changed, 54 insertions, 13 deletions
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. |