From 798a1fde09e1f1c2f5cca039b874b4a2ec6ecd2a Mon Sep 17 00:00:00 2001 From: Boshen Date: Fri, 15 Mar 2024 13:39:20 +0800 Subject: [PATCH] fix(parser): fix failed to parse `JSXChild` after `JSXEmptyExpression` (#2726) fixes #2723 --- crates/oxc_parser/Cargo.toml | 2 +- crates/oxc_parser/src/jsx/mod.rs | 18 +++++++++++------- tasks/coverage/codegen_misc.snap | 4 ++-- tasks/coverage/misc/pass/oxc-2723.jsx | 13 +++++++++++++ tasks/coverage/parser_misc.snap | 4 ++-- tasks/coverage/prettier_misc.snap | 5 +++-- 6 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 tasks/coverage/misc/pass/oxc-2723.jsx diff --git a/crates/oxc_parser/Cargo.toml b/crates/oxc_parser/Cargo.toml index bfb83c235..30dbeffdd 100644 --- a/crates/oxc_parser/Cargo.toml +++ b/crates/oxc_parser/Cargo.toml @@ -34,7 +34,7 @@ seq-macro = { workspace = true } memchr = "2.7.1" [dev-dependencies] -oxc_ast = { workspace = true } +oxc_ast = { workspace = true, features = ["serialize"] } miette = { workspace = true } serde_json = { workspace = true } ouroboros = "0.18.3" # for `multi-thread` example diff --git a/crates/oxc_parser/src/jsx/mod.rs b/crates/oxc_parser/src/jsx/mod.rs index 7bcfe1b02..33fe6de56 100644 --- a/crates/oxc_parser/src/jsx/mod.rs +++ b/crates/oxc_parser/src/jsx/mod.rs @@ -215,7 +215,7 @@ impl<'a> ParserImpl<'a> { } // {expr} Kind::LCurly => self - .parse_jsx_expression_container(true) + .parse_jsx_expression_container(/* is_jsx_child */ true) .map(JSXChild::ExpressionContainer) .map(Some), // text @@ -232,13 +232,17 @@ impl<'a> ParserImpl<'a> { let span = self.start_span(); self.bump_any(); // bump `{` - let expr = if self.eat(Kind::RCurly) { + let expr = if self.at(Kind::RCurly) { + if in_jsx_child { + self.expect_jsx_child(Kind::RCurly) + } else { + self.expect(Kind::RCurly) + }?; + let span = self.end_span(span); // Handle comment between curly braces (ex. `{/* comment */}`) // ^^^^^^^^^^^^^ span - let span = self.end_span(span); - JSXExpression::EmptyExpression( - self.ast.jsx_empty_expression(Span::new(span.start + 1, span.end - 1)), - ) + let expr = self.ast.jsx_empty_expression(Span::new(span.start + 1, span.end - 1)); + JSXExpression::EmptyExpression(expr) } else { let expr = self.parse_jsx_assignment_expression().map(JSXExpression::Expression)?; if in_jsx_child { @@ -339,7 +343,7 @@ impl<'a> ParserImpl<'a> { match self.cur_kind() { Kind::Str => self.parse_literal_string().map(JSXAttributeValue::StringLiteral), Kind::LCurly => { - let expr = self.parse_jsx_expression_container(false)?; + let expr = self.parse_jsx_expression_container(/* is_jsx_child */ false)?; Ok(JSXAttributeValue::ExpressionContainer(expr)) } Kind::LAngle => { diff --git a/tasks/coverage/codegen_misc.snap b/tasks/coverage/codegen_misc.snap index 7fe960a68..8844037bd 100644 --- a/tasks/coverage/codegen_misc.snap +++ b/tasks/coverage/codegen_misc.snap @@ -1,3 +1,3 @@ codegen_misc Summary: -AST Parsed : 14/14 (100.00%) -Positive Passed: 14/14 (100.00%) +AST Parsed : 15/15 (100.00%) +Positive Passed: 15/15 (100.00%) diff --git a/tasks/coverage/misc/pass/oxc-2723.jsx b/tasks/coverage/misc/pass/oxc-2723.jsx new file mode 100644 index 000000000..b004f9f88 --- /dev/null +++ b/tasks/coverage/misc/pass/oxc-2723.jsx @@ -0,0 +1,13 @@ +const A = ( +
+ {/* comment */} + AAAA +
+); + +const B = ( +
+ BBBB + {/* comment */} +
+); diff --git a/tasks/coverage/parser_misc.snap b/tasks/coverage/parser_misc.snap index 4a6c8f05e..842ba718e 100644 --- a/tasks/coverage/parser_misc.snap +++ b/tasks/coverage/parser_misc.snap @@ -1,6 +1,6 @@ parser_misc Summary: -AST Parsed : 14/14 (100.00%) -Positive Passed: 14/14 (100.00%) +AST Parsed : 15/15 (100.00%) +Positive Passed: 15/15 (100.00%) Negative Passed: 8/8 (100.00%) × Unexpected token diff --git a/tasks/coverage/prettier_misc.snap b/tasks/coverage/prettier_misc.snap index 6c052f32d..5406892e6 100644 --- a/tasks/coverage/prettier_misc.snap +++ b/tasks/coverage/prettier_misc.snap @@ -1,9 +1,10 @@ prettier_misc Summary: -AST Parsed : 14/14 (100.00%) -Positive Passed: 8/14 (57.14%) +AST Parsed : 15/15 (100.00%) +Positive Passed: 8/15 (53.33%) Expect to Parse: "pass/oxc-1740.tsx" Expect to Parse: "pass/oxc-2087.ts" Expect to Parse: "pass/oxc-2394.ts" Expect to Parse: "pass/oxc-2674.tsx" +Expect to Parse: "pass/oxc-2723.jsx" Expect to Parse: "pass/swc-1627.js" Expect to Parse: "pass/swc-8243.tsx"