check usage before declaration for decorators (#50372)

Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
Zzzen
2025-05-03 05:01:09 +08:00
committed by GitHub
parent e37ca49c70
commit 5e36778330
11 changed files with 1194 additions and 3 deletions

View File

@@ -3068,13 +3068,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return isForInOrOfStatement(grandparent) && isSameScopeDescendentOf(usage, grandparent.expression, declContainer);
}
function isUsedInFunctionOrInstanceProperty(usage: Node, declaration: Node): boolean {
function isUsedInFunctionOrInstanceProperty(usage: Node, declaration: Node) {
return isUsedInFunctionOrInstancePropertyWorker(usage, declaration);
}
function isUsedInFunctionOrInstancePropertyWorker(usage: Node, declaration: Node): boolean {
return !!findAncestor(usage, current => {
if (current === declContainer) {
return "quit";
}
if (isFunctionLike(current)) {
return true;
return !getImmediatelyInvokedFunctionExpression(current);
}
if (isClassStaticBlockDeclaration(current)) {
return declaration.pos < usage.pos;
@@ -3107,6 +3111,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
}
const decorator = tryCast(current.parent, isDecorator);
if (decorator && decorator.expression === current) {
if (isParameter(decorator.parent)) {
return isUsedInFunctionOrInstancePropertyWorker(decorator.parent.parent.parent, declaration) ? true : "quit";
}
if (isMethodDeclaration(decorator.parent)) {
return isUsedInFunctionOrInstancePropertyWorker(decorator.parent.parent, declaration) ? true : "quit";
}
}
return false;
});
}

View File

@@ -5,9 +5,12 @@ blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448: Block-scoped variable
blockScopedVariablesUseBeforeDef.ts(111,28): error TS2448: Block-scoped variable 'a' used before its declaration.
blockScopedVariablesUseBeforeDef.ts(112,21): error TS2448: Block-scoped variable 'a' used before its declaration.
blockScopedVariablesUseBeforeDef.ts(122,22): error TS2448: Block-scoped variable 'a' used before its declaration.
blockScopedVariablesUseBeforeDef.ts(128,9): error TS2448: Block-scoped variable 'foo' used before its declaration.
blockScopedVariablesUseBeforeDef.ts(131,9): error TS2448: Block-scoped variable 'foo' used before its declaration.
blockScopedVariablesUseBeforeDef.ts(153,20): error TS2450: Enum 'Enum' used before its declaration.
==== blockScopedVariablesUseBeforeDef.ts (7 errors) ====
==== blockScopedVariablesUseBeforeDef.ts (10 errors) ====
function foo0() {
let a = x;
~
@@ -157,9 +160,15 @@ blockScopedVariablesUseBeforeDef.ts(122,22): error TS2448: Block-scoped variable
const promise = (async () => {
promise
foo
~~~
!!! error TS2448: Block-scoped variable 'foo' used before its declaration.
!!! related TS2728 blockScopedVariablesUseBeforeDef.ts:134:11: 'foo' is declared here.
await null
promise
foo
~~~
!!! error TS2448: Block-scoped variable 'foo' used before its declaration.
!!! related TS2728 blockScopedVariablesUseBeforeDef.ts:134:11: 'foo' is declared here.
})()
const foo = 1;
@@ -179,4 +188,15 @@ blockScopedVariablesUseBeforeDef.ts(122,22): error TS2448: Block-scoped variable
yield 1;
})();
}
function foo18() {
let a = (() => Enum.Yes)();
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 blockScopedVariablesUseBeforeDef.ts:154:10: 'Enum' is declared here.
enum Enum {
No = 0,
Yes = 1,
}
}

View File

