refactor(rome_js_formatter): Remove `Copy` from `JsFormatContext`
MODIFY
crates/rome_js_formatter/src/check_reformat.rs
crates/rome_js_formatter/src/check_reformat.rs
@@ -19,7 +19,7 @@ pub fn check_reformat(params: CheckReformatParams) {
text,
source_type,
file_name,
- format_context: format_options,
+ format_context: context,
} = params;
let re_parse = parse(text, 0, source_type);
@@ -44,11 +44,11 @@ pub fn check_reformat(params: CheckReformatParams) {
)
}
- let formatted = format_node(format_options, &re_parse.syntax()).unwrap();
+ let formatted = format_node(context.clone(), &re_parse.syntax()).unwrap();
let printed = formatted.print();
if text != printed.as_code() {
- let input_formatted = format_node(format_options, root).unwrap();
+ let input_formatted = format_node(context, root).unwrap();
// Print a diff of the Formatter IR emitted for the input and the output
let diff =

MODIFY
crates/rome_js_formatter/src/context.rs
crates/rome_js_formatter/src/context.rs
@@ -8,25 +8,24 @@ use std::fmt;
use std::fmt::Debug;
use std::str::FromStr;
-#[derive(Debug, Copy, Clone, Default)]
+#[derive(Debug, Clone, Default)]
pub struct JsFormatContext {
/// The indent style.
- pub indent_style: IndentStyle,
+ indent_style: IndentStyle,
/// What's the max width of a line. Defaults to 80.
- pub line_width: LineWidth,
+ line_width: LineWidth,
- /// Options of current instance of the formatter
- pub options: JsFormatOptions,
+ /// The style for quotes. Defaults to double.
+ quote_style: QuoteStyle,
/// Information relative to the current file
- pub source_type: SourceType,
+ source_type: SourceType,
}
impl JsFormatContext {
- pub fn new(options: JsFormatOptions, source_type: SourceType) -> Self {
+ pub fn new(source_type: SourceType) -> Self {
Self {
- options,
source_type,
..JsFormatContext::default()
}
@@ -42,22 +41,49 @@ impl JsFormatContext {
self
}
+ pub fn with_quote_style(mut self, quote_style: QuoteStyle) -> Self {
+ self.quote_style = quote_style;
+ self
+ }
+
+ pub fn with_source_type(mut self, source_type: SourceType) -> Self {
+ self.source_type = source_type;
+ self
+ }
+
+ pub fn line_width(&self) -> LineWidth {
+ self.line_width
+ }
+
pub fn quote_style(&self) -> QuoteStyle {
- self.options.quote_style
+ self.quote_style
+ }
+
+ pub fn source_type(&self) -> SourceType {
+ self.source_type
+ }
+}
+
+#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)]
+pub struct TabWidth(u8);
+
+impl From<u8> for TabWidth {
+ fn from(value: u8) -> Self {
+ TabWidth(value)
}
}
-#[derive(Debug, Copy, Clone, Default)]
-pub struct JsFormatOptions {
- // The style for quotes. Defaults to double.
- pub quote_style: QuoteStyle,
+impl From<TabWidth> for u8 {
+ fn from(width: TabWidth) -> Self {
+ width.0
+ }
}
impl JsFormatContext {
- pub fn tab_width(&self) -> u8 {
+ pub fn tab_width(&self) -> TabWidth {
match self.indent_style {
- IndentStyle::Tab => 2,
- IndentStyle::Space(quantities) => quantities,
+ IndentStyle::Tab => 2.into(),
+ IndentStyle::Space(quantities) => quantities.into(),
}
}
}
@@ -82,8 +108,7 @@ impl fmt::Display for JsFormatContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Indent style: {}", self.indent_style)?;
writeln!(f, "Line width: {}", self.line_width.value())?;
- write!(f, "{}", self.options)?;
- Ok(())
+ writeln!(f, "Quote style: {}", self.quote_style)
}
}
@@ -132,13 +157,6 @@ impl CommentStyle<JsLanguage> for JsCommentStyle {
}
}
-impl fmt::Display for JsFormatOptions {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- writeln!(f, "Quote style: {}", self.quote_style)?;
- Ok(())
- }
-}
-
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum QuoteStyle {
Double,

MODIFY
crates/rome_js_formatter/src/lib.rs
crates/rome_js_formatter/src/lib.rs
@@ -322,10 +322,7 @@ while(
let tree = parse_script(input, 0);
let result = format_range(
- JsFormatContext {
- indent_style: IndentStyle::Space(4),
- ..JsFormatContext::default()
- },
+ JsFormatContext::default().with_indent_style(IndentStyle::Space(4)),
&tree.syntax(),
TextRange::new(range_start, range_end),
);
@@ -357,10 +354,7 @@ function() {
let tree = parse_script(input, 0);
let result = format_range(
- JsFormatContext {
- indent_style: IndentStyle::Space(4),
- ..JsFormatContext::default()
- },
+ JsFormatContext::default().with_indent_style(IndentStyle::Space(4)),
&tree.syntax(),
TextRange::new(range_start, range_end),
);
@@ -391,10 +385,7 @@ function() {
let tree = parse_script(input, 0);
let result = format_range(
- JsFormatContext {
- indent_style: IndentStyle::Space(4),
- ..JsFormatContext::default()
- },
+ JsFormatContext::default().with_indent_style(IndentStyle::Space(4)),
&tree.syntax(),
TextRange::new(range_start, range_end),
);
@@ -413,10 +404,7 @@ function() {
let tree = parse_script(input, 0);
let result = format_range(
- JsFormatContext {
- indent_style: IndentStyle::Space(4),
- ..JsFormatContext::default()
- },
+ JsFormatContext::default().with_indent_style(IndentStyle::Space(4)),
&tree.syntax(),
TextRange::new(range_start, range_end),
);
@@ -438,10 +426,7 @@ function() {
let tree = parse_script(input, 0);
let result = format_range(
- JsFormatContext {
- indent_style: IndentStyle::Space(4),
- ..JsFormatContext::default()
- },
+ JsFormatContext::default().with_indent_style(IndentStyle::Space(4)),
&tree.syntax(),
TextRange::new(range_start, range_end),
);

MODIFY
crates/rome_js_formatter/src/utils/assignment_like.rs
crates/rome_js_formatter/src/utils/assignment_like.rs
@@ -330,7 +330,7 @@ impl JsAnyAssignmentLike {
JsAnyAssignmentLike::JsPropertyObjectMember(property) => {
let width = write_member_name(&property.name()?, f)?;
let text_width_for_break =
- (f.context().tab_width() + MIN_OVERLAP_FOR_BREAK) as usize;
+ (u8::from(f.context().tab_width()) + MIN_OVERLAP_FOR_BREAK) as usize;
Ok(width < text_width_for_break)
}
JsAnyAssignmentLike::JsAssignmentExpression(assignment) => {
@@ -341,7 +341,7 @@ impl JsAnyAssignmentLike {
JsAnyAssignmentLike::JsObjectAssignmentPatternProperty(property) => {
let width = write_member_name(&property.member()?, f)?;
let text_width_for_break =
- (f.context().tab_width() + MIN_OVERLAP_FOR_BREAK) as usize;
+ (u8::from(f.context().tab_width()) + MIN_OVERLAP_FOR_BREAK) as usize;
Ok(width < text_width_for_break)
}
JsAnyAssignmentLike::JsVariableDeclarator(variable_declarator) => {

MODIFY
crates/rome_js_formatter/src/utils/member_chain/flatten_item.rs
crates/rome_js_formatter/src/utils/member_chain/flatten_item.rs
+use crate::context::TabWidth;
use crate::prelude::*;
use rome_formatter::write;
use rome_js_syntax::{
@@ -123,14 +124,14 @@ impl FlattenItem {
}
}
- pub(crate) fn has_short_name(&self, tab_width: u8) -> SyntaxResult<bool> {
+ pub(crate) fn has_short_name(&self, tab_width: TabWidth) -> SyntaxResult<bool> {
if let FlattenItem::StaticMember(static_member, ..) = self {
if let JsAnyExpression::JsIdentifierExpression(identifier_expression) =
static_member.object()?
{
let value_token = identifier_expression.name()?.value_token()?;
let text = value_token.text_trimmed();
- Ok(text.len() <= tab_width as usize)
+ Ok(text.len() <= u8::from(tab_width) as usize)
} else {
Ok(false)
}

MODIFY
crates/rome_js_formatter/src/utils/member_chain/groups.rs
crates/rome_js_formatter/src/utils/member_chain/groups.rs
@@ -2,6 +2,7 @@ use crate::prelude::*;
use crate::utils::member_chain::flatten_item::FlattenItem;
use crate::utils::member_chain::simple_argument::SimpleArgument;
+use crate::context::TabWidth;
use rome_js_syntax::JsCallExpression;
use rome_rowan::{AstSeparatedList, SyntaxResult};
use std::mem;
@@ -23,17 +24,17 @@ pub(crate) struct Groups {
/// By default, it's 2, meaning that we start breaking after the second group.
cutoff: u8,
- context: JsFormatContext,
+ tab_width: TabWidth,
}
impl Groups {
- pub fn new(in_expression_statement: bool, context: JsFormatContext) -> Self {
+ pub fn new(in_expression_statement: bool, tab_width: TabWidth) -> Self {
Self {
in_expression_statement,
groups: Vec::new(),
current_group: Vec::new(),
cutoff: 2,
- context,
+ tab_width,
}
}
@@ -145,7 +146,7 @@ impl Groups {
/// This is an heuristic needed to check when the first element of the group
/// Should be part of the "head" or the "tail".
fn should_not_wrap(&self, first_group: &HeadGroup) -> SyntaxResult<bool> {
- let tab_with = self.context.tab_width();
+ let tab_with = self.tab_width;
let has_computed_property = if self.groups.len() > 1 {
// SAFETY: guarded by the previous check
let group = &self.groups[0];

MODIFY
crates/rome_js_formatter/src/utils/member_chain/mod.rs
crates/rome_js_formatter/src/utils/member_chain/mod.rs
@@ -238,7 +238,7 @@ fn compute_groups(
f: &JsFormatter,
) -> FormatResult<Groups> {
let mut has_seen_call_expression = false;
- let mut groups = Groups::new(in_expression_statement, *f.context());
+ let mut groups = Groups::new(in_expression_statement, f.context().tab_width());
for item in flatten_items {
let has_trailing_comments = item.as_syntax().has_trailing_comments();

MODIFY
crates/rome_js_formatter/src/utils/string_utils.rs
crates/rome_js_formatter/src/utils/string_utils.rs
@@ -79,7 +79,7 @@ impl<'token> FormatLiteralStringToken<'token> {
let chosen_quote_style = context.quote_style();
let mut string_cleaner = LiteralStringNormaliser::new(self, chosen_quote_style);
- let content = string_cleaner.normalise_text(context.source_type.into());
+ let content = string_cleaner.normalise_text(context.source_type().into());
let normalized_text_width = content.width();
CleanedStringLiteralText {

MODIFY
crates/rome_js_formatter/tests/check_reformat.rs
crates/rome_js_formatter/tests/check_reformat.rs
@@ -20,7 +20,7 @@ pub fn check_reformat(params: CheckReformatParams) {
text,
source_type,
file_name,
- format_context: format_options,
+ format_context: context,
} = params;
let re_parse = parse(text, 0, source_type);
@@ -45,11 +45,11 @@ pub fn check_reformat(params: CheckReformatParams) {
)
}
- let formatted = format_node(format_options, &re_parse.syntax()).unwrap();
+ let formatted = format_node(context.clone(), &re_parse.syntax()).unwrap();
let printed = formatted.print();
if text != printed.as_code() {
- let input_format_element = format_node(format_options, root).unwrap();
+ let input_format_element = format_node(context, root).unwrap();
// Print a diff of the Formatter IR emitted for the input and the output
let diff =

MODIFY
crates/rome_js_formatter/tests/prettier_tests.rs
crates/rome_js_formatter/tests/prettier_tests.rs
@@ -60,10 +60,7 @@ fn test_snapshot(input: &'static str, _: &str, _: &str, _: &str) {
let has_errors = parsed.has_errors();
let syntax = parsed.syntax();
- let context = JsFormatContext {
- indent_style: IndentStyle::Space(2),
- ..JsFormatContext::default()
- };
+ let context = JsFormatContext::default().with_indent_style(IndentStyle::Space(2));
let result = match (range_start_index, range_end_index) {
(Some(start), Some(end)) => {
@@ -74,7 +71,7 @@ fn test_snapshot(input: &'static str, _: &str, _: &str, _: &str) {
}
rome_js_formatter::format_range(
- context,
+ context.clone(),
&syntax,
TextRange::new(
TextSize::try_from(start).unwrap(),
@@ -82,7 +79,8 @@ fn test_snapshot(input: &'static str, _: &str, _: &str, _: &str) {
),
)
}
- _ => rome_js_formatter::format_node(context, &syntax).map(|formatted| formatted.print()),
+ _ => rome_js_formatter::format_node(context.clone(), &syntax)
+ .map(|formatted| formatted.print()),
};
let formatted = result.expect("formatting failed");
@@ -106,7 +104,7 @@ fn test_snapshot(input: &'static str, _: &str, _: &str, _: &str) {
text: &result,
source_type,
file_name,
- format_context: context,
+ format_context: context.clone(),
});
}
@@ -155,7 +153,7 @@ fn test_snapshot(input: &'static str, _: &str, _: &str, _: &str) {
writeln!(snapshot).unwrap();
}
- let max_width = context.line_width.value() as usize;
+ let max_width = context.line_width().value() as usize;
let mut lines_exceeding_max_width = formatted
.lines()
.enumerate()

MODIFY
crates/rome_js_formatter/tests/spec_test.rs
crates/rome_js_formatter/tests/spec_test.rs
use rome_formatter::LineWidth;
use rome_formatter::{IndentStyle, Printed};
use rome_fs::RomePath;
-use rome_js_formatter::context::{JsFormatContext, JsFormatOptions, QuoteStyle};
+use rome_js_formatter::context::{JsFormatContext, QuoteStyle};
use rome_js_formatter::format_node;
use rome_js_parser::parse;
use rome_js_syntax::{ModuleKind, SourceType};
@@ -62,21 +62,20 @@ pub struct SerializableFormatContext {
impl From<SerializableFormatContext> for JsFormatContext {
fn from(test: SerializableFormatContext) -> Self {
- Self {
- indent_style: test
- .indent_style
+ Self::new(SourceType::default())
+ .with_indent_style(
+ test.indent_style
.map_or_else(|| IndentStyle::Tab, |value| value.into()),
- line_width: test
- .line_width
+ )
+ .with_line_width(
+ test.line_width
.and_then(|width| LineWidth::try_from(width).ok())
.unwrap_or_default(),
- options: JsFormatOptions {
- quote_style: test
- .quote_style
+ )
+ .with_quote_style(
+ test.quote_style
.map_or_else(|| QuoteStyle::Double, |value| value.into()),
- },
- source_type: SourceType::default(),
- }
+ )
}
}
@@ -92,7 +91,7 @@ struct SnapshotContent {
}
impl SnapshotContent {
- fn add_output(&mut self, formatted: Printed, options: JsFormatContext) {
+ fn add_output(&mut self, formatted: Printed, context: JsFormatContext) {
let code = formatted.as_code();
let mut output: String = code.to_string();
if !formatted.verbatim_ranges().is_empty() {
@@ -104,7 +103,7 @@ impl SnapshotContent {
}
}
- let line_width_limit = options.line_width.value() as usize;
+ let line_width_limit = context.line_width().value() as usize;
let mut exceeding_lines = code
.lines()
.enumerate()
@@ -122,7 +121,7 @@ impl SnapshotContent {
}
}
- self.output.push((output, options));
+ self.output.push((output, context));
}
fn set_input(&mut self, content: impl Into<String>) {
@@ -231,8 +230,8 @@ pub fn run(spec_input_file: &str, _expected_file: &str, test_directory: &str, fi
let mut format_context: JsFormatContext = test_case.into();
// we don't track the source type inside the serializable structs, so we
// inject it here
- format_context.source_type = source_type;
- let formatted = format_node(format_context, &root).unwrap();
+ format_context = format_context.with_source_type(source_type);
+ let formatted = format_node(format_context.clone(), &root).unwrap();
let printed = formatted.print();
if !has_errors {
@@ -241,7 +240,7 @@ pub fn run(spec_input_file: &str, _expected_file: &str, test_directory: &str, fi
text: printed.as_code(),
source_type,
file_name,
- format_context,
+ format_context: format_context.clone(),
});
}

MODIFY
crates/rome_service/src/file_handlers/javascript.rs
crates/rome_service/src/file_handlers/javascript.rs
@@ -3,7 +3,7 @@ use rome_diagnostics::{Applicability, Diagnostic};
use rome_formatter::{IndentStyle, LineWidth, Printed};
use rome_fs::RomePath;
use rome_js_analyze::analyze;
-use rome_js_formatter::context::{JsFormatOptions, QuoteStyle};
+use rome_js_formatter::context::QuoteStyle;
use rome_js_formatter::{context::JsFormatContext, format_node};
use rome_js_parser::Parse;
use rome_js_syntax::{JsAnyRoot, JsLanguage, SourceType, TextRange, TextSize, TokenAtOffset};
@@ -40,20 +40,20 @@ impl Language for JsLanguage {
editor: IndentStyle,
path: &RomePath,
) -> JsFormatContext {
- JsFormatContext {
- indent_style: language
+ JsFormatContext::new(path.as_path().try_into().unwrap_or_default())
+ .with_indent_style(
+ language
.indent_style
.or(global.indent_style)
.unwrap_or(editor),
- line_width: language
+ )
+ .with_line_width(
+ language
.line_width
.or(global.line_width)
.unwrap_or_default(),
- options: JsFormatOptions {
- quote_style: language.quote_style.unwrap_or_default(),
- },
- source_type: path.as_path().try_into().unwrap_or_default(),
- }
+ )
+ .with_quote_style(language.quote_style.unwrap_or_default())
}
}

MODIFY
website/playground/src/lib.rs
website/playground/src/lib.rs
@@ -5,7 +5,7 @@ use rome_diagnostics::file::SimpleFiles;
use rome_diagnostics::termcolor::{ColorSpec, WriteColor};
use rome_diagnostics::Emitter;
use rome_formatter::IndentStyle;
-use rome_js_formatter::context::{JsFormatContext, JsFormatOptions};
+use rome_js_formatter::context::JsFormatContext;
use rome_js_formatter::format_node;
use rome_js_parser::parse;
use rome_js_syntax::{LanguageVariant, SourceType};
@@ -173,14 +173,10 @@ pub fn run(
IndentStyle::Tab
};
- let context = JsFormatContext {
- indent_style,
- line_width: options.line_width.try_into().unwrap_or_default(),
- options: JsFormatOptions {
- quote_style: options.quote_style.parse().unwrap_or_default(),
- },
- source_type,
- };
+ let context = JsFormatContext::new(source_type)
+ .with_indent_style(indent_style)
+ .with_line_width(options.line_width.try_into().unwrap_or_default())
+ .with_quote_style(options.quote_style.parse().unwrap_or_default());
let (cst, ast) = if output_json {
let cst_json = clean_up_json(

refactor(rome_js_formatter): Remove `Copy` from `JsFormatContext` (#2779)