From 7f5d3a4db18e34d3f4e8a3e5ab6e745a92e59190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Wed, 23 Oct 2019 20:44:22 +0900 Subject: [PATCH] Fix parsing of single untyped param in IIFE Closes #433 --- ecmascript/parser/src/parser/expr/mod.rs | 42 ++- .../fail/7f9bbf314145e16f.js.stderr | 6 +- .../typescript/custom/issue-433-1/input.ts | 1 + .../custom/issue-433-1/input.ts.json | 203 +++++++++++++++ .../typescript/custom/issue-433-2/input.ts | 1 + .../custom/issue-433-2/input.ts.json | 240 ++++++++++++++++++ 6 files changed, 488 insertions(+), 5 deletions(-) create mode 100644 ecmascript/parser/tests/typescript/custom/issue-433-1/input.ts create mode 100644 ecmascript/parser/tests/typescript/custom/issue-433-1/input.ts.json create mode 100644 ecmascript/parser/tests/typescript/custom/issue-433-2/input.ts create mode 100644 ecmascript/parser/tests/typescript/custom/issue-433-2/input.ts.json diff --git a/ecmascript/parser/src/parser/expr/mod.rs b/ecmascript/parser/src/parser/expr/mod.rs index b716afb55d1..bce2d4a938e 100644 --- a/ecmascript/parser/src/parser/expr/mod.rs +++ b/ecmascript/parser/src/parser/expr/mod.rs @@ -999,8 +999,6 @@ impl<'a, I: Input> Parser<'a, I> { // as a pattern instead of reparsing) while !eof!() && !is!(')') { if first { - first = false; - if is!("async") { // https://github.com/swc-project/swc/issues/410 self.state.potential_arrow_start = Some(cur_pos!()); @@ -1159,6 +1157,46 @@ impl<'a, I: Input> Parser<'a, I> { } else { items.push(PatOrExprOrSpread::ExprOrSpread(arg)); } + + // https://github.com/swc-project/swc/issues/433 + if first && eat!("=>") && { + debug_assert_eq!(items.len(), 1); + match items[0] { + PatOrExprOrSpread::ExprOrSpread(ExprOrSpread { ref expr, .. }) + | PatOrExprOrSpread::Pat(Pat::Expr(ref expr)) => match **expr { + Expr::Ident(..) => true, + _ => false, + }, + PatOrExprOrSpread::Pat(Pat::Ident(..)) => true, + _ => false, + } + } { + let params = self + .parse_paren_items_as_params(items)? + .into_iter() + .collect(); + + let body: BlockStmtOrExpr = self.parse_fn_body(false, false)?; + expect!(')'); + let span = span!(start); + return Ok(vec![PatOrExprOrSpread::ExprOrSpread(ExprOrSpread { + expr: Box::new( + ArrowExpr { + span, + body, + is_async: false, + is_generator: false, + params, + type_params: None, + return_type: None, + } + .into(), + ), + spread: None, + })]); + } + + first = false; } expect!(')'); diff --git a/ecmascript/parser/tests/test262-error-references/fail/7f9bbf314145e16f.js.stderr b/ecmascript/parser/tests/test262-error-references/fail/7f9bbf314145e16f.js.stderr index 3df5d0c2748..7a8ecf05f38 100644 --- a/ecmascript/parser/tests/test262-error-references/fail/7f9bbf314145e16f.js.stderr +++ b/ecmascript/parser/tests/test262-error-references/fail/7f9bbf314145e16f.js.stderr @@ -1,6 +1,6 @@ -error: Expected Comma, got Some(Arrow) - --> $DIR/tests/test262-parser/fail/7f9bbf314145e16f.js:1:4 +error: Expected Comma, got Some(Num(0.0)) + --> $DIR/tests/test262-parser/fail/7f9bbf314145e16f.js:1:6 | 1 | ({}=>0) - | ^^ + | ^ diff --git a/ecmascript/parser/tests/typescript/custom/issue-433-1/input.ts b/ecmascript/parser/tests/typescript/custom/issue-433-1/input.ts new file mode 100644 index 00000000000..ed97112378b --- /dev/null +++ b/ecmascript/parser/tests/typescript/custom/issue-433-1/input.ts @@ -0,0 +1 @@ +const result = (x => x)(1); diff --git a/ecmascript/parser/tests/typescript/custom/issue-433-1/input.ts.json b/ecmascript/parser/tests/typescript/custom/issue-433-1/input.ts.json new file mode 100644 index 00000000000..0495308ff8d --- /dev/null +++ b/ecmascript/parser/tests/typescript/custom/issue-433-1/input.ts.json @@ -0,0 +1,203 @@ +{ + "type": "Module", + "span": { + "start": 0, + "end": 27, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + } + }, + "body": [ + { + "type": "VariableDeclaration", + "span": { + "start": 0, + "end": 27, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 27 + } + } + }, + "kind": "const", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 6, + "end": 26, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 26 + } + } + }, + "id": { + "type": "Identifier", + "span": { + "start": 6, + "end": 12, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 12 + } + } + }, + "value": "result", + "optional": false + }, + "init": { + "type": "CallExpression", + "span": { + "start": 15, + "end": 26, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 26 + } + } + }, + "callee": { + "type": "ParenthesisExpression", + "span": { + "start": 15, + "end": 23, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + "expression": { + "type": "ArrowFunctionExpression", + "span": { + "start": 16, + "end": 23, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + "params": [ + { + "type": "Identifier", + "span": { + "start": 16, + "end": 17, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 17 + } + } + }, + "value": "x", + "optional": false + } + ], + "body": { + "type": "Identifier", + "span": { + "start": 21, + "end": 22, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 22 + } + } + }, + "value": "x", + "optional": false + }, + "async": false, + "generator": false + } + }, + "arguments": [ + { + "expr": { + "type": "NumericLiteral", + "span": { + "start": 24, + "end": 25, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 24 + }, + "end": { + "line": 1, + "column": 25 + } + } + }, + "value": 1.0 + } + } + ], + "typeArguments": null + }, + "definite": false + } + ] + } + ] +} diff --git a/ecmascript/parser/tests/typescript/custom/issue-433-2/input.ts b/ecmascript/parser/tests/typescript/custom/issue-433-2/input.ts new file mode 100644 index 00000000000..7ef6e77f8c9 --- /dev/null +++ b/ecmascript/parser/tests/typescript/custom/issue-433-2/input.ts @@ -0,0 +1 @@ +const result2 = ((x: number) => x)(1); diff --git a/ecmascript/parser/tests/typescript/custom/issue-433-2/input.ts.json b/ecmascript/parser/tests/typescript/custom/issue-433-2/input.ts.json new file mode 100644 index 00000000000..f33d79940f7 --- /dev/null +++ b/ecmascript/parser/tests/typescript/custom/issue-433-2/input.ts.json @@ -0,0 +1,240 @@ +{ + "type": "Module", + "span": { + "start": 0, + "end": 38, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 38 + } + } + }, + "body": [ + { + "type": "VariableDeclaration", + "span": { + "start": 0, + "end": 38, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 38 + } + } + }, + "kind": "const", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 6, + "end": 37, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 37 + } + } + }, + "id": { + "type": "Identifier", + "span": { + "start": 6, + "end": 13, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 13 + } + } + }, + "value": "result2", + "optional": false + }, + "init": { + "type": "CallExpression", + "span": { + "start": 16, + "end": 37, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 37 + } + } + }, + "callee": { + "type": "ParenthesisExpression", + "span": { + "start": 16, + "end": 34, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 34 + } + } + }, + "expression": { + "type": "ArrowFunctionExpression", + "span": { + "start": 17, + "end": 33, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 17 + }, + "end": { + "line": 1, + "column": 33 + } + } + }, + "params": [ + { + "type": "Identifier", + "span": { + "start": 18, + "end": 19, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 19 + } + } + }, + "value": "x", + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 19, + "end": 27, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 27 + } + } + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 21, + "end": 27, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 21 + }, + "end": { + "line": 1, + "column": 27 + } + } + }, + "kind": "number" + } + }, + "optional": false + } + ], + "body": { + "type": "Identifier", + "span": { + "start": 32, + "end": 33, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 33 + } + } + }, + "value": "x", + "optional": false + }, + "async": false, + "generator": false + } + }, + "arguments": [ + { + "expr": { + "type": "NumericLiteral", + "span": { + "start": 35, + "end": 36, + "ctxt": 0, + "loc": { + "start": { + "line": 1, + "column": 35 + }, + "end": { + "line": 1, + "column": 36 + } + } + }, + "value": 1.0 + } + } + ], + "typeArguments": null + }, + "definite": false + } + ] + } + ] +}