@@ -151,6 +151,14 @@ function wrapI2() {
yield 1;
})();
}
function foo18() {
let a = (() => Enum.Yes)();
enum Enum {
No = 0,
Yes = 1,
}
}
//// [blockScopedVariablesUseBeforeDef.js]
@@ -389,3 +397,11 @@ function wrapI2() {
});
})();
}
function foo18() {
var a = (function () { return Enum.Yes; })();
var Enum;
(function (Enum) {
Enum[Enum["No"] = 0] = "No";
Enum[Enum["Yes"] = 1] = "Yes";
})(Enum || (Enum = {}));
}

View File

@@ -312,3 +312,23 @@ function wrapI2() {
})();
}
function foo18() {
>foo18 : Symbol(foo18, Decl(blockScopedVariablesUseBeforeDef.ts, 149, 1))
let a = (() => Enum.Yes)();
>a : Symbol(a, Decl(blockScopedVariablesUseBeforeDef.ts, 152, 7))
>Enum.Yes : Symbol(Enum.Yes, Decl(blockScopedVariablesUseBeforeDef.ts, 154, 15))
>Enum : Symbol(Enum, Decl(blockScopedVariablesUseBeforeDef.ts, 152, 31))
>Yes : Symbol(Enum.Yes, Decl(blockScopedVariablesUseBeforeDef.ts, 154, 15))
enum Enum {
>Enum : Symbol(Enum, Decl(blockScopedVariablesUseBeforeDef.ts, 152, 31))
No = 0,
>No : Symbol(Enum.No, Decl(blockScopedVariablesUseBeforeDef.ts, 153, 15))
Yes = 1,
>Yes : Symbol(Enum.Yes, Decl(blockScopedVariablesUseBeforeDef.ts, 154, 15))
}
}

View File

@@ -510,3 +510,41 @@ function wrapI2() {
})();
}
function foo18() {
>foo18 : () => void
> : ^^^^^^^^^^
let a = (() => Enum.Yes)();
>a : Enum
> : ^^^^
>(() => Enum.Yes)() : Enum
> : ^^^^
>(() => Enum.Yes) : () => Enum
> : ^^^^^^^^^^
>() => Enum.Yes : () => Enum
> : ^^^^^^^^^^
>Enum.Yes : Enum.Yes
> : ^^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>Yes : Enum.Yes
> : ^^^^^^^^
enum Enum {
>Enum : Enum
> : ^^^^
No = 0,
>No : Enum.No
> : ^^^^^^^
>0 : 0
> : ^
Yes = 1,
>Yes : Enum.Yes
> : ^^^^^^^^
>1 : 1
> : ^
}
}

View File

