aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion')
-rw-r--r--crates/ra_ide/src/completion/complete_attribute.rs19
-rw-r--r--crates/ra_ide/src/completion/complete_qualified_path.rs25
-rw-r--r--crates/ra_ide/src/completion/complete_trait_impl.rs46
-rw-r--r--crates/ra_ide/src/completion/complete_unqualified_path.rs21
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs4
-rw-r--r--crates/ra_ide/src/completion/completion_item.rs7
6 files changed, 83 insertions, 39 deletions
diff --git a/crates/ra_ide/src/completion/complete_attribute.rs b/crates/ra_ide/src/completion/complete_attribute.rs
index 20e6edc17..f17266221 100644
--- a/crates/ra_ide/src/completion/complete_attribute.rs
+++ b/crates/ra_ide/src/completion/complete_attribute.rs
@@ -3,20 +3,21 @@
3//! This module uses a bit of static metadata to provide completions 3//! This module uses a bit of static metadata to provide completions
4//! for built-in attributes. 4//! for built-in attributes.
5 5
6use super::completion_context::CompletionContext; 6use ra_syntax::{ast, AstNode, SyntaxKind};
7use super::completion_item::{CompletionItem, CompletionItemKind, CompletionKind, Completions};
8use ast::AttrInput;
9use ra_syntax::{
10 ast::{self, AttrKind},
11 AstNode, SyntaxKind,
12};
13use rustc_hash::FxHashSet; 7use rustc_hash::FxHashSet;
14 8
9use crate::completion::{
10 completion_context::CompletionContext,
11 completion_item::{CompletionItem, CompletionItemKind, CompletionKind, Completions},
12};
13
15pub(super) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { 14pub(super) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
16 let attribute = ctx.attribute_under_caret.as_ref()?; 15 let attribute = ctx.attribute_under_caret.as_ref()?;
17 16
18 match (attribute.path(), attribute.input()) { 17 match (attribute.path(), attribute.input()) {
19 (Some(path), Some(AttrInput::TokenTree(token_tree))) if path.to_string() == "derive" => { 18 (Some(path), Some(ast::AttrInput::TokenTree(token_tree)))
19 if path.to_string() == "derive" =>
20 {
20 complete_derive(acc, ctx, token_tree) 21 complete_derive(acc, ctx, token_tree)
21 } 22 }
22 _ => complete_attribute_start(acc, ctx, attribute), 23 _ => complete_attribute_start(acc, ctx, attribute),
@@ -40,7 +41,7 @@ fn complete_attribute_start(acc: &mut Completions, ctx: &CompletionContext, attr
40 _ => {} 41 _ => {}
41 } 42 }
42 43
43 if attribute.kind() == AttrKind::Inner || !attr_completion.should_be_inner { 44 if attribute.kind() == ast::AttrKind::Inner || !attr_completion.should_be_inner {
44 acc.add(item); 45 acc.add(item);
45 } 46 }
46 } 47 }
diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs
index aa56a5cd8..7fcd22525 100644
--- a/crates/ra_ide/src/completion/complete_qualified_path.rs
+++ b/crates/ra_ide/src/completion/complete_qualified_path.rs
@@ -2,16 +2,21 @@
2 2
3use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; 3use hir::{Adt, HasVisibility, PathResolution, ScopeDef};
4use ra_syntax::AstNode; 4use ra_syntax::AstNode;
5use rustc_hash::FxHashSet;
5use test_utils::tested_by; 6use test_utils::tested_by;
6 7
7use crate::completion::{CompletionContext, Completions}; 8use crate::completion::{CompletionContext, Completions};
8use rustc_hash::FxHashSet;
9 9
10pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { 10pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
11 let path = match &ctx.path_prefix { 11 let path = match &ctx.path_prefix {
12 Some(path) => path.clone(), 12 Some(path) => path.clone(),
13 _ => return, 13 None => return,
14 }; 14 };
15
16 if ctx.attribute_under_caret.is_some() {
17 return;
18 }
19
15 let scope = ctx.scope(); 20 let scope = ctx.scope();
16 let context_module = scope.module(); 21 let context_module = scope.module();
17 22
@@ -79,7 +84,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
79 }); 84 });
80 85
81 // Iterate assoc types separately 86 // Iterate assoc types separately
82 ty.iterate_impl_items(ctx.db, krate, |item| { 87 ty.iterate_assoc_items(ctx.db, krate, |item| {
83 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { 88 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
84 return None; 89 return None;
85 } 90 }
@@ -1325,4 +1330,18 @@ mod tests {
1325 "### 1330 "###
1326 ); 1331 );
1327 } 1332 }
1333
1334 #[test]
1335 fn dont_complete_attr() {
1336 assert_debug_snapshot!(
1337 do_reference_completion(
1338 r"
1339 mod foo { pub struct Foo; }
1340 #[foo::<|>]
1341 fn f() {}
1342 "
1343 ),
1344 @r###"[]"###
1345 )
1346 }
1328} 1347}
diff --git a/crates/ra_ide/src/completion/complete_trait_impl.rs b/crates/ra_ide/src/completion/complete_trait_impl.rs
index ee32d1ff6..039df03e0 100644
--- a/crates/ra_ide/src/completion/complete_trait_impl.rs
+++ b/crates/ra_ide/src/completion/complete_trait_impl.rs
@@ -32,7 +32,7 @@
32//! ``` 32//! ```
33 33
34use hir::{self, Docs, HasSource}; 34use hir::{self, Docs, HasSource};
35use ra_assists::utils::get_missing_impl_items; 35use ra_assists::utils::get_missing_assoc_items;
36use ra_syntax::{ 36use ra_syntax::{
37 ast::{self, edit, ImplDef}, 37 ast::{self, edit, ImplDef},
38 AstNode, SyntaxKind, SyntaxNode, TextRange, T, 38 AstNode, SyntaxKind, SyntaxNode, TextRange, T,
@@ -50,7 +50,7 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
50 if let Some((trigger, impl_def)) = completion_match(ctx) { 50 if let Some((trigger, impl_def)) = completion_match(ctx) {
51 match trigger.kind() { 51 match trigger.kind() {
52 SyntaxKind::NAME_REF => { 52 SyntaxKind::NAME_REF => {
53 get_missing_impl_items(&ctx.sema, &impl_def).iter().for_each(|item| match item { 53 get_missing_assoc_items(&ctx.sema, &impl_def).iter().for_each(|item| match item {
54 hir::AssocItem::Function(fn_item) => { 54 hir::AssocItem::Function(fn_item) => {
55 add_function_impl(&trigger, acc, ctx, &fn_item) 55 add_function_impl(&trigger, acc, ctx, &fn_item)
56 } 56 }
@@ -64,34 +64,40 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
64 } 64 }
65 65
66 SyntaxKind::FN_DEF => { 66 SyntaxKind::FN_DEF => {
67 for missing_fn in get_missing_impl_items(&ctx.sema, &impl_def).iter().filter_map( 67 for missing_fn in
68 |item| match item { 68 get_missing_assoc_items(&ctx.sema, &impl_def).iter().filter_map(|item| {
69 hir::AssocItem::Function(fn_item) => Some(fn_item), 69 match item {
70 _ => None, 70 hir::AssocItem::Function(fn_item) => Some(fn_item),
71 }, 71 _ => None,
72 ) { 72 }
73 })
74 {
73 add_function_impl(&trigger, acc, ctx, &missing_fn); 75 add_function_impl(&trigger, acc, ctx, &missing_fn);
74 } 76 }
75 } 77 }
76 78
77 SyntaxKind::TYPE_ALIAS_DEF => { 79 SyntaxKind::TYPE_ALIAS_DEF => {
78 for missing_fn in get_missing_impl_items(&ctx.sema, &impl_def).iter().filter_map( 80 for missing_fn in
79 |item| match item { 81 get_missing_assoc_items(&ctx.sema, &impl_def).iter().filter_map(|item| {
80 hir::AssocItem::TypeAlias(type_item) => Some(type_item), 82 match item {
81 _ => None, 83 hir::AssocItem::TypeAlias(type_item) => Some(type_item),
82 }, 84 _ => None,
83 ) { 85 }
86 })
87 {
84 add_type_alias_impl(&trigger, acc, ctx, &missing_fn); 88 add_type_alias_impl(&trigger, acc, ctx, &missing_fn);
85 } 89 }
86 } 90 }
87 91
88 SyntaxKind::CONST_DEF => { 92 SyntaxKind::CONST_DEF => {
89 for missing_fn in get_missing_impl_items(&ctx.sema, &impl_def).iter().filter_map( 93 for missing_fn in
90 |item| match item { 94 get_missing_assoc_items(&ctx.sema, &impl_def).iter().filter_map(|item| {
91 hir::AssocItem::Const(const_item) => Some(const_item), 95 match item {
92 _ => None, 96 hir::AssocItem::Const(const_item) => Some(const_item),
93 }, 97 _ => None,
94 ) { 98 }
99 })
100 {
95 add_const_impl(&trigger, acc, ctx, &missing_fn); 101 add_const_impl(&trigger, acc, ctx, &missing_fn);
96 } 102 }
97 } 103 }
diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs
index a6a5568de..bd40af1cb 100644
--- a/crates/ra_ide/src/completion/complete_unqualified_path.rs
+++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs
@@ -8,9 +8,12 @@ use hir::{Adt, ModuleDef, Type};
8use ra_syntax::AstNode; 8use ra_syntax::AstNode;
9 9
10pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) { 10pub(super) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
11 if (!ctx.is_trivial_path && !ctx.is_pat_binding_or_const) 11 if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) {
12 || ctx.record_lit_syntax.is_some() 12 return;
13 }
14 if ctx.record_lit_syntax.is_some()
13 || ctx.record_pat_syntax.is_some() 15 || ctx.record_pat_syntax.is_some()
16 || ctx.attribute_under_caret.is_some()
14 { 17 {
15 return; 18 return;
16 } 19 }
@@ -1369,4 +1372,18 @@ mod tests {
1369 "### 1372 "###
1370 ) 1373 )
1371 } 1374 }
1375
1376 #[test]
1377 fn dont_complete_attr() {
1378 assert_debug_snapshot!(
1379 do_reference_completion(
1380 r"
1381 struct Foo;
1382 #[<|>]
1383 fn f() {}
1384 "
1385 ),
1386 @r###"[]"###
1387 )
1388 }
1372} 1389}
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index dd87bd119..b6b9627de 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -9,7 +9,7 @@ use ra_syntax::{
9 SyntaxKind::*, 9 SyntaxKind::*,
10 SyntaxNode, SyntaxToken, TextRange, TextSize, 10 SyntaxNode, SyntaxToken, TextRange, TextSize,
11}; 11};
12use ra_text_edit::AtomTextEdit; 12use ra_text_edit::Indel;
13 13
14use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition}; 14use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition};
15 15
@@ -76,7 +76,7 @@ impl<'a> CompletionContext<'a> {
76 // actual completion. 76 // actual completion.
77 let file_with_fake_ident = { 77 let file_with_fake_ident = {
78 let parse = db.parse(position.file_id); 78 let parse = db.parse(position.file_id);
79 let edit = AtomTextEdit::insert(position.offset, "intellijRulezz".to_string()); 79 let edit = Indel::insert(position.offset, "intellijRulezz".to_string());
80 parse.reparse(&edit).tree() 80 parse.reparse(&edit).tree()
81 }; 81 };
82 let fake_ident_token = 82 let fake_ident_token =
diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs
index 5936fb8f7..6021f7279 100644
--- a/crates/ra_ide/src/completion/completion_item.rs
+++ b/crates/ra_ide/src/completion/completion_item.rs
@@ -2,11 +2,12 @@
2 2
3use std::fmt; 3use std::fmt;
4 4
5use super::completion_config::SnippetCap;
6use hir::Documentation; 5use hir::Documentation;
7use ra_syntax::TextRange; 6use ra_syntax::TextRange;
8use ra_text_edit::TextEdit; 7use ra_text_edit::TextEdit;
9 8
9use crate::completion::completion_config::SnippetCap;
10
10/// `CompletionItem` describes a single completion variant in the editor pop-up. 11/// `CompletionItem` describes a single completion variant in the editor pop-up.
11/// It is basically a POD with various properties. To construct a 12/// It is basically a POD with various properties. To construct a
12/// `CompletionItem`, use `new` method and the `Builder` struct. 13/// `CompletionItem`, use `new` method and the `Builder` struct.
@@ -62,8 +63,8 @@ impl fmt::Debug for CompletionItem {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 63 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 let mut s = f.debug_struct("CompletionItem"); 64 let mut s = f.debug_struct("CompletionItem");
64 s.field("label", &self.label()).field("source_range", &self.source_range()); 65 s.field("label", &self.label()).field("source_range", &self.source_range());
65 if self.text_edit().as_atoms().len() == 1 { 66 if self.text_edit().as_indels().len() == 1 {
66 let atom = &self.text_edit().as_atoms()[0]; 67 let atom = &self.text_edit().as_indels()[0];
67 s.field("delete", &atom.delete); 68 s.field("delete", &atom.delete);
68 s.field("insert", &atom.insert); 69 s.field("insert", &atom.insert);
69 } else { 70 } else {