aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/completion/presentation.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-11-26 11:05:05 +0000
committerGitHub <[email protected]>2019-11-26 11:05:05 +0000
commit500e022f7decbee29a693b0f0dd2f63789a99e5a (patch)
tree2f7839288ce5676a89c6d6062cbaf70544e0beed /crates/ra_ide_api/src/completion/presentation.rs
parent5901cc736074bbc4d780a8e45079d405ab2cec4b (diff)
parente5eadb339039e21718d382c0b3d02a4bf053b3f4 (diff)
Merge #2398
2398: WIP: introduce hir::Type r=matklad a=matklad This introduces `hir::Type` wrapper over `hir::Ty`, with two purposes: * bind `Ty` and it's corresponding environment * Am I correct that `Ty` without an env doesn't make much sense, because the meaning of type parameters is unclear * Am I correct that we can safely re-use the same environment for all types derived from the given type? * hide representation defails of `Ty`. Specifically, I want to change `Ty::Adt` to use `hir_def::AdtId` instead of `hir::Adt`, but IDE doesn't know about underlying IDs. More generally, I feel like IDE shouldn't know that `Ty` is enum. @flodiebold what do you think about this? Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_ide_api/src/completion/presentation.rs')
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs39
1 files changed, 16 insertions, 23 deletions
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs
index 85b053a6e..5f056730a 100644
--- a/crates/ra_ide_api/src/completion/presentation.rs
+++ b/crates/ra_ide_api/src/completion/presentation.rs
@@ -1,12 +1,12 @@
1//! This modules takes care of rendering various definitions as completion items. 1//! This modules takes care of rendering various definitions as completion items.
2 2
3use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; 3use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Type};
4use join_to_string::join; 4use join_to_string::join;
5use ra_syntax::ast::NameOwner; 5use ra_syntax::ast::NameOwner;
6use test_utils::tested_by; 6use test_utils::tested_by;
7 7
8use crate::completion::{ 8use crate::completion::{
9 db, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, 9 CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions,
10}; 10};
11 11
12use crate::display::{const_label, function_label, macro_label, type_label}; 12use crate::display::{const_label, function_label, macro_label, type_label};
@@ -16,7 +16,7 @@ impl Completions {
16 &mut self, 16 &mut self,
17 ctx: &CompletionContext, 17 ctx: &CompletionContext,
18 field: hir::StructField, 18 field: hir::StructField,
19 substs: &hir::Substs, 19 ty: &Type,
20 ) { 20 ) {
21 let is_deprecated = is_deprecated(field, ctx.db); 21 let is_deprecated = is_deprecated(field, ctx.db);
22 CompletionItem::new( 22 CompletionItem::new(
@@ -25,13 +25,13 @@ impl Completions {
25 field.name(ctx.db).to_string(), 25 field.name(ctx.db).to_string(),
26 ) 26 )
27 .kind(CompletionItemKind::Field) 27 .kind(CompletionItemKind::Field)
28 .detail(field.ty(ctx.db).subst(substs).display(ctx.db).to_string()) 28 .detail(ty.display(ctx.db).to_string())
29 .set_documentation(field.docs(ctx.db)) 29 .set_documentation(field.docs(ctx.db))
30 .set_deprecated(is_deprecated) 30 .set_deprecated(is_deprecated)
31 .add_to(self); 31 .add_to(self);
32 } 32 }
33 33
34 pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &hir::Ty) { 34 pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &Type) {
35 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string()) 35 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string())
36 .kind(CompletionItemKind::Field) 36 .kind(CompletionItemKind::Field)
37 .detail(ty.display(ctx.db).to_string()) 37 .detail(ty.display(ctx.db).to_string())
@@ -98,7 +98,7 @@ impl Completions {
98 CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone()); 98 CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone());
99 if let ScopeDef::Local(local) = resolution { 99 if let ScopeDef::Local(local) = resolution {
100 let ty = local.ty(ctx.db); 100 let ty = local.ty(ctx.db);
101 if ty != Ty::Unknown { 101 if !ty.is_unknown() {
102 completion_item = completion_item.detail(ty.display(ctx.db).to_string()); 102 completion_item = completion_item.detail(ty.display(ctx.db).to_string());
103 } 103 }
104 }; 104 };
@@ -108,19 +108,17 @@ impl Completions {
108 && !ctx.has_type_args 108 && !ctx.has_type_args
109 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis") 109 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
110 { 110 {
111 let generic_def: Option<hir::GenericDef> = match resolution { 111 let has_non_default_type_params = match resolution {
112 ScopeDef::ModuleDef(Adt(it)) => Some((*it).into()), 112 ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
113 ScopeDef::ModuleDef(TypeAlias(it)) => Some((*it).into()), 113 ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
114 _ => None, 114 _ => false,
115 }; 115 };
116 if let Some(def) = generic_def { 116 if has_non_default_type_params {
117 if has_non_default_type_params(def, ctx.db) { 117 tested_by!(inserts_angle_brackets_for_generics);
118 tested_by!(inserts_angle_brackets_for_generics); 118 completion_item = completion_item
119 completion_item = completion_item 119 .lookup_by(local_name.clone())
120 .lookup_by(local_name.clone()) 120 .label(format!("{}<…>", local_name))
121 .label(format!("{}<…>", local_name)) 121 .insert_snippet(format!("{}<$0>", local_name));
122 .insert_snippet(format!("{}<$0>", local_name));
123 }
124 } 122 }
125 } 123 }
126 124
@@ -291,11 +289,6 @@ fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool {
291 node.attrs(db).by_key("deprecated").exists() 289 node.attrs(db).by_key("deprecated").exists()
292} 290}
293 291
294fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool {
295 let subst = db.generic_defaults(def.into());
296 subst.iter().any(|ty| ty == &Ty::Unknown)
297}
298
299#[cfg(test)] 292#[cfg(test)]
300mod tests { 293mod tests {
301 use insta::assert_debug_snapshot; 294 use insta::assert_debug_snapshot;