aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/code_model.rs5
-rw-r--r--crates/ra_hir/src/lib.rs1
-rw-r--r--crates/ra_hir_def/src/adt.rs9
-rw-r--r--crates/ra_ide/src/completion/presentation.rs101
4 files changed, 109 insertions, 7 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index a56b8ab04..b6adb7589 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -3,6 +3,7 @@ use std::sync::Arc;
3 3
4use either::Either; 4use either::Either;
5use hir_def::{ 5use hir_def::{
6 adt::StructKind,
6 adt::VariantData, 7 adt::VariantData,
7 builtin_type::BuiltinType, 8 builtin_type::BuiltinType,
8 docs::Documentation, 9 docs::Documentation,
@@ -424,6 +425,10 @@ impl EnumVariant {
424 .collect() 425 .collect()
425 } 426 }
426 427
428 pub fn kind(self, db: &impl HirDatabase) -> StructKind {
429 self.variant_data(db).kind()
430 }
431
427 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 432 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
428 db.enum_data(self.parent.id).variants[self.id].variant_data.clone() 433 db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
429 } 434 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 5cd965f7a..7a9745ebe 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -50,6 +50,7 @@ pub use crate::{
50}; 50};
51 51
52pub use hir_def::{ 52pub use hir_def::{
53 adt::StructKind,
53 body::scope::ExprScopes, 54 body::scope::ExprScopes,
54 builtin_type::BuiltinType, 55 builtin_type::BuiltinType,
55 docs::Documentation, 56 docs::Documentation,
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index aac5f3e15..4582c7314 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -140,6 +140,13 @@ impl VariantData {
140 self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None }) 140 self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None })
141 } 141 }
142 142
143 pub fn kind(&self) -> StructKind {
144 match self {
145 VariantData::Record(_) => StructKind::Record,
146 VariantData::Tuple(_) => StructKind::Tuple,
147 VariantData::Unit => StructKind::Unit,
148 }
149 }
143 pub fn is_unit(&self) -> bool { 150 pub fn is_unit(&self) -> bool {
144 match self { 151 match self {
145 VariantData::Unit => true, 152 VariantData::Unit => true,
@@ -173,7 +180,7 @@ impl HasChildSource for VariantId {
173 } 180 }
174} 181}
175 182
176enum StructKind { 183pub enum StructKind {
177 Tuple, 184 Tuple,
178 Record, 185 Record,
179 Unit, 186 Unit,
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index 97475fc0b..4de09d82c 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -1,6 +1,6 @@
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, Type}; 3use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, StructKind, 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;
@@ -268,11 +268,22 @@ impl Completions {
268 pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { 268 pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) {
269 let is_deprecated = is_deprecated(variant, ctx.db); 269 let is_deprecated = is_deprecated(variant, ctx.db);
270 let name = variant.name(ctx.db); 270 let name = variant.name(ctx.db);
271 let detail_types = variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db)); 271 let detail_types =
272 let detail = join(detail_types.map(|t| t.display(ctx.db).to_string())) 272 variant.fields(ctx.db).into_iter().map(|field| (field.name(ctx.db), field.ty(ctx.db)));
273 .separator(", ") 273 let detail = match variant.kind(ctx.db) {
274 .surround_with("(", ")") 274 StructKind::Tuple | StructKind::Unit => {
275 .to_string(); 275 join(detail_types.map(|(_, t)| t.display(ctx.db).to_string()))
276 .separator(", ")
277 .surround_with("(", ")")
278 .to_string()
279 }
280 StructKind::Record => {
281 join(detail_types.map(|(n, t)| format!("{}: {}", n, t.display(ctx.db).to_string())))
282 .separator(", ")
283 .surround_with("{", "}")
284 .to_string()
285 }
286 };
276 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) 287 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string())
277 .kind(CompletionItemKind::EnumVariant) 288 .kind(CompletionItemKind::EnumVariant)
278 .set_documentation(variant.docs(ctx.db)) 289 .set_documentation(variant.docs(ctx.db))
@@ -298,6 +309,84 @@ mod tests {
298 } 309 }
299 310
300 #[test] 311 #[test]
312 fn enum_detail_includes_names_for_record() {
313 assert_debug_snapshot!(
314 do_reference_completion(
315 r#"
316 enum Foo {
317 Foo {x: i32, y: i32}
318 }
319
320 fn main() { Foo::Fo<|> }
321 "#,
322 ),
323 @r###"
324 [
325 CompletionItem {
326 label: "Foo",
327 source_range: [121; 123),
328 delete: [121; 123),
329 insert: "Foo",
330 kind: EnumVariant,
331 detail: "{x: i32, y: i32}",
332 },
333 ]"###
334 );
335 }
336
337 #[test]
338 fn enum_detail_doesnt_include_names_for_tuple() {
339 assert_debug_snapshot!(
340 do_reference_completion(
341 r#"
342 enum Foo {
343 Foo (i32, i32)
344 }
345
346 fn main() { Foo::Fo<|> }
347 "#,
348 ),
349 @r###"
350 [
351 CompletionItem {
352 label: "Foo",
353 source_range: [115; 117),
354 delete: [115; 117),
355 insert: "Foo",
356 kind: EnumVariant,
357 detail: "(i32, i32)",
358 },
359 ]"###
360 );
361 }
362
363 #[test]
364 fn enum_detail_just_parentheses_for_unit() {
365 assert_debug_snapshot!(
366 do_reference_completion(
367 r#"
368 enum Foo {
369 Foo
370 }
371
372 fn main() { Foo::Fo<|> }
373 "#,
374 ),
375 @r###"
376 [
377 CompletionItem {
378 label: "Foo",
379 source_range: [104; 106),
380 delete: [104; 106),
381 insert: "Foo",
382 kind: EnumVariant,
383 detail: "()",
384 },
385 ]"###
386 );
387 }
388
389 #[test]
301 fn sets_deprecated_flag_in_completion_items() { 390 fn sets_deprecated_flag_in_completion_items() {
302 assert_debug_snapshot!( 391 assert_debug_snapshot!(
303 do_reference_completion( 392 do_reference_completion(