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

Commit

Permalink
chore: deserialize formatter options (#4401)
Browse files Browse the repository at this point in the history
* chore: deserialize formatter options

* fix: codegen
  • Loading branch information
ematipico committed Apr 22, 2023
1 parent 10ec2ab commit 0ce9198
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 191 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion crates/rome_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ impl std::fmt::Display for IndentStyle {
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema),
serde(rename_all = "camelCase")
)]
pub struct LineWidth(u16);

Expand Down
2 changes: 2 additions & 0 deletions crates/rome_js_formatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ categories = [
[dependencies]
cfg-if = "1.0.0"
rome_js_syntax = { version = "0.0.2", path = "../rome_js_syntax" }
rome_json_syntax = { version = "0.0.1", path = "../rome_json_syntax" }
rome_js_factory = { version = "0.0.2", path = "../rome_js_factory" }
rome_formatter = { version = "0.0.1", path = "../rome_formatter" }
rome_rowan = { version = "0.0.1", path = "../rome_rowan" }
rome_text_size = { version = "0.0.1", path = "../rome_text_size" }
rome_diagnostics_categories = { version = "0.0.1", path = "../rome_diagnostics_categories" }
rome_deserialize = { path = "../rome_deserialize", version = "0.0.0" }
tracing = { workspace = true }
unicode-width = "0.1.9"
serde = { version = "1.0.136", features = ["derive"], optional = true }
Expand Down
69 changes: 66 additions & 3 deletions crates/rome_js_formatter/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use crate::comments::{FormatJsLeadingComment, JsCommentStyle, JsComments};
use crate::context::trailing_comma::TrailingComma;
use rome_deserialize::json::with_only_known_variants;
use rome_deserialize::{DeserializationDiagnostic, VisitNode};
use rome_formatter::printer::PrinterOptions;
use rome_formatter::token::string::Quote;
use rome_formatter::{
CstFormatContext, FormatContext, FormatElement, FormatOptions, IndentStyle, LineWidth,
TransformSourceMap,
};
use rome_js_syntax::{AnyJsFunctionBody, JsLanguage, SourceType};
use rome_json_syntax::JsonLanguage;
use rome_rowan::SyntaxNode;
use std::fmt;
use std::fmt::Debug;
use std::rc::Rc;
Expand Down Expand Up @@ -252,7 +256,8 @@ impl fmt::Display for JsFormatOptions {
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema),
serde(rename_all = "camelCase")
)]
#[derive(Default)]
pub enum QuoteStyle {
Expand Down Expand Up @@ -284,6 +289,8 @@ impl fmt::Display for QuoteStyle {
}

impl QuoteStyle {
pub(crate) const KNOWN_VALUES: &'static [&'static str] = &["double", "single"];

pub fn as_char(&self) -> char {
match self {
QuoteStyle::Double => '"',
Expand Down Expand Up @@ -336,10 +343,27 @@ impl From<QuoteStyle> for Quote {
}
}

impl VisitNode<JsonLanguage> for QuoteStyle {
fn visit_member_value(
&mut self,
node: &SyntaxNode<JsonLanguage>,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<()> {
let node = with_only_known_variants(node, QuoteStyle::KNOWN_VALUES, diagnostics)?;
if node.inner_string_text().ok()?.text() == "single" {
*self = QuoteStyle::Single;
} else {
*self = QuoteStyle::Double;
}
Some(())
}
}

#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema),
serde(rename_all = "camelCase")
)]
pub enum QuoteProperties {
#[default]
Expand Down Expand Up @@ -369,10 +393,31 @@ impl fmt::Display for QuoteProperties {
}
}

impl QuoteProperties {
pub(crate) const KNOWN_VALUES: &'static [&'static str] = &["preserve", "asNeeded"];
}

