Skip to content

Commit 90a5d64

Browse files
authored
feat: add parenExpression.spaceAround (#607)
1 parent 3bb079a commit 90a5d64

File tree

6 files changed

+229
-4
lines changed

6 files changed

+229
-4
lines changed

deployment/schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,9 @@
886886
"parameters.spaceAround": {
887887
"$ref": "#/definitions/spaceAround"
888888
},
889+
"parenExpression.spaceAround": {
890+
"$ref": "#/definitions/spaceAround"
891+
},
889892
"switchStatement.spaceAround": {
890893
"$ref": "#/definitions/spaceAround"
891894
},

src/configuration/builder.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,10 @@ impl ConfigurationBuilder {
10321032
self.insert("parameters.spaceAround", value.into())
10331033
}
10341034

1035+
pub fn paren_expression_space_around(&mut self, value: bool) -> &mut Self {
1036+
self.insert("parenExpression.spaceAround", value.into())
1037+
}
1038+
10351039
pub fn switch_statement_space_around(&mut self, value: bool) -> &mut Self {
10361040
self.insert("switchStatement.spaceAround", value.into())
10371041
}
@@ -1254,12 +1258,13 @@ mod tests {
12541258
.for_statement_space_around(true)
12551259
.if_statement_space_around(true)
12561260
.parameters_space_around(true)
1261+
.paren_expression_space_around(true)
12571262
.switch_statement_space_around(true)
12581263
.tuple_type_space_around(true)
12591264
.while_statement_space_around(true);
12601265

12611266
let inner_config = config.get_inner_config();
1262-
assert_eq!(inner_config.len(), 177);
1267+
assert_eq!(inner_config.len(), 178);
12631268
let diagnostics = resolve_config(inner_config, &Default::default()).diagnostics;
12641269
assert_eq!(diagnostics.len(), 0);
12651270
}

src/configuration/resolve_config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration)
315315
for_statement_space_around: get_value(&mut config, "forStatement.spaceAround", space_around, &mut diagnostics),
316316
if_statement_space_around: get_value(&mut config, "ifStatement.spaceAround", space_around, &mut diagnostics),
317317
parameters_space_around: get_value(&mut config, "parameters.spaceAround", space_around, &mut diagnostics),
318+
paren_expression_space_around: get_value(&mut config, "parenExpression.spaceAround", space_around, &mut diagnostics),
318319
switch_statement_space_around: get_value(&mut config, "switchStatement.spaceAround", space_around, &mut diagnostics),
319320
tuple_type_space_around: get_value(&mut config, "tupleType.spaceAround", space_around, &mut diagnostics),
320321
while_statement_space_around: get_value(&mut config, "whileStatement.spaceAround", space_around, &mut diagnostics),

src/configuration/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,8 @@ pub struct Configuration {
622622
pub if_statement_space_around: bool,
623623
#[serde(rename = "parameters.spaceAround")]
624624
pub parameters_space_around: bool,
625+
#[serde(rename = "parenExpression.spaceAround")]
626+
pub paren_expression_space_around: bool,
625627
#[serde(rename = "switchStatement.spaceAround")]
626628
pub switch_statement_space_around: bool,
627629
#[serde(rename = "tupleType.spaceAround")]

src/generation/generate.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2572,7 +2572,11 @@ fn gen_fn_expr<'a>(node: &FnExpr<'a>, context: &mut Context<'a>) -> PrintItems {
25722572
);
25732573

25742574
if should_add_parens_around_expr(node.into(), context) {
2575-
surround_with_parens(items)
2575+
if context.config.paren_expression_space_around {
2576+
surround_with_parens(surround_with_spaces(items))
2577+
} else {
2578+
surround_with_parens(items)
2579+
}
25762580
} else {
25772581
items
25782582
}
@@ -2741,7 +2745,11 @@ fn gen_object_lit<'a>(node: &ObjectLit<'a>, context: &mut Context<'a>) -> PrintI
27412745
);
27422746

27432747
if should_add_parens_around_expr(node.into(), context) {
2744-
surround_with_parens(items)
2748+
surround_with_parens(if context.config.paren_expression_space_around {
2749+
surround_with_spaces(items)
2750+
} else {
2751+
items
2752+
})
27452753
} else {
27462754
items
27472755
}
@@ -2758,7 +2766,7 @@ fn gen_paren_expr<'a>(node: &'a ParenExpr<'a>, context: &mut Context<'a>) -> Pri
27582766
inner_range: node.expr.range(),
27592767
prefer_hanging: true,
27602768
allow_open_paren_trailing_comments: true,
2761-
single_line_space_around: false,
2769+
single_line_space_around: context.config.paren_expression_space_around,
27622770
},
27632771
context,
27642772
))
@@ -9380,6 +9388,14 @@ fn surround_with_parens(items: PrintItems) -> PrintItems {
93809388
new_items
93819389
}
93829390

9391+
fn surround_with_spaces(items: PrintItems) -> PrintItems {
9392+
let mut new_items = PrintItems::new();
9393+
new_items.push_str(" ");
9394+
new_items.extend(items);
9395+
new_items.push_str(" ");
9396+
new_items
9397+
}
9398+
93839399
/* is/has functions */
93849400

