10000 Emit parameter initializers unless we are certain they don't have any… · ezhangle/TypeScript@53ed427 · GitHub
[go: up one dir, main page]

Skip to content

Commit 53ed427

Browse files
Emit parameter initializers unless we are certain they don't have any side effects.
1 parent a2d0d59 commit 53ed427

File tree

77 files changed

+562
-75
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+562
-75
lines changed

src/compiler/emitter.ts

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3850,7 +3850,9 @@ module ts {
38503850
emitSignatureParameters(node);
38513851
}
38523852

3853-
if (isSingleLineEmptyBlock(node.body) || !node.body) {
3853+
if (!node.body) {
3854+
// There can be no body when there are parse errors. Just emit an empty block
3855+
// in that case.
38543856
write(" { }");
38553857
}
38563858
else if (node.body.kind === SyntaxKind.Block) {
@@ -3930,15 +3932,117 @@ module ts {
39303932
}
39313933

39323934
function emitBlockFunctionBody(node: FunctionLikeDeclaration, body: Block) {
3935+
// If the body has no statements, and we know there's no code that would have to
3936+
// run that could cause side effects, then just do a simple emit if the empty
3937+
// block.
3938+
if (body.statements.length === 0 && !hasPossibleSideEffectingParameterInitializers(node)) {
3939+
emitFunctionBodyWithNoStatements(node, body);
3940+
}
3941+
else {
3942+
emitFunctionBodyWithStatements(node, body);
3943+
}
3944+
}
3945+
3946+
function hasPossibleSideEffectingParameterInitializers(func: FunctionLikeDeclaration) {
3947+
return forEach(func.parameters, hasPossibleSideEffects);
3948+
}
3949+
3950+
function hasPossibleSideEffects(node: Node): boolean {
3951+
if (!node) {
3952+
return false;
3953+
}
3954+
3955+
switch (node.kind) {
3956+
// TODO(cyrusn): Increase the number of cases we support for determining if
3957+
// something is side effect free.
3958+
//
3959+
// NOTE(cyrusn): Some expressions may seem to be side effect free, but may
3960+
// actually have side effects. For example, a binary + expression may cause
3961+
// the toString method to be called on value, which may have side effects.
3962+
case SyntaxKind.StringLiteral:
3963+
case SyntaxKind.NoSubstitutionTemplateLiteral:
3964+
case SyntaxKind.NumericLiteral:
3965+
case SyntaxKind.RegularExpressionLiteral:
3966+
case SyntaxKind.TrueKeyword:
3967+
case SyntaxKind.FalseKeyword:
3968+
case SyntaxKind.NullKeyword:
3969+
case SyntaxKind.Identifier:
3970+
case SyntaxKind.FunctionExpression:
3971+
case SyntaxKind.ArrowFunction:
3972+
case SyntaxKind.ShorthandPropertyAssignment:
3973+
case SyntaxKind.MethodDeclaration:
3974+
case SyntaxKind.GetAccessor:
3975+
case SyntaxKind.SetAccessor:
3976+
return false;
3977+
3978+
case SyntaxKind.ArrayBindingPattern:
3979+
case SyntaxKind.ObjectBindingPattern:
3980+
return forEach((<BindingPattern>node).elements, hasPossibleSideEffects);
3981+
3982+
case SyntaxKind.BindingElement:
3983+
return hasPossibleSideEffects((<BindingElement>node).name) ||
3984+
hasPossibleSideEffects((<BindingElement>node).initializer);
3985+
3986+
case SyntaxKind.Parameter:
3987+
return hasPossibleSideEffects((<ParameterDeclaration>node).name) ||
3988+
hasPossibleSideEffects((<ParameterDeclaration>node).initializer);
3989+
3990+
case SyntaxKind.PropertyAccessExpression:
3991+
return hasPossibleSideEffects((<PropertyAccessExpression>node).expression);
3992+
3993+
case SyntaxKind.ArrayLiteralExpression:
3994+
return forEach((<ArrayLiteralExpression>node).elements, hasPossibleSideEffects);
3995+
3996+
case SyntaxKind.ElementAccessExpression:
3997+
return hasPossibleSideEffects((<ElementAccessExpression>node).expression) ||
3998+
hasPossibleSideEffects((<ElementAccessExpression>node).argumentExpression);
3999+
4000+
case SyntaxKind.ParenthesizedExpression:
4001+
return hasPossibleSideEffects((<ParenthesizedExpression>node).expression);
4002+
4003+
case SyntaxKind.ObjectLiteralExpression:
4004+
return forEach((<ObjectLiteralExpression>node).properties, hasPossibleSideEffects);
4005+
4006+
case SyntaxKind.PropertyAssignment:
4007+
return hasPossibleSideEffects((<PropertyAssignment>node).name) ||
4008+
hasPossibleSideEffects((<PropertyAssignment>node).initializer);
4009+
4010+
case SyntaxKind.ComputedPropertyName:
4011+
return hasPossibleSideEffects((<ComputedPropertyName>node).expression);
4012+
4013+
default:
4014+
// We are conservative. Unless we have proved something is side effect
4015+
// free, we assume it has possible side effects.
4016+
return true;
4017+
}
4018+
}
4019+
4020+
function emitFunctionBodyWithNoStatements(node: FunctionLikeDeclaration, body: Block) {
4021+
if (isSingleLineEmptyBlock(node.body)) {
4022+
write(" { }");
4023+
}
4024+
else {
4025+
write(" {");
4026+
writeLine();
4027+
increaseIndent();
4028+
emitLeadingCommentsOfPosition(body.statements.end);
4029+
decreaseIndent();
4030+
emitToken(SyntaxKind.CloseBraceToken, body.statements.end);
4031+
}
4032+
}
4033+
4034+
function emitFunctionBodyWithStatements(node: FunctionLikeDeclaration, body: Block) {
39334035
write(" {");
39344036
scopeEmitStart(node);
39354037

39364038
var outPos = writer.getTextPos();
4039+
39374040
increaseIndent();
39384041
emitDetachedComments(body.statements);
39394042
var startIndex = emitDirectivePrologues(body.statements, /*startWithNewLine*/ true);
39404043
emitFunctionBodyPreamble(node);
39414044
decreaseIndent();
4045+
39424046
var preambleEmitted = writer.getTextPos() !== outPos;
39434047

39444048
if (!preambleEmitted && nodeEndIsOnSameLineAsNodeStart(body, body)) {

tests/baselines/reference/FunctionDeclaration10_es6.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ function * foo(a = yield => yield) {
44

55
//// [FunctionDeclaration10_es6.js]
66
function foo(a) {
7-
if (a === void 0) { a = function (yield) { return yield; }; }
87
}

tests/baselines/reference/FunctionDeclaration3_es6.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ function f(yield = yield) {
44

55
//// [FunctionDeclaration3_es6.js]
66
function f(yield) {
7-
if (yield === void 0) { yield = yield; }
87
}

tests/baselines/reference/FunctionDeclaration6_es6.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ function*foo(a = yield) {
44

55
//// [FunctionDeclaration6_es6.js]
66
function foo(a) {
7-
if (a === void 0) { a = yield; }
87
}

tests/baselines/reference/FunctionDeclaration7_es6.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,5 @@ function*bar() {
99
function bar() {
1010
// 'yield' here is an identifier, and not a yield expression.
1111
function foo(a) {
12-
if (a === void 0) { a = yield; }
1312
}
1413
}

tests/baselines/reference/callWithSpread.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ var __extends = this.__extends || function (d, b) {
6161
d.prototype = new __();
6262
};
6363
function foo(x, y) {
64-
var z = [];
65-
for (var _i = 2; _i < arguments.length; _i++) {
66-
z[_i - 2] = arguments[_i];
67-
}
6864
}
6965
var a;
7066
var z;
@@ -93,10 +89,6 @@ var C = (function () {
9389
this.foo.apply(this, [x, y].concat(z));
9490
}
9591
C.prototype.foo = function (x, y) {
96-
var z = [];
97-
for (var _i = 2; _i < arguments.length; _i++) {
98-
z[_i - 2] = arguments[_i];
99-
}
10092
};
10193
return C;
10294
})();

tests/baselines/reference/collisionRestParameterFunction.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ function f3NoError() {
5656
var _i = 10; // no error
5757
}
5858
function f4(_i) {
59-
var rest = [];
60-
for (var _a = 1; _a < arguments.length; _a++) {
61-
rest[_a - 1] = arguments[_a];
62-
}
6359
}
6460
function f4NoError(_i) {
6561
}

tests/baselines/reference/collisionRestParameterFunctionExpressions.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,6 @@ function foo() {
4747
var _i = 10; // no error
4848
}
4949
function f4(_i) {
50-
var rest = [];
51-
for (var _a = 1; _a < arguments.length; _a++) {
52-
rest[_a - 1] = arguments[_a];
53-
}
5450
}
5551
function f4NoError(_i) {
5652
}

tests/baselines/reference/declarationsAndAssignments.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ function f16() {
290290
var _a = f15(), a = _a.a, b = _a.b, c = _a.c;
291291
}
292292
function f17(_a) {
293-
var _b = _a.a, a = _b === void 0 ? "" : _b, _c = _a.b, b = _c === void 0 ? 0 : _c, _d = _a.c, c = _d === void 0 ? false : _d;
294293
}
295294
f17({});
296295
f17({ a: "hello" });

tests/baselines/reference/funcdecl.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,9 @@ function withOptionalParams(a) {
9595
}
9696
var withOptionalParamsVar = withOptionalParams;
9797
function withInitializedParams(a, b0, b, c) {
98-
if (b === void 0) { b = 30; }
99-
if (c === void 0) { c = "string value"; }
10098
}
10199
var withInitializedParamsVar = withInitializedParams;
102100
function withOptionalInitializedParams(a, c) {
103-
if (c === void 0) { c = "hello string"; }
104101
}
105102
var withOptionalInitializedParamsVar = withOptionalInitializedParams;
106103
function withRestParams(a) {

0 commit comments

Comments
 (0)
0