impl VisitNode<JsonLanguage> for QuoteProperties {
fn visit_member_value(
&mut self,
node: &SyntaxNode<JsonLanguage>,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<()> {
let node = with_only_known_variants(node, QuoteProperties::KNOWN_VALUES, diagnostics)?;
if node.inner_string_text().ok()?.text() == "asNeeded" {
*self = QuoteProperties::AsNeeded;
} else {
*self = QuoteProperties::Preserve;
}
Some(())
}
}

#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema),
serde(rename_all = "camelCase")
)]
pub enum Semicolons {
#[default]
Expand All @@ -381,6 +426,8 @@ pub enum Semicolons {
}

impl Semicolons {
pub(crate) const KNOWN_VALUES: &'static [&'static str] = &["always", "asNeeded"];

pub const fn is_as_needed(&self) -> bool {
matches!(self, Self::AsNeeded)
}
Expand Down Expand Up @@ -410,3 +457,19 @@ impl fmt::Display for Semicolons {
}
}
}

impl VisitNode<JsonLanguage> for Semicolons {
fn visit_member_value(
&mut self,
node: &SyntaxNode<JsonLanguage>,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<()> {
let node = with_only_known_variants(node, Semicolons::KNOWN_VALUES, diagnostics)?;
if node.inner_string_text().ok()?.text() == "asNeeded" {
*self = Semicolons::AsNeeded;
} else {
*self = Semicolons::Always;
}
Some(())
}
}
42 changes: 36 additions & 6 deletions crates/rome_js_formatter/src/context/trailing_comma.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use crate::prelude::*;
use crate::{JsFormatContext, JsFormatOptions};
use rome_deserialize::json::with_only_known_variants;
use rome_deserialize::{DeserializationDiagnostic, VisitNode};
use rome_formatter::formatter::Formatter;
use rome_formatter::prelude::{if_group_breaks, text};
use rome_formatter::write;
use rome_formatter::{Format, FormatResult};
use rome_json_syntax::JsonLanguage;
use rome_rowan::SyntaxNode;
use std::fmt;
use std::str::FromStr;

Expand All @@ -12,7 +16,7 @@ use std::str::FromStr;
pub(crate) enum FormatTrailingComma {
/// Print trailing comma if the option is [TrailingComma::All].
All,
/// Print trailing comma if the option is [TrailingComma::All] or [TrailingComma::ES5].
/// Print trailing comma if the option is [TrailingComma::All] or [TrailingComma::Es5].
ES5,
}

Expand Down Expand Up @@ -54,21 +58,24 @@ impl Format<JsFormatContext> for FormatTrailingComma {
#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema)
derive(serde::Serialize, serde::Deserialize, schemars::JsonSchema),
serde(rename_all = "camelCase")
)]
pub enum TrailingComma {
/// Trailing commas wherever possible (including function parameters and calls).
#[default]
All,
/// Trailing commas where valid in ES5 (objects, arrays, etc.). No trailing commas in type parameters in TypeScript.
ES5,
Es5,
/// No trailing commas.
None,
}

impl TrailingComma {
pub(crate) const KNOWN_VALUES: &'static [&'static str] = &["all", "es5", "none"];

