From eebc9731287a54e462cce225f22dae9ca84985b5 Mon Sep 17 00:00:00 2001 From: "kirill.artemov" Date: Mon, 16 Jan 2023 16:28:44 +0100 Subject: [PATCH] Added support for `typeLiteral.separatorKind.multiLine: newLine` --- src/configuration/builder.rs | 4 +- src/configuration/resolve_config.rs | 10 ++++- src/configuration/types.rs | 16 +++++++- src/generation/generate.rs | 20 +++++++++- ...ratorKind_SemiColonSingle_NewLineMulti.txt | 38 +++++++++++++++++++ 5 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 tests/specs/types/TypeLiteral/TypeLiteral_SeparatorKind_SemiColonSingle_NewLineMulti.txt diff --git a/src/configuration/builder.rs b/src/configuration/builder.rs index e813bc90..1936e4d7 100644 --- a/src/configuration/builder.rs +++ b/src/configuration/builder.rs @@ -509,7 +509,7 @@ impl ConfigurationBuilder { } /// The kind of separator to use in type literals when multi-line. - pub fn type_literal_separator_kind_multi_line(&mut self, value: SemiColonOrComma) -> &mut Self { + pub fn type_literal_separator_kind_multi_line(&mut self, value: SemiColonOrCommaOrNewLine) -> &mut Self { self.insert("typeLiteral.separatorKind.multiLine", value.to_string().into()) } @@ -1081,7 +1081,7 @@ mod tests { .member_expression_line_per_expression(false) .type_literal_separator_kind(SemiColonOrComma::Comma) .type_literal_separator_kind_single_line(SemiColonOrComma::Comma) - .type_literal_separator_kind_multi_line(SemiColonOrComma::Comma) + .type_literal_separator_kind_multi_line(SemiColonOrCommaOrNewLine::Comma) /* sorting */ .module_sort_import_declarations(SortOrder::Maintain) .module_sort_export_declarations(SortOrder::Maintain) diff --git a/src/configuration/resolve_config.rs b/src/configuration/resolve_config.rs index f489ad5a..2c039722 100644 --- a/src/configuration/resolve_config.rs +++ b/src/configuration/resolve_config.rs @@ -63,6 +63,14 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration) let space_around = get_value(&mut config, "spaceAround", false, &mut diagnostics); let jsx_bracket_position = get_value(&mut config, "jsx.bracketPosition", SameOrNextLinePosition::NextLine, &mut diagnostics); + let type_literal_separator_kind_multi_line = match get_nullable_value(&mut config, "typeLiteral.separatorKind.multiLine", &mut diagnostics) { + Some(value) => value, + None => match type_literal_separator_kind { + SemiColonOrComma::SemiColon => SemiColonOrCommaOrNewLine::SemiColon, + SemiColonOrComma::Comma => SemiColonOrCommaOrNewLine::Comma + } + }; + let resolved_config = Configuration { line_width: get_value( &mut config, @@ -110,7 +118,7 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration) type_literal_separator_kind_multi_line: get_value( &mut config, "typeLiteral.separatorKind.multiLine", - type_literal_separator_kind, + type_literal_separator_kind_multi_line, &mut diagnostics, ), /* sorting */ diff --git a/src/configuration/types.rs b/src/configuration/types.rs index 4476ba6c..47e8e886 100644 --- a/src/configuration/types.rs +++ b/src/configuration/types.rs @@ -247,6 +247,20 @@ pub enum SemiColonOrComma { generate_str_to_from![SemiColonOrComma, [SemiColon, "semiColon"], [Comma, "comma"]]; +/// Whether to use semi-colons, commas or new lines. +#[derive(Clone, PartialEq, Copy, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum SemiColonOrCommaOrNewLine { + /// Use semi colons (default). + SemiColon, + /// Use commas. + Comma, + /// Use new lines. + NewLine, +} + +generate_str_to_from![SemiColonOrCommaOrNewLine, [SemiColon, "semiColon"], [Comma, "comma"], [NewLine, "newLine"]]; + /// The kind of sort ordering to use. #[derive(Clone, PartialEq, Copy, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -298,7 +312,7 @@ pub struct Configuration { #[serde(rename = "typeLiteral.separatorKind.singleLine")] pub type_literal_separator_kind_single_line: SemiColonOrComma, #[serde(rename = "typeLiteral.separatorKind.multiLine")] - pub type_literal_separator_kind_multi_line: SemiColonOrComma, + pub type_literal_separator_kind_multi_line: SemiColonOrCommaOrNewLine, /* sorting */ #[serde(rename = "module.sortImportDeclarations")] pub module_sort_import_declarations: SortOrder, diff --git a/src/generation/generate.rs b/src/generation/generate.rs index 26bcfaa5..b953ceaf 100644 --- a/src/generation/generate.rs +++ b/src/generation/generate.rs @@ -3347,7 +3347,7 @@ fn gen_type_lit<'a>(node: &'a TsTypeLit, context: &mut Context<'a>) -> PrintItem context.config.type_literal_separator_kind_single_line, context, )), - multi_line: Some(semi_colon_or_comma_to_separator_value( + multi_line: Some(semi_colon_or_comma_or_new_line_to_separator_value( context.config.type_literal_separator_kind_multi_line, context, )), @@ -3368,6 +3368,14 @@ fn gen_type_lit<'a>(node: &'a TsTypeLit, context: &mut Context<'a>) -> PrintItem SemiColonOrComma::SemiColon => SeparatorValue::SemiColon(context.config.semi_colons), } } + + fn semi_colon_or_comma_or_new_line_to_separator_value(value: SemiColonOrCommaOrNewLine, context: &mut Context) -> SeparatorValue { + match value { + SemiColonOrCommaOrNewLine::Comma => SeparatorValue::Comma(context.config.type_literal_trailing_commas), + SemiColonOrCommaOrNewLine::SemiColon => SeparatorValue::SemiColon(context.config.semi_colons), + SemiColonOrCommaOrNewLine::NewLine => SeparatorValue::NewLine() + } + } } /* jsx */ @@ -7219,6 +7227,7 @@ fn gen_close_paren_with_type<'a>(opts: GenCloseParenWithTypeOptions<'a>, context enum SeparatorValue { SemiColon(SemiColons), Comma(TrailingCommas), + NewLine() } struct Separator { @@ -9282,6 +9291,7 @@ fn get_generated_separator(separator: &Separator, is_trailing: bool, is_multi_li match value { Some(SeparatorValue::Comma(trailing_comma)) => get_generated_trailing_comma(*trailing_comma, is_trailing, is_multi_line), Some(SeparatorValue::SemiColon(semi_colons)) => get_generated_semi_colon(*semi_colons, is_trailing, is_multi_line), + Some(SeparatorValue::NewLine()) => get_generated_new_line(is_trailing, is_multi_line), None => PrintItems::new(), } } @@ -9319,6 +9329,14 @@ fn get_generated_semi_colon(option: SemiColons, is_trailing: bool, is_multi_line } } +fn get_generated_new_line(is_trailing: bool, is_multi_line: &ConditionResolver) -> PrintItems { + if is_trailing { + PrintItems::new() + } else { + if_false("newLineIfMultiLine", is_multi_line.clone(), ";".into()).into() + } +} + fn get_comma_tokens_from_children_with_tokens<'a>(node: Node<'a>, program: &Program<'a>) -> Vec<&'a TokenAndSpan> { node .children_with_tokens_fast(program) diff --git a/tests/specs/types/TypeLiteral/TypeLiteral_SeparatorKind_SemiColonSingle_NewLineMulti.txt b/tests/specs/types/TypeLiteral/TypeLiteral_SeparatorKind_SemiColonSingle_NewLineMulti.txt new file mode 100644 index 00000000..04c88eab --- /dev/null +++ b/tests/specs/types/TypeLiteral/TypeLiteral_SeparatorKind_SemiColonSingle_NewLineMulti.txt @@ -0,0 +1,38 @@ +~~ typeLiteral.separatorKind.singleLine: semiColon, typeLiteral.separatorKind.multiLine: newLine, lineWidth: 40 ~~ +== should use commas when single line == +type Test = { p: string, u: number }; + +[expect] +type Test = { p: string; u: number }; + +== should use newlines when multi-line == +type Test = { + p: string, u: number }; + +[expect] +type Test = { + p: string + u: number +}; + +== should use newlines going from single line to multi == +type Test = { p: string; u: number; test: other }; + +[expect] +type Test = { + p: string + u: number + test: other +}; + +== should handle comments after semi-colons == +type Test = { + p: string; // testing + u: number; // testing + }; + +[expect] +type Test = { + p: string // testing + u: number // testing +};