Skip to content

Commit fba1dfb

Browse files
committed
Merge pull request #8201 from Microsoft/jsDocCommentAndEmit
Do not emit transform rest parameter if its declared as rest parameter type through jsDoc comment
2 parents d0cfe43 + 6f24144 commit fba1dfb

File tree

7 files changed

+253
-15
lines changed

7 files changed

+253
-15
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13815,7 +13815,7 @@ namespace ts {
1381513815

1381613816
function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) {
1381713817
// no rest parameters \ declaration context \ overload - no codegen impact
13818-
if (!hasRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
13818+
if (!hasDeclaredRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((<FunctionLikeDeclaration>node).body)) {
1381913819
return;
1382013820
}
1382113821

src/compiler/emitter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4487,7 +4487,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
44874487
}
44884488

44894489
function emitRestParameter(node: FunctionLikeDeclaration) {
4490-
if (languageVersion < ScriptTarget.ES6 && hasRestParameter(node)) {
4490+
if (languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node)) {
44914491
const restIndex = node.parameters.length - 1;
44924492
const restParam = node.parameters[restIndex];
44934493

@@ -4644,7 +4644,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
46444644
if (node) {
46454645
const parameters = node.parameters;
46464646
const skipCount = node.parameters.length && (<Identifier>node.parameters[0].name).text === "this" ? 1 : 0;
4647-
const omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameter(node) ? 1 : 0;
4647+
const omitCount = languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node) ? 1 : 0;
46484648
emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false);
46494649
}
46504650
write(")");

src/compiler/utilities.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,23 +1377,26 @@ namespace ts {
13771377
return isRestParameter(lastOrUndefined(s.parameters));
13781378
}
13791379

1380-
export function isRestParameter(node: ParameterDeclaration) {
1381-
if (node) {
1382-
if (node.flags & NodeFlags.JavaScriptFile) {
1383-
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) {
1384-
return true;
1385-
}
1380+
export function hasDeclaredRestParameter(s: SignatureDeclaration): boolean {
1381+
return isDeclaredRestParam(lastOrUndefined(s.parameters));
1382+
}
13861383

1387-
const paramTag = getCorrespondingJSDocParameterTag(node);
1388-
if (paramTag && paramTag.typeExpression) {
1389-
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType;
1390-
}
1384+
export function isRestParameter(node: ParameterDeclaration) {
1385+
if (node && (node.flags & NodeFlags.JavaScriptFile)) {
1386+
if (node.type && node.type.kind === SyntaxKind.JSDocVariadicType) {
1387+
return true;
13911388
}
13921389

1393-
return node.dotDotDotToken !== undefined;
1390+
const paramTag = getCorrespondingJSDocParameterTag(node);
1391+
if (paramTag && paramTag.typeExpression) {
1392+
return paramTag.typeExpression.type.kind === SyntaxKind.JSDocVariadicType;
1393+
}
13941394
}
1395+
return isDeclaredRestParam(node);
1396+
}
13951397

1396-
return false;
1398+
export function isDeclaredRestParam(node: ParameterDeclaration) {
1399+
return node && node.dotDotDotToken !== undefined;
13971400
}
13981401

13991402
export function isLiteralKind(kind: SyntaxKind): boolean {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//// [_apply.js]
2+
3+
/**
4+
* A faster alternative to `Function#apply`, this function invokes `func`
5+
* with the `this` binding of `thisArg` and the arguments of `args`.
6+
*
7+
* @private
8+
* @param {Function} func The function to invoke.
9+
* @param {*} thisArg The `this` binding of `func`.
10+
* @param {...*} args The arguments to invoke `func` with.
11+
* @returns {*} Returns the result of `func`.
12+
*/
13+
function apply(func, thisArg, args) {
14+
var length = args.length;
15+
switch (length) {
16+
case 0: return func.call(thisArg);
17+
case 1: return func.call(thisArg, args[0]);
18+
case 2: return func.call(thisArg, args[0], args[1]);
19+
case 3: return func.call(thisArg, args[0], args[1], args[2]);
20+
}
21+
return func.apply(thisArg, args);
22+
}
23+
24+
export default apply;
25+
26+
//// [apply.js]
27+
define("_apply", ["require", "exports"], function (require, exports) {
28+
"use strict";
29+
/**
30+
* A faster alternative to `Function#apply`, this function invokes `func`
31+
* with the `this` binding of `thisArg` and the arguments of `args`.
32+
*
33+
* @private
34+
* @param {Function} func The function to invoke.
35+
* @param {*} thisArg The `this` binding of `func`.
36+
* @param {...*} args The arguments to invoke `func` with.
37+
* @returns {*} Returns the result of `func`.
38+
*/
39+
function apply(func, thisArg, args) {
40+
var length = args.length;
41+
switch (length) {
42+
case 0: return func.call(thisArg);
43+
case 1: return func.call(thisArg, args[0]);
44+
case 2: return func.call(thisArg, args[0], args[1]);
45+
case 3: return func.call(thisArg, args[0], args[1], args[2]);
46+
}
47+
return func.apply(thisArg, args);
48+
}
49+
exports.__esModule = true;
50+
exports["default"] = apply;
51+
});
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
=== tests/cases/compiler/_apply.js ===
2+
3+
/**
4+
* A faster alternative to `Function#apply`, this function invokes `func`
5+
* with the `this` binding of `thisArg` and the arguments of `args`.
6+
*
7+
* @private
8+
* @param {Function} func The function to invoke.
9+
* @param {*} thisArg The `this` binding of `func`.
10+
* @param {...*} args The arguments to invoke `func` with.
11+
* @returns {*} Returns the result of `func`.
12+
*/
13+
function apply(func, thisArg, args) {
14+
>apply : Symbol(apply, Decl(_apply.js, 0, 0))
15+
>func : Symbol(func, Decl(_apply.js, 11, 15))
16+
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
17+
>args : Symbol(args, Decl(_apply.js, 11, 29))
18+
19+
var length = args.length;
20+
>length : Symbol(length, Decl(_apply.js, 12, 7))
21+
>args.length : Symbol(Array.length, Decl(lib.d.ts, --, --))
22+
>args : Symbol(args, Decl(_apply.js, 11, 29))
23+
>length : Symbol(Array.length, Decl(lib.d.ts, --, --))
24+
25+
switch (length) {
26+
>length : Symbol(length, Decl(_apply.js, 12, 7))
27+
28+
case 0: return func.call(thisArg);
29+
>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
30+
>func : Symbol(func, Decl(_apply.js, 11, 15))
31+
>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
32+
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
33+
34+
case 1: return func.call(thisArg, args[0]);
35+
>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
36+
>func : Symbol(func, Decl(_apply.js, 11, 15))
37+
>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
38+
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
39+
>args : Symbol(args, Decl(_apply.js, 11, 29))
40+
41+
case 2: return func.call(thisArg, args[0], args[1]);
42+
>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
43+
>func : Symbol(func, Decl(_apply.js, 11, 15))
44+
>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
45+
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
46+
>args : Symbol(args, Decl(_apply.js, 11, 29))
47+
>args : Symbol(args, Decl(_apply.js, 11, 29))
48+
49+
case 3: return func.call(thisArg, args[0], args[1], args[2]);
50+
>func.call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
51+
>func : Symbol(func, Decl(_apply.js, 11, 15))
52+
>call : Symbol(Function.call, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
53+
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
54+
>args : Symbol(args, Decl(_apply.js, 11, 29))
55+
>args : Symbol(args, Decl(_apply.js, 11, 29))
56+
>args : Symbol(args, Decl(_apply.js, 11, 29))
57+
}
58+
return func.apply(thisArg, args);
59+
>func.apply : Symbol(Function.apply, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
60+
>func : Symbol(func, Decl(_apply.js, 11, 15))
61+
>apply : Symbol(Function.apply, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
62+
>thisArg : Symbol(thisArg, Decl(_apply.js, 11, 20))
63+
>args : Symbol(args, Decl(_apply.js, 11, 29))
64+
}
65+
66+
export default apply;
67+
>apply : Symbol(apply, Decl(_apply.js, 0, 0))
68+
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
=== tests/cases/compiler/_apply.js ===
2+
3+
/**
4+
* A faster alternative to `Function#apply`, this function invokes `func`
5+
* with the `this` binding of `thisArg` and the arguments of `args`.
6+
*
7+
* @private
8+
* @param {Function} func The function to invoke.
9+
* @param {*} thisArg The `this` binding of `func`.
10+
* @param {...*} args The arguments to invoke `func` with.
11+
* @returns {*} Returns the result of `func`.
12+
*/
13+
function apply(func, thisArg, args) {
14+
>apply : (func: Function, thisArg: any, ...args: any[]) => any
15+
>func : Function
16+
>thisArg : any
17+
>args : any[]
18+
19+
var length = args.length;
20+
>length : number
21+
>args.length : number
22+
>args : any[]
23+
>length : number
24+
25+
switch (length) {
26+
>length : number
27+
28+
case 0: return func.call(thisArg);
29+
>0 : number
30+
>func.call(thisArg) : any
31+
>func.call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
32+
>func : Function
33+
>call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
34+
>thisArg : any
35+
36+
case 1: return func.call(thisArg, args[0]);
37+
>1 : number
38+
>func.call(thisArg, args[0]) : any
39+
>func.call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
40+
>func : Function
41+
>call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
42+
>thisArg : any
43+
>args[0] : any
44+
>args : any[]
45+
>0 : number
46+
47+
case 2: return func.call(thisArg, args[0], args[1]);
48+
>2 : number
49+
>func.call(thisArg, args[0], args[1]) : any
50+
>func.call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
51+
>func : Function
52+
>call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
53+
>thisArg : any
54+
>args[0] : any
55+
>args : any[]
56+
>0 : number
57+
>args[1] : any
58+
>args : any[]
59+
>1 : number
60+
61+
case 3: return func.call(thisArg, args[0], args[1], args[2]);
62+
>3 : number
63+
>func.call(thisArg, args[0], args[1], args[2]) : any
64+
>func.call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
65+
>func : Function
66+
>call : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, ...argArray: any[]): U; (this: Function, thisArg: any, ...argArray: any[]): any; }
67+
>thisArg : any
68+
>args[0] : any
69+
>args : any[]
70+
>0 : number
71+
>args[1] : any
72+
>args : any[]
73+
>1 : number
74+
>args[2] : any
75+
>args : any[]
76+
>2 : number
77+
}
78+
return func.apply(thisArg, args);
79+
>func.apply(thisArg, args) : any
80+
>func.apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
81+
>func : Function
82+
>apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
83+
>thisArg : any
84+
>args : any[]
85+
}
86+
87+
export default apply;
88+
>apply : (func: Function, thisArg: any, ...args: any[]) => any
89+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// @allowJs: true
2+
// @out: apply.js
3+
// @module: amd
4+
5+
// @filename: _apply.js
6+
/**
7+
* A faster alternative to `Function#apply`, this function invokes `func`
8+
* with the `this` binding of `thisArg` and the arguments of `args`.
9+
*
10+
* @private
11+
* @param {Function} func The function to invoke.
12+
* @param {*} thisArg The `this` binding of `func`.
13+
* @param {...*} args The arguments to invoke `func` with.
14+
* @returns {*} Returns the result of `func`.
15+
*/
16+
function apply(func, thisArg, args) {
17+
var length = args.length;
18+
switch (length) {
19+
case 0: return func.call(thisArg);
20+
case 1: return func.call(thisArg, args[0]);
21+
case 2: return func.call(thisArg, args[0], args[1]);
22+
case 3: return func.call(thisArg, args[0], args[1], args[2]);
23+
}
24+
return func.apply(thisArg, args);
25+
}
26+
27+
export default apply;

0 commit comments

Comments
 (0)