pub const fn is_es5(&self) -> bool {
matches!(self, TrailingComma::ES5)
matches!(self, TrailingComma::Es5)
}
pub const fn is_all(&self) -> bool {
matches!(self, TrailingComma::All)
Expand All @@ -83,7 +90,7 @@ impl FromStr for TrailingComma {

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"es5" | "ES5" => Ok(Self::ES5),
"es5" | "ES5" => Ok(Self::Es5),
"all" | "All" => Ok(Self::All),
"none" | "None" => Ok(Self::None),
// TODO: replace this error with a diagnostic
Expand All @@ -95,9 +102,32 @@ impl FromStr for TrailingComma {
impl fmt::Display for TrailingComma {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TrailingComma::ES5 => std::write!(f, "ES5"),
TrailingComma::Es5 => std::write!(f, "ES5"),
TrailingComma::All => std::write!(f, "All"),
TrailingComma::None => std::write!(f, "None"),
}
}
}

impl VisitNode<JsonLanguage> for TrailingComma {
fn visit_member_value(
&mut self,
node: &SyntaxNode<JsonLanguage>,
diagnostics: &mut Vec<DeserializationDiagnostic>,
) -> Option<()> {
let node = with_only_known_variants(node, TrailingComma::KNOWN_VALUES, diagnostics)?;
match node.inner_string_text().ok()?.text() {
"all" => {
*self = TrailingComma::All;
}
"es5" => {
*self = TrailingComma::Es5;
}
"none" => {
*self = TrailingComma::None;
}
_ => {}
}
Some(())
}
}
2 changes: 1 addition & 1 deletion crates/rome_js_formatter/tests/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl From<JsSerializableTrailingComma> for TrailingComma {
fn from(test: JsSerializableTrailingComma) -> Self {
match test {
JsSerializableTrailingComma::All => TrailingComma::All,
JsSerializableTrailingComma::ES5 => TrailingComma::ES5,
JsSerializableTrailingComma::ES5 => TrailingComma::Es5,
JsSerializableTrailingComma::None => TrailingComma::None,
}
}
Expand Down
94 changes: 0 additions & 94 deletions crates/rome_service/src/configuration/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,12 @@ impl JavascriptConfiguration {
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct JavascriptFormatter {
/// The style for quotes. Defaults to double.
#[serde(with = "PlainQuoteStyle")]
pub quote_style: QuoteStyle,
/// When properties in objects are quoted. Defaults to asNeeded.
#[serde(with = "PlainQuoteProperties")]
pub quote_properties: QuoteProperties,
/// Print trailing commas wherever possible in multi-line comma-separated syntactic structures. Defaults to "all".
#[serde(with = "PlainTrailingComma")]
pub trailing_comma: TrailingComma,
/// Whether the formatter prints semicolons for all statements or only in for statements where it is necessary because of ASI.
#[serde(with = "PlainSemicolons")]
pub semicolons: Semicolons,
}

Expand All @@ -66,96 +62,6 @@ impl JavascriptFormatter {
];
}

#[derive(Deserialize, Serialize, Debug, Eq, PartialEq, Default)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(rename_all = "camelCase", remote = "QuoteStyle")]
pub enum PlainQuoteStyle {
#[default]
Double,
Single,
}

impl From<PlainQuoteStyle> for QuoteStyle {
fn from(variant: PlainQuoteStyle) -> Self {
match variant {
PlainQuoteStyle::Double => QuoteStyle::Double,
PlainQuoteStyle::Single => QuoteStyle::Single,
}
}
}

impl PlainQuoteStyle {
pub(crate) const KNOWN_VALUES: &'static [&'static str] = &["double", "single"];
}

#[derive(Deserialize, Default, Serialize, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(rename_all = "camelCase", remote = "QuoteProperties")]
pub enum PlainQuoteProperties {
#[default]
AsNeeded,
Preserve,
}

impl From<PlainQuoteProperties> for QuoteProperties {
fn from(variant: PlainQuoteProperties) -> Self {
match variant {
PlainQuoteProperties::AsNeeded => QuoteProperties::AsNeeded,
PlainQuoteProperties::Preserve => QuoteProperties::Preserve,
}
}
}

impl PlainQuoteProperties {
pub(crate) const KNOWN_VALUES: &'static [&'static str] = &["preserve", "asNeeded"];
}

#[derive(Deserialize, Default, Serialize, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(rename_all = "lowercase", remote = "TrailingComma")]
pub enum PlainTrailingComma {
#[default]
All,
ES5,
None,
}

impl From<PlainTrailingComma> for TrailingComma {
fn from(variant: PlainTrailingComma) -> Self {
match variant {
PlainTrailingComma::All => TrailingComma::All,
PlainTrailingComma::ES5 => TrailingComma::ES5,
PlainTrailingComma::None => TrailingComma::None,
}
}
}

impl PlainTrailingComma {
pub(crate) const KNOWN_VALUES: &'static [&'static str] = &["all", "es5", "none"];
}

#[derive(Deserialize, Default, Serialize, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(rename_all = "camelCase", remote = "Semicolons")]
pub enum PlainSemicolons {
#[default]
Always,
AsNeeded,
}

impl From<PlainSemicolons> for Semicolons {
fn from(variant: PlainSemicolons) -> Self {
match variant {
PlainSemicolons::Always => Semicolons::Always,
PlainSemicolons::AsNeeded => Semicolons::AsNeeded,
}
}
}

impl PlainSemicolons {
pub(crate) const KNOWN_VALUES: &'static [&'static str] = &["always", "asNeeded"];
}

#[derive(Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(default, deny_unknown_fields)]
Expand Down
Loading

0 comments on commit 0ce9198

Please sign in to comment.