Skip to content

Commit e26de71

Browse files
Merge pull request #2109 from Microsoft/sideEffects
Emit downlevel parameter initializers unless we are certain they don't have any side effects.
2 parents eaba180 + cfe3bb8 commit e26de71

File tree

96 files changed

+889
-168
lines changed

Some content is hidden

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

96 files changed

+889
-168
lines changed

src/compiler/emitter.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3899,7 +3899,9 @@ module ts {
38993899
emitSignatureParameters(node);
39003900
}
39013901

3902-
if (isSingleLineEmptyBlock(node.body) || !node.body) {
3902+
if (!node.body) {
3903+
// There can be no body when there are parse errors. Just emit an empty block
3904+
// in that case.
39033905
write(" { }");
39043906
}
39053907
else if (node.body.kind === SyntaxKind.Block) {
@@ -3979,15 +3981,57 @@ module ts {
39793981
}
39803982

39813983
function emitBlockFunctionBody(node: FunctionLikeDeclaration, body: Block) {
3984+
// If the body has no statements, and we know there's no code that would cause any
3985+
// prologue to be emitted, then just do a simple emit if the empty block.
3986+
if (body.statements.length === 0 && !anyParameterHasBindingPatternOrInitializer(node)) {
3987+
emitFunctionBodyWithNoStatements(node, body);
3988+
}
3989+
else {
3990+
emitFunctionBodyWithStatements(node, body);
3991+
}
3992+
}
3993+
3994+
function anyParameterHasBindingPatternOrInitializer(func: FunctionLikeDeclaration) {
3995+
return forEach(func.parameters, hasBindingPatternOrInitializer);
3996+
}
3997+
3998+
function hasBindingPatternOrInitializer(parameter: ParameterDeclaration) {
3999+
return parameter.initializer || isBindingPattern(parameter.name);
4000+
}
4001+
4002+
function emitFunctionBodyWithNoStatements(node: FunctionLikeDeclaration, body: Block) {
4003+
var singleLine = isSingleLineEmptyBlock(node.body);
4004+
4005+
write(" {");
4006+
if (singleLine) {
4007+
write(" ");
4008+
}
4009+
else {
4010+
increaseIndent();
4011+
writeLine();
4012+
}
4013+
4014+
emitLeadingCommentsOfPosition(body.statements.end);
4015+
4016+
if (!singleLine) {
4017+
decreaseIndent();
4018+
}
4019+
4020+
emitToken(SyntaxKind.CloseBraceToken, body.statements.end);
4021+
}
4022+
4023+
function emitFunctionBodyWithStatements(node: FunctionLikeDeclaration, body: Block) {
39824024
write(" {");
39834025
scopeEmitStart(node);
39844026

39854027
var outPos = writer.getTextPos();
4028+
39864029
increaseIndent();
39874030
emitDetachedComments(body.statements);
39884031
var startIndex = emitDirectivePrologues(body.statements, /*startWithNewLine*/ true);
39894032
emitFunctionBodyPreamble(node);
39904033
decreaseIndent();
4034+
39914035
var preambleEmitted = writer.getTextPos() !== outPos;
39924036

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

tests/baselines/reference/accessorWithInitializer.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@ var C = (function () {
1010
function C() {
1111
}
1212
Object.defineProperty(C.prototype, "X", {
13-
set: function (v) { },
13+
set: function (v) {
14+
if (v === void 0) { v = 0; }
15+
},
1416
enumerable: true,
1517
configurable: true
1618
});
1719
Object.defineProperty(C, "X", {
18-
set: function (v2) { },
20+
set: function (v2) {
21+
if (v2 === void 0) { v2 = 0; }
22+
},
1923
enumerable: true,
2024
configurable: true
2125
});

tests/baselines/reference/callSignatureWithOptionalParameterAndInitializer.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,15 @@ b.b(1);
5757

5858
//// [callSignatureWithOptionalParameterAndInitializer.js]
5959
// Optional parameters cannot also have initializer expressions, these are all errors
60-
function foo(x) { }
61-
var f = function foo(x) { };
62-
var f2 = function (x, y) { };
60+
function foo(x) {
61+
if (x === void 0) { x = 1; }
62+
}
63+
var f = function foo(x) {
64+
if (x === void 0) { x = 1; }
65+
};
66+
var f2 = function (x, y) {
67+
if (y === void 0) { y = 1; }
68+
};
6369
foo(1);
6470
foo();
6571
f(1);
@@ -69,7 +75,9 @@ f2(1, 2);
6975
var C = (function () {
7076
function C() {
7177
}
72-
C.prototype.foo = function (x) { };
78+
C.prototype.foo = function (x) {
79+
if (x === void 0) { x = 1; }
80+
};
7381
return C;
7482
})();
7583
var c;
@@ -86,9 +94,15 @@ a(1);
8694
a.foo();
8795
a.foo(1);
8896
var b = {
89-
foo: function (x) { },
90-
a: function foo(x, y) { },
91-
b: function (x) { }
97+
foo: function (x) {
98+
if (x === void 0) { x = 1; }
99+
},
100+
a: function foo(x, y) {
101+
if (y === void 0) { y = ''; }
102+
},
103+
b: function (x) {
104+
if (x === void 0) { x = ''; }
105+
}
92106
};
93107
b.foo();
94108
b.foo(1);

tests/baselines/reference/callSignaturesWithParameterInitializers.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,15 @@ b.b(1);
5959

6060
//// [callSignaturesWithParameterInitializers.js]
6161
// Optional parameters allow initializers only in implementation signatures
62-
function foo(x) { }
63-
var f = function foo(x) { };
64-
var f2 = function (x, y) { };
62+
function foo(x) {
63+
if (x === void 0) { x = 1; }
64+
}
65+
var f = function foo(x) {
66+
if (x === void 0) { x = 1; }
67+
};
68+
var f2 = function (x, y) {
69+
if (y === void 0) { y = 1; }
70+
};
6571
foo(1);
6672
foo();
6773
f(1);
@@ -71,7 +77,9 @@ f2(1, 2);
7177
var C = (function () {
7278
function C() {
7379
}
74-
C.prototype.foo = function (x) { };
80+
C.prototype.foo = function (x) {
81+
if (x === void 0) { x = 1; }
82+
};
7583
return C;
7684
})();
7785
var c;
@@ -89,9 +97,15 @@ a(1);
8997
a.foo();
9098
a.foo(1);
9199
var b = {
92-
foo: function (x) { },
93-
a: function foo(x, y) { },
94-
b: function (x) { }
100+
foo: function (x) {
101+
if (x === void 0) { x = 1; }
102+
},
103+
a: function foo(x, y) {
104+
if (y === void 0) { y = 1; }
105+
},
106+
b: function (x) {
107+
if (x === void 0) { x = 1; }
108+
}
95109
};
96110
b.foo();
97111
b.foo(1);

tests/baselines/reference/callSignaturesWithParameterInitializers2.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,29 @@ b.foo(1);
2828
//// [callSignaturesWithParameterInitializers2.js]
2929
// Optional parameters allow initializers only in implementation signatures
3030
// All the below declarations are errors
31-
function foo(x) { }
31+
function foo(x) {
32+
if (x === void 0) { x = 1; }
33+
}
3234
foo(1);
3335
foo();
3436
var C = (function () {
3537
function C() {
3638
}
37-
C.prototype.foo = function (x) { };
39+
C.prototype.foo = function (x) {
40+
if (x === void 0) { x = 1; }
41+
};
3842
return C;
3943
})();
4044
var c;
4145
c.foo();
4246
c.foo(1);
4347
var b = {
44-
foo: function (x) { },
45-
foo: function (x) { }
48+
foo: function (x) {
49+
if (x === void 0) { x = 1; }
50+
},
51+
foo: function (x) {
52+
if (x === void 0) { x = 1; }
53+
}
4654
};
4755
b.foo();
4856
b.foo(1);

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/collisionCodeGenModuleWithFunctionChildren.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ module M {
2323
var M;
2424
(function (_M) {
2525
_M.x = 3;
26-
function fn(M, p) { }
26+
function fn(M, p) {
27+
if (p === void 0) { p = _M.x; }
28+
}
2729
})(M || (M = {}));
2830
var M;
2931
(function (_M_1) {

tests/baselines/reference/collisionCodeGenModuleWithMethodChildren.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ var M;
3939
var c = (function () {
4040
function c() {
4141
}
42-
c.prototype.fn = function (M, p) { };
42+
c.prototype.fn = function (M, p) {
43+
if (p === void 0) { p = _M.x; }
44+
};
4345
return c;
4446
})();
4547
})(M || (M = {}));

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
}

0 commit comments

Comments
 (0)