aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-02-17 10:54:32 +0000
committerGitHub <[email protected]>2020-02-17 10:54:32 +0000
commitfcf15cc05afaeda6880664777ff2a3db342ea088 (patch)
treeac34e90a9884d7166daa5022ea402196483c26c0 /crates/ra_ide
parent334f53465f5baf5094844ab3ca2d28e477d07b24 (diff)
parent0e260aa6b15d9dc8c067adb05f3774aec3fb66ec (diff)
Merge #3169
3169: Show record field names in Enum completion r=flodiebold a=adamrk Adresses https://github.com/rust-analyzer/rust-analyzer/issues/2947. Previously the details shown when autocompleting an Enum variant would look like the variant was a tuple even if it was a record: ![2020-02-16-15:59:32_crop](https://user-images.githubusercontent.com/16367467/74607233-64f21980-50d7-11ea-99db-e973e29c71d7.png) This change will show the names of the fields for a record and use curly braces instead of parentheses: ![2020-02-16-15:33:00_crop](https://user-images.githubusercontent.com/16367467/74607251-8ce17d00-50d7-11ea-9d4d-38d198a4aec0.png) This required exposing the type `adt::StructKind` from `ra_hir` and adding a function ``` kind(self, db: &impl HirDatabase) -> StructKind ``` in the `impl` of `EnumVariant`. There was also a previously existing function `is_unit(self, db: &impl HirDatabase) -> bool` for `EnumVariant` which I removed because it seemed redundant after adding `kind`. Co-authored-by: adamrk <[email protected]>
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/completion/presentation.rs101
1 files changed, 95 insertions, 6 deletions
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index 97475fc0b..1a3bcffae 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(