diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5acaf560273..9b409a7e237 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3404,77 +3404,14 @@ module ts { emitSignatureParameters(node); } - if (isSingleLineBlock(node.body)) { + if (isSingleLineBlock(node.body) || !node.body) { write(" { }"); } + else if (node.body.kind === SyntaxKind.Block) { + emitBlockFunctionBody(node, node.body); + } else { - write(" {"); - scopeEmitStart(node); - - if (!node.body) { - writeLine(); - write("}"); - } - else { - increaseIndent(); - - emitDetachedComments(node.body.kind === SyntaxKind.Block ? (node.body).statements : node.body); - - var startIndex = 0; - if (node.body.kind === SyntaxKind.Block) { - startIndex = emitDirectivePrologues((node.body).statements, /*startWithNewLine*/ true); - } - var outPos = writer.getTextPos(); - - emitCaptureThisForNodeIfNecessary(node); - emitDefaultValueAssignments(node); - emitRestParameter(node); - if (node.body.kind !== SyntaxKind.Block && outPos === writer.getTextPos()) { - decreaseIndent(); - write(" "); - emitStart(node.body); - write("return "); - - // Don't emit comments on this body. We'll have already taken care of it above - // when we called emitDetachedComments. - emitNode(node.body, /*disableComments:*/ true); - emitEnd(node.body); - write(";"); - emitTempDeclarations(/*newLine*/ false); - write(" "); - emitStart(node.body); - write("}"); - emitEnd(node.body); - } - else { - if (node.body.kind === SyntaxKind.Block) { - emitLinesStartingAt((node.body).statements, startIndex); - } - else { - writeLine(); - emitLeadingComments(node.body); - write("return "); - emit(node.body, /*disableComments:*/ true); - write(";"); - emitTrailingComments(node.body); - } - emitTempDeclarations(/*newLine*/ true); - writeLine(); - if (node.body.kind === SyntaxKind.Block) { - emitLeadingCommentsOfPosition((node.body).statements.end); - decreaseIndent(); - emitToken(SyntaxKind.CloseBraceToken, (node.body).statements.end); - } - else { - decreaseIndent(); - emitStart(node.body); - write("}"); - emitEnd(node.body); - } - } - } - - scopeEmitEnd(); + emitExpressionFunctionBody(node, node.body); } if (node.flags & NodeFlags.Export) { @@ -3486,11 +3423,86 @@ module ts { emitEnd(node); write(";"); } + tempCount = saveTempCount; tempVariables = saveTempVariables; tempParameters = saveTempParameters; } + // Returns true if any preamble code was emitted. + function emitFunctionBodyPreamble(node: FunctionLikeDeclaration): void { + emitCaptureThisForNodeIfNecessary(node); + emitDefaultValueAssignments(node); + emitRestParameter(node); + } + + function emitExpressionFunctionBody(node: FunctionLikeDeclaration, body: Expression) { + write(" {"); + scopeEmitStart(node); + + increaseIndent(); + var outPos = writer.getTextPos(); + emitDetachedComments(node.body); + emitFunctionBodyPreamble(node); + var preambleEmitted = writer.getTextPos() !== outPos; + decreaseIndent(); + + // If we didn't have to emit any preamble code, then attempt to keep the arrow + // function on one line. + if (!preambleEmitted && isOnSameLine(node, body)) { + write(" "); + emitStart(body); + write("return "); + + // Don't emit comments on this body. We'll have already taken care of it above + // when we called emitDetachedComments. + emitNode(body, /*disableComments:*/ true); + emitEnd(body); + write(";"); + emitTempDeclarations(/*newLine*/ false); + write(" "); + } + else { + increaseIndent(); + writeLine(); + emitLeadingComments(node.body); + write("return "); + emit(node.body, /*disableComments:*/ true); + write(";"); + emitTrailingComments(node.body); + + emitTempDeclarations(/*newLine*/ true); + decreaseIndent(); + writeLine(); + } + + emitStart(node.body); + write("}"); + emitEnd(node.body); + + scopeEmitEnd(); + } + + function emitBlockFunctionBody(node: FunctionLikeDeclaration, body: Block) { + write(" {"); + scopeEmitStart(node); + + increaseIndent(); + emitDetachedComments(body.statements); + var startIndex = emitDirectivePrologues(body.statements, /*startWithNewLine*/ true); + + emitFunctionBodyPreamble(node); + emitLinesStartingAt(body.statements, startIndex); + emitTempDeclarations(/*newLine*/ true); + + writeLine(); + emitLeadingCommentsOfPosition(body.statements.end); + decreaseIndent(); + emitToken(SyntaxKind.CloseBraceToken, body.statements.end); + + scopeEmitEnd(); + } + function findInitialSuperCall(ctor: ConstructorDeclaration): ExpressionStatement { if (ctor.body) { var statement = (ctor.body).statements[0]; diff --git a/tests/baselines/reference/FunctionPropertyAssignments4_es6.js b/tests/baselines/reference/FunctionPropertyAssignments4_es6.js index 595f7fc9124..71076523414 100644 --- a/tests/baselines/reference/FunctionPropertyAssignments4_es6.js +++ b/tests/baselines/reference/FunctionPropertyAssignments4_es6.js @@ -2,5 +2,4 @@ var v = { * } //// [FunctionPropertyAssignments4_es6.js] -var v = { : function () { -} }; +var v = { : function () { } }; diff --git a/tests/baselines/reference/accessorWithoutBody1.js b/tests/baselines/reference/accessorWithoutBody1.js index 37f0ecbcfee..e06e305e161 100644 --- a/tests/baselines/reference/accessorWithoutBody1.js +++ b/tests/baselines/reference/accessorWithoutBody1.js @@ -2,5 +2,4 @@ var v = { get foo() } //// [accessorWithoutBody1.js] -var v = { get foo() { -} }; +var v = { get foo() { } }; diff --git a/tests/baselines/reference/accessorWithoutBody2.js b/tests/baselines/reference/accessorWithoutBody2.js index 9dc34c1e744..3b5a821d580 100644 --- a/tests/baselines/reference/accessorWithoutBody2.js +++ b/tests/baselines/reference/accessorWithoutBody2.js @@ -2,5 +2,4 @@ var v = { set foo(a) } //// [accessorWithoutBody2.js] -var v = { set foo(a) { -} }; +var v = { set foo(a) { } }; diff --git a/tests/baselines/reference/commentOnSimpleArrowFunctionBody1.js b/tests/baselines/reference/commentOnSimpleArrowFunctionBody1.js index dc9bac84fa5..39f967555bf 100644 --- a/tests/baselines/reference/commentOnSimpleArrowFunctionBody1.js +++ b/tests/baselines/reference/commentOnSimpleArrowFunctionBody1.js @@ -11,4 +11,7 @@ Foo(() => //// [commentOnSimpleArrowFunctionBody1.js] function Foo(x) { } -Foo(function () { return 127; }); +Foo(function () { + // do something + return 127; +}); diff --git a/tests/baselines/reference/genericsAndHigherOrderFunctions.js b/tests/baselines/reference/genericsAndHigherOrderFunctions.js index 1086bd78c54..f2e6ef58f22 100644 --- a/tests/baselines/reference/genericsAndHigherOrderFunctions.js +++ b/tests/baselines/reference/genericsAndHigherOrderFunctions.js @@ -19,5 +19,13 @@ var foo: (g: (x: K) => N) => //// [genericsAndHigherOrderFunctions.js] // no errors expected -var combine = function (f) { return function (g) { return function (x) { return f(g(x)); }; }; }; -var foo = function (g) { return function (h) { return function (f) { return h(combine(f)(g)); }; }; }; +var combine = function (f) { + return function (g) { + return function (x) { return f(g(x)); }; + }; +}; +var foo = function (g) { + return function (h) { + return function (f) { return h(combine(f)(g)); }; + }; +}; diff --git a/tests/baselines/reference/giant.js b/tests/baselines/reference/giant.js index 7f2c2453b0f..a5109b6e113 100644 --- a/tests/baselines/reference/giant.js +++ b/tests/baselines/reference/giant.js @@ -706,44 +706,38 @@ define(["require", "exports"], function (require, exports) { C.prototype.rF = function () { }; C.prototype.pgF = function () { }; Object.defineProperty(C.prototype, "pgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); C.prototype.psF = function (param) { }; Object.defineProperty(C.prototype, "psF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.prototype.rgF = function () { }; Object.defineProperty(C.prototype, "rgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); C.prototype.rsF = function (param) { }; Object.defineProperty(C.prototype, "rsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.tF = function () { }; C.tsF = function (param) { }; Object.defineProperty(C, "tsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.tgF = function () { }; Object.defineProperty(C, "tgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); @@ -761,44 +755,38 @@ define(["require", "exports"], function (require, exports) { C.prototype.rF = function () { }; C.prototype.pgF = function () { }; Object.defineProperty(C.prototype, "pgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); C.prototype.psF = function (param) { }; Object.defineProperty(C.prototype, "psF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.prototype.rgF = function () { }; Object.defineProperty(C.prototype, "rgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); C.prototype.rsF = function (param) { }; Object.defineProperty(C.prototype, "rsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.tF = function () { }; C.tsF = function (param) { }; Object.defineProperty(C, "tsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.tgF = function () { }; Object.defineProperty(C, "tgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); @@ -845,44 +833,38 @@ define(["require", "exports"], function (require, exports) { eC.prototype.rF = function () { }; eC.prototype.pgF = function () { }; Object.defineProperty(eC.prototype, "pgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); eC.prototype.psF = function (param) { }; Object.defineProperty(eC.prototype, "psF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.prototype.rgF = function () { }; Object.defineProperty(eC.prototype, "rgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); eC.prototype.rsF = function (param) { }; Object.defineProperty(eC.prototype, "rsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.tF = function () { }; eC.tsF = function (param) { }; Object.defineProperty(eC, "tsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.tgF = function () { }; Object.defineProperty(eC, "tgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); @@ -932,44 +914,38 @@ define(["require", "exports"], function (require, exports) { eC.prototype.rF = function () { }; eC.prototype.pgF = function () { }; Object.defineProperty(eC.prototype, "pgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); eC.prototype.psF = function (param) { }; Object.defineProperty(eC.prototype, "psF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.prototype.rgF = function () { }; Object.defineProperty(eC.prototype, "rgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); eC.prototype.rsF = function (param) { }; Object.defineProperty(eC.prototype, "rsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.tF = function () { }; eC.tsF = function (param) { }; Object.defineProperty(eC, "tsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.tgF = function () { }; Object.defineProperty(eC, "tgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); @@ -988,44 +964,38 @@ define(["require", "exports"], function (require, exports) { C.prototype.rF = function () { }; C.prototype.pgF = function () { }; Object.defineProperty(C.prototype, "pgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); C.prototype.psF = function (param) { }; Object.defineProperty(C.prototype, "psF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.prototype.rgF = function () { }; Object.defineProperty(C.prototype, "rgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); C.prototype.rsF = function (param) { }; Object.defineProperty(C.prototype, "rsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.tF = function () { }; C.tsF = function (param) { }; Object.defineProperty(C, "tsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); C.tgF = function () { }; Object.defineProperty(C, "tgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); @@ -1072,44 +1042,38 @@ define(["require", "exports"], function (require, exports) { eC.prototype.rF = function () { }; eC.prototype.pgF = function () { }; Object.defineProperty(eC.prototype, "pgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); eC.prototype.psF = function (param) { }; Object.defineProperty(eC.prototype, "psF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.prototype.rgF = function () { }; Object.defineProperty(eC.prototype, "rgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); eC.prototype.rsF = function (param) { }; Object.defineProperty(eC.prototype, "rsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.tF = function () { }; eC.tsF = function (param) { }; Object.defineProperty(eC, "tsF", { - set: function (param) { - }, + set: function (param) { }, enumerable: true, configurable: true }); eC.tgF = function () { }; Object.defineProperty(eC, "tgF", { - get: function () { - }, + get: function () { }, enumerable: true, configurable: true }); diff --git a/tests/baselines/reference/lambdaASIEmit.js b/tests/baselines/reference/lambdaASIEmit.js index 551aa5f93dd..49672b75c7c 100644 --- a/tests/baselines/reference/lambdaASIEmit.js +++ b/tests/baselines/reference/lambdaASIEmit.js @@ -12,4 +12,7 @@ Foo(() => //// [lambdaASIEmit.js] function Foo(x) { } -Foo(function () { return 127; }); +Foo(function () { + // do something + return 127; +}); diff --git a/tests/baselines/reference/objectLiteralMemberWithoutBlock1.js b/tests/baselines/reference/objectLiteralMemberWithoutBlock1.js index 2ad13950b14..d6a8579be04 100644 --- a/tests/baselines/reference/objectLiteralMemberWithoutBlock1.js +++ b/tests/baselines/reference/objectLiteralMemberWithoutBlock1.js @@ -2,5 +2,4 @@ var v = { foo(); } //// [objectLiteralMemberWithoutBlock1.js] -var v = { foo: function () { -} }; +var v = { foo: function () { } }; diff --git a/tests/baselines/reference/thisReferencedInFunctionInsideArrowFunction1.js b/tests/baselines/reference/thisReferencedInFunctionInsideArrowFunction1.js index d6718a56106..77fdc507887 100644 --- a/tests/baselines/reference/thisReferencedInFunctionInsideArrowFunction1.js +++ b/tests/baselines/reference/thisReferencedInFunctionInsideArrowFunction1.js @@ -10,7 +10,9 @@ function test() //// [thisReferencedInFunctionInsideArrowFunction1.js] var foo = function (dummy) { }; function test() { - foo(function () { return function () { - return this; - }; }); + foo(function () { + return function () { + return this; + }; + }); }