From b89937c3c081132e3cf126467476080f29272cdd Mon Sep 17 00:00:00 2001 From: William Tetlow <9057181+williamtetlow@users.noreply.github.com> Date: Thu, 7 Apr 2022 04:15:59 +0100 Subject: [PATCH] fix(es/parser): Adjust context in a function block (#4264) --- .../src/parser/class_and_fn.rs | 8 +- .../typescript/issue-4178/{ => 1}/index.ts | 0 .../issue-4178/{ => 1}/index.ts.json | 0 .../tests/typescript/issue-4178/2/index.ts | 3 + .../typescript/issue-4178/2/index.ts.json | 259 ++++++++++++++++++ .../tests/typescript/issue-4178/3/index.ts | 5 + .../typescript/issue-4178/3/index.ts.json | 229 ++++++++++++++++ 7 files changed, 503 insertions(+), 1 deletion(-) rename crates/swc_ecma_parser/tests/typescript/issue-4178/{ => 1}/index.ts (100%) rename crates/swc_ecma_parser/tests/typescript/issue-4178/{ => 1}/index.ts.json (100%) create mode 100644 crates/swc_ecma_parser/tests/typescript/issue-4178/2/index.ts create mode 100644 crates/swc_ecma_parser/tests/typescript/issue-4178/2/index.ts.json create mode 100644 crates/swc_ecma_parser/tests/typescript/issue-4178/3/index.ts create mode 100644 crates/swc_ecma_parser/tests/typescript/issue-4178/3/index.ts.json diff --git a/crates/swc_ecma_parser/src/parser/class_and_fn.rs b/crates/swc_ecma_parser/src/parser/class_and_fn.rs index 312ecf7ad42..91c3cc96544 100644 --- a/crates/swc_ecma_parser/src/parser/class_and_fn.rs +++ b/crates/swc_ecma_parser/src/parser/class_and_fn.rs @@ -1514,7 +1514,13 @@ fn has_use_strict(block: &BlockStmt) -> Option { impl FnBodyParser for Parser { fn parse_fn_body_inner(&mut self, is_simple_parameter_list: bool) -> PResult { if is!(self, '{') { - self.parse_block(false).map(|block_stmt| { + let cur_ctx = self.ctx(); + let ctx = Context { + is_direct_child_of_braceless_arrow_function: false, + ..cur_ctx + }; + let result = self.with_ctx(ctx).parse_block(false); + result.map(|block_stmt| { if !self.input.syntax().typescript() && !is_simple_parameter_list { if let Some(span) = has_use_strict(&block_stmt) { self.emit_err(span, SyntaxError::IllegalLanguageModeDirective); diff --git a/crates/swc_ecma_parser/tests/typescript/issue-4178/index.ts b/crates/swc_ecma_parser/tests/typescript/issue-4178/1/index.ts similarity index 100% rename from crates/swc_ecma_parser/tests/typescript/issue-4178/index.ts rename to crates/swc_ecma_parser/tests/typescript/issue-4178/1/index.ts diff --git a/crates/swc_ecma_parser/tests/typescript/issue-4178/index.ts.json b/crates/swc_ecma_parser/tests/typescript/issue-4178/1/index.ts.json similarity index 100% rename from crates/swc_ecma_parser/tests/typescript/issue-4178/index.ts.json rename to crates/swc_ecma_parser/tests/typescript/issue-4178/1/index.ts.json diff --git a/crates/swc_ecma_parser/tests/typescript/issue-4178/2/index.ts b/crates/swc_ecma_parser/tests/typescript/issue-4178/2/index.ts new file mode 100644 index 00000000000..e698233b2d2 --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/issue-4178/2/index.ts @@ -0,0 +1,3 @@ +export const x = (a: number) => () => { + const y = a && b ? (z: number): string => "hello" : null +} \ No newline at end of file diff --git a/crates/swc_ecma_parser/tests/typescript/issue-4178/2/index.ts.json b/crates/swc_ecma_parser/tests/typescript/issue-4178/2/index.ts.json new file mode 100644 index 00000000000..ce6bae8ec8a --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/issue-4178/2/index.ts.json @@ -0,0 +1,259 @@ +{ + "type": "Module", + "span": { + "start": 0, + "end": 100, + "ctxt": 0 + }, + "body": [ + { + "type": "ExportDeclaration", + "span": { + "start": 0, + "end": 100, + "ctxt": 0 + }, + "declaration": { + "type": "VariableDeclaration", + "span": { + "start": 7, + "end": 100, + "ctxt": 0 + }, + "kind": "const", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 13, + "end": 100, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 13, + "end": 14, + "ctxt": 0 + }, + "value": "x", + "optional": false, + "typeAnnotation": null + }, + "init": { + "type": "ArrowFunctionExpression", + "span": { + "start": 17, + "end": 100, + "ctxt": 0 + }, + "params": [ + { + "type": "Identifier", + "span": { + "start": 18, + "end": 27, + "ctxt": 0 + }, + "value": "a", + "optional": false, + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 19, + "end": 27, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 21, + "end": 27, + "ctxt": 0 + }, + "kind": "number" + } + } + } + ], + "body": { + "type": "ArrowFunctionExpression", + "span": { + "start": 32, + "end": 100, + "ctxt": 0 + }, + "params": [], + "body": { + "type": "BlockStatement", + "span": { + "start": 38, + "end": 100, + "ctxt": 0 + }, + "stmts": [ + { + "type": "VariableDeclaration", + "span": { + "start": 42, + "end": 98, + "ctxt": 0 + }, + "kind": "const", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 48, + "end": 98, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 48, + "end": 49, + "ctxt": 0 + }, + "value": "y", + "optional": false, + "typeAnnotation": null + }, + "init": { + "type": "ConditionalExpression", + "span": { + "start": 52, + "end": 98, + "ctxt": 0 + }, + "test": { + "type": "BinaryExpression", + "span": { + "start": 52, + "end": 58, + "ctxt": 0 + }, + "operator": "&&", + "left": { + "type": "Identifier", + "span": { + "start": 52, + "end": 53, + "ctxt": 0 + }, + "value": "a", + "optional": false + }, + "right": { + "type": "Identifier", + "span": { + "start": 57, + "end": 58, + "ctxt": 0 + }, + "value": "b", + "optional": false + } + }, + "consequent": { + "type": "ArrowFunctionExpression", + "span": { + "start": 61, + "end": 91, + "ctxt": 0 + }, + "params": [ + { + "type": "Identifier", + "span": { + "start": 62, + "end": 71, + "ctxt": 0 + }, + "value": "z", + "optional": false, + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 63, + "end": 71, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 65, + "end": 71, + "ctxt": 0 + }, + "kind": "number" + } + } + } + ], + "body": { + "type": "StringLiteral", + "span": { + "start": 84, + "end": 91, + "ctxt": 0 + }, + "value": "hello", + "raw": "\"hello\"" + }, + "async": false, + "generator": false, + "typeParameters": null, + "returnType": { + "type": "TsTypeAnnotation", + "span": { + "start": 72, + "end": 80, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 74, + "end": 80, + "ctxt": 0 + }, + "kind": "string" + } + } + }, + "alternate": { + "type": "NullLiteral", + "span": { + "start": 94, + "end": 98, + "ctxt": 0 + } + } + }, + "definite": false + } + ] + } + ] + }, + "async": false, + "generator": false, + "typeParameters": null, + "returnType": null + }, + "async": false, + "generator": false, + "typeParameters": null, + "returnType": null + }, + "definite": false + } + ] + } + } + ], + "interpreter": null +} diff --git a/crates/swc_ecma_parser/tests/typescript/issue-4178/3/index.ts b/crates/swc_ecma_parser/tests/typescript/issue-4178/3/index.ts new file mode 100644 index 00000000000..70e2f25ba1c --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/issue-4178/3/index.ts @@ -0,0 +1,5 @@ +export function x() { + return () => { + const y = a && b ? (z: number): string => "hello" : null; + }; +} diff --git a/crates/swc_ecma_parser/tests/typescript/issue-4178/3/index.ts.json b/crates/swc_ecma_parser/tests/typescript/issue-4178/3/index.ts.json new file mode 100644 index 00000000000..783d5247cdc --- /dev/null +++ b/crates/swc_ecma_parser/tests/typescript/issue-4178/3/index.ts.json @@ -0,0 +1,229 @@ +{ + "type": "Module", + "span": { + "start": 0, + "end": 109, + "ctxt": 0 + }, + "body": [ + { + "type": "ExportDeclaration", + "span": { + "start": 0, + "end": 109, + "ctxt": 0 + }, + "declaration": { + "type": "FunctionDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 16, + "end": 17, + "ctxt": 0 + }, + "value": "x", + "optional": false + }, + "declare": false, + "params": [], + "decorators": [], + "span": { + "start": 7, + "end": 109, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 20, + "end": 109, + "ctxt": 0 + }, + "stmts": [ + { + "type": "ReturnStatement", + "span": { + "start": 24, + "end": 107, + "ctxt": 0 + }, + "argument": { + "type": "ArrowFunctionExpression", + "span": { + "start": 31, + "end": 106, + "ctxt": 0 + }, + "params": [], + "body": { + "type": "BlockStatement", + "span": { + "start": 37, + "end": 106, + "ctxt": 0 + }, + "stmts": [ + { + "type": "VariableDeclaration", + "span": { + "start": 45, + "end": 102, + "ctxt": 0 + }, + "kind": "const", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 51, + "end": 101, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 51, + "end": 52, + "ctxt": 0 + }, + "value": "y", + "optional": false, + "typeAnnotation": null + }, + "init": { + "type": "ConditionalExpression", + "span": { + "start": 55, + "end": 101, + "ctxt": 0 + }, + "test": { + "type": "BinaryExpression", + "span": { + "start": 55, + "end": 61, + "ctxt": 0 + }, + "operator": "&&", + "left": { + "type": "Identifier", + "span": { + "start": 55, + "end": 56, + "ctxt": 0 + }, + "value": "a", + "optional": false + }, + "right": { + "type": "Identifier", + "span": { + "start": 60, + "end": 61, + "ctxt": 0 + }, + "value": "b", + "optional": false + } + }, + "consequent": { + "type": "ArrowFunctionExpression", + "span": { + "start": 64, + "end": 94, + "ctxt": 0 + }, + "params": [ + { + "type": "Identifier", + "span": { + "start": 65, + "end": 74, + "ctxt": 0 + }, + "value": "z", + "optional": false, + "typeAnnotation": { + "type": "TsTypeAnnotation", + "span": { + "start": 66, + "end": 74, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 68, + "end": 74, + "ctxt": 0 + }, + "kind": "number" + } + } + } + ], + "body": { + "type": "StringLiteral", + "span": { + "start": 87, + "end": 94, + "ctxt": 0 + }, + "value": "hello", + "raw": "\"hello\"" + }, + "async": false, + "generator": false, + "typeParameters": null, + "returnType": { + "type": "TsTypeAnnotation", + "span": { + "start": 75, + "end": 83, + "ctxt": 0 + }, + "typeAnnotation": { + "type": "TsKeywordType", + "span": { + "start": 77, + "end": 83, + "ctxt": 0 + }, + "kind": "string" + } + } + }, + "alternate": { + "type": "NullLiteral", + "span": { + "start": 97, + "end": 101, + "ctxt": 0 + } + } + }, + "definite": false + } + ] + } + ] + }, + "async": false, + "generator": false, + "typeParameters": null, + "returnType": null + } + } + ] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + } + } + ], + "interpreter": null +}