@@ -0,0 +1,140 @@
decoratorUsedBeforeDeclaration.ts(1,2): error TS2448: Block-scoped variable 'lambda' used before its declaration.
decoratorUsedBeforeDeclaration.ts(1,9): error TS2450: Enum 'Enum' used before its declaration.
decoratorUsedBeforeDeclaration.ts(2,7): error TS2450: Enum 'Enum' used before its declaration.
decoratorUsedBeforeDeclaration.ts(4,4): error TS2448: Block-scoped variable 'lambda' used before its declaration.
decoratorUsedBeforeDeclaration.ts(4,11): error TS2450: Enum 'Enum' used before its declaration.
decoratorUsedBeforeDeclaration.ts(4,16): error TS2729: Property 'No' is used before its initialization.
decoratorUsedBeforeDeclaration.ts(5,9): error TS2450: Enum 'Enum' used before its declaration.
decoratorUsedBeforeDeclaration.ts(5,14): error TS2729: Property 'No' is used before its initialization.
decoratorUsedBeforeDeclaration.ts(12,4): error TS2448: Block-scoped variable 'lambda' used before its declaration.
decoratorUsedBeforeDeclaration.ts(12,11): error TS2450: Enum 'Enum' used before its declaration.
decoratorUsedBeforeDeclaration.ts(13,9): error TS2450: Enum 'Enum' used before its declaration.
decoratorUsedBeforeDeclaration.ts(18,4): error TS2448: Block-scoped variable 'lambda' used before its declaration.
decoratorUsedBeforeDeclaration.ts(24,11): error TS2448: Block-scoped variable 'lambda' used before its declaration.
decoratorUsedBeforeDeclaration.ts(24,18): error TS2450: Enum 'Enum' used before its declaration.
decoratorUsedBeforeDeclaration.ts(24,33): error TS2450: Enum 'Enum' used before its declaration.
decoratorUsedBeforeDeclaration.ts(28,11): error TS2448: Block-scoped variable 'lambda' used before its declaration.
==== decoratorUsedBeforeDeclaration.ts (16 errors) ====
@lambda(Enum.No)
~~~~~~
!!! error TS2448: Block-scoped variable 'lambda' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:40:7: 'lambda' is declared here.
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:35:6: 'Enum' is declared here.
@deco(Enum.No)
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:35:6: 'Enum' is declared here.
class Greeter {
@lambda(Enum.No)
~~~~~~
!!! error TS2448: Block-scoped variable 'lambda' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:40:7: 'lambda' is declared here.
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:35:6: 'Enum' is declared here.
~~
!!! error TS2729: Property 'No' is used before its initialization.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:36:3: 'No' is declared here.
@deco(Enum.No)
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:35:6: 'Enum' is declared here.
~~
!!! error TS2729: Property 'No' is used before its initialization.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:36:3: 'No' is declared here.
greeting: string;
constructor(message: string) {
this.greeting = message;
}
@lambda(Enum.No)
~~~~~~
!!! error TS2448: Block-scoped variable 'lambda' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:40:7: 'lambda' is declared here.
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:35:6: 'Enum' is declared here.
@deco(Enum.No)
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:35:6: 'Enum' is declared here.
greet() {
return "Hello, " + this.greeting;
}
@lambda
~~~~~~
!!! error TS2448: Block-scoped variable 'lambda' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:40:7: 'lambda' is declared here.
@deco
greet1() {
return "Hello, " + this.greeting;
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
~~~~~~
!!! error TS2448: Block-scoped variable 'lambda' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:40:7: 'lambda' is declared here.
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:35:6: 'Enum' is declared here.
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:35:6: 'Enum' is declared here.
return "Hello, " + this.greeting;
}
greet3(@lambda @deco param) {
~~~~~~
!!! error TS2448: Block-scoped variable 'lambda' used before its declaration.
!!! related TS2728 decoratorUsedBeforeDeclaration.ts:40:7: 'lambda' is declared here.
return "Hello, " + this.greeting;
}
}
function deco(...args: any[]): any {}
enum Enum {
No = 0,
Yes = 1,
}
const lambda = (...args: any[]): any => {};
@lambda(Enum.No)
@deco(Enum.No)
class Greeter1 {
@lambda(Enum.No)
@deco(Enum.No)
greeting: string;
constructor(message: string) {
this.greeting = message;
}
@lambda(Enum.No)
@deco(Enum.No)
greet() {
return "Hello, " + this.greeting;
}
@lambda
@deco
greet1() {
return "Hello, " + this.greeting;
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
return "Hello, " + this.greeting;
}
greet3(@lambda @deco param) {
return "Hello, " + this.greeting;
}
}

View File

