diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2021-12-21 15:01:52 +0100 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2021-12-21 15:01:52 +0100 |
| commit | e99ed3e407ad6c043e53ebadf2b62fbc2f8e678c (patch) | |
| tree | de596bcc0b3677e345b53ab5a2e082266791168d | |
| parent | a720fc8e3a8ae3d8052d0c87767056408bc25ffa (diff) | |
| download | rust-e99ed3e407ad6c043e53ebadf2b62fbc2f8e678c.tar.gz rust-e99ed3e407ad6c043e53ebadf2b62fbc2f8e678c.zip | |
Simplify enum variant rendering, remove constructor structs
| -rw-r--r-- | crates/ide_completion/src/render/enum_variant.rs | 172 |
1 files changed, 71 insertions, 101 deletions
diff --git a/crates/ide_completion/src/render/enum_variant.rs b/crates/ide_completion/src/render/enum_variant.rs index 26cb73d09c9..f613f0dfde2 100644 --- a/crates/ide_completion/src/render/enum_variant.rs +++ b/crates/ide_completion/src/render/enum_variant.rs @@ -1,10 +1,10 @@ //! Renderer for `enum` variants. -use std::{iter, mem}; +use std::iter; -use hir::{HasAttrs, HirDisplay}; +use hir::{db::HirDatabase, HasAttrs, HirDisplay, StructKind}; use ide_db::SymbolKind; -use stdx::format_to; +use itertools::Itertools; use crate::{ item::{CompletionItem, ImportEdit}, @@ -20,116 +20,86 @@ pub(crate) fn render_variant( path: Option<hir::ModPath>, ) -> CompletionItem { let _p = profile::span("render_enum_variant"); - EnumRender::new(ctx, local_name, variant, path).render(import_to_add) + render(ctx, local_name, variant, path, import_to_add) } -#[derive(Debug)] -struct EnumRender<'a> { - ctx: RenderContext<'a>, +fn render( + ctx @ RenderContext { completion }: RenderContext<'_>, + local_name: Option<hir::Name>, variant: hir::Variant, path: Option<hir::ModPath>, - qualified_name: hir::ModPath, - short_qualified_name: hir::ModPath, - variant_kind: hir::StructKind, -} - -impl<'a> EnumRender<'a> { - fn new( - ctx: RenderContext<'a>, - local_name: Option<hir::Name>, - variant: hir::Variant, - path: Option<hir::ModPath>, - ) -> EnumRender<'a> { - let name = local_name.unwrap_or_else(|| variant.name(ctx.db())); - let variant_kind = variant.kind(ctx.db()); - - let (qualified_name, short_qualified_name) = match &path { - Some(path) => { - let short = hir::ModPath::from_segments( - hir::PathKind::Plain, - path.segments().iter().skip(path.segments().len().saturating_sub(2)).cloned(), - ); - (path.clone(), short) - } - None => ( - hir::ModPath::from_segments(hir::PathKind::Plain, iter::once(name.clone())), - hir::ModPath::from_segments(hir::PathKind::Plain, iter::once(name)), - ), - }; - - EnumRender { ctx, variant, path, qualified_name, short_qualified_name, variant_kind } - } - fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem { - let mut item = CompletionItem::new( - SymbolKind::Variant, - self.ctx.source_range(), - self.qualified_name.to_string(), - ); - item.set_documentation(self.variant.docs(self.ctx.db())) - .set_deprecated(self.ctx.is_deprecated(self.variant)) - .detail(self.detail()); - - if let Some(import_to_add) = import_to_add { - item.add_import(import_to_add); - } - - if self.variant_kind == hir::StructKind::Tuple { - cov_mark::hit!(inserts_parens_for_tuple_enums); - let params = Params::Anonymous(self.variant.fields(self.ctx.db()).len()); - item.add_call_parens( - self.ctx.completion, - self.short_qualified_name.to_string(), - params, + import_to_add: Option<ImportEdit>, +) -> CompletionItem { + let db = completion.db; + let name = local_name.unwrap_or_else(|| variant.name(db)); + let variant_kind = variant.kind(db); + + let (qualified_name, short_qualified_name, qualified) = match path { + Some(path) => { + let short = hir::ModPath::from_segments( + hir::PathKind::Plain, + path.segments().iter().skip(path.segments().len().saturating_sub(2)).cloned(), ); - } else if self.path.is_some() { - item.lookup_by(self.short_qualified_name.to_string()); + (path, short, true) } + None => ( + hir::ModPath::from_segments(hir::PathKind::Plain, iter::once(name.clone())), + hir::ModPath::from_segments(hir::PathKind::Plain, iter::once(name)), + false, + ), + }; + + // FIXME: ModPath::to_smol_str()? + let mut item = + CompletionItem::new(SymbolKind::Variant, ctx.source_range(), qualified_name.to_string()); + item.set_documentation(variant.docs(db)) + .set_deprecated(ctx.is_deprecated(variant)) + .detail(detail(db, variant, variant_kind)); + + if let Some(import_to_add) = import_to_add { + item.add_import(import_to_add); + } - let ty = self.variant.parent_enum(self.ctx.completion.db).ty(self.ctx.completion.db); - item.set_relevance(CompletionRelevance { - type_match: compute_type_match(self.ctx.completion, &ty), - ..CompletionRelevance::default() - }); + // FIXME: ModPath::to_smol_str()? + let short_qualified_name = short_qualified_name.to_string(); + if variant_kind == hir::StructKind::Tuple { + cov_mark::hit!(inserts_parens_for_tuple_enums); + let params = Params::Anonymous(variant.fields(db).len()); + item.add_call_parens(ctx.completion, short_qualified_name, params); + } else if qualified { + item.lookup_by(short_qualified_name); + } - if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ty) { - item.ref_match(ref_match); - } + let ty = variant.parent_enum(ctx.completion.db).ty(ctx.completion.db); + item.set_relevance(CompletionRelevance { + type_match: compute_type_match(ctx.completion, &ty), + ..CompletionRelevance::default() + }); - item.build() + if let Some(ref_match) = compute_ref_match(ctx.completion, &ty) { + item.ref_match(ref_match); } - fn detail(&self) -> String { - let detail_types = self - .variant - .fields(self.ctx.db()) - .into_iter() - .map(|field| (field.name(self.ctx.db()), field.ty(self.ctx.db()))); - - let mut b = String::new(); - let mut first_run = true; - match self.variant_kind { - hir::StructKind::Tuple | hir::StructKind::Unit => { - format_to!(b, "("); - for (_, t) in detail_types { - if !mem::take(&mut first_run) { - format_to!(b, ", "); - } - format_to!(b, "{}", t.display(self.ctx.db())); - } - format_to!(b, ")"); - } - hir::StructKind::Record => { - format_to!(b, "{{"); - for (n, t) in detail_types { - if !mem::take(&mut first_run) { - format_to!(b, ", "); - } - format_to!(b, "{}: {}", n, t.display(self.ctx.db())); - } - format_to!(b, "}}"); - } + item.build() +} + +fn detail(db: &dyn HirDatabase, variant: hir::Variant, variant_kind: StructKind) -> String { + let detail_types = variant.fields(db).into_iter().map(|field| (field.name(db), field.ty(db))); + + match variant_kind { + hir::StructKind::Tuple | hir::StructKind::Unit => { + format!("({})", detail_types.format_with(", ", |(_, t), f| f(&t.display(db)))) + } + hir::StructKind::Record => { + format!( + "{{{}}}", + detail_types.format_with(", ", |(n, t), f| { + f(&n)?; + f(&": ")?; + f(&t.display(db)) + }), + ) } - b } } |
