Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions deployment/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,17 @@
},
"forceMultiLineSpecifiers": {
"description": "If code import/export specifiers should be forced to be on multiple lines.",
"type": "boolean",
"default": false,
"type": "string",
"default": "never",
"oneOf": [{
"const": true,
"const": "always",
"description": ""
}, {
"const": false,
"const": "never",
"description": ""
}, {
"const": "onlyWhenMultiple",
"description": "Force multiple lines only if importing more than one thing."
}]
},
"sortOrder": {
Expand Down
12 changes: 6 additions & 6 deletions src/configuration/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,12 +759,12 @@ impl ConfigurationBuilder {

/* force multi line specifiers */

pub fn export_declaration_force_multi_line(&mut self, value: bool) -> &mut Self {
self.insert("exportDeclaration.forceMultiLine", value.into())
pub fn export_declaration_force_multi_line(&mut self, value: ForceMultiLine) -> &mut Self {
self.insert("exportDeclaration.forceMultiLine", value.to_string().into())
}

pub fn import_declaration_force_multi_line(&mut self, value: bool) -> &mut Self {
self.insert("importDeclaration.forceMultiLine", value.into())
pub fn import_declaration_force_multi_line(&mut self, value: ForceMultiLine) -> &mut Self {
self.insert("importDeclaration.forceMultiLine", value.to_string().into())
}

/* member spacing */
Expand Down Expand Up @@ -1220,8 +1220,8 @@ mod tests {
.export_declaration_force_single_line(true)
.import_declaration_force_single_line(true)
/* force multi line specifiers */
.export_declaration_force_multi_line(true)
.import_declaration_force_multi_line(true)
.export_declaration_force_multi_line(ForceMultiLine::Always)
.import_declaration_force_multi_line(ForceMultiLine::Always)
/* space settings */
.binary_expression_space_surrounding_bitwise_and_arithmetic_operator(true)
.comment_line_force_space_after_slashes(false)
Expand Down
4 changes: 2 additions & 2 deletions src/configuration/resolve_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration)
import_declaration_force_single_line: get_value(&mut config, "importDeclaration.forceSingleLine", false, &mut diagnostics),
export_declaration_force_single_line: get_value(&mut config, "exportDeclaration.forceSingleLine", false, &mut diagnostics),
/* force multi line specifiers */
import_declaration_force_multi_line: get_value(&mut config, "importDeclaration.forceMultiLine", false, &mut diagnostics),
export_declaration_force_multi_line: get_value(&mut config, "exportDeclaration.forceMultiLine", false, &mut diagnostics),
import_declaration_force_multi_line: get_value(&mut config, "importDeclaration.forceMultiLine", ForceMultiLine::Never, &mut diagnostics),
export_declaration_force_multi_line: get_value(&mut config, "exportDeclaration.forceMultiLine", ForceMultiLine::Never, &mut diagnostics),
/* space settings */
binary_expression_space_surrounding_bitwise_and_arithmetic_operator: get_value(
&mut config,
Expand Down
18 changes: 16 additions & 2 deletions src/configuration/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ pub enum TrailingCommas {

generate_str_to_from![TrailingCommas, [Always, "always"], [Never, "never"], [OnlyMultiLine, "onlyMultiLine"]];

/// Force multilines possibilities.
#[derive(Clone, PartialEq, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ForceMultiLine {
/// Multiline imports/exports should not be forced.
Never,
/// Always force multiline imports/exports.
Always,
/// Mulitline imports/exports should be forced only when importing/exporting multiple items.
OnlyWhenMultiple,
}

generate_str_to_from![ForceMultiLine, [Always, "always"], [Never, "never"], [OnlyWhenMultiple, "onlyWhenMultiple"]];

/// Where to place the opening brace.
#[derive(Clone, PartialEq, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -541,9 +555,9 @@ pub struct Configuration {
pub export_declaration_force_single_line: bool,
/* force multi line specifiers */
#[serde(rename = "exportDeclaration.forceMultiLine")]
pub export_declaration_force_multi_line: bool,
pub export_declaration_force_multi_line: ForceMultiLine,
#[serde(rename = "importDeclaration.forceMultiLine")]
pub import_declaration_force_multi_line: bool,
pub import_declaration_force_multi_line: ForceMultiLine,

/* use space separator */
#[serde(rename = "binaryExpression.spaceSurroundingBitwiseAndArithmeticOperator")]
Expand Down
20 changes: 16 additions & 4 deletions src/generation/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1033,10 +1033,16 @@ fn gen_export_named_decl<'a>(node: &NamedExport<'a>, context: &mut Context<'a>)
}

let force_single_line = context.config.export_declaration_force_single_line && !contains_line_or_multiline_comment(node.into(), context.program);

let force_multi_line = !force_single_line
&& ((context.config.export_declaration_force_multi_line == ForceMultiLine::Always)
|| (named_exports.len() > 1 && context.config.export_declaration_force_multi_line == ForceMultiLine::OnlyWhenMultiple));

let should_single_line = force_single_line
|| (default_export.is_none()
&& namespace_export.is_none()
&& (named_exports.len() <= 1 && !context.config.export_declaration_force_multi_line)
&& !force_multi_line
&& (named_exports.len() <= 1 && context.config.export_declaration_force_multi_line == ForceMultiLine::Never)
&& node.start_line_fast(context.program) == node.end_line_fast(context.program));

// generate
Expand All @@ -1055,7 +1061,7 @@ fn gen_export_named_decl<'a>(node: &NamedExport<'a>, context: &mut Context<'a>)
parent: node.into(),
specifiers: named_exports.into_iter().map(|x| x.into()).collect(),
force_single_line,
force_multi_line_specifiers: context.config.export_declaration_force_multi_line,
force_multi_line_specifiers: force_multi_line,
},
context,
));
Expand Down Expand Up @@ -1218,11 +1224,17 @@ fn gen_import_decl<'a>(node: &ImportDecl<'a>, context: &mut Context<'a>) -> Prin
}