93859401
fn is_arrow_function_with_expr_body(node: Node) -> bool {
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
~~ parenExpression.spaceAround: true ~~
2+
== should format allowing comment on header line ==
3+
const test = ( // test
4+
test
5+
);
6+
7+
[expect]
8+
const test = ( // test
9+
test
10+
);
11+
12+
== should keep comment inside ==
13+
const test = (
14+
// test
15+
test
16+
);
17+
18+
[expect]
19+
const test = (
20+
// test
21+
test
22+
);
23+
24+
== should keep paren expr on left hand side of assignment ==
25+
(x.test as unknown) = 6;
26+
27+
[expect]
28+
( x.test as unknown ) = 6;
29+
30+
== should not keep paren expr on right hand side of assignment ==
31+
const a = (1);
32+
const b = ((((1))));
33+
const c = (1 + 1) + 1;
34+
const d = 1 + (1 + 1);
35+
// except here it should because of the type assertion
36+
const e = /** @type {number} */ (((1)));
37+
// keep this too as some people like it for clarity
38+
const a = (b = 5);
39+
40+
[expect]
41+
const a = 1;
42+
const b = 1;
43+
const c = ( 1 + 1 ) + 1;
44+
const d = 1 + ( 1 + 1 );
45+
// except here it should because of the type assertion
46+
const e = /** @type {number} */ ( 1 );
47+
// keep this too as some people like it for clarity
48+
const a = ( b = 5 );
49+
50+
== should keep for IIFE ==
51+
(function foo() {
52+
test;
53+
})();
54+
55+
(() => {
56+
test;
57+
})();
58+
59+
((() => {
60+
test;
61+
}))();
62+
63+
(function foo() {
64+
test;
65+
})((function test() {}));
66+
67+
[expect]
68+
( function foo() {
69+
test;
70+
} )();
71+
72+
( () => {
73+
test;
74+
} )();
75+
76+
( () => {
77+
test;
78+
} )();
79+
80+
( function foo() {
81+
test;
82+
} )(function test() {});
83+
84+
== should keep for property access expr where appropriate ==
85+
(function test() {
86+
test;
87+
}).prop;
88+
89+
(() => {
90+
test;
91+
}).prop;
92+
93+
({
94+
prop: 5,
95+
}).prop;
96+
97+
([5]).prop;
98+
99+
[expect]
100+
( function test() {
101+
test;
102+
} ).prop;
103+
104+
( () => {
105+
test;
106+
} ).prop;
107+
108+
( {
109+
prop: 5,
110+
} ).prop;
111+
112+
[5].prop;
113+
114+
== should handle wrapped exprs for function expressions ==
115+
(function test() {}());
116+
(function test() {}?.());
117+
(function test() {}.prop);
118+
(function test() {}?.prop);
119+
(function test() {}[56]);
120+
(function test() {} + 2);
121+
(2 + function test() {});
122+
1 + (function test() {} + 2);
123+
obj[(function test() {})];
124+
(function test() {}) ? true : false;
125+
true ? function test() {} : false;
126+
true ? true : function test() {};
127+
128+
[expect]
129+
( function test() {} )();
130+
( function test() {} )?.();
131+
( function test() {} ).prop;
132+
( function test() {} )?.prop;
133+
( function test() {} )[56];
134+
( function test() {} ) + 2;
135+
2 + function test() {};
136+
1 + ( function test() {} + 2 );
137+
obj[function test() {}];
138+
( function test() {} ) ? true : false;
139+
true ? function test() {} : false;
140+
true ? true : function test() {};
141+
142+
== should handle wrapped exprs for arrow fn expressions ==
143+
(() => {})();
144+
(() => {})?.();
145+
(() => {}).prop;
146+
(() => {})?.prop;
147+
(() => {})[56];
148+
(() => {}) + 2;
149+
1 + ((() => {}) + 2);
150+
obj[() => {}];
151+
(() => {}) ? true : false;
152+
true ? () => {} : false;
153+
true ? true : () => {};
154+
new (() => {})();
155+
test = (() => {});
156+
test = () => {};
157+
158+
[expect]
159+
( () => {} )();
160+
( () => {} )?.();
161+
( () => {} ).prop;
162+
( () => {} )?.prop;
163+
( () => {} )[56];
164+
( () => {} ) + 2;
165+
1 + ( ( () => {} ) + 2 );
166+
obj[() => {}];
167+
( () => {} ) ? true : false;
168+
true ? () => {} : false;
169+
true ? true : () => {};
170+
new ( () => {} )();
171+
test = () => {};
172+
test = () => {};
173+
174+
== should handle object literal expr in paren expr in expr stmt ==
175+
({ prop: 5 }.prop);
176+
({ prop: 5 }).prop;
177+
178+
[expect]
179+
( { prop: 5 } ).prop;
180+
( { prop: 5 } ).prop;
181+
182+
== should not remove when there's a JS doc type assertion ==
183+
typeAssertedNumber = /** @type {number} */ (numberOrString)
184+
// not a js doc so won't keep it
185+
typeAssertedNumber = /* @type {number} */ (numberOrString);
186+
187+
[expect]
188+
typeAssertedNumber = /** @type {number} */ ( numberOrString );
189+
// not a js doc so won't keep it
190+
typeAssertedNumber = /* @type {number} */ numberOrString;
191+
192+
== should add spaces for update expr with assertion ==
193+
(<number>thing)--;
194+
(thing as number)--;
195+
196+
[expect]
197+
( <number> thing )--;
198+
( thing as number )--;

0 commit comments

Comments
 (0)