diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index e144ee8d2473b..0fcd39939f3dd 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -1731,8 +1731,8 @@ impl<'a, const MINIFY: bool> GenExpr for UnaryExpression<'a> { impl<'a, const MINIFY: bool> GenExpr for BinaryExpression<'a> { fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) { let mut ctx = ctx; - let wrap_in = self.operator == BinaryOperator::In && ctx.intersects(Context::FORBID_IN); - let wrap = precedence >= self.precedence() || wrap_in; + let wrap = precedence >= self.precedence() + || (self.operator == BinaryOperator::In && ctx.intersects(Context::FORBID_IN)); if wrap { ctx &= Context::FORBID_IN.not(); } @@ -2333,7 +2333,14 @@ impl<'a, const MINIFY: bool> Gen for JSXOpeningElement<'a> { p.print_char(b'<'); self.name.gen(p, ctx); for attr in &self.attributes { - p.print_hard_space(); + match attr { + JSXAttributeItem::Attribute(_) => { + p.print_hard_space(); + } + JSXAttributeItem::SpreadAttribute(_) => { + p.print_soft_space(); + } + } attr.gen(p, ctx); } if self.self_closing { diff --git a/crates/oxc_codegen/tests/integration/esbuild.rs b/crates/oxc_codegen/tests/integration/esbuild.rs index 2cb726f020ed1..d65fe0faf7477 100644 --- a/crates/oxc_codegen/tests/integration/esbuild.rs +++ b/crates/oxc_codegen/tests/integration/esbuild.rs @@ -373,7 +373,7 @@ fn test_template() { #[test] fn test_object() { - // test("let x = {'(':')'}", "let x = { \"(\": \");\" };\n"); + test("let x = {'(':')'}", "let x = { \"(\": \")\" };\n"); test("({})", "({});\n"); test("({}.x)", "({}).x;\n"); test("({} = {})", "({} = {});\n"); @@ -601,11 +601,10 @@ fn test_private_identifiers() { } #[test] -#[ignore] 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 {}}" - // test( example, "class Foo {\n @w\n w;\n @x x;\n @a1\n @b1 @b2\n @c1 @c2 @c3\n "+ - // "y = @y1 @y2 class {\n };\n @a1\n @b1 @b2\n @c1 @c2 @c3 z = @z1 @z2 class {\n };\n}\n"); + 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 {}}"; + 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"; + 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{}}"); } @@ -878,7 +877,6 @@ fn test_ascii_only() { } #[test] -#[ignore] fn test_jsx() { test("", ";\n"); test("", ";\n"); @@ -886,18 +884,18 @@ fn test_jsx() { test("", ";\n"); test("", ";\n"); test("", ";\n"); - test("", ";\n"); - test("", ";\n"); - - test("", ";\n"); - test("", ";\n"); - test("", ";\n"); - test("", ";\n"); - test("", ";\n"); - test("", ";\n"); - test("", ";\n"); - test("", ";\n"); - test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); + + // test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); test("x", "x;\n"); test("x\ny", "x\ny;\n"); @@ -955,14 +953,13 @@ fn test_jsx() { } #[test] -#[ignore] fn test_jsx_single_line() { test("", ";\n"); test("", ";\n"); test("", ";\n"); - test("", ";\n"); - test("", ";\n"); - test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); + // test("", ";\n"); test_minify("", ";"); test_minify("", ";"); @@ -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"); // Make sure deeply-nested ASTs don't cause a stack overflow - // x := "x = f()" + strings.Repeat(" || f()", 10_000) + ";\n" - // test( x, x) + // FIXME: + // 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 diff --git a/crates/oxc_parser/src/js/binding.rs b/crates/oxc_parser/src/js/binding.rs index 5cb439120d994..450097676c92d 100644 --- a/crates/oxc_parser/src/js/binding.rs +++ b/crates/oxc_parser/src/js/binding.rs @@ -89,7 +89,6 @@ impl<'a> ParserImpl<'a> { } fn parse_rest_binding(&mut self) -> Result> { - // self.eat_decorators()?; let elem = self.parse_rest_element()?; if self.at(Kind::Comma) { if matches!(self.peek_kind(), Kind::RCurly | Kind::RBrack) { diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index f606af61cf96a..363a3b3475cb9 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -434,15 +434,8 @@ impl<'a> ParserImpl<'a> { ) -> Result> { let type_annotation = if self.ts_enabled() { self.parse_ts_type_annotation()? } else { None }; - let value = if self.eat(Kind::Eq) { - // let current_flags = self.scope.current_flags(); - // 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 - }; + let decorators = self.consume_decorators(); + let value = if self.eat(Kind::Eq) { Some(self.parse_expr()?) } else { None }; self.asi()?; let r#type = if r#abstract { @@ -464,7 +457,7 @@ impl<'a> ParserImpl<'a> { accessibility, optional, definite, - decorators: self.consume_decorators(), + decorators, }; Ok(ClassElement::PropertyDefinition(self.ast.alloc(property_definition))) }