@@ -0,0 +1,188 @@
//// [tests/cases/compiler/decoratorUsedBeforeDeclaration.ts] ////
//// [decoratorUsedBeforeDeclaration.ts]
@lambda(Enum.No)
@deco(Enum.No)
class Greeter {
@lambda(Enum.No)
@deco(Enum.No)
greeting: string;
constructor(message: string) {
this.greeting = message;
}
@lambda(Enum.No)
@deco(Enum.No)
greet() {
return "Hello, " + this.greeting;
}
@lambda
@deco
greet1() {
return "Hello, " + this.greeting;
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
return "Hello, " + this.greeting;
}
greet3(@lambda @deco param) {
return "Hello, " + this.greeting;
}
}
function deco(...args: any[]): any {}
enum Enum {
No = 0,
Yes = 1,
}
const lambda = (...args: any[]): any => {};
@lambda(Enum.No)
@deco(Enum.No)
class Greeter1 {
@lambda(Enum.No)
@deco(Enum.No)
greeting: string;
constructor(message: string) {
this.greeting = message;
}
@lambda(Enum.No)
@deco(Enum.No)
greet() {
return "Hello, " + this.greeting;
}
@lambda
@deco
greet1() {
return "Hello, " + this.greeting;
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
return "Hello, " + this.greeting;
}
greet3(@lambda @deco param) {
return "Hello, " + this.greeting;
}
}
//// [decoratorUsedBeforeDeclaration.js]
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var Greeter = /** @class */ (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
Greeter.prototype.greet1 = function () {
return "Hello, " + this.greeting;
};
Greeter.prototype.greet2 = function (param) {
return "Hello, " + this.greeting;
};
Greeter.prototype.greet3 = function (param) {
return "Hello, " + this.greeting;
};
__decorate([
lambda(Enum.No),
deco(Enum.No)
], Greeter.prototype, "greeting", void 0);
__decorate([
lambda(Enum.No),
deco(Enum.No)
], Greeter.prototype, "greet", null);
__decorate([
lambda,
deco
], Greeter.prototype, "greet1", null);
__decorate([
__param(0, lambda(Enum.No)),
__param(0, deco(Enum.No))
], Greeter.prototype, "greet2", null);
__decorate([
__param(0, lambda),
__param(0, deco)
], Greeter.prototype, "greet3", null);
Greeter = __decorate([
lambda(Enum.No),
deco(Enum.No)
], Greeter);
return Greeter;
}());
function deco() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
}
var Enum;
(function (Enum) {
Enum[Enum["No"] = 0] = "No";
Enum[Enum["Yes"] = 1] = "Yes";
})(Enum || (Enum = {}));
var lambda = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
};
var Greeter1 = /** @class */ (function () {
function Greeter1(message) {
this.greeting = message;
}
Greeter1.prototype.greet = function () {
return "Hello, " + this.greeting;
};
Greeter1.prototype.greet1 = function () {
return "Hello, " + this.greeting;
};
Greeter1.prototype.greet2 = function (param) {
return "Hello, " + this.greeting;
};
Greeter1.prototype.greet3 = function (param) {
return "Hello, " + this.greeting;
};
__decorate([
lambda(Enum.No),
deco(Enum.No)
], Greeter1.prototype, "greeting", void 0);
__decorate([
lambda(Enum.No),
deco(Enum.No)
], Greeter1.prototype, "greet", null);
__decorate([
lambda,
deco
], Greeter1.prototype, "greet1", null);
__decorate([
__param(0, lambda(Enum.No)),
__param(0, deco(Enum.No))
], Greeter1.prototype, "greet2", null);
__decorate([
__param(0, lambda),
__param(0, deco)
], Greeter1.prototype, "greet3", null);
Greeter1 = __decorate([
lambda(Enum.No),
deco(Enum.No)
], Greeter1);
return Greeter1;
}());

View File

