mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 11:54:44 -06:00
Add used-before-declaration errors for class refs inside computed names (#23784)
This commit is contained in:
parent
96b2cf8aba
commit
0c244d86b3
@ -1111,6 +1111,10 @@ namespace ts {
|
||||
// still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
|
||||
return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration as VariableDeclaration, usage);
|
||||
}
|
||||
else if (isClassDeclaration(declaration)) {
|
||||
// still might be illegal if the usage is within a computed property name in the class (eg class A { static p = "a"; [A.p]() {} })
|
||||
return !findAncestor(usage, n => isComputedPropertyName(n) && n.parent.parent === declaration);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(5,22): error TS2449: Class 'A' used before its declaration.
|
||||
tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(6,13): error TS2449: Class 'A' used before its declaration.
|
||||
tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(7,6): error TS2449: Class 'A' used before its declaration.
|
||||
tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(8,6): error TS2449: Class 'A' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts (4 errors) ====
|
||||
class A {
|
||||
static readonly p1 = Symbol();
|
||||
static readonly p2 = Symbol();
|
||||
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
|
||||
static readonly [A.p1] = 0;
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
static [A.p2]() { return 0 };
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
[A.p1]() { }
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
[A.p2] = 0
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
//// [classDeclarationShouldBeOutOfScopeInComputedNames.ts]
|
||||
class A {
|
||||
static readonly p1 = Symbol();
|
||||
static readonly p2 = Symbol();
|
||||
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
|
||||
static readonly [A.p1] = 0;
|
||||
static [A.p2]() { return 0 };
|
||||
[A.p1]() { }
|
||||
[A.p2] = 0
|
||||
}
|
||||
|
||||
|
||||
//// [classDeclarationShouldBeOutOfScopeInComputedNames.js]
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
this[_a] = 0;
|
||||
}
|
||||
A[(_b = A.p1, A.p2)] = function () { return 0; };
|
||||
;
|
||||
A.prototype[A.p1] = function () { };
|
||||
_a = A.p2;
|
||||
A.p1 = Symbol();
|
||||
A.p2 = Symbol();
|
||||
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
|
||||
A[_b] = 0;
|
||||
return A;
|
||||
var _b, _a;
|
||||
}());
|
||||
@ -0,0 +1,38 @@
|
||||
=== tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts ===
|
||||
class A {
|
||||
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
|
||||
|
||||
static readonly p1 = Symbol();
|
||||
>p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --))
|
||||
|
||||
static readonly p2 = Symbol();
|
||||
>p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --))
|
||||
|
||||
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
|
||||
static readonly [A.p1] = 0;
|
||||
>[A.p1] : Symbol(A[A.p1], Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 2, 34))
|
||||
>A.p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
|
||||
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
|
||||
>p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
|
||||
|
||||
static [A.p2]() { return 0 };
|
||||
>[A.p2] : Symbol(A[A.p2], Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 4, 31))
|
||||
>A.p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
|
||||
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
|
||||
>p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
|
||||
|
||||
[A.p1]() { }
|
||||
>[A.p1] : Symbol(A[A.p1], Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 5, 33))
|
||||
>A.p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
|
||||
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
|
||||
>p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
|
||||
|
||||
[A.p2] = 0
|
||||
>[A.p2] : Symbol(A[A.p2], Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 6, 16))
|
||||
>A.p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
|
||||
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
|
||||
>p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
=== tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts ===
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
static readonly p1 = Symbol();
|
||||
>p1 : unique symbol
|
||||
>Symbol() : unique symbol
|
||||
>Symbol : SymbolConstructor
|
||||
|
||||
static readonly p2 = Symbol();
|
||||
>p2 : unique symbol
|
||||
>Symbol() : unique symbol
|
||||
>Symbol : SymbolConstructor
|
||||
|
||||
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
|
||||
static readonly [A.p1] = 0;
|
||||
>[A.p1] : 0
|
||||
>A.p1 : unique symbol
|
||||
>A : typeof A
|
||||
>p1 : unique symbol
|
||||
>0 : 0
|
||||
|
||||
static [A.p2]() { return 0 };
|
||||
>[A.p2] : () => number
|
||||
>A.p2 : unique symbol
|
||||
>A : typeof A
|
||||
>p2 : unique symbol
|
||||
>0 : 0
|
||||
|
||||
[A.p1]() { }
|
||||
>[A.p1] : () => void
|
||||
>A.p1 : unique symbol
|
||||
>A : typeof A
|
||||
>p1 : unique symbol
|
||||
|
||||
[A.p2] = 0
|
||||
>[A.p2] : number
|
||||
>A.p2 : unique symbol
|
||||
>A : typeof A
|
||||
>p2 : unique symbol
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts(3,10): error TS2449: Class 'C' used before its declaration.
|
||||
tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts(6,10): error TS2449: Class 'C' used before its declaration.
|
||||
tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts(9,6): error TS2449: Class 'C' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts (3 errors) ====
|
||||
class C {
|
||||
static staticProp = 10;
|
||||
get [C.staticProp]() {
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
return "hello";
|
||||
}
|
||||
set [C.staticProp](x: string) {
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
var y = x;
|
||||
}
|
||||
[C.staticProp]() { }
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
// @lib: es6
|
||||
class A {
|
||||
static readonly p1 = Symbol();
|
||||
static readonly p2 = Symbol();
|
||||
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
|
||||
static readonly [A.p1] = 0;
|
||||
static [A.p2]() { return 0 };
|
||||
[A.p1]() { }
|
||||
[A.p2] = 0
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user