Skip to content

Commit

Permalink
fix(codegen): fixes for esbuild test cases (#4503)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Jul 28, 2024
1 parent b1b66e2 commit 6a94e3f
Show file tree
Hide file tree
Showing 13 changed files with 811 additions and 930 deletions.
125 changes: 86 additions & 39 deletions crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Program<'a> {
if let Some(hashbang) = &self.hashbang {
hashbang.gen(p, ctx);
}
p.print_directives_and_statements(Some(&self.directives), &self.body, ctx);
for directive in &self.directives {
directive.gen(p, ctx);
}
for stmt in &self.body {
stmt.gen(p, ctx);
p.print_semicolon_if_needed();
}
}
}

Expand All @@ -64,7 +70,8 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Directive<'a> {
p.wrap_quote(|p, _| {
p.print_str(self.directive.as_str());
});
p.print_semicolon_after_statement();
p.print_char(b';');
p.print_soft_newline();
}
}

Expand Down Expand Up @@ -112,9 +119,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Statement<'a> {
decl.gen(p, ctx);
p.print_soft_newline();
}
Self::UsingDeclaration(declaration) => {
Self::UsingDeclaration(decl) => {
p.print_indent();
declaration.gen(p, ctx);
decl.gen(p, ctx);
p.print_semicolon_after_statement();
}
Self::TSModuleDeclaration(decl) => {
Expand Down Expand Up @@ -560,11 +567,9 @@ impl<const MINIFY: bool> Gen<MINIFY> for DebuggerStatement {
impl<'a, const MINIFY: bool> Gen<MINIFY> for UsingDeclaration<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
if self.is_await {
p.print_str("await");
p.print_soft_space();
p.print_str("await ");
}
p.print_str("using");
p.print_soft_space();
p.print_str("using ");
p.print_list(&self.declarations, ctx);
}
}
Expand Down Expand Up @@ -665,7 +670,13 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for Function<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for FunctionBody<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.print_curly_braces(self.span, self.is_empty(), |p| {
p.print_directives_and_statements(Some(&self.directives), &self.statements, ctx);
for directive in &self.directives {
directive.gen(p, ctx);
}
for stmt in &self.statements {
p.print_semicolon_if_needed();
stmt.gen(p, ctx);
}
});
p.needs_semicolon = false;
}
Expand Down Expand Up @@ -711,9 +722,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
p.print_soft_space();
p.print_str("from");
p.print_soft_space();
p.print_char(b'\'');
p.print_char(b'"');
p.print_str(self.source.value.as_str());
p.print_char(b'\'');
p.print_char(b'"');
if self.with_clause.is_some() {
p.print_hard_space();
}
Expand Down Expand Up @@ -996,7 +1007,10 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ExportDefaultDeclarationKind<'a> {
self.to_expression().gen_expr(p, Precedence::Assign, Context::default());
p.print_semicolon_after_statement();
}
Self::FunctionDeclaration(fun) => fun.gen(p, ctx),
Self::FunctionDeclaration(fun) => {
fun.gen(p, ctx);
p.print_soft_newline();
}
Self::ClassDeclaration(class) => {
class.gen(p, ctx);
p.print_soft_newline();
Expand Down Expand Up @@ -1477,23 +1491,36 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ArrayExpression<'a> {
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ObjectExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, _precedence: Precedence, ctx: Context) {
let n = p.code_len();
p.wrap(p.start_of_stmt == n || p.start_of_arrow_expr == n, |p| {
let single_line = self.properties.len() <= 1;
p.print_curly_braces(self.span, single_line, |p| {
for (index, item) in self.properties.iter().enumerate() {
if index != 0 {
p.print_comma();
p.print_soft_newline();
}
if !single_line {
p.print_indent();
}
item.gen(p, ctx);
let len = self.properties.len();
let is_multi_line = len > 1;
let wrap = p.start_of_stmt == n || p.start_of_arrow_expr == n;
p.wrap(wrap, |p| {
p.add_source_mapping(self.span.start);
p.print_char(b'{');
if is_multi_line {
p.indent();
}
for (i, item) in self.properties.iter().enumerate() {
if i != 0 {
p.print_comma();
}
if !single_line {
if is_multi_line {
p.print_soft_newline();
p.print_indent();
} else {
p.print_soft_space();
}
});
item.gen(p, ctx);
}
if is_multi_line {
p.print_soft_newline();
p.dedent();
p.print_indent();
} else if len > 0 {
p.print_soft_space();
}
p.add_source_mapping(self.span.end);
p.print_char(b'}');
});
}
}
Expand Down Expand Up @@ -1555,7 +1582,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ObjectProperty<'a> {
let mut shorthand = false;
if let PropertyKey::StaticIdentifier(key) = &self.key {
if let Expression::Identifier(ident) = self.value.without_parenthesized() {
if key.name == p.get_identifier_reference_name(ident) {
if key.name == p.get_identifier_reference_name(ident) && key.name != "__proto__" {
shorthand = true;
}
}
Expand Down Expand Up @@ -1981,7 +2008,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetRest<'a> {
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for SequenceExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, _ctx: Context) {
p.wrap(precedence > self.precedence(), |p| {
p.print_expressions(&self.expressions, Precedence::Assign, Context::default());
p.print_expressions(&self.expressions, Precedence::Comma, Context::default());
});
}
}
Expand Down Expand Up @@ -2278,17 +2305,17 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXAttributeItem<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXOpeningElement<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.add_source_mapping(self.span.start);
p.print_str("<");
p.print_char(b'<');
self.name.gen(p, ctx);
for attr in &self.attributes {
p.print_hard_space();
attr.gen(p, ctx);
}
if self.self_closing {
p.print_str("/>");
} else {
p.print_char(b'>');
p.print_soft_space();
p.print_str("/");
}
p.print_char(b'>');
}
}

Expand Down Expand Up @@ -2490,9 +2517,12 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AccessorProperty<'a> {
if self.r#static {
p.print_str("static ");
}
p.print_str("accessor ");
p.print_str("accessor");
if self.computed {
p.print_soft_space();
p.print_char(b'[');
} else {
p.print_hard_space();
}
self.key.gen(p, ctx);
if self.computed {
Expand Down Expand Up @@ -2559,10 +2589,22 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for BindingProperty<'a> {

let mut shorthand = false;
if let PropertyKey::StaticIdentifier(key) = &self.key {
if let BindingPatternKind::BindingIdentifier(ident) = &self.value.kind {
if key.name == p.get_binding_identifier_name(ident) {
match &self.value.kind {
BindingPatternKind::BindingIdentifier(ident)
if key.name == p.get_binding_identifier_name(ident) =>
{
shorthand = true;
}
BindingPatternKind::AssignmentPattern(assignment_pattern) => {
if let BindingPatternKind::BindingIdentifier(ident) =
&assignment_pattern.left.kind
{
if key.name == p.get_binding_identifier_name(ident) {
shorthand = true;
}
}
}
_ => {}
}
}

Expand Down Expand Up @@ -2595,9 +2637,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ArrayPattern<'a> {
for (index, item) in self.elements.iter().enumerate() {
if index != 0 {
p.print_comma();
if item.is_some() {
p.print_soft_space();
}
p.print_soft_space();
}
if let Some(item) = item {
item.gen(p, ctx);
Expand Down Expand Up @@ -3365,8 +3405,15 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSModuleBlock<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
let is_empty = self.directives.is_empty() && self.body.is_empty();
p.print_curly_braces(self.span, is_empty, |p| {
p.print_directives_and_statements(Some(&self.directives), &self.body, ctx);
for directive in &self.directives {
directive.gen(p, ctx);
}
for stmt in &self.body {
p.print_semicolon_if_needed();
stmt.gen(p, ctx);
}
});
p.needs_semicolon = false;
}
}

Expand Down
37 changes: 5 additions & 32 deletions crates/oxc_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ use std::{borrow::Cow, ops::Range};
use rustc_hash::FxHashMap;

use oxc_ast::{
ast::{
BindingIdentifier, BlockStatement, Directive, Expression, IdentifierReference, Program,
Statement,
},
ast::{BindingIdentifier, BlockStatement, Expression, IdentifierReference, Program, Statement},
Comment, Trivias,
};
use oxc_mangler::Mangler;
Expand Down Expand Up @@ -392,7 +389,10 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {

fn print_block_statement(&mut self, stmt: &BlockStatement<'_>, ctx: Context) {
self.print_curly_braces(stmt.span, stmt.body.is_empty(), |p| {
p.print_directives_and_statements(None, &stmt.body, ctx);
for stmt in &stmt.body {
p.print_semicolon_if_needed();
stmt.gen(p, ctx);
}
});
self.needs_semicolon = false;
}
Expand Down Expand Up @@ -500,33 +500,6 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
self.print_char(self.quote);
}

fn print_directives_and_statements(
&mut self,
directives: Option<&[Directive]>,
statements: &[Statement<'_>],
ctx: Context,
) {
if let Some(directives) = directives {
if directives.is_empty() {
if let Some(Statement::ExpressionStatement(s)) = statements.first() {
if matches!(s.expression.get_inner_expression(), Expression::StringLiteral(_)) {
self.print_semicolon();
self.print_soft_newline();
}
}
} else {
for directive in directives {
directive.gen(self, ctx);
self.print_semicolon_if_needed();
}
}
}
for stmt in statements {
self.print_semicolon_if_needed();
stmt.gen(self, ctx);
}
}

fn add_source_mapping(&mut self, position: u32) {
if let Some(sourcemap_builder) = self.sourcemap_builder.as_mut() {
sourcemap_builder.add_source_mapping(&self.code, position, None);
Expand Down
Loading

0 comments on commit 6a94e3f

Please sign in to comment.