@@ -0,0 +1,235 @@
//// [tests/cases/compiler/decoratorUsedBeforeDeclaration.ts] ////
=== decoratorUsedBeforeDeclaration.ts ===
@lambda(Enum.No)
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
@deco(Enum.No)
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
class Greeter {
>Greeter : Symbol(Greeter, Decl(decoratorUsedBeforeDeclaration.ts, 0, 0))
@lambda(Enum.No)
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
@deco(Enum.No)
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
greeting: string;
>greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
constructor(message: string) {
>message : Symbol(message, Decl(decoratorUsedBeforeDeclaration.ts, 7, 14))
this.greeting = message;
>this.greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
>this : Symbol(Greeter, Decl(decoratorUsedBeforeDeclaration.ts, 0, 0))
>greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
>message : Symbol(message, Decl(decoratorUsedBeforeDeclaration.ts, 7, 14))
}
@lambda(Enum.No)
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
@deco(Enum.No)
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
greet() {
>greet : Symbol(Greeter.greet, Decl(decoratorUsedBeforeDeclaration.ts, 9, 3))
return "Hello, " + this.greeting;
>this.greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
>this : Symbol(Greeter, Decl(decoratorUsedBeforeDeclaration.ts, 0, 0))
>greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
}
@lambda
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
@deco
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
greet1() {
>greet1 : Symbol(Greeter.greet1, Decl(decoratorUsedBeforeDeclaration.ts, 15, 3))
return "Hello, " + this.greeting;
>this.greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
>this : Symbol(Greeter, Decl(decoratorUsedBeforeDeclaration.ts, 0, 0))
>greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
>greet2 : Symbol(Greeter.greet2, Decl(decoratorUsedBeforeDeclaration.ts, 21, 3))
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>param : Symbol(param, Decl(decoratorUsedBeforeDeclaration.ts, 23, 9))
return "Hello, " + this.greeting;
>this.greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
>this : Symbol(Greeter, Decl(decoratorUsedBeforeDeclaration.ts, 0, 0))
>greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
}
greet3(@lambda @deco param) {
>greet3 : Symbol(Greeter.greet3, Decl(decoratorUsedBeforeDeclaration.ts, 25, 3))
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>param : Symbol(param, Decl(decoratorUsedBeforeDeclaration.ts, 27, 9))
return "Hello, " + this.greeting;
>this.greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
>this : Symbol(Greeter, Decl(decoratorUsedBeforeDeclaration.ts, 0, 0))
>greeting : Symbol(Greeter.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 2, 15))
}
}
function deco(...args: any[]): any {}
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>args : Symbol(args, Decl(decoratorUsedBeforeDeclaration.ts, 32, 14))
enum Enum {
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
No = 0,
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
Yes = 1,
>Yes : Symbol(Enum.Yes, Decl(decoratorUsedBeforeDeclaration.ts, 35, 9))
}
const lambda = (...args: any[]): any => {};
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>args : Symbol(args, Decl(decoratorUsedBeforeDeclaration.ts, 39, 16))
@lambda(Enum.No)
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
@deco(Enum.No)
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
class Greeter1 {
>Greeter1 : Symbol(Greeter1, Decl(decoratorUsedBeforeDeclaration.ts, 39, 43))
@lambda(Enum.No)
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
@deco(Enum.No)
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
greeting: string;
>greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
constructor(message: string) {
>message : Symbol(message, Decl(decoratorUsedBeforeDeclaration.ts, 48, 14))
this.greeting = message;
>this.greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
>this : Symbol(Greeter1, Decl(decoratorUsedBeforeDeclaration.ts, 39, 43))
>greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
>message : Symbol(message, Decl(decoratorUsedBeforeDeclaration.ts, 48, 14))
}
@lambda(Enum.No)
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
@deco(Enum.No)
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
greet() {
>greet : Symbol(Greeter1.greet, Decl(decoratorUsedBeforeDeclaration.ts, 50, 3))
return "Hello, " + this.greeting;
>this.greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
>this : Symbol(Greeter1, Decl(decoratorUsedBeforeDeclaration.ts, 39, 43))
>greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
}
@lambda
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
@deco
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
greet1() {
>greet1 : Symbol(Greeter1.greet1, Decl(decoratorUsedBeforeDeclaration.ts, 56, 3))
return "Hello, " + this.greeting;
>this.greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
>this : Symbol(Greeter1, Decl(decoratorUsedBeforeDeclaration.ts, 39, 43))
>greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
>greet2 : Symbol(Greeter1.greet2, Decl(decoratorUsedBeforeDeclaration.ts, 62, 3))
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>Enum.No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>Enum : Symbol(Enum, Decl(decoratorUsedBeforeDeclaration.ts, 32, 37))
>No : Symbol(Enum.No, Decl(decoratorUsedBeforeDeclaration.ts, 34, 11))
>param : Symbol(param, Decl(decoratorUsedBeforeDeclaration.ts, 64, 9))
return "Hello, " + this.greeting;
>this.greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
>this : Symbol(Greeter1, Decl(decoratorUsedBeforeDeclaration.ts, 39, 43))
>greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
}
greet3(@lambda @deco param) {
>greet3 : Symbol(Greeter1.greet3, Decl(decoratorUsedBeforeDeclaration.ts, 66, 3))
>lambda : Symbol(lambda, Decl(decoratorUsedBeforeDeclaration.ts, 39, 5))
>deco : Symbol(deco, Decl(decoratorUsedBeforeDeclaration.ts, 30, 1))
>param : Symbol(param, Decl(decoratorUsedBeforeDeclaration.ts, 68, 9))
return "Hello, " + this.greeting;
>this.greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
>this : Symbol(Greeter1, Decl(decoratorUsedBeforeDeclaration.ts, 39, 43))
>greeting : Symbol(Greeter1.greeting, Decl(decoratorUsedBeforeDeclaration.ts, 43, 16))
}
}

