From 0d56a0545c53c69d14ef0e7f5b751fc49b6a459e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 28 Dec 2017 15:23:44 -0800 Subject: [PATCH 1/3] Added tests. --- ...itializersUsePropertiesBeforeDeclaration.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts diff --git a/tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts b/tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts new file mode 100644 index 00000000000..fc2f7820697 --- /dev/null +++ b/tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts @@ -0,0 +1,18 @@ + +class Foo { + static enumMember = Enum.A; + static objLiteralMember = ObjLiteral.A; + static namespaceMember = Namespace.A; +} + +enum Enum { + A +} + +const ObjLiteral = { + A: 0 +}; + +namespace Namespace { + export let A = 0 +} From ea94a3430dbd7d39692578f2e80d890e5847d5ff Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 28 Dec 2017 15:43:20 -0800 Subject: [PATCH 2/3] Check whether we have a class before testing whether we have a super-class. --- src/compiler/checker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 82ab87d3160..af772733f05 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15872,6 +15872,9 @@ namespace ts { * In that case we won't consider it used before its declaration, because it gets its value from the superclass' declaration. */ function isPropertyDeclaredInAncestorClass(prop: Symbol): boolean { + if (!(prop.parent.flags & SymbolFlags.Class)) { + return false; + } let classType = getTypeOfSymbol(prop.parent) as InterfaceType; while (true) { classType = getSuperClass(classType); From b899c4921e8f9c5fa69bcba41eab3941edc922cb Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 29 Dec 2017 12:25:56 -0800 Subject: [PATCH 3/3] Accepted baselines. --- ...sUsePropertiesBeforeDeclaration.errors.txt | 36 ++++++++++++++ ...tializersUsePropertiesBeforeDeclaration.js | 40 ++++++++++++++++ ...zersUsePropertiesBeforeDeclaration.symbols | 45 +++++++++++++++++ ...lizersUsePropertiesBeforeDeclaration.types | 48 +++++++++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.errors.txt create mode 100644 tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.js create mode 100644 tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.symbols create mode 100644 tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.types diff --git a/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.errors.txt b/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.errors.txt new file mode 100644 index 00000000000..8b53637b884 --- /dev/null +++ b/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.errors.txt @@ -0,0 +1,36 @@ +tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts(2,25): error TS2450: Enum 'Enum' used before its declaration. +tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts(2,30): error TS2448: Block-scoped variable 'A' used before its declaration. +tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts(3,31): error TS2448: Block-scoped variable 'ObjLiteral' used before its declaration. +tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts(3,42): error TS2448: Block-scoped variable 'A' used before its declaration. +tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts(4,40): error TS2448: Block-scoped variable 'A' used before its declaration. + + +==== tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts (5 errors) ==== + class Foo { + static enumMember = Enum.A; + ~~~~ +!!! error TS2450: Enum 'Enum' used before its declaration. + ~ +!!! error TS2448: Block-scoped variable 'A' used before its declaration. + static objLiteralMember = ObjLiteral.A; + ~~~~~~~~~~ +!!! error TS2448: Block-scoped variable 'ObjLiteral' used before its declaration. + ~ +!!! error TS2448: Block-scoped variable 'A' used before its declaration. + static namespaceMember = Namespace.A; + ~ +!!! error TS2448: Block-scoped variable 'A' used before its declaration. + } + + enum Enum { + A + } + + const ObjLiteral = { + A: 0 + }; + + namespace Namespace { + export let A = 0 + } + \ No newline at end of file diff --git a/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.js b/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.js new file mode 100644 index 00000000000..28edb94345b --- /dev/null +++ b/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.js @@ -0,0 +1,40 @@ +//// [classStaticInitializersUsePropertiesBeforeDeclaration.ts] +class Foo { + static enumMember = Enum.A; + static objLiteralMember = ObjLiteral.A; + static namespaceMember = Namespace.A; +} + +enum Enum { + A +} + +const ObjLiteral = { + A: 0 +}; + +namespace Namespace { + export let A = 0 +} + + +//// [classStaticInitializersUsePropertiesBeforeDeclaration.js] +var Foo = /** @class */ (function () { + function Foo() { + } + Foo.enumMember = Enum.A; + Foo.objLiteralMember = ObjLiteral.A; + Foo.namespaceMember = Namespace.A; + return Foo; +}()); +var Enum; +(function (Enum) { + Enum[Enum["A"] = 0] = "A"; +})(Enum || (Enum = {})); +var ObjLiteral = { + A: 0 +}; +var Namespace; +(function (Namespace) { + Namespace.A = 0; +})(Namespace || (Namespace = {})); diff --git a/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.symbols b/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.symbols new file mode 100644 index 00000000000..4fb278142a6 --- /dev/null +++ b/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.symbols @@ -0,0 +1,45 @@ +=== tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts === +class Foo { +>Foo : Symbol(Foo, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 0, 0)) + + static enumMember = Enum.A; +>enumMember : Symbol(Foo.enumMember, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 0, 11)) +>Enum.A : Symbol(Enum.A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 6, 11)) +>Enum : Symbol(Enum, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 4, 1)) +>A : Symbol(Enum.A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 6, 11)) + + static objLiteralMember = ObjLiteral.A; +>objLiteralMember : Symbol(Foo.objLiteralMember, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 1, 31)) +>ObjLiteral.A : Symbol(A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 10, 20)) +>ObjLiteral : Symbol(ObjLiteral, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 10, 5)) +>A : Symbol(A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 10, 20)) + + static namespaceMember = Namespace.A; +>namespaceMember : Symbol(Foo.namespaceMember, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 2, 43)) +>Namespace.A : Symbol(Namespace.A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 15, 14)) +>Namespace : Symbol(Namespace, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 12, 2)) +>A : Symbol(Namespace.A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 15, 14)) +} + +enum Enum { +>Enum : Symbol(Enum, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 4, 1)) + + A +>A : Symbol(Enum.A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 6, 11)) +} + +const ObjLiteral = { +>ObjLiteral : Symbol(ObjLiteral, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 10, 5)) + + A: 0 +>A : Symbol(A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 10, 20)) + +}; + +namespace Namespace { +>Namespace : Symbol(Namespace, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 12, 2)) + + export let A = 0 +>A : Symbol(A, Decl(classStaticInitializersUsePropertiesBeforeDeclaration.ts, 15, 14)) +} + diff --git a/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.types b/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.types new file mode 100644 index 00000000000..72149f11a5c --- /dev/null +++ b/tests/baselines/reference/classStaticInitializersUsePropertiesBeforeDeclaration.types @@ -0,0 +1,48 @@ +=== tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts === +class Foo { +>Foo : Foo + + static enumMember = Enum.A; +>enumMember : Enum +>Enum.A : Enum +>Enum : typeof Enum +>A : Enum + + static objLiteralMember = ObjLiteral.A; +>objLiteralMember : number +>ObjLiteral.A : number +>ObjLiteral : { A: number; } +>A : number + + static namespaceMember = Namespace.A; +>namespaceMember : number +>Namespace.A : number +>Namespace : typeof Namespace +>A : number +} + +enum Enum { +>Enum : Enum + + A +>A : Enum +} + +const ObjLiteral = { +>ObjLiteral : { A: number; } +>{ A: 0} : { A: number; } + + A: 0 +>A : number +>0 : 0 + +}; + +namespace Namespace { +>Namespace : typeof Namespace + + export let A = 0 +>A : number +>0 : 0 +} +