Change static fields emits (#43114)

* use emit into iife

* Update emit

* Revert un-related changes

* Allow super in static context

* Allow this and super in static property declaration

* Add more tests

* Avoid errors

* Accept baseline

* Accept baseline

* Add decorated classes test

* Add errors

* Avoid this in emitter

* make lint happy

* Add class expression tests

* Add computed name test

* Avoid super if target below es6

* Adjust function boundary

* Add internal

* Fix minor CR issues

* accept baseline

* Update behavior

* Avoid spaces

* Make lint happy

* Avoid function boundary utils

* Update baseline

* Avoid errors

* Accept baseline

* Accept baseline

* Accept baseline

* Accept baseline

* Use substitutions

* Full coverage for super, this, merge static and private context

* Fix use-before-def in static fields

Co-authored-by: Ron Buckton <ron.buckton@microsoft.com>
This commit is contained in:
Wenlu Wang
2021-06-25 15:49:27 -07:00
committed by GitHub
co-authored by Ron Buckton
parent 328e888a9d
commit dc237b317e
215 changed files with 9185 additions and 782 deletions
@@ -2,7 +2,7 @@ function log(a) { }
class Vector {
static foo = () => {
// 'this' should not be available in a static initializer.
// 'this' should be allowed in a static initializer.
log(this);
}
}
@@ -0,0 +1,15 @@
// @target: esnext
// @noEmit: true
// @strict: true
class C {
static x;
static {
this.x = 1;
}
static y = this.x;
static z;
static {
this.z = this.y;
}
}
@@ -0,0 +1,10 @@
// @target: esnext
// @noEmit: true
// @strict: true
class C {
static {
this.x = 1;
}
static x;
}
@@ -0,0 +1,42 @@
// @target: esnext, es2015
// @useDefineForClassFields: true
// @noTypesAndSymbols: true
declare class B {
static a: any;
static f(): number;
a: number;
f(): number;
}
class C extends B {
static x: any = undefined!;
static y1 = this.x;
static y2 = this.x();
static y3 = this?.x();
static y4 = this[("x")]();
static y5 = this?.[("x")]();
static z1 = super.a;
static z2 = super["a"];
static z3 = super.f();
static z4 = super["f"]();
static z5 = super.a = 0;
static z6 = super.a += 1;
static z7 = (() => { super.a = 0; })();
static z8 = [super.a] = [0];
static z9 = [super.a = 0] = [0];
static z10 = [...super.a] = [0];
static z11 = { x: super.a } = { x: 0 };
static z12 = { x: super.a = 0 } = { x: 0 };
static z13 = { ...super.a } = { x: 0 };
static z14 = ++super.a;
static z15 = --super.a;
static z16 = ++super[("a")];
static z17 = super.a++;
static z18 = super.a``;
// these should be unaffected
x = 1;
y = this.x;
z = super.f();
}
@@ -0,0 +1,42 @@
// @target: esnext, es2015
// @useDefineForClassFields: false
// @noTypesAndSymbols: true
declare class B {
static a: any;
static f(): number;
a: number;
f(): number;
}
class C extends B {
static x: any = undefined!;
static y1 = this.x;
static y2 = this.x();
static y3 = this?.x();
static y4 = this[("x")]();
static y5 = this?.[("x")]();
static z1 = super.a;
static z2 = super["a"];
static z3 = super.f();
static z4 = super["f"]();
static z5 = super.a = 0;
static z6 = super.a += 1;
static z7 = (() => { super.a = 0; })();
static z8 = [super.a] = [0];
static z9 = [super.a = 0] = [0];
static z10 = [...super.a] = [0];
static z11 = { x: super.a } = { x: 0 };
static z12 = { x: super.a = 0 } = { x: 0 };
static z13 = { ...super.a } = { x: 0 };
static z14 = ++super.a;
static z15 = --super.a;
static z16 = ++super[("a")];
static z17 = super.a++;
static z18 = super.a``;
// these should be unaffected
x = 1;
y = this.x;
z = super.f();
}
@@ -0,0 +1,26 @@
// @target: es5
// @useDefineForClassFields: true
// @noTypesAndSymbols: true
declare class B {
static a: any;
static f(): number;
a: number;
f(): number;
}
class C extends B {
static x: any = undefined!;
static y1 = this.x;
static y2 = this.x();
static y3 = this?.x();
static y4 = this[("x")]();
static y5 = this?.[("x")]();
static z3 = super.f();
static z4 = super["f"]();
// these should be unaffected
x = 1;
y = this.x;
z = super.f();
}
@@ -0,0 +1,26 @@
// @target: es5
// @useDefineForClassFields: false
// @noTypesAndSymbols: true
declare class B {
static a: any;
static f(): number;
a: number;
f(): number;
}
class C extends B {
static x: any = undefined!;
static y1 = this.x;
static y2 = this.x();
static y3 = this?.x();
static y4 = this[("x")]();
static y5 = this?.[("x")]();
static z3 = super.f();
static z4 = super["f"]();
// these should be unaffected
x = 1;
y = this.x;
z = super.f();
}
@@ -0,0 +1,51 @@
// @target: esnext, es6, es5
// @experimentalDecorators: true
// @useDefineForClassFields: false
declare const foo: any;
@foo
class C {
static a = 1;
static b = this.a + 1;
}
@foo
class D extends C {
static c = 2;
static d = this.c + 1;
static e = super.a + this.c + 1;
static f = () => this.c + 1;
static ff = function () { this.c + 1 }
static foo () {
return this.c + 1;
}
static get fa () {
return this.c + 1;
}
static set fa (v: number) {
this.c = v + 1;
}
}
class CC {
static a = 1;
static b = this.a + 1;
}
class DD extends CC {
static c = 2;
static d = this.c + 1;
static e = super.a + this.c + 1;
static f = () => this.c + 1;
static ff = function () { this.c + 1 }
static foo () {
return this.c + 1;
}
static get fa () {
return this.c + 1;
}
static set fa (v: number) {
this.c = v + 1;
}
}
@@ -0,0 +1,51 @@
// @target: esnext, es6, es5
// @experimentalDecorators: true
// @useDefineForClassFields: true
declare const foo: any;
@foo
class C {
static a = 1;
static b = this.a + 1;
}
@foo
class D extends C {
static c = 2;
static d = this.c + 1;
static e = super.a + this.c + 1;
static f = () => this.c + 1;
static ff = function () { this.c + 1 }
static foo () {
return this.c + 1;
}
static get fa () {
return this.c + 1;
}
static set fa (v: number) {
this.c = v + 1;
}
}
class CC {
static a = 1;
static b = this.a + 1;
}
class DD extends CC {
static c = 2;
static d = this.c + 1;
static e = super.a + this.c + 1;
static f = () => this.c + 1;
static ff = function () { this.c + 1 }
static foo () {
return this.c + 1;
}
static get fa () {
return this.c + 1;
}
static set fa (v: number) {
this.c = v + 1;
}
}
@@ -0,0 +1,10 @@
// @target: esnext, es6, es5
// @useDefineForClassFields: false
class C {
static readonly c: "foo" = "foo"
static bar = class Inner {
static [this.c] = 123;
[this.c] = 123;
}
}
@@ -0,0 +1,10 @@
// @target: esnext, es6, es5
// @useDefineForClassFields: true
class C {
static readonly c: "foo" = "foo"
static bar = class Inner {
static [this.c] = 123;
[this.c] = 123;
}
}
@@ -1,7 +1,7 @@
class C {
static foo = this; // error
static foo = this; // ok
}
class C2<T> {
static foo = this; // error
static foo = this; // ok
}
@@ -0,0 +1,12 @@
// @target: esnext, es6, es5
// @useDefineForClassFields: false
class C {
static a = 1;
static b = this.a + 1;
}
class D extends C {
static c = 2;
static d = this.c + 1;
static e = super.a + this.c + 1;
}
@@ -0,0 +1,12 @@
// @target: esnext, es6, es5
// @useDefineForClassFields: true
class C {
static a = 1;
static b = this.a + 1;
}
class D extends C {
static c = 2;
static d = this.c + 1;
static e = super.a + this.c + 1;
}
@@ -0,0 +1,9 @@
// @target: esnext, es6, es5
class C {
static create = () => new this("yep")
constructor (private foo: string) {
}
}
@@ -0,0 +1,7 @@
class C {
static f = 1
}
class D extends C {
static c = super();
}
@@ -0,0 +1,12 @@
// @target: esnext, es6, es5
class C {
static a = 1;
static b = this.a + 1;
}
class D extends C {
static c = 2;
static d = this.c + 1;
static e = 1 + (super.a) + (this.c + 1) + 1;
}
@@ -0,0 +1,19 @@
// @target: esnext, es6, es5
class C {
static f = 1;
static arrowFunctionBoundary = () => this.f + 1;
static functionExprBoundary = function () { return this.f + 2 };
static classExprBoundary = class { a = this.f + 3 };
static functionAndClassDeclBoundary = (() => {
function foo () {
return this.f + 4
}
class CC {
a = this.f + 5
method () {
return this.f + 6
}
}
})();
}
@@ -0,0 +1,22 @@
// @target: esnext, es6, es5
class C {
static f = 1
}
class D extends C {
static arrowFunctionBoundary = () => super.f + 1;
static functionExprBoundary = function () { return super.f + 2 };
static classExprBoundary = class { a = super.f + 3 };
static functionAndClassDeclBoundary = (() => {
function foo () {
return super.f + 4
}
class C {
a = super.f + 5
method () {
return super.f +6
}
}
})();
}
@@ -1,8 +1,3 @@
//'this' in static member initializer
class ErrClass1 {
static t = this; // Error
}
class BaseErrClass {
constructor(t: any) { }
}
@@ -1,8 +1,3 @@
//'this' in static member initializer
class ErrClass1 {
static t = this; // Error
}
class BaseErrClass {
constructor(t: any) { }
}
@@ -17,7 +17,7 @@ const z: Foo<number> = x;
// Repro from #30118
class Bar<T extends string> {
private static instance: Bar<string>[];
private static instance: Bar<string>[] = [];
cast(_name: ([T] extends [string] ? string : string)) { }
@@ -10,7 +10,7 @@
verify.codeFix({
description: "Initialize static property 'foo'",
index: 2,
index: 0,
newFileContent: `class C {
static p = ()=>{ this.foo === 10 };
}