View File

@@ -0,0 +1,438 @@
//// [tests/cases/compiler/decoratorUsedBeforeDeclaration.ts] ////
=== decoratorUsedBeforeDeclaration.ts ===
@lambda(Enum.No)
>lambda(Enum.No) : any
> : ^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
@deco(Enum.No)
>deco(Enum.No) : any
> : ^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
class Greeter {
>Greeter : Greeter
> : ^^^^^^^
@lambda(Enum.No)
>lambda(Enum.No) : any
> : ^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
@deco(Enum.No)
>deco(Enum.No) : any
> : ^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
greeting: string;
>greeting : string
> : ^^^^^^
constructor(message: string) {
>message : string
> : ^^^^^^
this.greeting = message;
>this.greeting = message : string
> : ^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
>message : string
> : ^^^^^^
}
@lambda(Enum.No)
>lambda(Enum.No) : any
> : ^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
@deco(Enum.No)
>deco(Enum.No) : any
> : ^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
greet() {
>greet : () => string
> : ^^^^^^^^^^^^
return "Hello, " + this.greeting;
>"Hello, " + this.greeting : string
> : ^^^^^^
>"Hello, " : "Hello, "
> : ^^^^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
}
@lambda
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
@deco
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
greet1() {
>greet1 : () => string
> : ^^^^^^^^^^^^
return "Hello, " + this.greeting;
>"Hello, " + this.greeting : string
> : ^^^^^^
>"Hello, " : "Hello, "
> : ^^^^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
>greet2 : (param: any) => string
> : ^ ^^^^^^^^^^^^^^^^
>lambda(Enum.No) : any
> : ^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
>deco(Enum.No) : any
> : ^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
>param : any
> : ^^^
return "Hello, " + this.greeting;
>"Hello, " + this.greeting : string
> : ^^^^^^
>"Hello, " : "Hello, "
> : ^^^^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
}
greet3(@lambda @deco param) {
>greet3 : (param: any) => string
> : ^ ^^^^^^^^^^^^^^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>param : any
> : ^^^
return "Hello, " + this.greeting;
>"Hello, " + this.greeting : string
> : ^^^^^^
>"Hello, " : "Hello, "
> : ^^^^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
}
}
function deco(...args: any[]): any {}
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>args : any[]
> : ^^^^^
enum Enum {
>Enum : Enum
> : ^^^^
No = 0,
>No : Enum.No
> : ^^^^^^^
>0 : 0
> : ^
Yes = 1,
>Yes : Enum.Yes
> : ^^^^^^^^
>1 : 1
> : ^
}
const lambda = (...args: any[]): any => {};
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>(...args: any[]): any => {} : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>args : any[]
> : ^^^^^
@lambda(Enum.No)
>lambda(Enum.No) : any
> : ^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
@deco(Enum.No)
>deco(Enum.No) : any
> : ^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
class Greeter1 {
>Greeter1 : Greeter1
> : ^^^^^^^^
@lambda(Enum.No)
>lambda(Enum.No) : any
> : ^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
@deco(Enum.No)
>deco(Enum.No) : any
> : ^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
greeting: string;
>greeting : string
> : ^^^^^^
constructor(message: string) {
>message : string
> : ^^^^^^
this.greeting = message;
>this.greeting = message : string
> : ^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
>message : string
> : ^^^^^^
}
@lambda(Enum.No)
>lambda(Enum.No) : any
> : ^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
@deco(Enum.No)
>deco(Enum.No) : any
> : ^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
greet() {
>greet : () => string
> : ^^^^^^^^^^^^
return "Hello, " + this.greeting;
>"Hello, " + this.greeting : string
> : ^^^^^^
>"Hello, " : "Hello, "
> : ^^^^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
}
@lambda
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
@deco
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
greet1() {
>greet1 : () => string
> : ^^^^^^^^^^^^
return "Hello, " + this.greeting;
>"Hello, " + this.greeting : string
> : ^^^^^^
>"Hello, " : "Hello, "
> : ^^^^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
>greet2 : (param: any) => string
> : ^ ^^^^^^^^^^^^^^^^
>lambda(Enum.No) : any
> : ^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
>deco(Enum.No) : any
> : ^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>Enum.No : Enum.No
> : ^^^^^^^
>Enum : typeof Enum
> : ^^^^^^^^^^^
>No : Enum.No
> : ^^^^^^^
>param : any
> : ^^^
return "Hello, " + this.greeting;
>"Hello, " + this.greeting : string
> : ^^^^^^
>"Hello, " : "Hello, "
> : ^^^^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
}
greet3(@lambda @deco param) {
>greet3 : (param: any) => string
> : ^ ^^^^^^^^^^^^^^^^
>lambda : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>deco : (...args: any[]) => any
> : ^^^^ ^^ ^^^^^
>param : any
> : ^^^
return "Hello, " + this.greeting;
>"Hello, " + this.greeting : string
> : ^^^^^^
>"Hello, " : "Hello, "
> : ^^^^^^^^^
>this.greeting : string
> : ^^^^^^
>this : this
> : ^^^^
>greeting : string
> : ^^^^^^
}
}

