mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-10 15:25:54 -06:00
Merge pull request #15010 from Microsoft/static-initialisers-can-refer-to-later-static-methods
Static initializers may refer to later static methods
This commit is contained in:
commit
c62cc3fea3
@ -751,6 +751,7 @@ namespace ts {
|
||||
// declaration is after usage, but it can still be legal if usage is deferred:
|
||||
// 1. inside a function
|
||||
// 2. inside an instance property initializer, a reference to a non-instance property
|
||||
// 3. inside a static property initializer, a reference to a static method in the same class
|
||||
const container = getEnclosingBlockScopeContainer(declaration);
|
||||
return isUsedInFunctionOrInstanceProperty(usage, declaration, container);
|
||||
|
||||
@ -792,14 +793,22 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
const initializerOfInstanceProperty = current.parent &&
|
||||
const initializerOfProperty = current.parent &&
|
||||
current.parent.kind === SyntaxKind.PropertyDeclaration &&
|
||||
(getModifierFlags(current.parent) & ModifierFlags.Static) === 0 &&
|
||||
(<PropertyDeclaration>current.parent).initializer === current;
|
||||
|
||||
if (initializerOfInstanceProperty) {
|
||||
const isDeclarationInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !(getModifierFlags(declaration) & ModifierFlags.Static);
|
||||
return !isDeclarationInstanceProperty || getContainingClass(usage) !== getContainingClass(declaration);
|
||||
if (initializerOfProperty) {
|
||||
if (getModifierFlags(current.parent) & ModifierFlags.Static) {
|
||||
if (declaration.kind === SyntaxKind.MethodDeclaration) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const isDeclarationInstanceProperty = declaration.kind === SyntaxKind.PropertyDeclaration && !(getModifierFlags(declaration) & ModifierFlags.Static);
|
||||
if (!isDeclarationInstanceProperty || getContainingClass(usage) !== getContainingClass(declaration)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current = current.parent;
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
tests/cases/compiler/scopeCheckStaticInitializer.ts(2,38): error TS2448: Block-scoped variable 'data' used before its declaration.
|
||||
tests/cases/compiler/scopeCheckStaticInitializer.ts(5,23): error TS2449: Class 'After' used before its declaration.
|
||||
tests/cases/compiler/scopeCheckStaticInitializer.ts(5,29): error TS2448: Block-scoped variable 'data' used before its declaration.
|
||||
tests/cases/compiler/scopeCheckStaticInitializer.ts(6,23): error TS2449: Class 'After' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/scopeCheckStaticInitializer.ts (4 errors) ====
|
||||
class X {
|
||||
static illegalBeforeProperty = X.data;
|
||||
~~~~
|
||||
!!! error TS2448: Block-scoped variable 'data' used before its declaration.
|
||||
static okBeforeMethod = X.method;
|
||||
|
||||
static illegal2 = After.data;
|
||||
~~~~~
|
||||
!!! error TS2449: Class 'After' used before its declaration.
|
||||
~~~~
|
||||
!!! error TS2448: Block-scoped variable 'data' used before its declaration.
|
||||
static illegal3 = After.method;
|
||||
~~~~~
|
||||
!!! error TS2449: Class 'After' used before its declaration.
|
||||
static data = 13;
|
||||
static method() { }
|
||||
}
|
||||
class After {
|
||||
static data = 12;
|
||||
static method() { };
|
||||
}
|
||||
|
||||
|
||||
37
tests/baselines/reference/scopeCheckStaticInitializer.js
Normal file
37
tests/baselines/reference/scopeCheckStaticInitializer.js
Normal file
@ -0,0 +1,37 @@
|
||||
//// [scopeCheckStaticInitializer.ts]
|
||||
class X {
|
||||
static illegalBeforeProperty = X.data;
|
||||
static okBeforeMethod = X.method;
|
||||
|
||||
static illegal2 = After.data;
|
||||
static illegal3 = After.method;
|
||||
static data = 13;
|
||||
static method() { }
|
||||
}
|
||||
class After {
|
||||
static data = 12;
|
||||
static method() { };
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// [scopeCheckStaticInitializer.js]
|
||||
var X = (function () {
|
||||
function X() {
|
||||
}
|
||||
X.method = function () { };
|
||||
return X;
|
||||
}());
|
||||
X.illegalBeforeProperty = X.data;
|
||||
X.okBeforeMethod = X.method;
|
||||
X.illegal2 = After.data;
|
||||
X.illegal3 = After.method;
|
||||
X.data = 13;
|
||||
var After = (function () {
|
||||
function After() {
|
||||
}
|
||||
After.method = function () { };
|
||||
;
|
||||
return After;
|
||||
}());
|
||||
After.data = 12;
|
||||
14
tests/cases/compiler/scopeCheckStaticInitializer.ts
Normal file
14
tests/cases/compiler/scopeCheckStaticInitializer.ts
Normal file
@ -0,0 +1,14 @@
|
||||
class X {
|
||||
static illegalBeforeProperty = X.data;
|
||||
static okBeforeMethod = X.method;
|
||||
|
||||
static illegal2 = After.data;
|
||||
static illegal3 = After.method;
|
||||
static data = 13;
|
||||
static method() { }
|
||||
}
|
||||
class After {
|
||||
static data = 12;
|
||||
static method() { };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user