From c76f71cfaeeac94a35fae7601f7a4247e35092d9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 7 Mar 2015 01:30:45 -0800 Subject: [PATCH] When emitting an arrow function, parenthesize the body if it could be interpreted as a block instead of an object literal. --- src/compiler/emitter.ts | 14 ++++++++++++-- .../arrowFunctionWithObjectLiteralBody1.js | 5 +++++ .../arrowFunctionWithObjectLiteralBody1.types | 8 ++++++++ .../arrowFunctionWithObjectLiteralBody2.js | 5 +++++ .../arrowFunctionWithObjectLiteralBody2.types | 9 +++++++++ .../arrowFunctionWithObjectLiteralBody3.js | 5 +++++ .../arrowFunctionWithObjectLiteralBody3.types | 8 ++++++++ .../arrowFunctionWithObjectLiteralBody4.js | 5 +++++ .../arrowFunctionWithObjectLiteralBody4.types | 9 +++++++++ .../arrowFunctionWithObjectLiteralBody1.ts | 1 + .../arrowFunctionWithObjectLiteralBody2.ts | 1 + .../arrowFunctionWithObjectLiteralBody3.ts | 2 ++ .../arrowFunctionWithObjectLiteralBody4.ts | 2 ++ 13 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/arrowFunctionWithObjectLiteralBody1.js create mode 100644 tests/baselines/reference/arrowFunctionWithObjectLiteralBody1.types create mode 100644 tests/baselines/reference/arrowFunctionWithObjectLiteralBody2.js create mode 100644 tests/baselines/reference/arrowFunctionWithObjectLiteralBody2.types create mode 100644 tests/baselines/reference/arrowFunctionWithObjectLiteralBody3.js create mode 100644 tests/baselines/reference/arrowFunctionWithObjectLiteralBody3.types create mode 100644 tests/baselines/reference/arrowFunctionWithObjectLiteralBody4.js create mode 100644 tests/baselines/reference/arrowFunctionWithObjectLiteralBody4.types create mode 100644 tests/cases/compiler/arrowFunctionWithObjectLiteralBody1.ts create mode 100644 tests/cases/compiler/arrowFunctionWithObjectLiteralBody2.ts create mode 100644 tests/cases/compiler/arrowFunctionWithObjectLiteralBody3.ts create mode 100644 tests/cases/compiler/arrowFunctionWithObjectLiteralBody4.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d3b248b41ff..c96ed1299fe 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4202,9 +4202,19 @@ module ts { return; } - // For es6 and higher we can emit the expression as is. + // For es6 and higher we can emit the expression as is. However, in the case + // where the expression might end up looking like a block when down-leveled, we'll + // also wrap it in parentheses first. For example if you have: a => {} + // then we need to generate: a => ({}) write(" "); - emit(body); + + // Unwrap all type assertions. + var current = body; + while (current.kind === SyntaxKind.TypeAssertionExpression) { + current = (current).expression; + } + + emitParenthesizedIf(body, current.kind === SyntaxKind.ObjectLiteralExpression); } function emitDownLevelExpressionFunctionBody(node: FunctionLikeDeclaration, body: Expression) { diff --git a/tests/baselines/reference/arrowFunctionWithObjectLiteralBody1.js b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody1.js new file mode 100644 index 00000000000..d53f33deadc --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody1.js @@ -0,0 +1,5 @@ +//// [arrowFunctionWithObjectLiteralBody1.ts] +var v = a => {} + +//// [arrowFunctionWithObjectLiteralBody1.js] +var v = function (a) { return {}; }; diff --git a/tests/baselines/reference/arrowFunctionWithObjectLiteralBody1.types b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody1.types new file mode 100644 index 00000000000..2446c97d4ce --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody1.types @@ -0,0 +1,8 @@ +=== tests/cases/compiler/arrowFunctionWithObjectLiteralBody1.ts === +var v = a => {} +>v : (a: any) => any +>a => {} : (a: any) => any +>a : any +>{} : any +>{} : {} + diff --git a/tests/baselines/reference/arrowFunctionWithObjectLiteralBody2.js b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody2.js new file mode 100644 index 00000000000..f2fc086c082 --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody2.js @@ -0,0 +1,5 @@ +//// [arrowFunctionWithObjectLiteralBody2.ts] +var v = a => {} + +//// [arrowFunctionWithObjectLiteralBody2.js] +var v = function (a) { return {}; }; diff --git a/tests/baselines/reference/arrowFunctionWithObjectLiteralBody2.types b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody2.types new file mode 100644 index 00000000000..df8e87e82ea --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody2.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/arrowFunctionWithObjectLiteralBody2.ts === +var v = a => {} +>v : (a: any) => any +>a => {} : (a: any) => any +>a : any +>{} : any +>{} : any +>{} : {} + diff --git a/tests/baselines/reference/arrowFunctionWithObjectLiteralBody3.js b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody3.js new file mode 100644 index 00000000000..91a699dfc4b --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody3.js @@ -0,0 +1,5 @@ +//// [arrowFunctionWithObjectLiteralBody3.ts] +var v = a => {} + +//// [arrowFunctionWithObjectLiteralBody3.js] +var v = a => ({}); diff --git a/tests/baselines/reference/arrowFunctionWithObjectLiteralBody3.types b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody3.types new file mode 100644 index 00000000000..91e11ab9104 --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody3.types @@ -0,0 +1,8 @@ +=== tests/cases/compiler/arrowFunctionWithObjectLiteralBody3.ts === +var v = a => {} +>v : (a: any) => any +>a => {} : (a: any) => any +>a : any +>{} : any +>{} : {} + diff --git a/tests/baselines/reference/arrowFunctionWithObjectLiteralBody4.js b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody4.js new file mode 100644 index 00000000000..83bc0c878ca --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody4.js @@ -0,0 +1,5 @@ +//// [arrowFunctionWithObjectLiteralBody4.ts] +var v = a => {} + +//// [arrowFunctionWithObjectLiteralBody4.js] +var v = a => ({}); diff --git a/tests/baselines/reference/arrowFunctionWithObjectLiteralBody4.types b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody4.types new file mode 100644 index 00000000000..400a91b459d --- /dev/null +++ b/tests/baselines/reference/arrowFunctionWithObjectLiteralBody4.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/arrowFunctionWithObjectLiteralBody4.ts === +var v = a => {} +>v : (a: any) => any +>a => {} : (a: any) => any +>a : any +>{} : any +>{} : any +>{} : {} + diff --git a/tests/cases/compiler/arrowFunctionWithObjectLiteralBody1.ts b/tests/cases/compiler/arrowFunctionWithObjectLiteralBody1.ts new file mode 100644 index 00000000000..3c874f3fd5e --- /dev/null +++ b/tests/cases/compiler/arrowFunctionWithObjectLiteralBody1.ts @@ -0,0 +1 @@ +var v = a => {} \ No newline at end of file diff --git a/tests/cases/compiler/arrowFunctionWithObjectLiteralBody2.ts b/tests/cases/compiler/arrowFunctionWithObjectLiteralBody2.ts new file mode 100644 index 00000000000..f5dd4fc2bcc --- /dev/null +++ b/tests/cases/compiler/arrowFunctionWithObjectLiteralBody2.ts @@ -0,0 +1 @@ +var v = a => {} \ No newline at end of file diff --git a/tests/cases/compiler/arrowFunctionWithObjectLiteralBody3.ts b/tests/cases/compiler/arrowFunctionWithObjectLiteralBody3.ts new file mode 100644 index 00000000000..f5c1a86f296 --- /dev/null +++ b/tests/cases/compiler/arrowFunctionWithObjectLiteralBody3.ts @@ -0,0 +1,2 @@ +// @target: es6 +var v = a => {} \ No newline at end of file diff --git a/tests/cases/compiler/arrowFunctionWithObjectLiteralBody4.ts b/tests/cases/compiler/arrowFunctionWithObjectLiteralBody4.ts new file mode 100644 index 00000000000..33fe8439ebe --- /dev/null +++ b/tests/cases/compiler/arrowFunctionWithObjectLiteralBody4.ts @@ -0,0 +1,2 @@ +// @target: es6 +var v = a => {} \ No newline at end of file