From 04aff742b15ebab39f493ba480d20c61e1f3bdd5 Mon Sep 17 00:00:00 2001 From: adamrk Date: Sat, 15 Feb 2020 21:48:20 +0100 Subject: show names for record fields in enum completion --- crates/ra_hir/src/code_model.rs | 5 ++ crates/ra_hir/src/lib.rs | 1 + crates/ra_hir_def/src/adt.rs | 9 ++- crates/ra_ide/src/completion/presentation.rs | 101 +++++++++++++++++++++++++-- 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; use either::Either; use hir_def::{ + adt::StructKind, adt::VariantData, builtin_type::BuiltinType, docs::Documentation, @@ -424,6 +425,10 @@ impl EnumVariant { .collect() } + pub fn kind(self, db: &impl HirDatabase) -> StructKind { + self.variant_data(db).kind() + } + pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc { db.enum_data(self.parent.id).variants[self.id].variant_data.clone() } 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::{ }; pub use hir_def::{ + adt::StructKind, body::scope::ExprScopes, builtin_type::BuiltinType, 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 { self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None }) } + pub fn kind(&self) -> StructKind { + match self { + VariantData::Record(_) => StructKind::Record, + VariantData::Tuple(_) => StructKind::Tuple, + VariantData::Unit => StructKind::Unit, + } + } pub fn is_unit(&self) -> bool { match self { VariantData::Unit => true, @@ -173,7 +180,7 @@ impl HasChildSource for VariantId { } } -enum StructKind { +pub enum StructKind { Tuple, Record, 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 @@ //! This modules takes care of rendering various definitions as completion items. -use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, Type}; +use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, StructKind, Type}; use join_to_string::join; use ra_syntax::ast::NameOwner; use test_utils::tested_by; @@ -268,11 +268,22 @@ impl Completions { pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { let is_deprecated = is_deprecated(variant, ctx.db); let name = variant.name(ctx.db); - let detail_types = variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db)); - let detail = join(detail_types.map(|t| t.display(ctx.db).to_string())) - .separator(", ") - .surround_with("(", ")") - .to_string(); + let detail_types = + variant.fields(ctx.db).into_iter().map(|field| (field.name(ctx.db), field.ty(ctx.db))); + let detail = match variant.kind(ctx.db) { + StructKind::Tuple | StructKind::Unit => { + join(detail_types.map(|(_, t)| t.display(ctx.db).to_string())) + .separator(", ") + .surround_with("(", ")") + .to_string() + } + StructKind::Record => { + join(detail_types.map(|(n, t)| format!("{}: {}", n, t.display(ctx.db).to_string()))) + .separator(", ") + .surround_with("{", "}") + .to_string() + } + }; CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) .kind(CompletionItemKind::EnumVariant) .set_documentation(variant.docs(ctx.db)) @@ -297,6 +308,84 @@ mod tests { do_completion(code, CompletionKind::Reference) } + #[test] + fn enum_detail_includes_names_for_record() { + assert_debug_snapshot!( + do_reference_completion( + r#" + enum Foo { + Foo {x: i32, y: i32} + } + + fn main() { Foo::Fo<|> } + "#, + ), + @r###" + [ + CompletionItem { + label: "Foo", + source_range: [121; 123), + delete: [121; 123), + insert: "Foo", + kind: EnumVariant, + detail: "{x: i32, y: i32}", + }, + ]"### + ); + } + + #[test] + fn enum_detail_doesnt_include_names_for_tuple() { + assert_debug_snapshot!( + do_reference_completion( + r#" + enum Foo { + Foo (i32, i32) + } + + fn main() { Foo::Fo<|> } + "#, + ), + @r###" + [ + CompletionItem { + label: "Foo", + source_range: [115; 117), + delete: [115; 117), + insert: "Foo", + kind: EnumVariant, + detail: "(i32, i32)", + }, + ]"### + ); + } + + #[test] + fn enum_detail_just_parentheses_for_unit() { + assert_debug_snapshot!( + do_reference_completion( + r#" + enum Foo { + Foo + } + + fn main() { Foo::Fo<|> } + "#, + ), + @r###" + [ + CompletionItem { + label: "Foo", + source_range: [104; 106), + delete: [104; 106), + insert: "Foo", + kind: EnumVariant, + detail: "()", + }, + ]"### + ); + } + #[test] fn sets_deprecated_flag_in_completion_items() { assert_debug_snapshot!( -- cgit v1.2.3 From 68d3743faf51926f0a63207686f860bdffafe0d7 Mon Sep 17 00:00:00 2001 From: adamrk Date: Sat, 15 Feb 2020 22:12:48 +0100 Subject: replace uses of VariantData::is_unit with VariantData::kind --- crates/ra_hir_def/src/adt.rs | 6 ------ crates/ra_hir_ty/src/lower.rs | 11 +++++++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 4582c7314..985f409e8 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -147,12 +147,6 @@ impl VariantData { VariantData::Unit => StructKind::Unit, } } - pub fn is_unit(&self) -> bool { - match self { - VariantData::Unit => true, - _ => false, - } - } } impl HasChildSource for VariantId { diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 6a2aded02..a5b2734a0 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -9,6 +9,7 @@ use std::iter; use std::sync::Arc; use hir_def::{ + adt::StructKind, builtin_type::BuiltinType, generics::{TypeParamProvenance, WherePredicate, WherePredicateTarget}, path::{GenericArg, Path, PathSegment, PathSegments}, @@ -805,8 +806,9 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> PolyFn /// Build the type of a tuple struct constructor. fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Binders { let struct_data = db.struct_data(def.into()); - if struct_data.variant_data.is_unit() { - return type_for_adt(db, def.into()); // Unit struct + match struct_data.variant_data.kind() { + StructKind::Unit => return type_for_adt(db, def.into()), + StructKind::Tuple | StructKind::Record => (), } let generics = generics(db, def.into()); let substs = Substs::bound_vars(&generics); @@ -830,8 +832,9 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Binders { let enum_data = db.enum_data(def.parent); let var_data = &enum_data.variants[def.local_id].variant_data; - if var_data.is_unit() { - return type_for_adt(db, def.parent.into()); // Unit variant + match var_data.kind() { + StructKind::Unit => return type_for_adt(db, def.parent.into()), + StructKind::Record | StructKind::Tuple => (), } let generics = generics(db, def.parent.into()); let substs = Substs::bound_vars(&generics); -- cgit v1.2.3 From e88eb89132d2407614aebee1b43472b577a2394c Mon Sep 17 00:00:00 2001 From: adamrk Date: Sun, 16 Feb 2020 16:33:15 +0100 Subject: add space before/after wrapping braces --- crates/ra_ide/src/completion/presentation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 4de09d82c..1a3bcffae 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -280,7 +280,7 @@ impl Completions { StructKind::Record => { join(detail_types.map(|(n, t)| format!("{}: {}", n, t.display(ctx.db).to_string()))) .separator(", ") - .surround_with("{", "}") + .surround_with("{ ", " }") .to_string() } }; @@ -328,7 +328,7 @@ mod tests { delete: [121; 123), insert: "Foo", kind: EnumVariant, - detail: "{x: i32, y: i32}", + detail: "{ x: i32, y: i32 }", }, ]"### ); -- cgit v1.2.3 From 0e260aa6b15d9dc8c067adb05f3774aec3fb66ec Mon Sep 17 00:00:00 2001 From: adamrk Date: Mon, 17 Feb 2020 11:53:12 +0100 Subject: use 'if let' instead of match on kind in lower.rs --- crates/ra_hir_ty/src/lower.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index a5b2734a0..c2a3703fa 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -806,9 +806,8 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> PolyFn /// Build the type of a tuple struct constructor. fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Binders { let struct_data = db.struct_data(def.into()); - match struct_data.variant_data.kind() { - StructKind::Unit => return type_for_adt(db, def.into()), - StructKind::Tuple | StructKind::Record => (), + if let StructKind::Unit = struct_data.variant_data.kind() { + return type_for_adt(db, def.into()); } let generics = generics(db, def.into()); let substs = Substs::bound_vars(&generics); @@ -832,9 +831,8 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) -> Binders { let enum_data = db.enum_data(def.parent); let var_data = &enum_data.variants[def.local_id].variant_data; - match var_data.kind() { - StructKind::Unit => return type_for_adt(db, def.parent.into()), - StructKind::Record | StructKind::Tuple => (), + if let StructKind::Unit = var_data.kind() { + return type_for_adt(db, def.parent.into()); } let generics = generics(db, def.parent.into()); let substs = Substs::bound_vars(&generics); -- cgit v1.2.3