Skip to content

Commit 5a99d30

Browse files
committed
feat(codegen): improve codegen formatting (#3735)
1 parent 4d46263 commit 5a99d30

File tree

6 files changed

+4789
-4744
lines changed

6 files changed

+4789
-4744
lines changed

crates/oxc_codegen/src/gen.rs

+72-44
Original file line numberDiff line numberDiff line change
@@ -193,45 +193,46 @@ fn print_if<const MINIFY: bool>(
193193
p.print(b'(');
194194
p.print_expression(&if_stmt.test);
195195
p.print(b')');
196-
p.print_soft_space();
197196

198197
match &if_stmt.consequent {
199198
Statement::BlockStatement(block) => {
199+
p.print_soft_space();
200200
p.print_block_statement(block, ctx);
201+
if if_stmt.alternate.is_some() {
202+
p.print_soft_space();
203+
} else {
204+
p.print_soft_newline();
205+
}
201206
}
202207
stmt if wrap_to_avoid_ambiguous_else(stmt) => {
208+
p.print_soft_space();
203209
p.print_block_start(stmt.span().start);
204210
stmt.gen(p, ctx);
205211
p.needs_semicolon = false;
206212
p.print_block_end(stmt.span().end);
213+
if if_stmt.alternate.is_some() {
214+
p.print_soft_space();
215+
} else {
216+
p.print_soft_newline();
217+
}
207218
}
208-
stmt => {
209-
stmt.gen(p, ctx);
210-
}
211-
}
212-
if if_stmt.alternate.is_some() {
213-
p.print_soft_space();
214-
} else {
215-
p.print_soft_newline();
219+
stmt => p.print_body(stmt, false, ctx),
216220
}
217221
if let Some(alternate) = if_stmt.alternate.as_ref() {
218222
p.print_semicolon_if_needed();
219223
p.print_space_before_identifier();
220-
p.print_str(b"else ");
224+
p.print_str(b"else");
221225
match alternate {
222226
Statement::BlockStatement(block) => {
227+
p.print_soft_space();
223228
p.print_block_statement(block, ctx);
224229
p.print_soft_newline();
225230
}
226231
Statement::IfStatement(if_stmt) => {
232+
p.print_hard_space();
227233
print_if(if_stmt, p, ctx);
228234
}
229-
_ => {
230-
p.print_soft_newline();
231-
p.indent();
232-
alternate.gen(p, ctx);
233-
p.dedent();
234-
}
235+
stmt => p.print_body(stmt, true, ctx),
235236
}
236237
}
237238
}
@@ -296,12 +297,12 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForStatement<'a> {
296297
p.print_semicolon();
297298

298299
if let Some(update) = self.update.as_ref() {
300+
p.print_soft_space();
299301
p.print_expression(update);
300302
}
301303

302304
p.print(b')');
303-
p.print_soft_space();
304-
p.print_body(&self.body, ctx);
305+
p.print_body(&self.body, false, ctx);
305306
}
306307
}
307308

@@ -319,8 +320,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForInStatement<'a> {
319320
p.print_hard_space();
320321
p.print_expression(&self.right);
321322
p.print(b')');
322-
p.print_soft_space();
323-
p.print_body(&self.body, ctx);
323+
p.print_body(&self.body, false, ctx);
324324
}
325325
}
326326

@@ -340,8 +340,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForOfStatement<'a> {
340340
p.print_str(b"of ");
341341
self.right.gen_expr(p, Precedence::Assign, Context::default());
342342
p.print(b')');
343-
p.print_soft_space();
344-
p.print_body(&self.body, ctx);
343+
p.print_body(&self.body, false, ctx);
345344
}
346345
}
347346

@@ -370,8 +369,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for WhileStatement<'a> {
370369
p.print(b'(');
371370
p.print_expression(&self.test);
372371
p.print(b')');
373-
p.print_soft_space();
374-
p.print_body(&self.body, ctx);
372+
p.print_body(&self.body, false, ctx);
375373
}
376374
}
377375

@@ -470,12 +468,8 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for SwitchCase<'a> {
470468
p.print_colon();
471469

472470
if self.consequent.len() == 1 {
473-
if let Statement::BlockStatement(block) = &self.consequent[0] {
474-
p.print_soft_space();
475-
p.print_block_statement(block, ctx);
476-
p.print_soft_newline();
477-
return;
478-
}
471+
p.print_body(&self.consequent[0], false, ctx);
472+
return;
479473
}
480474

481475
p.print_soft_newline();
@@ -503,12 +497,14 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ReturnStatement<'a> {
503497