View File

@@ -150,3 +150,11 @@ function wrapI2() {
yield 1;
})();
}
function foo18() {
let a = (() => Enum.Yes)();
enum Enum {
No = 0,
Yes = 1,
}
}

View File

@@ -0,0 +1,73 @@
// @experimentalDecorators: true
@lambda(Enum.No)
@deco(Enum.No)
class Greeter {
@lambda(Enum.No)
@deco(Enum.No)
greeting: string;
constructor(message: string) {
this.greeting = message;
}
@lambda(Enum.No)
@deco(Enum.No)
greet() {
return "Hello, " + this.greeting;
}
@lambda
@deco
greet1() {
return "Hello, " + this.greeting;
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
return "Hello, " + this.greeting;
}
greet3(@lambda @deco param) {
return "Hello, " + this.greeting;
}
}
function deco(...args: any[]): any {}
enum Enum {
No = 0,
Yes = 1,
}
const lambda = (...args: any[]): any => {};
@lambda(Enum.No)
@deco(Enum.No)
class Greeter1 {
@lambda(Enum.No)
@deco(Enum.No)
greeting: string;
constructor(message: string) {
this.greeting = message;
}
@lambda(Enum.No)
@deco(Enum.No)
greet() {
return "Hello, " + this.greeting;
}
@lambda
@deco
greet1() {
return "Hello, " + this.greeting;
}
greet2(@lambda(Enum.No) @deco(Enum.No) param) {
return "Hello, " + this.greeting;
}
greet3(@lambda @deco param) {
return "Hello, " + this.greeting;
}
}