Skip to content

Commit 57eac1b

Browse files
authored
Merge pull request #9692 from Microsoft/fix-emit-with-this-and-rest-parameters
Fix emit with this and rest parameters
2 parents a2f45e9 + ebb0906 commit 57eac1b

9 files changed

+93
-12
lines changed

src/compiler/emitter.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4571,14 +4571,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
45714571

45724572
function emitRestParameter(node: FunctionLikeDeclaration) {
45734573
if (languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node)) {
4574-
const restIndex = node.parameters.length - 1;
4575-
const restParam = node.parameters[restIndex];
4574+
const restParam = node.parameters[node.parameters.length - 1];
45764575

45774576
// A rest parameter cannot have a binding pattern, so let's just ignore it if it does.
45784577
if (isBindingPattern(restParam.name)) {
45794578
return;
45804579
}
45814580

4581+
const skipThisCount = node.parameters.length && (<Identifier>node.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword ? 1 : 0;
4582+
const restIndex = node.parameters.length - 1 - skipThisCount;
45824583
const tempName = createTempVariable(TempFlags._i).text;
45834584
writeLine();
45844585
emitLeadingComments(restParam);
@@ -4726,7 +4727,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
47264727
write("(");
47274728
if (node) {
47284729
const parameters = node.parameters;
4729-
const skipCount = node.parameters.length && (<Identifier>node.parameters[0].name).text === "this" ? 1 : 0;
4730+
const skipCount = node.parameters.length && (<Identifier>node.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword ? 1 : 0;
47304731
const omitCount = languageVersion < ScriptTarget.ES6 && hasDeclaredRestParameter(node) ? 1 : 0;
47314732
emitList(parameters, skipCount, parameters.length - omitCount - skipCount, /*multiLine*/ false, /*trailingComma*/ false);
47324733
}
@@ -6156,10 +6157,11 @@ const _super = (function (geti, seti) {
61566157

61576158
if (valueDeclaration) {
61586159
const parameters = valueDeclaration.parameters;
6160+
const skipThisCount = parameters.length && (<Identifier>parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword ? 1 : 0;
61596161
const parameterCount = parameters.length;
6160-
if (parameterCount > 0) {
6161-
for (let i = 0; i < parameterCount; i++) {
6162-
if (i > 0) {
6162+
if (parameterCount > skipThisCount) {
6163+
for (let i = skipThisCount; i < parameterCount; i++) {
6164+
if (i > skipThisCount) {
61636165
write(", ");
61646166
}
61656167

tests/baselines/reference/emitDecoratorMetadata_restArgs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class A {
1414
class B {
1515
constructor(...args: number[]) {}
1616
@MyMethodDecorator
17-
method(...args: string[]) {}
17+
method(this: this, ...args: string[]) {}
1818
}
1919

2020

tests/baselines/reference/emitDecoratorMetadata_restArgs.symbols

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ class B {
3737
@MyMethodDecorator
3838
>MyMethodDecorator : Symbol(MyMethodDecorator, Decl(emitDecoratorMetadata_restArgs.ts, 2, 13))
3939

40-
method(...args: string[]) {}
40+
method(this: this, ...args: string[]) {}
4141
>method : Symbol(B.method, Decl(emitDecoratorMetadata_restArgs.ts, 13, 37))
42-
>args : Symbol(args, Decl(emitDecoratorMetadata_restArgs.ts, 15, 11))
42+
>this : Symbol(this, Decl(emitDecoratorMetadata_restArgs.ts, 15, 11))
43+
>args : Symbol(args, Decl(emitDecoratorMetadata_restArgs.ts, 15, 22))
4344
}
4445

tests/baselines/reference/emitDecoratorMetadata_restArgs.types

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ class B {
3737
@MyMethodDecorator
3838
>MyMethodDecorator : <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void
3939

40-
method(...args: string[]) {}
41-
>method : (...args: string[]) => void
40+
method(this: this, ...args: string[]) {}
41+
>method : (this: this, ...args: string[]) => void
42+
>this : this
4243
>args : string[]
4344
}
4445

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//// [emitSkipsThisWithRestParameter.ts]
2+
function rebase(fn: (base: any, ...args: any[]) => any): (...args: any[]) => any {
3+
return function(this: any, ...args: any[]) {
4+
return fn.apply(this, [ this ].concat(args));
5+
};
6+
}
7+
8+
9+
//// [emitSkipsThisWithRestParameter.js]
10+
function rebase(fn) {
11+
return function () {
12+
var args = [];
13+
for (var _i = 0; _i < arguments.length; _i++) {
14+
args[_i - 0] = arguments[_i];
15+
}
16+
return fn.apply(this, [this].concat(args));
17+
};
18+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
=== tests/cases/compiler/emitSkipsThisWithRestParameter.ts ===
2+
function rebase(fn: (base: any, ...args: any[]) => any): (...args: any[]) => any {
3+
>rebase : Symbol(rebase, Decl(emitSkipsThisWithRestParameter.ts, 0, 0))
4+
>fn : Symbol(fn, Decl(emitSkipsThisWithRestParameter.ts, 0, 16))
5+
>base : Symbol(base, Decl(emitSkipsThisWithRestParameter.ts, 0, 21))
6+
>args : Symbol(args, Decl(emitSkipsThisWithRestParameter.ts, 0, 31))
7+
>args : Symbol(args, Decl(emitSkipsThisWithRestParameter.ts, 0, 58))
8+
9+
return function(this: any, ...args: any[]) {
10+
>this : Symbol(this, Decl(emitSkipsThisWithRestParameter.ts, 1, 20))
11+
>args : Symbol(args, Decl(emitSkipsThisWithRestParameter.ts, 1, 30))
12+
13+
return fn.apply(this, [ this ].concat(args));
14+
>fn.apply : Symbol(Function.apply, Decl(lib.d.ts, --, --))
15+
>fn : Symbol(fn, Decl(emitSkipsThisWithRestParameter.ts, 0, 16))
16+
>apply : Symbol(Function.apply, Decl(lib.d.ts, --, --))
17+
>this : Symbol(this, Decl(emitSkipsThisWithRestParameter.ts, 1, 20))
18+
>[ this ].concat : Symbol(Array.concat, Decl(lib.d.ts, --, --))
19+
>this : Symbol(this, Decl(emitSkipsThisWithRestParameter.ts, 1, 20))
20+
>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --))
21+
>args : Symbol(args, Decl(emitSkipsThisWithRestParameter.ts, 1, 30))
22+
23+
};
24+
}
25+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== tests/cases/compiler/emitSkipsThisWithRestParameter.ts ===
2+
function rebase(fn: (base: any, ...args: any[]) => any): (...args: any[]) => any {
3+
>rebase : (fn: (base: any, ...args: any[]) => any) => (...args: any[]) => any
4+
>fn : (base: any, ...args: any[]) => any
5+
>base : any
6+
>args : any[]
7+
>args : any[]
8+
9+
return function(this: any, ...args: any[]) {
10+
>function(this: any, ...args: any[]) { return fn.apply(this, [ this ].concat(args)); } : (this: any, ...args: any[]) => any
11+
>this : any
12+
>args : any[]
13+
14+
return fn.apply(this, [ this ].concat(args));
15+
>fn.apply(this, [ this ].concat(args)) : any
16+
>fn.apply : (this: Function, thisArg: any, argArray?: any) => any
17+
>fn : (base: any, ...args: any[]) => any
18+
>apply : (this: Function, thisArg: any, argArray?: any) => any
19+
>this : any
20+
>[ this ].concat(args) : any[]
21+
>[ this ].concat : (...items: any[]) => any[]
22+
>[ this ] : any[]
23+
>this : any
24+
>concat : (...items: any[]) => any[]
25+
>args : any[]
26+
27+
};
28+
}
29+

tests/cases/compiler/emitDecoratorMetadata_restArgs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ class A {
1616
class B {
1717
constructor(...args: number[]) {}
1818
@MyMethodDecorator
19-
method(...args: string[]) {}
19+
method(this: this, ...args: string[]) {}
2020
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function rebase(fn: (base: any, ...args: any[]) => any): (...args: any[]) => any {
2+
return function(this: any, ...args: any[]) {
3+
return fn.apply(this, [ this ].concat(args));
4+
};
5+
}

0 commit comments

Comments
 (0)