Skip to content

Commit 37de252

Browse files
committed
Reduce rest parameter reduce if not referenced
1 parent fd0ad29 commit 37de252

File tree

166 files changed

+2258
-5526
lines changed

Some content is hidden

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

166 files changed

+2258
-5526
lines changed

src/compiler/checker.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21693,6 +21693,18 @@ namespace ts {
2169321693
return getTypeOfSymbol(symbol);
2169421694
}
2169521695

21696+
if ((symbol.flags & SymbolFlags.Value) && symbol.valueDeclaration && isParameter(symbol.valueDeclaration) && isRestParameter(symbol.valueDeclaration)) {
21697+
const containerFunctionLikeDeclaration = findAncestor(symbol.valueDeclaration, isFunctionLikeDeclaration);
21698+
if (containerFunctionLikeDeclaration) {
21699+
const topLevelStatementInContainer = findAncestor(node, n => {
21700+
return n.parent && (isBlock(n.parent) ? n.parent.parent === containerFunctionLikeDeclaration : n.parent === containerFunctionLikeDeclaration);
21701+
})
21702+
if (topLevelStatementInContainer) {
21703+
(<Mutable<Node>>topLevelStatementInContainer).flags |= NodeFlags.ContainsRestParameterReference;
21704+
}
21705+
}
21706+
}
21707+
2169621708
// We should only mark aliases as referenced if there isn't a local value declaration
2169721709
// for the symbol. Also, don't mark any property access expression LHS - checkPropertyAccessExpression will handle that
2169821710
if (!(node.parent && isPropertyAccessExpression(node.parent) && node.parent.expression === node)) {
@@ -21787,7 +21799,7 @@ namespace ts {
2178721799
// The declaration container is the innermost function that encloses the declaration of the variable
2178821800
// or parameter. The flow container is the innermost function starting with which we analyze the control
2178921801
// flow graph to determine the control flow based type.
21790-
const isParameter = getRootDeclaration(declaration).kind === SyntaxKind.Parameter;
21802+
const isParameterDecl = getRootDeclaration(declaration).kind === SyntaxKind.Parameter;
2179121803
const declarationContainer = getControlFlowContainer(declaration);
2179221804
let flowContainer = getControlFlowContainer(node);
2179321805
const isOuterVariable = flowContainer !== declarationContainer;
@@ -21798,19 +21810,19 @@ namespace ts {
2179821810
// analysis to include the immediately enclosing function.
2179921811
while (flowContainer !== declarationContainer && (flowContainer.kind === SyntaxKind.FunctionExpression ||
2180021812
flowContainer.kind === SyntaxKind.ArrowFunction || isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
21801-
(isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
21813+
(isConstVariable(localOrExportSymbol) || isParameterDecl && !isParameterAssigned(localOrExportSymbol))) {
2180221814
flowContainer = getControlFlowContainer(flowContainer);
2180321815
}
2180421816
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
2180521817
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
2180621818
// declaration container are the same).
21807-
const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isBindingElement(declaration) ||
21819+
const assumeInitialized = isParameterDecl || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isBindingElement(declaration) ||
2180821820
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 ||
2180921821
isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
2181021822
node.parent.kind === SyntaxKind.NonNullExpression ||
2181121823
declaration.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>declaration).exclamationToken ||
2181221824
declaration.flags & NodeFlags.Ambient;
21813-
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration as VariableLikeDeclaration) : type) :
21825+
const initialType = assumeInitialized ? (isParameterDecl ? removeOptionalityFromDeclaredType(type, declaration as VariableLikeDeclaration) : type) :
2181421826
type === autoType || type === autoArrayType ? undefinedType :
2181521827
getOptionalType(type);
2181621828
const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);

src/compiler/transformers/es2015.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,14 @@ namespace ts {
13541354
return false;
13551355
}
13561356

1357+
const firstStatementContainsRestParameter = node.body && (isBlock(node.body) ?
1358+
find(node.body.statements, stmt => !!(stmt.flags & NodeFlags.ContainsRestParameterReference)) :
1359+
(node.body.flags & NodeFlags.ContainsRestParameterReference) ? node.body : undefined
1360+
);
1361+
if (!firstStatementContainsRestParameter) {
1362+
return false;
1363+
}
1364+
13571365
// `declarationName` is the name of the local declaration for the parameter.
13581366
// TODO(rbuckton): Does this need to be parented?
13591367
const declarationName = parameter.name.kind === SyntaxKind.Identifier ? setParent(setTextRange(factory.cloneNode(parameter.name), parameter.name), parameter.name.parent) : factory.createTempVariable(/*recordTempVariable*/ undefined);

src/compiler/types.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -746,15 +746,17 @@ namespace ts {
746746
// removal, it is likely that users will add the import anyway.
747747
// The advantage of this approach is its simplicity. For the case of batch compilation,
748748
// we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
749-
/* @internal */ PossiblyContainsDynamicImport = 1 << 20,
750-
/* @internal */ PossiblyContainsImportMeta = 1 << 21,
751-
752-
JSDoc = 1 << 22, // If node was parsed inside jsdoc
753-
/* @internal */ Ambient = 1 << 23, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
754-
/* @internal */ InWithStatement = 1 << 24, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
755-
JsonFile = 1 << 25, // If node was parsed in a Json
756-
/* @internal */ TypeCached = 1 << 26, // If a type was cached for node at any point
757-
/* @internal */ Deprecated = 1 << 27, // If has '@deprecated' JSDoc tag
749+
/* @internal */ PossiblyContainsDynamicImport = 1 << 20,
750+
/* @internal */ PossiblyContainsImportMeta = 1 << 21,
751+
752+
JSDoc = 1 << 22, // If node was parsed inside jsdoc
753+
/* @internal */ Ambient = 1 << 23, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
754+
/* @internal */ InWithStatement = 1 << 24, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
755+
JsonFile = 1 << 25, // If node was parsed in a Json
756+
/* @internal */ TypeCached = 1 << 26, // If a type was cached for node at any point
757+
/* @internal */ Deprecated = 1 << 27, // If has '@deprecated' JSDoc tag
758+
759+
/* @internal */ ContainsRestParameterReference = 1 << 28, // If contains rest parameter reference
758760

759761
BlockScoped = Let | Const,
760762

tests/baselines/reference/accessorWithRestParam.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,12 @@ var C = /** @class */ (function () {
99
function C() {
1010
}
1111
Object.defineProperty(C.prototype, "X", {
12-
set: function () {
13-
var v = [];
14-
for (var _i = 0; _i < arguments.length; _i++) {
15-
v[_i] = arguments[_i];
16-
}
17-
},
12+
set: function () { },
1813
enumerable: false,
1914
configurable: true
2015
});
2116
Object.defineProperty(C, "X", {
22-
set: function () {
23-
var v2 = [];
24-
for (var _i = 0; _i < arguments.length; _i++) {
25-
v2[_i] = arguments[_i];
26-
}
27-
},
17+
set: function () { },
2818
enumerable: false,
2919
configurable: true
3020
});

tests/baselines/reference/arrayLiteralInNonVarArgParameter.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,5 @@ panic([], 'one', 'two');
55

66

77
//// [arrayLiteralInNonVarArgParameter.js]
8-
function panic(val) {
9-
var opt = [];
10-
for (var _i = 1; _i < arguments.length; _i++) {
11-
opt[_i - 1] = arguments[_i];
12-
}
13-
}
8+
function panic(val) { }
149
panic([], 'one', 'two');

tests/baselines/reference/assignmentCompatWithCallSignaturesWithRestParameters.js

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -49,49 +49,19 @@ var a4: (x?: number, y?: string, ...z: number[]) => number;
4949
// call signatures in derived types must have the same or fewer optional parameters as the target for assignment
5050
var a; // ok, same number of required params
5151
a = function () { return 1; }; // ok, same number of required params
52-
a = function () {
53-
var args = [];
54-
for (var _i = 0; _i < arguments.length; _i++) {
55-
args[_i] = arguments[_i];
56-
}
57-
return 1;
58-
}; // ok, same number of required params
59-
a = function () {
60-
var args = [];
61-
for (var _i = 0; _i < arguments.length; _i++) {
62-
args[_i] = arguments[_i];
63-
}
64-
return 1;
65-
}; // error, type mismatch
52+
a = function () { return 1; }; // ok, same number of required params
53+
a = function () { return 1; }; // error, type mismatch
6654
a = function (x) { return 1; }; // ok, same number of required params
6755
a = function (x, y, z) { return 1; }; // ok, same number of required params
6856
a = function (x) { return 1; }; // ok, rest param corresponds to infinite number of params
6957
a = function (x) { return 1; }; // error, incompatible type
7058
var a2;
7159
a2 = function () { return 1; }; // ok, fewer required params
72-
a2 = function () {
73-
var args = [];
74-
for (var _i = 0; _i < arguments.length; _i++) {
75-
args[_i] = arguments[_i];
76-
}
77-
return 1;
78-
}; // ok, fewer required params
60+
a2 = function () { return 1; }; // ok, fewer required params
7961
a2 = function (x) { return 1; }; // ok, fewer required params
8062
a2 = function (x) { return 1; }; // ok, same number of required params
81-
a2 = function (x) {
82-
var args = [];
83-
for (var _i = 1; _i < arguments.length; _i++) {
84-
args[_i - 1] = arguments[_i];
85-
}
86-
return 1;
87-
}; // ok, same number of required params
88-
a2 = function (x) {
89-
var args = [];
90-
for (var _i = 1; _i < arguments.length; _i++) {
91-
args[_i - 1] = arguments[_i];
92-
}
93-
return 1;
94-
}; // should be type mismatch error
63+
a2 = function (x) { return 1; }; // ok, same number of required params
64+
a2 = function (x) { return 1; }; // should be type mismatch error
9565
a2 = function (x, y) { return 1; }; // ok, rest param corresponds to infinite number of params
9666
a2 = function (x, y) { return 1; }; // ok, same number of required params
9767
var a3;
@@ -100,24 +70,12 @@ a3 = function (x) { return 1; }; // ok, fewer required params
10070
a3 = function (x) { return 1; }; // ok, same number of required params
10171
a3 = function (x, y) { return 1; }; // ok, all present params match
10272
a3 = function (x, y, z) { return 1; }; // error
103-
a3 = function (x) {
104-
var z = [];
105-
for (var _i = 1; _i < arguments.length; _i++) {
106-
z[_i - 1] = arguments[_i];
107-
}
108-
return 1;
109-
}; // error
73+
a3 = function (x) { return 1; }; // error
11074
a3 = function (x, y, z) { return 1; }; // error
11175
var a4;
11276
a4 = function () { return 1; }; // ok, fewer required params
11377
a4 = function (x, y) { return 1; }; // error, type mismatch
11478
a4 = function (x) { return 1; }; // ok, all present params match
11579
a4 = function (x, y) { return 1; }; // error, second param has type mismatch
11680
a4 = function (x, y) { return 1; }; // ok, same number of required params with matching types
117-
a4 = function (x) {
118-
var args = [];
119-
for (var _i = 1; _i < arguments.length; _i++) {
120-
args[_i - 1] = arguments[_i];
121-
}
122-
return 1;
123-
}; // error, rest params have type mismatch
81+
a4 = function (x) { return 1; }; // error, rest params have type mismatch

tests/baselines/reference/asyncArrowFunction11_es5.js

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,20 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
4848
var A = /** @class */ (function () {
4949
function A() {
5050
var _this = this;
51-
this.b = function () {
52-
var args = [];
53-
for (var _i = 0; _i < arguments.length; _i++) {
54-
args[_i] = arguments[_i];
55-
}
56-
return __awaiter(_this, void 0, void 0, function () {
57-
var obj;
58-
var _a;
59-
var _this = this;
60-
return __generator(this, function (_b) {
61-
switch (_b.label) {
62-
case 0: return [4 /*yield*/, Promise.resolve()];
63-
case 1:
64-
_b.sent();
65-
obj = (_a = {}, _a["a"] = function () { return _this; }, _a);
66-
return [2 /*return*/];
67-
}
68-
});
51+
this.b = function () { return __awaiter(_this, void 0, void 0, function () {
52+
var obj;
53+
var _a;
54+
var _this = this;
55+
return __generator(this, function (_b) {
56+
switch (_b.label) {
57+
case 0: return [4 /*yield*/, Promise.resolve()];
58+
case 1:
59+
_b.sent();
60+
obj = (_a = {}, _a["a"] = function () { return _this; }, _a);
61+
return [2 /*return*/];
62+
}
6963
});
70-
};
64+
}); };
7165
}
7266
return A;
7367
}());

tests/baselines/reference/baseTypeAfterDerivedType.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ interface Base2 {
2020
var Derived2 = /** @class */ (function () {
2121
function Derived2() {
2222
}
23-
Derived2.prototype.method = function () {
24-
var args = [];
25-
for (var _i = 0; _i < arguments.length; _i++) {
26-
args[_i] = arguments[_i];
27-
}
28-
};
23+
Derived2.prototype.method = function () { };
2924
return Derived2;
3025
}());

tests/baselines/reference/callWithSpread.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,6 @@ var __spreadArrays = (this && this.__spreadArrays) || function () {
8181
};
8282
var _a, _b, _c, _d, _e, _f, _g;
8383
function foo(x, y) {
84-
var z = [];
85-
for (var _i = 2; _i < arguments.length; _i++) {
86-
z[_i - 2] = arguments[_i];
87-
}
8884
}
8985
var a;
9086
var z;
@@ -119,10 +115,6 @@ var C = /** @class */ (function () {
119115
this.foo.apply(this, __spreadArrays([x, y], z));
120116
}
121117
C.prototype.foo = function (x, y) {
122-
var z = [];
123-
for (var _i = 2; _i < arguments.length; _i++) {
124-
z[_i - 2] = arguments[_i];
125-
}
126118
};
127119
return C;
128120
}());

tests/baselines/reference/checkSuperCallBeforeThisAccessing5.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ var __extends = (this && this.__extends) || (function () {
2323
})();
2424
var Based = /** @class */ (function () {
2525
function Based() {
26-
var arg = [];
27-
for (var _i = 0; _i < arguments.length; _i++) {
28-
arg[_i] = arguments[_i];
29-
}
3026
}
3127
return Based;
3228
}());

tests/baselines/reference/checkSuperCallBeforeThisAccessing6.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ var __extends = (this && this.__extends) || (function () {
2626
})();
2727
var Base = /** @class */ (function () {
2828
function Base() {
29-
var arg = [];
30-
for (var _i = 0; _i < arguments.length; _i++) {
31-
arg[_i] = arguments[_i];
32-
}
3329
}
3430
return Base;
3531
}());

tests/baselines/reference/checkSuperCallBeforeThisAccessing8.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ var __extends = (this && this.__extends) || (function () {
2626
})();
2727
var Base = /** @class */ (function () {
2828
function Base() {
29-
var arg = [];
30-
for (var _i = 0; _i < arguments.length; _i++) {
31-
arg[_i] = arguments[_i];
32-
}
3329
}
3430
return Base;
3531
}());

tests/baselines/reference/collisionArgumentsArrowFunctions.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,15 @@ var f2NoError = () => {
1818

1919
//// [collisionArgumentsArrowFunctions.js]
2020
var f1 = function (i) {
21-
var arguments = [];
22-
for (var _i = 1; _i < arguments.length; _i++) {
23-
arguments[_i - 1] = arguments[_i];
24-
}
2521
var arguments; // no error
2622
};
2723
var f12 = function (arguments) {
28-
var rest = [];
29-
for (var _i = 1; _i < arguments.length; _i++) {
30-
rest[_i - 1] = arguments[_i];
31-
}
3224
var arguments = 10; // no error
3325
};
3426
var f1NoError = function (arguments) {
3527
var arguments = 10; // no error
3628
};
3729
var f2 = function () {
38-
var restParameters = [];
39-
for (var _i = 0; _i < arguments.length; _i++) {
40-
restParameters[_i] = arguments[_i];
41-
}
4230
var arguments = 10; // No Error
4331
};
4432
var f2NoError = function () {

0 commit comments

Comments
 (0)