aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/completion')
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs12
-rw-r--r--crates/ra_ide_api/src/completion/complete_scope.rs63
-rw-r--r--crates/ra_ide_api/src/completion/completion_context.rs5
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs44
-rw-r--r--crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap18
5 files changed, 74 insertions, 68 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index b33ddcde5..9e61c0212 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -7,13 +7,13 @@ use crate::{
7use hir::Docs; 7use hir::Docs;
8 8
9pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { 9pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
10 let (path, module) = match (&ctx.path_prefix, &ctx.module) { 10 let path = match &ctx.path_prefix {
11 (Some(path), Some(module)) => (path.clone(), module), 11 Some(path) => path.clone(),
12 _ => return, 12 _ => return,
13 }; 13 };
14 let def_id = match module.resolve_path(ctx.db, &path).take_types() { 14 let def = match ctx.resolver.resolve_path(ctx.db, &path).take_types() {
15 Some(it) => it, 15 Some(Resolution::Def { def }) => def,
16 None => return, 16 _ => return,
17 }; 17 };
18 match def_id { 18 match def_id {
19 hir::ModuleDef::Module(module) => { 19 hir::ModuleDef::Module(module) => {
@@ -24,7 +24,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
24 ctx.source_range(), 24 ctx.source_range(),
25 name.to_string(), 25 name.to_string(),
26 ) 26 )
27 .from_resolution(ctx, res) 27 .from_resolution(ctx, &res.def.map(|def| hir::Resolution::Def { def }))
28 .add_to(acc); 28 .add_to(acc);
29 } 29 }
30 } 30 }
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs
index f837bb1db..3488d6480 100644
--- a/crates/ra_ide_api/src/completion/complete_scope.rs
+++ b/crates/ra_ide_api/src/completion/complete_scope.rs
@@ -1,61 +1,32 @@
1use rustc_hash::FxHashSet; 1use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionContext};
2use ra_syntax::ast::AstNode;
3use crate::completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext};
4 2
5pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { 3pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
6 if !ctx.is_trivial_path { 4 if !ctx.is_trivial_path {
7 return; 5 return;
8 } 6 }
9 let module = match &ctx.module { 7 let names = ctx.resolver.all_names();
10 Some(it) => it,
11 None => return,
12 };
13 if let Some(function) = &ctx.function {
14 let scopes = function.scopes(ctx.db);
15 complete_fn(acc, &scopes, ctx);
16 }
17 8
18 let module_scope = module.scope(ctx.db); 9 // let module_scope = module.scope(ctx.db);
19 module_scope 10 names
20 .entries() 11 .into_iter()
21 .filter(|(_name, res)| { 12 // FIXME check tests
22 // For cases like `use self::foo<|>` don't suggest foo itself. 13 // .filter(|(_name, res)| {
23 match res.import { 14 // // For cases like `use self::foo<|>` don't suggest foo itself.
24 None => true, 15 // match res.import {
25 Some(import) => { 16 // None => true,
26 let source = module.import_source(ctx.db, import); 17 // Some(import) => {
27 !source.syntax().range().is_subrange(&ctx.leaf.range()) 18 // let source = module.import_source(ctx.db, import);
28 } 19 // !source.syntax().range().is_subrange(&ctx.leaf.range())
29 } 20 // }
30 }) 21 // }
22 // })
31 .for_each(|(name, res)| { 23 .for_each(|(name, res)| {
32 CompletionItem::new( 24 CompletionItem::new(
33 CompletionKind::Reference, 25 CompletionKind::Reference,
34 ctx.source_range(), 26 ctx.source_range(),
35 name.to_string(), 27 name.to_string(),
36 ) 28 )
37 .from_resolution(ctx, res) 29 .from_resolution(ctx, &res)
38 .add_to(acc)
39 });
40}
41
42fn complete_fn(
43 acc: &mut Completions,
44 scopes: &hir::ScopesWithSyntaxMapping,
45 ctx: &CompletionContext,
46) {
47 let mut shadowed = FxHashSet::default();
48 scopes
49 .scope_chain_for_offset(ctx.offset)
50 .flat_map(|scope| scopes.scopes.entries(scope).iter())
51 .filter(|entry| shadowed.insert(entry.name()))
52 .for_each(|entry| {
53 CompletionItem::new(
54 CompletionKind::Reference,
55 ctx.source_range(),
56 entry.name().to_string(),
57 )
58 .kind(CompletionItemKind::Binding)
59 .add_to(acc) 30 .add_to(acc)
60 }); 31 });
61} 32}
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs
index 578af6e5b..aea32fce3 100644
--- a/crates/ra_ide_api/src/completion/completion_context.rs
+++ b/crates/ra_ide_api/src/completion/completion_context.rs
@@ -5,7 +5,7 @@ use ra_syntax::{
5 algo::{find_leaf_at_offset, find_covering_node, find_node_at_offset}, 5 algo::{find_leaf_at_offset, find_covering_node, find_node_at_offset},
6 SyntaxKind::*, 6 SyntaxKind::*,
7}; 7};
8use hir::source_binder; 8use hir::{source_binder, Resolver};
9 9
10use crate::{db, FilePosition}; 10use crate::{db, FilePosition};
11 11
@@ -16,6 +16,7 @@ pub(crate) struct CompletionContext<'a> {
16 pub(super) db: &'a db::RootDatabase, 16 pub(super) db: &'a db::RootDatabase,
17 pub(super) offset: TextUnit, 17 pub(super) offset: TextUnit,
18 pub(super) leaf: &'a SyntaxNode, 18 pub(super) leaf: &'a SyntaxNode,
19 pub(super) resolver: Resolver<'static>,
19 pub(super) module: Option<hir::Module>, 20 pub(super) module: Option<hir::Module>,
20 pub(super) function: Option<hir::Function>, 21 pub(super) function: Option<hir::Function>,
21 pub(super) function_syntax: Option<&'a ast::FnDef>, 22 pub(super) function_syntax: Option<&'a ast::FnDef>,
@@ -42,12 +43,14 @@ impl<'a> CompletionContext<'a> {
42 original_file: &'a SourceFile, 43 original_file: &'a SourceFile,
43 position: FilePosition, 44 position: FilePosition,
44 ) -> Option<CompletionContext<'a>> { 45 ) -> Option<CompletionContext<'a>> {
46 let resolver = source_binder::resolver_for_position(db, position);
45 let module = source_binder::module_from_position(db, position); 47 let module = source_binder::module_from_position(db, position);
46 let leaf = find_leaf_at_offset(original_file.syntax(), position.offset).left_biased()?; 48 let leaf = find_leaf_at_offset(original_file.syntax(), position.offset).left_biased()?;
47 let mut ctx = CompletionContext { 49 let mut ctx = CompletionContext {
48 db, 50 db,
49 leaf, 51 leaf,
50 offset: position.offset, 52 offset: position.offset,
53 resolver,
51 module, 54 module,
52 function: None, 55 function: None,
53 function_syntax: None, 56 function_syntax: None,
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs
index d3bc14894..4101ce88a 100644
--- a/crates/ra_ide_api/src/completion/completion_item.rs
+++ b/crates/ra_ide_api/src/completion/completion_item.rs
@@ -1,5 +1,7 @@
1use hir::{Docs, Documentation}; 1use hir::{Docs, Documentation, PerNs, Resolution};
2use ra_syntax::TextRange; 2use ra_syntax::{
3 TextRange,
4};
3use ra_text_edit::TextEdit; 5use ra_text_edit::TextEdit;
4use test_utils::tested_by; 6use test_utils::tested_by;
5 7
@@ -48,6 +50,7 @@ pub enum CompletionItemKind {
48 Trait, 50 Trait,
49 TypeAlias, 51 TypeAlias,
50 Method, 52 Method,
53 TypeParam,
51} 54}
52 55
53#[derive(Debug, PartialEq, Eq, Copy, Clone)] 56#[derive(Debug, PartialEq, Eq, Copy, Clone)]
@@ -207,23 +210,38 @@ impl Builder {
207 pub(super) fn from_resolution( 210 pub(super) fn from_resolution(
208 mut self, 211 mut self,
209 ctx: &CompletionContext, 212 ctx: &CompletionContext,
210 resolution: &hir::Resolution, 213 resolution: &PerNs<Resolution>,
211 ) -> Builder { 214 ) -> Builder {
212 let def = resolution.def.take_types().or(resolution.def.take_values()); 215 use hir::ModuleDef::*;
216
217 let def = resolution
218 .as_ref()
219 .take_types()
220 .or(resolution.as_ref().take_values());
213 let def = match def { 221 let def = match def {
214 None => return self, 222 None => return self,
215 Some(it) => it, 223 Some(it) => it,
216 }; 224 };
217 let (kind, docs) = match def { 225 let (kind, docs) = match def {
218 hir::ModuleDef::Module(it) => (CompletionItemKind::Module, it.docs(ctx.db)), 226 Resolution::Def { def: Module(it) } => (CompletionItemKind::Module, it.docs(ctx.db)),
219 hir::ModuleDef::Function(func) => return self.from_function(ctx, func), 227 Resolution::Def {
220 hir::ModuleDef::Struct(it) => (CompletionItemKind::Struct, it.docs(ctx.db)), 228 def: Function(func),
221 hir::ModuleDef::Enum(it) => (CompletionItemKind::Enum, it.docs(ctx.db)), 229 } => return self.from_function(ctx, *func),
222 hir::ModuleDef::EnumVariant(it) => (CompletionItemKind::EnumVariant, it.docs(ctx.db)), 230 Resolution::Def { def: Struct(it) } => (CompletionItemKind::Struct, it.docs(ctx.db)),
223 hir::ModuleDef::Const(it) => (CompletionItemKind::Const, it.docs(ctx.db)), 231 Resolution::Def { def: Enum(it) } => (CompletionItemKind::Enum, it.docs(ctx.db)),
224 hir::ModuleDef::Static(it) => (CompletionItemKind::Static, it.docs(ctx.db)), 232 Resolution::Def {
225 hir::ModuleDef::Trait(it) => (CompletionItemKind::Trait, it.docs(ctx.db)), 233 def: EnumVariant(it),
226 hir::ModuleDef::Type(it) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), 234 } => (CompletionItemKind::EnumVariant, it.docs(ctx.db)),
235 Resolution::Def { def: Const(it) } => (CompletionItemKind::Const, it.docs(ctx.db)),
236 Resolution::Def { def: Static(it) } => (CompletionItemKind::Static, it.docs(ctx.db)),
237 Resolution::Def { def: Trait(it) } => (CompletionItemKind::Trait, it.docs(ctx.db)),
238 Resolution::Def { def: Type(it) } => (CompletionItemKind::TypeAlias, it.docs(ctx.db)),
239 Resolution::GenericParam { .. } => (CompletionItemKind::TypeParam, None),
240 Resolution::LocalBinding { .. } => (CompletionItemKind::Binding, None),
241 Resolution::SelfType { .. } => (
242 CompletionItemKind::TypeParam, // (does this need its own kind?)
243 None,
244 ),
227 }; 245 };
228 self.kind = Some(kind); 246 self.kind = Some(kind);
229 self.documentation = docs; 247 self.documentation = docs;
diff --git a/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap b/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
index 6a49e325c..ba1d4abbd 100644
--- a/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
+++ b/crates/ra_ide_api/src/completion/snapshots/completion_item__self_in_methods.snap
@@ -1,12 +1,26 @@
1--- 1---
2created: "2019-01-23T05:27:32.422259+00:00" 2created: "2019-01-27T20:17:10.051725945+00:00"
3creator: insta@0.4.0 3creator: insta@0.5.2
4expression: kind_completions 4expression: kind_completions
5source: crates/ra_ide_api/src/completion/completion_item.rs 5source: crates/ra_ide_api/src/completion/completion_item.rs
6--- 6---
7[ 7[
8 CompletionItem { 8 CompletionItem {
9 completion_kind: Reference, 9 completion_kind: Reference,
10 label: "Self",
11 kind: Some(
12 TypeParam
13 ),
14 detail: None,
15 documentation: None,
16 lookup: None,
17 insert_text: None,
18 insert_text_format: PlainText,
19 source_range: [25; 25),
20 text_edit: None
21 },
22 CompletionItem {
23 completion_kind: Reference,
10 label: "self", 24 label: "self",
11 kind: Some( 25 kind: Some(
12 Binding 26 Binding