let force_single_line = context.config.import_declaration_force_single_line && !contains_line_or_multiline_comment(node.into(), context.program);

let force_multi_line = context.config.import_declaration_force_multi_line == ForceMultiLine::Always
|| (named_imports.len() > 1 && context.config.import_declaration_force_multi_line == ForceMultiLine::OnlyWhenMultiple);

let should_single_line = force_single_line
|| (default_import.is_none()
&& namespace_import.is_none()
&& (named_imports.len() <= 1 && !context.config.import_declaration_force_multi_line)
&& !force_multi_line
&& (named_imports.len() <= 1 && context.config.import_declaration_force_multi_line == ForceMultiLine::Never)
&& node.start_line_fast(context.program) == node.end_line_fast(context.program));

let has_named_imports = !named_imports.is_empty() || {
let from_keyword = context.token_finder.get_previous_token_if_from_keyword(node.src);
if let Some(from_keyword) = from_keyword {
Expand Down Expand Up @@ -1267,7 +1279,7 @@ fn gen_import_decl<'a>(node: &ImportDecl<'a>, context: &mut Context<'a>) -> Prin
parent: node.into(),
specifiers: named_imports.into_iter().map(|x| x.into()).collect(),
force_single_line,
force_multi_line_specifiers: context.config.import_declaration_force_multi_line,
force_multi_line_specifiers: force_multi_line,
},
context,
));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
~~ exportDeclaration.forceMultiLine: true, lineWidth: 40 ~~
~~ exportDeclaration.forceMultiLine: always, lineWidth: 40 ~~
== should always add a new line between exports ==
export { testing, a, b, c, d, e } from "./test.ts";
export { testing, a, b, c, d, e // test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
~~ exportDeclaration.forceMultiLine: onlyWhenMultiple, lineWidth: 40 ~~
== should never add a new line between exports ==
export { testing, a, b, c, d, e } from "./test.ts";
export { testing, a, b, c, d, e // test
} from "./test.ts";
export { a, b, c, d, e /* this is ok though testing testing */ } from "./test.ts";
export { a, b, c, d, e /* and
not ok */ } from "./test.ts";

[expect]
export {
a,
b,
c,
d,
e,
testing,
} from "./test.ts";
export {
a,
b,
c,
d,
e, // test
testing,
} from "./test.ts";
export {
a,
b,
c,
d,
e, /* this is ok though testing testing */
} from "./test.ts";
export {
a,
b,
c,
d,
e, /* and
not ok */
} from "./test.ts";

== should not collapse a single-line one ==
export { a } from "./test.ts";
export { b } from "./test.ts";

[expect]
export { a } from "./test.ts";
export { b } from "./test.ts";
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
~~ importDeclaration.forceMultiLine: true, lineWidth: 40 ~~
~~ importDeclaration.forceMultiLine: always, lineWidth: 40 ~~
== should always add a new line between ==
import { testing, a, b, c, d, e } from "./test.ts";
import { testing, a, b, c, d, e // test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
~~ importDeclaration.forceMultiLine: never, lineWidth: 40 ~~
== should never add a new line between ==
import { a, b } from "./test.ts";

[expect]
import { a, b } from "./test.ts";
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
~~ importDeclaration.forceMultiLine: onlyWhenMultiple, lineWidth: 40 ~~
== should break imports when more than one ==
import { a, b } from "./test.ts";

[expect]
import {
a,
b,
} from "./test.ts";

== should not break single-line imports ==
import { a } from "./test.ts";


[expect]
import { a } from "./test.ts";