mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Corrected parsing for decorators on 'this' parameters (#43175)
* Corrected parsing for decorators on 'this' parameters * Moved checking to parser and added a specific test * Remove unrelated checker.ts blank line * Missed some baseeline updates...
This commit is contained in:
@@ -1360,6 +1360,10 @@
|
||||
"category": "Error",
|
||||
"code": 1432
|
||||
},
|
||||
"Decorators may not be applied to 'this' parameters.": {
|
||||
"category": "Error",
|
||||
"code": 1433
|
||||
},
|
||||
|
||||
"The types of '{0}' are incompatible between these types.": {
|
||||
"category": "Error",
|
||||
|
||||
+13
-6
@@ -2991,9 +2991,16 @@ namespace ts {
|
||||
function parseParameterWorker(inOuterAwaitContext: boolean): ParameterDeclaration {
|
||||
const pos = getNodePos();
|
||||
const hasJSDoc = hasPrecedingJSDocComment();
|
||||
|
||||
// FormalParameter [Yield,Await]:
|
||||
// BindingElement[?Yield,?Await]
|
||||
|
||||
// Decorators are parsed in the outer [Await] context, the rest of the parameter is parsed in the function's [Await] context.
|
||||
const decorators = inOuterAwaitContext ? doInAwaitContext(parseDecorators) : parseDecorators();
|
||||
|
||||
if (token() === SyntaxKind.ThisKeyword) {
|
||||
const node = factory.createParameterDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
decorators,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
createIdentifier(/*isIdentifier*/ true),
|
||||
@@ -3001,14 +3008,14 @@ namespace ts {
|
||||
parseTypeAnnotation(),
|
||||
/*initializer*/ undefined
|
||||
);
|
||||
|
||||
if (decorators) {
|
||||
parseErrorAtRange(decorators[0], Diagnostics.Decorators_may_not_be_applied_to_this_parameters);
|
||||
}
|
||||
|
||||
return withJSDoc(finishNode(node, pos), hasJSDoc);
|
||||
}
|
||||
|
||||
// FormalParameter [Yield,Await]:
|
||||
// BindingElement[?Yield,?Await]
|
||||
|
||||
// Decorators are parsed in the outer [Await] context, the rest of the parameter is parsed in the function's [Await] context.
|
||||
const decorators = inOuterAwaitContext ? doInAwaitContext(parseDecorators) : parseDecorators();
|
||||
const savedTopLevel = topLevel;
|
||||
topLevel = false;
|
||||
const modifiers = parseModifiers();
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodThisParameter.ts(4,17): error TS1359: Identifier expected. 'this' is a reserved word that cannot be used here.
|
||||
tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodThisParameter.ts(4,17): error TS2680: A 'this' parameter must be the first parameter.
|
||||
tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodThisParameter.ts(4,12): error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodThisParameter.ts(8,29): error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodThisParameter.ts(8,30): error TS2680: A 'this' parameter must be the first parameter.
|
||||
|
||||
|
||||
==== tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodThisParameter.ts (2 errors) ====
|
||||
==== tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodThisParameter.ts (3 errors) ====
|
||||
declare function dec(target: Object, propertyKey: string | symbol, parameterIndex: number): void;
|
||||
|
||||
class C {
|
||||
method(@dec this: C) {}
|
||||
~~~~
|
||||
!!! error TS1359: Identifier expected. 'this' is a reserved word that cannot be used here.
|
||||
~~~~~~~
|
||||
~~~~
|
||||
!!! error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
}
|
||||
|
||||
class C2 {
|
||||
method(@dec allowed: C2, @dec this: C2) {}
|
||||
~~~~~
|
||||
!!! error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2680: A 'this' parameter must be the first parameter.
|
||||
}
|
||||
@@ -3,6 +3,10 @@ declare function dec(target: Object, propertyKey: string | symbol, parameterInde
|
||||
|
||||
class C {
|
||||
method(@dec this: C) {}
|
||||
}
|
||||
|
||||
class C2 {
|
||||
method(@dec allowed: C2, @dec this: C2) {}
|
||||
}
|
||||
|
||||
//// [decoratorOnClassMethodThisParameter.js]
|
||||
@@ -19,8 +23,14 @@ var C = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
C.prototype.method = function () { };
|
||||
__decorate([
|
||||
__param(0, dec)
|
||||
], C.prototype, "method", null);
|
||||
return C;
|
||||
}());
|
||||
var C2 = /** @class */ (function () {
|
||||
function C2() {
|
||||
}
|
||||
C2.prototype.method = function (allowed) { };
|
||||
__decorate([
|
||||
__param(0, dec), __param(1, dec)
|
||||
], C2.prototype, "method", null);
|
||||
return C2;
|
||||
}());
|
||||
|
||||
@@ -12,7 +12,19 @@ class C {
|
||||
method(@dec this: C) {}
|
||||
>method : Symbol(C.method, Decl(decoratorOnClassMethodThisParameter.ts, 2, 9))
|
||||
>dec : Symbol(dec, Decl(decoratorOnClassMethodThisParameter.ts, 0, 0))
|
||||
> : Symbol((Missing), Decl(decoratorOnClassMethodThisParameter.ts, 3, 11))
|
||||
>this : Symbol(this, Decl(decoratorOnClassMethodThisParameter.ts, 3, 15))
|
||||
>this : Symbol(this, Decl(decoratorOnClassMethodThisParameter.ts, 3, 11))
|
||||
>C : Symbol(C, Decl(decoratorOnClassMethodThisParameter.ts, 0, 97))
|
||||
}
|
||||
|
||||
class C2 {
|
||||
>C2 : Symbol(C2, Decl(decoratorOnClassMethodThisParameter.ts, 4, 1))
|
||||
|
||||
method(@dec allowed: C2, @dec this: C2) {}
|
||||
>method : Symbol(C2.method, Decl(decoratorOnClassMethodThisParameter.ts, 6, 10))
|
||||
>dec : Symbol(dec, Decl(decoratorOnClassMethodThisParameter.ts, 0, 0))
|
||||
>allowed : Symbol(allowed, Decl(decoratorOnClassMethodThisParameter.ts, 7, 11))
|
||||
>C2 : Symbol(C2, Decl(decoratorOnClassMethodThisParameter.ts, 4, 1))
|
||||
>dec : Symbol(dec, Decl(decoratorOnClassMethodThisParameter.ts, 0, 0))
|
||||
>this : Symbol(this, Decl(decoratorOnClassMethodThisParameter.ts, 7, 28))
|
||||
>C2 : Symbol(C2, Decl(decoratorOnClassMethodThisParameter.ts, 4, 1))
|
||||
}
|
||||
|
||||
@@ -9,8 +9,18 @@ class C {
|
||||
>C : C
|
||||
|
||||
method(@dec this: C) {}
|
||||
>method : (: any, this: C) => void
|
||||
>method : (this: C) => void
|
||||
>dec : (target: Object, propertyKey: string | symbol, parameterIndex: number) => void
|
||||
> : any
|
||||
>this : C
|
||||
}
|
||||
|
||||
class C2 {
|
||||
>C2 : C2
|
||||
|
||||
method(@dec allowed: C2, @dec this: C2) {}
|
||||
>method : (allowed: C2, this: C2) => void
|
||||
>dec : (target: Object, propertyKey: string | symbol, parameterIndex: number) => void
|
||||
>allowed : C2
|
||||
>dec : (target: Object, propertyKey: string | symbol, parameterIndex: number) => void
|
||||
>this : C2
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
tests/cases/conformance/decorators/invalid/decoratorOnFunctionParameter.ts(5,17): error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
tests/cases/conformance/decorators/invalid/decoratorOnFunctionParameter.ts(6,17): error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
|
||||
|
||||
==== tests/cases/conformance/decorators/invalid/decoratorOnFunctionParameter.ts (2 errors) ====
|
||||
declare const dec: any;
|
||||
|
||||
class C { n = true; }
|
||||
|
||||
function direct(@dec this: C) { return this.n; }
|
||||
~~~~
|
||||
!!! error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
function called(@dec() this: C) { return this.n; }
|
||||
~~~~~~
|
||||
!!! error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
@@ -0,0 +1,17 @@
|
||||
//// [decoratorOnFunctionParameter.ts]
|
||||
declare const dec: any;
|
||||
|
||||
class C { n = true; }
|
||||
|
||||
function direct(@dec this: C) { return this.n; }
|
||||
function called(@dec() this: C) { return this.n; }
|
||||
|
||||
//// [decoratorOnFunctionParameter.js]
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
this.n = true;
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
function direct() { return this.n; }
|
||||
function called() { return this.n; }
|
||||
@@ -0,0 +1,26 @@
|
||||
=== tests/cases/conformance/decorators/invalid/decoratorOnFunctionParameter.ts ===
|
||||
declare const dec: any;
|
||||
>dec : Symbol(dec, Decl(decoratorOnFunctionParameter.ts, 0, 13))
|
||||
|
||||
class C { n = true; }
|
||||
>C : Symbol(C, Decl(decoratorOnFunctionParameter.ts, 0, 23))
|
||||
>n : Symbol(C.n, Decl(decoratorOnFunctionParameter.ts, 2, 9))
|
||||
|
||||
function direct(@dec this: C) { return this.n; }
|
||||
>direct : Symbol(direct, Decl(decoratorOnFunctionParameter.ts, 2, 21))
|
||||
>dec : Symbol(dec, Decl(decoratorOnFunctionParameter.ts, 0, 13))
|
||||
>this : Symbol(this, Decl(decoratorOnFunctionParameter.ts, 4, 16))
|
||||
>C : Symbol(C, Decl(decoratorOnFunctionParameter.ts, 0, 23))
|
||||
>this.n : Symbol(C.n, Decl(decoratorOnFunctionParameter.ts, 2, 9))
|
||||
>this : Symbol(this, Decl(decoratorOnFunctionParameter.ts, 4, 16))
|
||||
>n : Symbol(C.n, Decl(decoratorOnFunctionParameter.ts, 2, 9))
|
||||
|
||||
function called(@dec() this: C) { return this.n; }
|
||||
>called : Symbol(called, Decl(decoratorOnFunctionParameter.ts, 4, 48))
|
||||
>dec : Symbol(dec, Decl(decoratorOnFunctionParameter.ts, 0, 13))
|
||||
>this : Symbol(this, Decl(decoratorOnFunctionParameter.ts, 5, 16))
|
||||
>C : Symbol(C, Decl(decoratorOnFunctionParameter.ts, 0, 23))
|
||||
>this.n : Symbol(C.n, Decl(decoratorOnFunctionParameter.ts, 2, 9))
|
||||
>this : Symbol(this, Decl(decoratorOnFunctionParameter.ts, 5, 16))
|
||||
>n : Symbol(C.n, Decl(decoratorOnFunctionParameter.ts, 2, 9))
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
=== tests/cases/conformance/decorators/invalid/decoratorOnFunctionParameter.ts ===
|
||||
declare const dec: any;
|
||||
>dec : any
|
||||
|
||||
class C { n = true; }
|
||||
>C : C
|
||||
>n : boolean
|
||||
>true : true
|
||||
|
||||
function direct(@dec this: C) { return this.n; }
|
||||
>direct : (this: C) => boolean
|
||||
>dec : any
|
||||
>this : C
|
||||
>this.n : boolean
|
||||
>this : C
|
||||
>n : boolean
|
||||
|
||||
function called(@dec() this: C) { return this.n; }
|
||||
>called : (this: C) => boolean
|
||||
>dec() : any
|
||||
>dec : any
|
||||
>this : C
|
||||
>this.n : boolean
|
||||
>this : C
|
||||
>n : boolean
|
||||
|
||||
@@ -79,8 +79,7 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(168,26): e
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(169,23): error TS1359: Identifier expected. 'this' is a reserved word that cannot be used here.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(169,23): error TS2680: A 'this' parameter must be the first parameter.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(170,23): error TS1005: ',' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,28): error TS1359: Identifier expected. 'this' is a reserved word that cannot be used here.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,28): error TS2680: A 'this' parameter must be the first parameter.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(171,20): error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,30): error TS1005: ',' expected.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,32): error TS1359: Identifier expected. 'new' is a reserved word that cannot be used here.
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(172,37): error TS1005: ',' expected.
|
||||
@@ -95,7 +94,7 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(177,19): e
|
||||
tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(178,22): error TS2730: An arrow function cannot have a 'this' parameter.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (65 errors) ====
|
||||
==== tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts (64 errors) ====
|
||||
class C {
|
||||
n: number;
|
||||
explicitThis(this: this, m: number): number {
|
||||
@@ -407,10 +406,8 @@ tests/cases/conformance/types/thisType/thisTypeInFunctionsNegative.ts(178,22): e
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
function decorated(@deco() this: C): number { return this.n; }
|
||||
~~~~
|
||||
!!! error TS1359: Identifier expected. 'this' is a reserved word that cannot be used here.
|
||||
~~~~~~~
|
||||
!!! error TS2680: A 'this' parameter must be the first parameter.
|
||||
~~~~~~~
|
||||
!!! error TS1433: Decorators may not be applied to 'this' parameters.
|
||||
function initializer(this: C = new C()): number { return this.n; }
|
||||
~
|
||||
!!! error TS1005: ',' expected.
|
||||
|
||||
@@ -646,9 +646,11 @@ function optional(this?: C): number { return this.n; }
|
||||
|
||||
function decorated(@deco() this: C): number { return this.n; }
|
||||
>decorated : Symbol(decorated, Decl(thisTypeInFunctionsNegative.ts, 169, 54))
|
||||
> : Symbol((Missing), Decl(thisTypeInFunctionsNegative.ts, 170, 19))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctionsNegative.ts, 170, 26))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctionsNegative.ts, 170, 19))
|
||||
>C : Symbol(C, Decl(thisTypeInFunctionsNegative.ts, 0, 0))
|
||||
>this.n : Symbol(C.n, Decl(thisTypeInFunctionsNegative.ts, 0, 9))
|
||||
>this : Symbol(this, Decl(thisTypeInFunctionsNegative.ts, 170, 19))
|
||||
>n : Symbol(C.n, Decl(thisTypeInFunctionsNegative.ts, 0, 9))
|
||||
|
||||
function initializer(this: C = new C()): number { return this.n; }
|
||||
>initializer : Symbol(initializer, Decl(thisTypeInFunctionsNegative.ts, 170, 62))
|
||||
|
||||
@@ -733,14 +733,13 @@ function optional(this?: C): number { return this.n; }
|
||||
>n : any
|
||||
|
||||
function decorated(@deco() this: C): number { return this.n; }
|
||||
>decorated : (: any, this: C) => number
|
||||
>decorated : (this: C) => number
|
||||
>deco() : any
|
||||
>deco : any
|
||||
> : any
|
||||
>this : C
|
||||
>this.n : any
|
||||
>this : any
|
||||
>n : any
|
||||
>this.n : number
|
||||
>this : C
|
||||
>n : number
|
||||
|
||||
function initializer(this: C = new C()): number { return this.n; }
|
||||
>initializer : (this: C, : any, C: any) => any
|
||||
|
||||
+4
@@ -4,4 +4,8 @@ declare function dec(target: Object, propertyKey: string | symbol, parameterInde
|
||||
|
||||
class C {
|
||||
method(@dec this: C) {}
|
||||
}
|
||||
|
||||
class C2 {
|
||||
method(@dec allowed: C2, @dec this: C2) {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
declare const dec: any;
|
||||
|
||||
class C { n = true; }
|
||||
|
||||
function direct(@dec this: C) { return this.n; }
|
||||
function called(@dec() this: C) { return this.n; }
|
||||
Reference in New Issue
Block a user