diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-26 11:05:05 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-26 11:05:05 +0000 |
commit | 500e022f7decbee29a693b0f0dd2f63789a99e5a (patch) | |
tree | 2f7839288ce5676a89c6d6062cbaf70544e0beed /crates/ra_ide_api/src/completion/presentation.rs | |
parent | 5901cc736074bbc4d780a8e45079d405ab2cec4b (diff) | |
parent | e5eadb339039e21718d382c0b3d02a4bf053b3f4 (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.rs | 39 |
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 | ||
3 | use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; | 3 | use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Type}; |
4 | use join_to_string::join; | 4 | use join_to_string::join; |
5 | use ra_syntax::ast::NameOwner; | 5 | use ra_syntax::ast::NameOwner; |
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
7 | 7 | ||
8 | use crate::completion::{ | 8 | use crate::completion::{ |
9 | db, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, | 9 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::display::{const_label, function_label, macro_label, type_label}; | 12 | use 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 | ||
294 | fn 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)] |
300 | mod tests { | 293 | mod tests { |
301 | use insta::assert_debug_snapshot; | 294 | use insta::assert_debug_snapshot; |