Skip to content
This repository was archived by the owner on Aug 31, 2023. It is now read-only.

Commit def1bac

Browse files
authored
refactor(rome_formatter): Use custom trait for unique LabelIds (#4599)
1 parent 8a81435 commit def1bac

File tree

5 files changed

+77
-34
lines changed

5 files changed

+77
-34
lines changed

crates/rome_formatter/src/builders.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -493,10 +493,25 @@ impl<Context> Format<Context> for LineSuffixBoundary {
493493
/// ## Examples
494494
///
495495
/// ```rust
496-
/// use rome_formatter::prelude::*;
497-
/// use rome_formatter::{format, write, LineWidth};
496+
/// # use rome_formatter::prelude::*;
497+
/// # use rome_formatter::{format, write, LineWidth};
498498
///
499-
/// enum SomeLabelId {}
499+
/// #[derive(Debug, Copy, Clone)]
500+
/// enum MyLabels {
501+
/// Main
502+
/// }
503+
///
504+
/// impl tag::Label for MyLabels {
505+
/// fn id(&self) -> u64 {
506+
/// *self as u64
507+
/// }
508+
///
509+
/// fn debug_name(&self) -> &'static str {
510+
/// match self {
511+
/// Self::Main => "Main"
512+
/// }
513+
/// }
514+
/// }
500515
///
501516
/// # fn main() -> FormatResult<()> {
502517
/// let formatted = format!(
@@ -505,31 +520,31 @@ impl<Context> Format<Context> for LineSuffixBoundary {
505520
/// let mut recording = f.start_recording();
506521
/// write!(recording, [
507522
/// labelled(
508-
/// LabelId::of::<SomeLabelId>(),
523+
/// LabelId::of(MyLabels::Main),
509524
/// &text("'I have a label'")
510525
/// )
511526
/// ])?;
512527
///
513528
/// let recorded = recording.stop();
514529
///
515-
/// let is_labelled = recorded.first().map_or(false, |element| element.has_label(LabelId::of::<SomeLabelId>()));
530+
/// let is_labelled = recorded.first().map_or(false, |element| element.has_label(LabelId::of(MyLabels::Main)));
516531
///
517532
/// if is_labelled {
518-
/// write!(f, [text(" has label SomeLabelId")])
533+
/// write!(f, [text(" has label `Main`")])
519534
/// } else {
520-
/// write!(f, [text(" doesn't have label SomeLabelId")])
535+
/// write!(f, [text(" doesn't have label `Main`")])
521536
/// }
522537
/// })]
523538
/// )?;
524539
///
525-
/// assert_eq!("'I have a label' has label SomeLabelId", formatted.print()?.as_code());
540+
/// assert_eq!("'I have a label' has label `Main`", formatted.print()?.as_code());
526541
/// # Ok(())
527542
/// # }
528543
/// ```
529544
///
530545
/// ## Alternatives
531546
///
532-
/// Use `Memoized.inspect(f)?.has_label(LabelId::of::<SomeLabelId>()` if you need to know if some content breaks that should
547+
/// Use `Memoized.inspect(f)?.has_label(LabelId::of(MyLabels::Main)` if you need to know if some content breaks that should
533548
/// only be written later.
534549
#[inline]
535550
pub fn labelled<Content, Context>(label_id: LabelId, content: &Content) -> FormatLabelled<Context>

crates/rome_formatter/src/format_element/tag.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
use crate::format_element::PrintMode;
22
use crate::{GroupId, TextSize};
3-
#[cfg(debug_assertions)]
4-
use std::any::type_name;
5-
use std::any::TypeId;
63
use std::cell::Cell;
74
use std::num::NonZeroU8;
85

@@ -239,37 +236,48 @@ impl Align {
239236
}
240237
}
241238

242-
#[derive(Eq, PartialEq, Copy, Clone)]
239+
#[derive(Debug, Eq, Copy, Clone)]
243240
pub struct LabelId {
244-
id: TypeId,
241+
value: u64,
245242
#[cfg(debug_assertions)]
246-
label: &'static str,
243+
name: &'static str,
247244
}
248245

249-
#[cfg(debug_assertions)]
250-
impl std::fmt::Debug for LabelId {
251-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
252-
f.write_str(self.label)
253-
}
254-
}
246+
impl PartialEq for LabelId {
247+
fn eq(&self, other: &Self) -> bool {
248+
let is_equal = self.value == other.value;
249+
250+
#[cfg(debug_assertions)]
251+
{
252+
if is_equal {
253+
assert_eq!(self.name, other.name, "Two `LabelId`s with different names have the same `value`. Are you mixing labels of two different `LabelDefinition` or are the values returned by the `LabelDefinition` not unique?");
254+
}
255+
}
255256

256-
#[cfg(not(debug_assertions))]
257-
impl std::fmt::Debug for LabelId {
258-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
259-
std::write!(f, "#{:?}", self.id)
257+
is_equal
260258
}
261259
}
262260

263261
impl LabelId {
264-
pub fn of<T: ?Sized + 'static>() -> Self {
262+
pub fn of<T: Label>(label: T) -> Self {
265263
Self {
266-
id: TypeId::of::<T>(),
264+
value: label.id(),
267265
#[cfg(debug_assertions)]
268-
label: type_name::<T>(),
266+
name: label.debug_name(),
269267
}
270268
}
271269
}
272270

271+
/// Defines the valid labels of a language. You want to have at most one implementation per formatter
272+
/// project.
273+
pub trait Label {
274+
/// Returns the `u64` uniquely identifying this specific label.
275+
fn id(&self) -> u64;
276+
277+
/// Returns the name of the label that is shown in debug builds.
278+
fn debug_name(&self) -> &'static str;
279+
}
280+
273281
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
274282
pub enum VerbatimKind {
275283
Bogus,

crates/rome_js_formatter/src/js/expressions/static_member_expression.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::prelude::*;
22

33
use crate::js::expressions::computed_member_expression::AnyJsComputedMemberLike;
44
use crate::parentheses::NeedsParentheses;
5-
use crate::utils::member_chain::MemberChainLabel;
5+
use crate::JsLabels;
66
use rome_formatter::{format_args, write};
77
use rome_js_syntax::{
88
AnyJsAssignment, AnyJsAssignmentPattern, AnyJsExpression, AnyJsName, JsAssignmentExpression,
@@ -45,7 +45,7 @@ impl Format<JsFormatContext> for AnyJsStaticMemberLike {
4545

4646
recording
4747
.stop()
48-
.has_label(LabelId::of::<MemberChainLabel>())
48+
.has_label(LabelId::of(JsLabels::MemberChain))
4949
};
5050

5151
let layout = self.layout(is_member_chain)?;
@@ -60,7 +60,7 @@ impl Format<JsFormatContext> for AnyJsStaticMemberLike {
6060
write!(
6161
f,
6262
[labelled(
63-
LabelId::of::<MemberChainLabel>(),
63+
LabelId::of(JsLabels::MemberChain),
6464
&format_no_break
6565
)]
6666
)

crates/rome_js_formatter/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ mod parentheses;
179179
pub(crate) mod separated;
180180
mod syntax_rewriter;
181181

182+
use rome_formatter::format_element::tag::Label;
182183
use rome_formatter::prelude::*;
183184
use rome_formatter::{
184185
comments::Comments, write, CstFormatContext, Format, FormatLanguage, FormatToken,
@@ -537,6 +538,23 @@ pub fn format_sub_tree(options: JsFormatOptions, root: &JsSyntaxNode) -> FormatR
537538
rome_formatter::format_sub_tree(root, JsFormatLanguage::new(options))
538539
}
539540

541+
#[derive(Copy, Clone, Debug)]
542+
pub(crate) enum JsLabels {
543+
MemberChain,
544+
}
545+
546+
impl Label for JsLabels {
547+
fn id(&self) -> u64 {
548+
*self as u64
549+
}
550+
551+
fn debug_name(&self) -> &'static str {
552+
match self {
553+
JsLabels::MemberChain => "MemberChain",
554+
}
555+
}
556+
}
557+
540558
#[cfg(test)]
541559
mod tests {
542560

crates/rome_js_formatter/src/utils/member_chain/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ use crate::utils::member_chain::groups::{
114114
MemberChainGroup, MemberChainGroupsBuilder, TailChainGroups,
115115
};
116116
use crate::utils::member_chain::simple_argument::SimpleArgument;
117+
use crate::JsLabels;
117118
use rome_formatter::{write, Buffer};
118119
use rome_js_syntax::{
119120
AnyJsCallArgument, AnyJsExpression, AnyJsLiteralExpression, JsCallExpression,
@@ -122,8 +123,6 @@ use rome_js_syntax::{
122123
use rome_rowan::{AstNode, SyntaxResult};
123124
use std::iter::FusedIterator;
124125

125-
pub(crate) enum MemberChainLabel {}
126-
127126
#[derive(Debug, Clone)]
128127
pub(crate) struct MemberChain {
129128
root: JsCallExpression,
@@ -399,7 +398,10 @@ impl Format<JsFormatContext> for MemberChain {
399398

400399
write!(
401400
f,
402-
[labelled(LabelId::of::<MemberChainLabel>(), &format_content)]
401+
[labelled(
402+
LabelId::of(JsLabels::MemberChain),
403+
&format_content
404+
)]
403405
)
404406
}
405407
}

0 commit comments

Comments
 (0)