Skip to content

Commit 04aff74

Browse files
committed
show names for record fields in enum completion
1 parent b2b94cb commit 04aff74

File tree

4 files changed

+109
-7
lines changed

4 files changed

+109
-7
lines changed

crates/ra_hir/src/code_model.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::sync::Arc;
33

44
use either::Either;
55
use hir_def::{
6+
adt::StructKind,
67
adt::VariantData,
78
builtin_type::BuiltinType,
89
docs::Documentation,
@@ -424,6 +425,10 @@ impl EnumVariant {
424425
.collect()
425426
}
426427

428+
pub fn kind(self, db: &impl HirDatabase) -> StructKind {
429+
self.variant_data(db).kind()
430+
}
431+
427432
pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
428433
db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
429434
}

crates/ra_hir/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub use crate::{
5050
};
5151

5252
pub use hir_def::{
53+
adt::StructKind,
5354
body::scope::ExprScopes,
5455
builtin_type::BuiltinType,
5556
docs::Documentation,

crates/ra_hir_def/src/adt.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ impl VariantData {
140140
self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None })
141141
}
142142

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+
}
143150
pub fn is_unit(&self) -> bool {
144151
match self {
145152
VariantData::Unit => true,
@@ -173,7 +180,7 @@ impl HasChildSource for VariantId {
173180
}
174181
}
175182

176-
enum StructKind {
183+
pub enum StructKind {
177184
Tuple,
178185
Record,
179186
Unit,

crates/ra_ide/src/completion/presentation.rs

Lines changed: 95 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This modules takes care of rendering various definitions as completion items.
22
3-
use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Type};
3+
use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, StructKind, Type};
44
use join_to_string::join;
55
use ra_syntax::ast::NameOwner;
66
use test_utils::tested_by;
@@ -268,11 +268,22 @@ impl Completions {
268268
pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) {
269269
let is_deprecated = is_deprecated(variant, ctx.db);
270270
let name = variant.name(ctx.db);
271-
let detail_types = variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db));
272-
let detail = join(detail_types.map(|t| t.display(ctx.db).to_string()))
273-
.separator(", ")
274-
.surround_with("(", ")")
275-
.to_string();
271+
let detail_types =
272+
variant.fields(ctx.db).into_iter().map(|field| (field.name(ctx.db), field.ty(ctx.db)));
273+
let detail = match variant.kind(ctx.db) {
274+
StructKind::Tuple | StructKind::Unit => {
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+
};
276287
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string())
277288
.kind(CompletionItemKind::EnumVariant)
278289
.set_documentation(variant.docs(ctx.db))
@@ -297,6 +308,84 @@ mod tests {
297308
do_completion(code, CompletionKind::Reference)
298309
}
299310

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+
300389
#[test]
301390
fn sets_deprecated_flag_in_completion_items() {
302391
assert_debug_snapshot!(

0 commit comments

Comments
 (0)