Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,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;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
}

Original file line number Diff line number Diff line change
@@ -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;
}());
Original file line number Diff line number Diff line change
@@ -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))
}

Original file line number Diff line number Diff line change
@@ -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
}

Original file line number Diff line number Diff line change
@@ -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.
}
Original file line number Diff line number Diff line change
@@ -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
}