diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 23c5568f2e5..933ad041b91 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19094,7 +19094,19 @@ namespace ts { case SyntaxKind.PropertyDeclaration: return true; case SyntaxKind.PropertyAssignment: - // We might be in `a = { b: this.b }`, so keep looking. See `tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts`. + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.SpreadAssignment: + case SyntaxKind.ComputedPropertyName: + case SyntaxKind.TemplateSpan: + case SyntaxKind.JsxExpression: + case SyntaxKind.JsxAttribute: + case SyntaxKind.JsxAttributes: + case SyntaxKind.JsxSpreadAttribute: + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.ExpressionWithTypeArguments: + case SyntaxKind.HeritageClause: return false; default: return isExpressionNode(node) ? false : "quit"; diff --git a/tests/baselines/reference/useBeforeDeclaration_jsx.errors.txt b/tests/baselines/reference/useBeforeDeclaration_jsx.errors.txt new file mode 100644 index 00000000000..ea15b246163 --- /dev/null +++ b/tests/baselines/reference/useBeforeDeclaration_jsx.errors.txt @@ -0,0 +1,38 @@ +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(6,19): error TS2729: Property 'z' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(7,19): error TS2729: Property 'z' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(8,28): error TS2729: Property 'x' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(9,28): error TS2729: Property 'y' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(10,25): error TS2729: Property 'y' is used before its initialization. + + +==== tests/cases/compiler/useBeforeDeclaration_jsx.tsx (5 errors) ==== + namespace JSX { + export interface Element {} + } + + class C { + static a = ; + ~ +!!! error TS2729: Property 'z' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:13:12: 'z' is declared here. + static b = ; + ~ +!!! error TS2729: Property 'z' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:13:12: 'z' is declared here. + static c = ; + ~ +!!! error TS2729: Property 'x' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:11:12: 'x' is declared here. + static d = ; + ~ +!!! error TS2729: Property 'y' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:12:12: 'y' is declared here. + static e = {C.y}; + ~ +!!! error TS2729: Property 'y' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:12:12: 'y' is declared here. + static x = {}; + static y = ''; + static z = () => ; + } + \ No newline at end of file diff --git a/tests/baselines/reference/useBeforeDeclaration_jsx.js b/tests/baselines/reference/useBeforeDeclaration_jsx.js new file mode 100644 index 00000000000..e95bf254644 --- /dev/null +++ b/tests/baselines/reference/useBeforeDeclaration_jsx.js @@ -0,0 +1,28 @@ +//// [useBeforeDeclaration_jsx.tsx] +namespace JSX { + export interface Element {} +} + +class C { + static a = ; + static b = ; + static c = ; + static d = ; + static e = {C.y}; + static x = {}; + static y = ''; + static z = () => ; +} + + +//// [useBeforeDeclaration_jsx.jsx] +class C { +} +C.a = ; +C.b = ; +C.c = ; +C.d = ; +C.e = {C.y}; +C.x = {}; +C.y = ''; +C.z = () => ; diff --git a/tests/baselines/reference/useBeforeDeclaration_jsx.symbols b/tests/baselines/reference/useBeforeDeclaration_jsx.symbols new file mode 100644 index 00000000000..434fe841fe0 --- /dev/null +++ b/tests/baselines/reference/useBeforeDeclaration_jsx.symbols @@ -0,0 +1,55 @@ +=== tests/cases/compiler/useBeforeDeclaration_jsx.tsx === +namespace JSX { +>JSX : Symbol(JSX, Decl(useBeforeDeclaration_jsx.tsx, 0, 0)) + + export interface Element {} +>Element : Symbol(Element, Decl(useBeforeDeclaration_jsx.tsx, 0, 15)) +} + +class C { +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) + + static a = ; +>a : Symbol(C.a, Decl(useBeforeDeclaration_jsx.tsx, 4, 9)) +>C.z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +>C.z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) + + static b = ; +>b : Symbol(C.b, Decl(useBeforeDeclaration_jsx.tsx, 5, 27)) +>C.z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) + + static c = ; +>c : Symbol(C.c, Decl(useBeforeDeclaration_jsx.tsx, 6, 22)) +>C.x : Symbol(C.x, Decl(useBeforeDeclaration_jsx.tsx, 9, 34)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>x : Symbol(C.x, Decl(useBeforeDeclaration_jsx.tsx, 9, 34)) + + static d = ; +>d : Symbol(C.d, Decl(useBeforeDeclaration_jsx.tsx, 7, 38)) +>id : Symbol(id, Decl(useBeforeDeclaration_jsx.tsx, 8, 20)) +>C.y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) + + static e = {C.y}; +>e : Symbol(C.e, Decl(useBeforeDeclaration_jsx.tsx, 8, 38)) +>C.y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) + + static x = {}; +>x : Symbol(C.x, Decl(useBeforeDeclaration_jsx.tsx, 9, 34)) + + static y = ''; +>y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) + + static z = () => ; +>z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +} + diff --git a/tests/baselines/reference/useBeforeDeclaration_jsx.types b/tests/baselines/reference/useBeforeDeclaration_jsx.types new file mode 100644 index 00000000000..18e0e341390 --- /dev/null +++ b/tests/baselines/reference/useBeforeDeclaration_jsx.types @@ -0,0 +1,69 @@ +=== tests/cases/compiler/useBeforeDeclaration_jsx.tsx === +namespace JSX { + export interface Element {} +} + +class C { +>C : C + + static a = ; +>a : JSX.Element +> : JSX.Element +>C.z : () => JSX.Element +>C : typeof C +>z : () => JSX.Element +>C.z : () => JSX.Element +>C : typeof C +>z : () => JSX.Element + + static b = ; +>b : JSX.Element +> : JSX.Element +>C.z : () => JSX.Element +>C : typeof C +>z : () => JSX.Element + + static c = ; +>c : JSX.Element +> : JSX.Element +>span : any +>C.x : {} +>C : typeof C +>x : {} +>span : any + + static d = ; +>d : JSX.Element +> : JSX.Element +>span : any +>id : string +>C.y : string +>C : typeof C +>y : string +>span : any + + static e = {C.y}; +>e : JSX.Element +>{C.y} : JSX.Element +>span : any +>C.y : string +>C : typeof C +>y : string +>span : any + + static x = {}; +>x : {} +>{} : {} + + static y = ''; +>y : string +>'' : "" + + static z = () => ; +>z : () => JSX.Element +>() => : () => JSX.Element +> : JSX.Element +>b : any +>b : any +} + diff --git a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.errors.txt b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.errors.txt index e58e7fa02e9..b1b2174d1dc 100644 --- a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.errors.txt +++ b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.errors.txt @@ -1,12 +1,44 @@ tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(2,27): error TS2729: Property 'b' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(2,38): error TS2729: Property 'c' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(2,47): error TS2729: Property 'b' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(2,59): error TS2729: Property 'c' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(8,32): error TS2729: Property 'B' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(13,12): error TS2729: Property 'D' is used before its initialization. -==== tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts (1 errors) ==== +==== tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts (6 errors) ==== export class C { - public a = { b: this.b }; + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; ~ !!! error TS2729: Property 'b' is used before its initialization. !!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:3:13: 'b' is declared here. + ~ +!!! error TS2729: Property 'c' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:4:12: 'c' is declared here. + ~ +!!! error TS2729: Property 'b' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:3:13: 'b' is declared here. + ~ +!!! error TS2729: Property 'c' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:4:12: 'c' is declared here. private b = 0; + public c = { c: this.b }; } - \ No newline at end of file + + class D { + static A = class extends D.B { + ~ +!!! error TS2729: Property 'B' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:11:12: 'B' is declared here. + [D.D]() {} // should be an error + } + static B = class {} + static C = { + [D.D]: 1, + ~ +!!! error TS2729: Property 'D' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:16:12: 'D' is declared here. + ...{get [D.D]() {return 0;}} // should be an error + }; + static D = ''; + } \ No newline at end of file diff --git a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.js b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.js index e34604e0a4e..47968d429ad 100644 --- a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.js +++ b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.js @@ -1,18 +1,37 @@ //// [useBeforeDeclaration_propertyAssignment.ts] export class C { - public a = { b: this.b }; + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; private b = 0; + public c = { c: this.b }; } - + +class D { + static A = class extends D.B { + [D.D]() {} // should be an error + } + static B = class {} + static C = { + [D.D]: 1, + ...{get [D.D]() {return 0;}} // should be an error + }; + static D = ''; +} //// [useBeforeDeclaration_propertyAssignment.js] -"use strict"; -exports.__esModule = true; -var C = /** @class */ (function () { - function C() { - this.a = { b: this.b }; +export class C { + constructor() { + this.a = Object.assign({ b: this.b }, this.c, { [this.b]: `${this.c}` }); this.b = 0; + this.c = { c: this.b }; } - return C; -}()); -exports.C = C; +} +class D { +} +D.A = class extends D.B { + [D.D]() { } // should be an error +}; +D.B = class { +}; +D.C = Object.assign({ [D.D]: 1 }, { get [D.D]() { return 0; } } // should be an error +); +D.D = ''; diff --git a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.symbols b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.symbols index 5b067232ef6..7c8acfc5375 100644 --- a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.symbols +++ b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.symbols @@ -2,14 +2,68 @@ export class C { >C : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) - public a = { b: this.b }; + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; >a : Symbol(C.a, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 16)) >b : Symbol(b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 17)) ->this.b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 30)) +>this.b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) >this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) ->b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 30)) +>b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) +>this.c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) +>this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) +>c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) +>[this.b] : Symbol([this.b], Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 39)) +>this.b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) +>this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) +>b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) +>this.c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) +>this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) +>c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) private b = 0; ->b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 30)) +>b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) + + public c = { c: this.b }; +>c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) +>c : Symbol(c, Decl(useBeforeDeclaration_propertyAssignment.ts, 3, 16)) +>this.b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) +>this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) +>b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) } +class D { +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) + + static A = class extends D.B { +>A : Symbol(D.A, Decl(useBeforeDeclaration_propertyAssignment.ts, 6, 9)) +>D.B : Symbol(D.B, Decl(useBeforeDeclaration_propertyAssignment.ts, 9, 5)) +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) +>B : Symbol(D.B, Decl(useBeforeDeclaration_propertyAssignment.ts, 9, 5)) + + [D.D]() {} // should be an error +>[D.D] : Symbol((Anonymous class)[D.D], Decl(useBeforeDeclaration_propertyAssignment.ts, 7, 34)) +>D.D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) +>D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) + } + static B = class {} +>B : Symbol(D.B, Decl(useBeforeDeclaration_propertyAssignment.ts, 9, 5)) + + static C = { +>C : Symbol(D.C, Decl(useBeforeDeclaration_propertyAssignment.ts, 10, 23)) + + [D.D]: 1, +>[D.D] : Symbol([D.D], Decl(useBeforeDeclaration_propertyAssignment.ts, 11, 16)) +>D.D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) +>D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) + + ...{get [D.D]() {return 0;}} // should be an error +>[D.D] : Symbol([D.D], Decl(useBeforeDeclaration_propertyAssignment.ts, 13, 12)) +>D.D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) +>D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) + + }; + static D = ''; +>D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) +} diff --git a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.types b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.types index cb30e36f28d..e4136fde22a 100644 --- a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.types +++ b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.types @@ -2,16 +2,79 @@ export class C { >C : C - public a = { b: this.b }; ->a : { b: number; } ->{ b: this.b } : { b: number; } + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; +>a : { c: number; b: number; } +>{ b: this.b, ...this.c, [this.b]: `${this.c}`} : { c: number; b: number; } >b : number >this.b : number >this : this >b : number +>this.c : { c: number; } +>this : this +>c : { c: number; } +>[this.b] : string +>this.b : number +>this : this +>b : number +>`${this.c}` : string +>this.c : { c: number; } +>this : this +>c : { c: number; } private b = 0; >b : number >0 : 0 + + public c = { c: this.b }; +>c : { c: number; } +>{ c: this.b } : { c: number; } +>c : number +>this.b : number +>this : this +>b : number } +class D { +>D : D + + static A = class extends D.B { +>A : typeof (Anonymous class) +>class extends D.B { [D.D]() {} // should be an error } : typeof (Anonymous class) +>D.B : (Anonymous class) +>D : typeof D +>B : typeof (Anonymous class) + + [D.D]() {} // should be an error +>[D.D] : () => void +>D.D : string +>D : typeof D +>D : string + } + static B = class {} +>B : typeof (Anonymous class) +>class {} : typeof (Anonymous class) + + static C = { +>C : { [x: string]: number; } +>{ [D.D]: 1, ...{get [D.D]() {return 0;}} // should be an error } : { [x: string]: number; } + + [D.D]: 1, +>[D.D] : number +>D.D : string +>D : typeof D +>D : string +>1 : 1 + + ...{get [D.D]() {return 0;}} // should be an error +>{get [D.D]() {return 0;}} : { [x: string]: number; } +>[D.D] : number +>D.D : string +>D : typeof D +>D : string +>0 : 0 + + }; + static D = ''; +>D : string +>'' : "" +} diff --git a/tests/cases/compiler/useBeforeDeclaration_jsx.tsx b/tests/cases/compiler/useBeforeDeclaration_jsx.tsx new file mode 100644 index 00000000000..3995bf8a738 --- /dev/null +++ b/tests/cases/compiler/useBeforeDeclaration_jsx.tsx @@ -0,0 +1,16 @@ +// @jsx: preserve +// @target: ES6 +namespace JSX { + export interface Element {} +} + +class C { + static a = ; + static b = ; + static c = ; + static d = ; + static e = {C.y}; + static x = {}; + static y = ''; + static z = () => ; +} diff --git a/tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts b/tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts index bdd84473c57..6ce314bcc03 100644 --- a/tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts +++ b/tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts @@ -1,4 +1,18 @@ +// @target: ES6 export class C { - public a = { b: this.b }; + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; private b = 0; + public c = { c: this.b }; } + +class D { + static A = class extends D.B { + [D.D]() {} // should be an error + } + static B = class {} + static C = { + [D.D]: 1, + ...{get [D.D]() {return 0;}} // should be an error + }; + static D = ''; +} \ No newline at end of file