504498
impl<'a, const MINIFY: bool> Gen<MINIFY> for LabeledStatement<'a> {
505499
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
506-
p.add_source_mapping(self.span.start);
507-
p.print_indent();
500+
if !MINIFY && (p.indent > 0 || p.print_next_indent_as_space) {
501+
p.add_source_mapping(self.span.start);
502+
p.print_indent();
503+
}
504+
p.print_space_before_identifier();
508505
self.label.gen(p, ctx);
509506
p.print_colon();
510-
p.print_soft_space();
511-
p.print_body(&self.body, ctx);
507+
p.print_body(&self.body, false, ctx);
512508
}
513509
}
514510

@@ -531,6 +527,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TryStatement<'a> {
531527
}
532528
p.print_soft_space();
533529
p.print_block_statement(&handler.body, ctx);
530+
if self.finalizer.is_some() {
531+
p.print_soft_newline();
532+
}
534533
}
535534
if let Some(finalizer) = &self.finalizer {
536535
p.print_soft_space();
@@ -560,7 +559,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for WithStatement<'a> {
560559
p.print(b'(');
561560
p.print_expression(&self.object);
562561
p.print(b')');
563-
p.print_body(&self.body, ctx);
562+
p.print_body(&self.body, false, ctx);
564563
}
565564
}
566565

