From f10ca0e172fc804daafe346d55ca1090ccf4c288 Mon Sep 17 00:00:00 2001 From: William Tetlow Date: Tue, 22 Feb 2022 19:26:38 +0000 Subject: [PATCH 1/5] handle trailing commad after arrow fn --- crates/swc_ecma_parser/src/parser/expr.rs | 2 +- crates/swc_ecma_parser/src/parser/expr/tests.rs | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/swc_ecma_parser/src/parser/expr.rs b/crates/swc_ecma_parser/src/parser/expr.rs index 2d56cc509d46..90c1a1dfc7c5 100644 --- a/crates/swc_ecma_parser/src/parser/expr.rs +++ b/crates/swc_ecma_parser/src/parser/expr.rs @@ -707,7 +707,7 @@ impl<'a, I: Tokens> Parser { params.is_simple_parameter_list(), )?; - if is_direct_child_of_cond && !is_one_of!(p, ':', ';') { + if is_direct_child_of_cond && !is_one_of!(p, ':', ';', ',') { trace_cur!(p, parse_arrow_in_cond__fail); unexpected!(p, "fail") } diff --git a/crates/swc_ecma_parser/src/parser/expr/tests.rs b/crates/swc_ecma_parser/src/parser/expr/tests.rs index 11294d76a4aa..d6236c7b856e 100644 --- a/crates/swc_ecma_parser/src/parser/expr/tests.rs +++ b/crates/swc_ecma_parser/src/parser/expr/tests.rs @@ -494,6 +494,17 @@ fn super_expr_computed() { ); } +#[test] +fn issue_3672() { + test_parser( + "report({ + fix: fixable ? null : (): RuleFix => {}, +});", + Syntax::Typescript(Default::default()), + |p| p.parse_module(), + ); +} + #[bench] fn bench_new_expr_ts(b: &mut Bencher) { bench_parser( From f6f06233a1415855adfaaf65a4f57692ffc88afc Mon Sep 17 00:00:00 2001 From: William Tetlow Date: Fri, 25 Feb 2022 09:37:56 +0000 Subject: [PATCH 2/5] allow ) after arrow func and remove test --- crates/swc_ecma_parser/src/parser/expr.rs | 13 +- .../swc_ecma_parser/src/parser/expr/tests.rs | 11 +- .../typescript/issue-2174/case1/input.ts | 5 - .../typescript/issue-2174/case1/input.ts.json | 160 ------------------ .../typescript/issue-2174/case2/input.tsx | 5 - .../issue-2174/case2/input.tsx.json | 160 ------------------ 6 files changed, 21 insertions(+), 333 deletions(-) delete mode 100644 crates/swc_ecma_parser/tests/typescript/issue-2174/case1/input.ts delete mode 100644 crates/swc_ecma_parser/tests/typescript/issue-2174/case1/input.ts.json delete mode 100644 crates/swc_ecma_parser/tests/typescript/issue-2174/case2/input.tsx delete mode 100644 crates/swc_ecma_parser/tests/typescript/issue-2174/case2/input.tsx.json diff --git a/crates/swc_ecma_parser/src/parser/expr.rs b/crates/swc_ecma_parser/src/parser/expr.rs index 90c1a1dfc7c5..d5d3d1bee552 100644 --- a/crates/swc_ecma_parser/src/parser/expr.rs +++ b/crates/swc_ecma_parser/src/parser/expr.rs @@ -667,7 +667,7 @@ impl<'a, I: Tokens> Parser { trace_cur!(self, parse_paren_expr_or_arrow_fn); let expr_start = async_span.map(|x| x.lo()).unwrap_or_else(|| cur_pos!(self)); - + println!("{:?}", &expr_start); // At this point, we can't know if it's parenthesized // expression or head of arrow function. // But as all patterns of javascript is subset of @@ -688,9 +688,17 @@ impl<'a, I: Tokens> Parser { let is_direct_child_of_cond = self.ctx().is_direct_child_of_cond; // This is slow path. We handle arrow in conditional expression. + // so we parse the expression body and then it checks this which passes but + // actually we don't want to enter here at all + // we want to return expr + if self.syntax().typescript() && self.ctx().in_cond_expr && is!(self, ':') { + println!("{:#?}", self.ctx()); + println!("{:#?}", paren_items); + println!("{}", can_be_arrow); // TODO: Remove clone let items_ref = &paren_items; + // let colon_pos = cur_pos!(self); if let Some(expr) = self.try_parse_ts(|p| { let return_type = p.parse_ts_type_or_type_predicate_ann(&tok!(':'))?; @@ -707,7 +715,7 @@ impl<'a, I: Tokens> Parser { params.is_simple_parameter_list(), )?; - if is_direct_child_of_cond && !is_one_of!(p, ':', ';', ',') { + if is_direct_child_of_cond && !is_one_of!(p, ':', ';', ',', ')') { trace_cur!(p, parse_arrow_in_cond__fail); unexpected!(p, "fail") } @@ -722,6 +730,7 @@ impl<'a, I: Tokens> Parser { type_params: None, })))) }) { + println!("{:#?}", &expr); return Ok(expr); } } diff --git a/crates/swc_ecma_parser/src/parser/expr/tests.rs b/crates/swc_ecma_parser/src/parser/expr/tests.rs index d6236c7b856e..29a0ad7de6aa 100644 --- a/crates/swc_ecma_parser/src/parser/expr/tests.rs +++ b/crates/swc_ecma_parser/src/parser/expr/tests.rs @@ -495,7 +495,7 @@ fn super_expr_computed() { } #[test] -fn issue_3672() { +fn issue_3672_1() { test_parser( "report({ fix: fixable ? null : (): RuleFix => {}, @@ -505,6 +505,15 @@ fn issue_3672() { ); } +#[test] +fn issue_3672_2() { + test_parser( + "f(a ? (): void => { } : (): void => { })", + Syntax::Typescript(Default::default()), + |p| p.parse_module(), + ); +} + #[bench] fn bench_new_expr_ts(b: &mut Bencher) { bench_parser( diff --git a/crates/swc_ecma_parser/tests/typescript/issue-2174/case1/input.ts b/crates/swc_ecma_parser/tests/typescript/issue-2174/case1/input.ts deleted file mode 100644 index 063d1f7bc403..000000000000 --- a/crates/swc_ecma_parser/tests/typescript/issue-2174/case1/input.ts +++ /dev/null @@ -1,5 +0,0 @@ -const x = { - prop: isCorrect - ? fn => ({ }) - : fn => true, -}; \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/typescript/issue-2174/case1/input.ts.json b/crates/swc_ecma_parser/tests/typescript/issue-2174/case1/input.ts.json deleted file mode 100644 index a8f94e67b146..000000000000 --- a/crates/swc_ecma_parser/tests/typescript/issue-2174/case1/input.ts.json +++ /dev/null @@ -1,160 +0,0 @@ -{ - "type": "Script", - "span": { - "start": 0, - "end": 82, - "ctxt": 0 - }, - "body": [ - { - "type": "VariableDeclaration", - "span": { - "start": 0, - "end": 82, - "ctxt": 0 - }, - "kind": "const", - "declare": false, - "declarations": [ - { - "type": "VariableDeclarator", - "span": { - "start": 6, - "end": 81, - "ctxt": 0 - }, - "id": { - "type": "Identifier", - "span": { - "start": 6, - "end": 7, - "ctxt": 0 - }, - "value": "x", - "optional": false, - "typeAnnotation": null - }, - "init": { - "type": "ObjectExpression", - "span": { - "start": 10, - "end": 81, - "ctxt": 0 - }, - "properties": [ - { - "type": "KeyValueProperty", - "key": { - "type": "Identifier", - "span": { - "start": 16, - "end": 20, - "ctxt": 0 - }, - "value": "prop", - "optional": false - }, - "value": { - "type": "ConditionalExpression", - "span": { - "start": 22, - "end": 78, - "ctxt": 0 - }, - "test": { - "type": "Identifier", - "span": { - "start": 22, - "end": 31, - "ctxt": 0 - }, - "value": "isCorrect", - "optional": false - }, - "consequent": { - "type": "ArrowFunctionExpression", - "span": { - "start": 42, - "end": 53, - "ctxt": 0 - }, - "params": [ - { - "type": "Identifier", - "span": { - "start": 42, - "end": 44, - "ctxt": 0 - }, - "value": "fn", - "optional": false, - "typeAnnotation": null - } - ], - "body": { - "type": "ParenthesisExpression", - "span": { - "start": 48, - "end": 53, - "ctxt": 0 - }, - "expression": { - "type": "ObjectExpression", - "span": { - "start": 49, - "end": 52, - "ctxt": 0 - }, - "properties": [] - } - }, - "async": false, - "generator": false, - "typeParameters": null, - "returnType": null - }, - "alternate": { - "type": "ArrowFunctionExpression", - "span": { - "start": 68, - "end": 78, - "ctxt": 0 - }, - "params": [ - { - "type": "Identifier", - "span": { - "start": 68, - "end": 70, - "ctxt": 0 - }, - "value": "fn", - "optional": false, - "typeAnnotation": null - } - ], - "body": { - "type": "BooleanLiteral", - "span": { - "start": 74, - "end": 78, - "ctxt": 0 - }, - "value": true - }, - "async": false, - "generator": false, - "typeParameters": null, - "returnType": null - } - } - } - ] - }, - "definite": false - } - ] - } - ], - "interpreter": null -} diff --git a/crates/swc_ecma_parser/tests/typescript/issue-2174/case2/input.tsx b/crates/swc_ecma_parser/tests/typescript/issue-2174/case2/input.tsx deleted file mode 100644 index 063d1f7bc403..000000000000 --- a/crates/swc_ecma_parser/tests/typescript/issue-2174/case2/input.tsx +++ /dev/null @@ -1,5 +0,0 @@ -const x = { - prop: isCorrect - ? fn => ({ }) - : fn => true, -}; \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/typescript/issue-2174/case2/input.tsx.json b/crates/swc_ecma_parser/tests/typescript/issue-2174/case2/input.tsx.json deleted file mode 100644 index a8f94e67b146..000000000000 --- a/crates/swc_ecma_parser/tests/typescript/issue-2174/case2/input.tsx.json +++ /dev/null @@ -1,160 +0,0 @@ -{ - "type": "Script", - "span": { - "start": 0, - "end": 82, - "ctxt": 0 - }, - "body": [ - { - "type": "VariableDeclaration", - "span": { - "start": 0, - "end": 82, - "ctxt": 0 - }, - "kind": "const", - "declare": false, - "declarations": [ - { - "type": "VariableDeclarator", - "span": { - "start": 6, - "end": 81, - "ctxt": 0 - }, - "id": { - "type": "Identifier", - "span": { - "start": 6, - "end": 7, - "ctxt": 0 - }, - "value": "x", - "optional": false, - "typeAnnotation": null - }, - "init": { - "type": "ObjectExpression", - "span": { - "start": 10, - "end": 81, - "ctxt": 0 - }, - "properties": [ - { - "type": "KeyValueProperty", - "key": { - "type": "Identifier", - "span": { - "start": 16, - "end": 20, - "ctxt": 0 - }, - "value": "prop", - "optional": false - }, - "value": { - "type": "ConditionalExpression", - "span": { - "start": 22, - "end": 78, - "ctxt": 0 - }, - "test": { - "type": "Identifier", - "span": { - "start": 22, - "end": 31, - "ctxt": 0 - }, - "value": "isCorrect", - "optional": false - }, - "consequent": { - "type": "ArrowFunctionExpression", - "span": { - "start": 42, - "end": 53, - "ctxt": 0 - }, - "params": [ - { - "type": "Identifier", - "span": { - "start": 42, - "end": 44, - "ctxt": 0 - }, - "value": "fn", - "optional": false, - "typeAnnotation": null - } - ], - "body": { - "type": "ParenthesisExpression", - "span": { - "start": 48, - "end": 53, - "ctxt": 0 - }, - "expression": { - "type": "ObjectExpression", - "span": { - "start": 49, - "end": 52, - "ctxt": 0 - }, - "properties": [] - } - }, - "async": false, - "generator": false, - "typeParameters": null, - "returnType": null - }, - "alternate": { - "type": "ArrowFunctionExpression", - "span": { - "start": 68, - "end": 78, - "ctxt": 0 - }, - "params": [ - { - "type": "Identifier", - "span": { - "start": 68, - "end": 70, - "ctxt": 0 - }, - "value": "fn", - "optional": false, - "typeAnnotation": null - } - ], - "body": { - "type": "BooleanLiteral", - "span": { - "start": 74, - "end": 78, - "ctxt": 0 - }, - "value": true - }, - "async": false, - "generator": false, - "typeParameters": null, - "returnType": null - } - } - } - ] - }, - "definite": false - } - ] - } - ], - "interpreter": null -} From 80be8b2765148743e095ccf823346a2f21854ad9 Mon Sep 17 00:00:00 2001 From: William Tetlow Date: Fri, 25 Feb 2022 10:08:59 +0000 Subject: [PATCH 3/5] remove debug logs --- crates/swc_ecma_parser/src/parser/expr.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/crates/swc_ecma_parser/src/parser/expr.rs b/crates/swc_ecma_parser/src/parser/expr.rs index d5d3d1bee552..814e084145e4 100644 --- a/crates/swc_ecma_parser/src/parser/expr.rs +++ b/crates/swc_ecma_parser/src/parser/expr.rs @@ -667,7 +667,6 @@ impl<'a, I: Tokens> Parser { trace_cur!(self, parse_paren_expr_or_arrow_fn); let expr_start = async_span.map(|x| x.lo()).unwrap_or_else(|| cur_pos!(self)); - println!("{:?}", &expr_start); // At this point, we can't know if it's parenthesized // expression or head of arrow function. // But as all patterns of javascript is subset of @@ -688,14 +687,7 @@ impl<'a, I: Tokens> Parser { let is_direct_child_of_cond = self.ctx().is_direct_child_of_cond; // This is slow path. We handle arrow in conditional expression. - // so we parse the expression body and then it checks this which passes but - // actually we don't want to enter here at all - // we want to return expr - if self.syntax().typescript() && self.ctx().in_cond_expr && is!(self, ':') { - println!("{:#?}", self.ctx()); - println!("{:#?}", paren_items); - println!("{}", can_be_arrow); // TODO: Remove clone let items_ref = &paren_items; // let colon_pos = cur_pos!(self); @@ -730,7 +722,6 @@ impl<'a, I: Tokens> Parser { type_params: None, })))) }) { - println!("{:#?}", &expr); return Ok(expr); } } From 21afd67d777f5a4cedffe4f163bad13991155de5 Mon Sep 17 00:00:00 2001 From: William Tetlow Date: Fri, 25 Feb 2022 10:09:55 +0000 Subject: [PATCH 4/5] remove debug code --- crates/swc_ecma_parser/src/parser/expr.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/swc_ecma_parser/src/parser/expr.rs b/crates/swc_ecma_parser/src/parser/expr.rs index 814e084145e4..e5bb9f2f172f 100644 --- a/crates/swc_ecma_parser/src/parser/expr.rs +++ b/crates/swc_ecma_parser/src/parser/expr.rs @@ -690,7 +690,6 @@ impl<'a, I: Tokens> Parser { if self.syntax().typescript() && self.ctx().in_cond_expr && is!(self, ':') { // TODO: Remove clone let items_ref = &paren_items; - // let colon_pos = cur_pos!(self); if let Some(expr) = self.try_parse_ts(|p| { let return_type = p.parse_ts_type_or_type_predicate_ann(&tok!(':'))?; From 116a9723c3a48cd16688106a9db81001059f0b6d Mon Sep 17 00:00:00 2001 From: William Tetlow Date: Fri, 25 Feb 2022 10:10:45 +0000 Subject: [PATCH 5/5] no whitespace change --- crates/swc_ecma_parser/src/parser/expr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/swc_ecma_parser/src/parser/expr.rs b/crates/swc_ecma_parser/src/parser/expr.rs index e5bb9f2f172f..66777a7951ad 100644 --- a/crates/swc_ecma_parser/src/parser/expr.rs +++ b/crates/swc_ecma_parser/src/parser/expr.rs @@ -667,6 +667,7 @@ impl<'a, I: Tokens> Parser { trace_cur!(self, parse_paren_expr_or_arrow_fn); let expr_start = async_span.map(|x| x.lo()).unwrap_or_else(|| cur_pos!(self)); + // At this point, we can't know if it's parenthesized // expression or head of arrow function. // But as all patterns of javascript is subset of