feat(codegen): align more esbuild implementations (#4510)

This commit is contained in:
Boshen 2024-07-28 13:35:37 +00:00
parent 35654e665c
commit 7446e986c3
4 changed files with 34 additions and 37 deletions

View file

@ -1731,8 +1731,8 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for UnaryExpression<'a> {
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for BinaryExpression<'a> { impl<'a, const MINIFY: bool> GenExpr<MINIFY> for BinaryExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) { fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
let mut ctx = ctx; let mut ctx = ctx;
let wrap_in = self.operator == BinaryOperator::In && ctx.intersects(Context::FORBID_IN); let wrap = precedence >= self.precedence()
let wrap = precedence >= self.precedence() || wrap_in; || (self.operator == BinaryOperator::In && ctx.intersects(Context::FORBID_IN));
if wrap { if wrap {
ctx &= Context::FORBID_IN.not(); ctx &= Context::FORBID_IN.not();
} }
@ -2333,7 +2333,14 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXOpeningElement<'a> {
p.print_char(b'<'); p.print_char(b'<');
self.name.gen(p, ctx); self.name.gen(p, ctx);
for attr in &self.attributes { for attr in &self.attributes {
match attr {
JSXAttributeItem::Attribute(_) => {
p.print_hard_space(); p.print_hard_space();
}
JSXAttributeItem::SpreadAttribute(_) => {
p.print_soft_space();
}
}
attr.gen(p, ctx); attr.gen(p, ctx);
} }
if self.self_closing { if self.self_closing {

View file

@ -373,7 +373,7 @@ fn test_template() {
#[test] #[test]
fn test_object() { fn test_object() {
// test("let x = {'(':')'}", "let x = { \"(\": \");\" };\n"); test("let x = {'(':')'}", "let x = { \"(\": \")\" };\n");
test("({})", "({});\n"); test("({})", "({});\n");
test("({}.x)", "({}).x;\n"); test("({}.x)", "({}).x;\n");
test("({} = {})", "({} = {});\n"); test("({} = {})", "({} = {});\n");
@ -601,11 +601,10 @@ fn test_private_identifiers() {
} }
#[test] #[test]
#[ignore]
fn test_decorators() { fn test_decorators() {
// example := "class Foo {\n@w\nw; @x x; @a1\n@b1@b2\n@c1@c2@c3\ny = @y1 @y2 class {}; @a1\n@b1@b2\n@c1@c2@c3 z =\n@z1\n@z2\nclass {}}" let source = "class Foo {\n@w\nw; @x x; @a1\n@b1@b2\n@c1@c2@c3\ny = @y1 @y2 class {}; @a1\n@b1@b2\n@c1@c2@c3 z =\n@z1\n@z2\nclass {}}";
// test( example, "class Foo {\n @w\n w;\n @x x;\n @a1\n @b1 @b2\n @c1 @c2 @c3\n "+ let expect = "class Foo {\n\t@w w;\n\t@x x;\n\t@a1 @b1 @b2 @c1 @c2 @c3 y = @y1 @y2 class {};\n\t@a1 @b1 @b2 @c1 @c2 @c3 z = @z1 @z2 class {};\n}\n";
// "y = @y1 @y2 class {\n };\n @a1\n @b1 @b2\n @c1 @c2 @c3 z = @z1 @z2 class {\n };\n}\n"); test(source, expect);
// test_minify( example, "class Foo{@w w;@x x;@a1@b1@b2@c1@c2@c3 y=@y1@y2 class{};@a1@b1@b2@c1@c2@c3 z=@z1@z2 class{}}"); // test_minify( example, "class Foo{@w w;@x x;@a1@b1@b2@c1@c2@c3 y=@y1@y2 class{};@a1@b1@b2@c1@c2@c3 z=@z1@z2 class{}}");
} }
@ -878,7 +877,6 @@ fn test_ascii_only() {
} }
#[test] #[test]
#[ignore]
fn test_jsx() { fn test_jsx() {
test("<a/>", "<a />;\n"); test("<a/>", "<a />;\n");
test("<A/>", "<A />;\n"); test("<A/>", "<A />;\n");
@ -886,18 +884,18 @@ fn test_jsx() {
test("<A.B/>", "<A.B />;\n"); test("<A.B/>", "<A.B />;\n");
test("<a-b/>", "<a-b />;\n"); test("<a-b/>", "<a-b />;\n");
test("<a:b/>", "<a:b />;\n"); test("<a:b/>", "<a:b />;\n");
test("<a></a>", "<a />;\n"); // test("<a></a>", "<a />;\n");
test("<a b></a>", "<a b />;\n"); // test("<a b></a>", "<a b />;\n");
test("<a b={true}></a>", "<a b={true} />;\n"); // test("<a b={true}></a>", "<a b={true} />;\n");
test("<a b='x'></a>", "<a b='x' />;\n"); // test("<a b='x'></a>", "<a b='x' />;\n");
test("<a b=\"x\"></a>", "<a b=\"x\" />;\n"); // test("<a b=\"x\"></a>", "<a b=\"x\" />;\n");
test("<a b={'x'}></a>", "<a b={\"x\"} />;\n"); // test("<a b={'x'}></a>", "<a b={\"x\"} />;\n");
test("<a b={`'`}></a>", "<a b={`'`} />;\n"); // test("<a b={`'`}></a>", "<a b={`'`} />;\n");
test("<a b={`\"`}></a>", "<a b={`\"`} />;\n"); // test("<a b={`\"`}></a>", "<a b={`\"`} />;\n");
test("<a b={`'\"`}></a>", "<a b={`'\"`} />;\n"); // test("<a b={`'\"`}></a>", "<a b={`'\"`} />;\n");
test("<a b=\"&quot;\"></a>", "<a b=\"&quot;\" />;\n"); // test("<a b=\"&quot;\"></a>", "<a b=\"&quot;\" />;\n");
test("<a b=\"&amp;\"></a>", "<a b=\"&amp;\" />;\n"); // test("<a b=\"&amp;\"></a>", "<a b=\"&amp;\" />;\n");
test("<a>x</a>", "<a>x</a>;\n"); test("<a>x</a>", "<a>x</a>;\n");
test("<a>x\ny</a>", "<a>x\ny</a>;\n"); test("<a>x\ny</a>", "<a>x\ny</a>;\n");
@ -955,14 +953,13 @@ fn test_jsx() {
} }
#[test] #[test]
#[ignore]
fn test_jsx_single_line() { fn test_jsx_single_line() {
test("<x/>", "<x />;\n"); test("<x/>", "<x />;\n");
test("<x y/>", "<x y />;\n"); test("<x y/>", "<x y />;\n");
test("<x\n/>", "<x />;\n"); test("<x\n/>", "<x />;\n");
test("<x\ny/>", "<x\n y\n/>;\n"); // test("<x\ny/>", "<x\n\ty\n/>;\n");
test("<x y\n/>", "<x\n y\n/>;\n"); // test("<x y\n/>", "<x\n\ty\n/>;\n");
test("<x\n{...y}/>", "<x\n {...y}\n/>;\n"); // test("<x\n{...y}/>", "<x\n\t{...y}\n/>;\n");
test_minify("<x/>", "<x/>;"); test_minify("<x/>", "<x/>;");
test_minify("<x y/>", "<x y/>;"); test_minify("<x y/>", "<x y/>;");
@ -1075,8 +1072,9 @@ fn test_binary_operator_visitor() {
// testMangle(t, "x = (0, /*a*/ (0, /*b*/ (0, /*c*/ 1 == 2) + 3) * 4)", "x = /*a*/\n/*b*/\n(/*c*/\n!1 + 3) * 4;\n"); // testMangle(t, "x = (0, /*a*/ (0, /*b*/ (0, /*c*/ 1 == 2) + 3) * 4)", "x = /*a*/\n/*b*/\n(/*c*/\n!1 + 3) * 4;\n");
// Make sure deeply-nested ASTs don't cause a stack overflow // Make sure deeply-nested ASTs don't cause a stack overflow
// x := "x = f()" + strings.Repeat(" || f()", 10_000) + ";\n" // FIXME:
// test( x, x) // let x = format!("x = f(){};\n", " || f()".repeat(2)); // TODO: change this to 10_000
// test(&x, &x);
} }
// See: https://github.com/tc39/proposal-explicit-resource-management // See: https://github.com/tc39/proposal-explicit-resource-management

View file

@ -89,7 +89,6 @@ impl<'a> ParserImpl<'a> {
} }
fn parse_rest_binding(&mut self) -> Result<BindingRestElement<'a>> { fn parse_rest_binding(&mut self) -> Result<BindingRestElement<'a>> {
// self.eat_decorators()?;
let elem = self.parse_rest_element()?; let elem = self.parse_rest_element()?;
if self.at(Kind::Comma) { if self.at(Kind::Comma) {
if matches!(self.peek_kind(), Kind::RCurly | Kind::RBrack) { if matches!(self.peek_kind(), Kind::RCurly | Kind::RBrack) {

View file

@ -434,15 +434,8 @@ impl<'a> ParserImpl<'a> {
) -> Result<ClassElement<'a>> { ) -> Result<ClassElement<'a>> {
let type_annotation = let type_annotation =
if self.ts_enabled() { self.parse_ts_type_annotation()? } else { None }; if self.ts_enabled() { self.parse_ts_type_annotation()? } else { None };
let value = if self.eat(Kind::Eq) { let decorators = self.consume_decorators();
// let current_flags = self.scope.current_flags(); let value = if self.eat(Kind::Eq) { Some(self.parse_expr()?) } else { None };
// self.scope.set_current_flags(self.scope.current_flags());
let expr = self.parse_expr()?;
// self.scope.set_current_flags(current_flags);
Some(expr)
} else {
None
};
self.asi()?; self.asi()?;
let r#type = if r#abstract { let r#type = if r#abstract {
@ -464,7 +457,7 @@ impl<'a> ParserImpl<'a> {
accessibility, accessibility,
optional, optional,
definite, definite,
decorators: self.consume_decorators(), decorators,
}; };
Ok(ClassElement::PropertyDefinition(self.ast.alloc(property_definition))) Ok(ClassElement::PropertyDefinition(self.ast.alloc(property_definition)))
} }