@@ -716,6 +715,10 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
716715
}
717716
if let Some(specifiers) = &self.specifiers {
718717
if specifiers.is_empty() {
718+
p.print_str(b"{}");
719+
p.print_soft_space();
720+
p.print_str(b"from");
721+
p.print_soft_space();
719722
p.print(b'\'');
720723
p.print_str(self.source.value.as_bytes());
721724
p.print(b'\'');
@@ -732,32 +735,39 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
732735
match specifier {
733736
ImportDeclarationSpecifier::ImportDefaultSpecifier(spec) => {
734737
if in_block {
738+
p.print_soft_space();
735739
p.print_str(b"},");
736740
in_block = false;
737741
} else if index != 0 {
738742
p.print_comma();
743+
p.print_soft_space();
739744
}
740745
spec.local.gen(p, ctx);
741746
}
742747
ImportDeclarationSpecifier::ImportNamespaceSpecifier(spec) => {
743748
if in_block {
749+
p.print_soft_space();
744750
p.print_str(b"},");
745751
in_block = false;
746752
} else if index != 0 {
747753
p.print_comma();
754+
p.print_soft_space();
748755
}
749756
p.print_str(b"* as ");
750757
spec.local.gen(p, ctx);
751758
}
752759
ImportDeclarationSpecifier::ImportSpecifier(spec) => {
753760
if in_block {
754761
p.print_comma();
762+
p.print_soft_space();
755763
} else {
756764
if index != 0 {
757765
p.print_comma();
766+
p.print_soft_space();
758767
}
759768
in_block = true;
760769
p.print(b'{');
770+
p.print_soft_space();
761771
}
762772

763773
if spec.import_kind.is_type() {
@@ -785,6 +795,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
785795
}
786796
}
787797
if in_block {
798+
p.print_soft_space();
788799
p.print(b'}');
789800
}
790801
p.print_str(b" from ");
@@ -825,6 +836,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportAttribute<'a> {
825836
ImportAttributeKey::StringLiteral(literal) => literal.gen(p, ctx),
826837
};
827838
p.print_colon();
839+
p.print_soft_space();
828840
self.value.gen(p, ctx);
829841
}
830842
}
@@ -1477,14 +1489,16 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ObjectExpression<'a> {
14771489
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, _precedence: Precedence, ctx: Context) {
14781490
let n = p.code_len();
14791491
p.wrap(p.start_of_stmt == n || p.start_of_arrow_expr == n, |p| {
1480-
let single_line = self.properties.is_empty();
1492+
let single_line = self.properties.len() <= 1;
14811493
p.print_curly_braces(self.span, single_line, |p| {
14821494
for (index, item) in self.properties.iter().enumerate() {
14831495
if index != 0 {
14841496
p.print_comma();
14851497
p.print_soft_newline();
14861498
}
1487-
p.print_indent();
1499+
if !single_line {
1500+
p.print_indent();
1501+
}
14881502
item.gen(p, ctx);
14891503
}
14901504
if !single_line {
@@ -1691,9 +1705,10 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for BinaryExpression<'a> {
16911705
self.left.gen_expr(p, left_precedence, ctx);
16921706
if self.operator.is_keyword() {
16931707
p.print_space_before_identifier();
1708+
} else {
1709+
p.print_soft_space();
16941710
}
16951711
self.operator.gen(p, ctx);
1696-
p.print_soft_space();
16971712
let right_precedence = if self.precedence().is_left_associative() {
16981713
self.precedence()
16991714
} else {
@@ -1714,6 +1729,7 @@ impl<const MINIFY: bool> Gen<MINIFY> for BinaryOperator {
17141729
let op: Operator = (*self).into();
17151730
p.print_space_before_operator(op);
17161731
p.print_str(operator);
1732+
p.print_soft_space();
17171733
p.prev_op = Some(op);
17181734
p.prev_op_end = p.code().len();
17191735
}
@@ -1755,7 +1771,7 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ConditionalExpression<'a> {
17551771
p.print_soft_space();
17561772
self.consequent.gen_expr(p, Precedence::Assign, ctx.and_in(true));
17571773
p.print_soft_space();
1758-
p.print(b':');
1774+
p.print_colon();
17591775
p.print_soft_space();
17601776
self.alternate.gen_expr(p, Precedence::Assign, ctx.union_in_if(wrap));
17611777
});
@@ -1898,7 +1914,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetMaybeDefault<'a> {
18981914
impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetWithDefault<'a> {
18991915
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
19001916
self.binding.gen(p, ctx);
1917+
p.print_soft_space();
19011918
p.print_equal();
1919+
p.print_soft_space();
19021920
self.init.gen_expr(p, Precedence::Assign, Context::default());
19031921
}
19041922
}
@@ -1916,7 +1934,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetPropertyIdentifier<
19161934
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
19171935
self.binding.gen(p, ctx);
19181936
if let Some(expr) = &self.init {
1937+
p.print_soft_space();
19191938
p.print_equal();
1939+
p.print_soft_space();
19201940
expr.gen_expr(p, Precedence::Assign, Context::default());
19211941
}
19221942
}
@@ -1938,6 +1958,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetPropertyProperty<'a
19381958
}
19391959
}
19401960
p.print_colon();
1961+
p.print_soft_space();
19411962
self.binding.gen(p, ctx);
19421963
}
19431964
}
@@ -2157,7 +2178,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXElementName<'a> {
21572178
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXNamespacedName<'a> {
21582179
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
21592180
self.namespace.gen(p, ctx);
2160-
p.print(b':');
2181+
p.print_colon();
21612182
self.property.gen(p, ctx);
21622183
}
21632184
}
@@ -2175,7 +2196,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXAttribute<'a> {
21752196
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
21762197
self.name.gen(p, ctx);
21772198
if let Some(value) = &self.value {
2178-
p.print(b'=');
2199+
p.print_equal();
21792200
value.gen(p, ctx);
21802201
}
21812202
}
@@ -2326,6 +2347,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for StaticBlock<'a> {
23262347
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
23272348
p.add_source_mapping(self.span.start);
23282349
p.print_str(b"static");
2350+
p.print_soft_space();
23292351
p.print_curly_braces(self.span, self.body.is_empty(), |p| {
23302352
for stmt in &self.body {
23312353
p.print_semicolon_if_needed();
@@ -2487,13 +2509,15 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ObjectPattern<'a> {
24872509
fn gen(&self, p: &mut Codegen<MINIFY>, ctx: Context) {
24882510
p.add_source_mapping(self.span.start);
24892511
p.print(b'{');
2512+
p.print_soft_space();
24902513
p.print_list(&self.properties, ctx);
24912514
if let Some(rest) = &self.rest {
24922515
if !self.properties.is_empty() {
24932516
p.print_comma();
24942517
}
24952518
rest.gen(p, ctx);
24962519
}
2520+
p.print_soft_space();
24972521
p.print(b'}');
24982522
p.add_source_mapping(self.span.end);
24992523
}
@@ -2513,6 +2537,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for BindingProperty<'a> {
25132537
}
25142538
if !self.shorthand {
25152539
p.print_colon();
2540+
p.print_soft_space();
25162541
}
25172542
self.value.gen(p, ctx);
25182543
}
@@ -2876,12 +2901,15 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTemplateLiteralType<'a> {
28762901

28772902
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTypeLiteral<'a> {
28782903
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
2879-
p.print_curly_braces(self.span, self.members.is_empty(), |p| {
2904+
let single_line = self.members.len() <= 1;
2905+
p.print_curly_braces(self.span, single_line, |p| {
28802906
for item in &self.members {
28812907
p.print_indent();
28822908
item.gen(p, ctx);
2883-
p.print_semicolon();
2884-
p.print_soft_newline();
2909+
if !single_line {
2910+
p.print_semicolon();
2911+
p.print_soft_newline();
2912+
}
28852913
}
28862914
});
28872915
}

0 commit comments

Comments
 (0)