@@ -3273,11 +3273,11 @@ public void testClassDeclarationWithFieldThisAndSuper() {
3273
3273
" /** @type {number} */" ,
3274
3274
" a = 2;" ,
3275
3275
" /** @type {number} */" ,
3276
- " b = this.b ;" ,
3276
+ " b = this.a ;" ,
3277
3277
"}" ,
3278
3278
"class Bar extends Foo {" ,
3279
3279
" /** @type {number} */" ,
3280
- " c = super .a + 1;" ,
3280
+ " c = this .a + 1;" , // Must use `this` and not `super` to access field of parent class
3281
3281
"}" ));
3282
3282
3283
3283
FunctionType fooCtor = globalScope .getVar ("Foo" ).getType ().assertFunctionType ();
@@ -3368,11 +3368,12 @@ public void testClassDeclarationWithStaticFieldThisAndSuper() {
3368
3368
" /** @type {number} */" ,
3369
3369
" static a = 2;" ,
3370
3370
" /** @type {number} */" ,
3371
- " static b = this.b ;" ,
3371
+ " static b = this.a ;" ,
3372
3372
"}" ,
3373
3373
"class Bar extends Foo {" ,
3374
3374
" /** @type {number} */" ,
3375
- " static c = super.a + 1;" ,
3375
+ " static c = this.a + 1;" , // Must use `this` and not `super` to access field of parent
3376
+ // class
3376
3377
"}" ));
3377
3378
3378
3379
FunctionType fooCtor = globalScope .getVar ("Foo" ).getType ().assertFunctionType ();
@@ -3391,6 +3392,104 @@ public void testClassDeclarationWithStaticFieldThisAndSuper() {
3391
3392
assertType (barCtor .getPropertyType ("c" )).isNumber ();
3392
3393
}
3393
3394
3395
+ @ Test
3396
+ public void testTypeOfThisInObjectLitInPublicField () {
3397
+ // Make sure the `this` on the RHS of a class field declaration has the appropriate type, even
3398
+ // when it appears within an object literal
3399
+ testSame (
3400
+ lines (
3401
+ "class Foo {" , //
3402
+ " x = 3;" ,
3403
+ " bar = {" ,
3404
+ " b: this.x" ,
3405
+ " };" ,
3406
+ "}" ));
3407
+
3408
+ FunctionType fooCtor = globalScope .getVar ("Foo" ).getType ().assertFunctionType ();
3409
+ ObjectType fooInstance = fooCtor .getInstanceType ();
3410
+ Node getProp =
3411
+ fooInstance
3412
+ .getPropertyNode ("bar" )
3413
+ .getOnlyChild () // OBJECTLIT
3414
+ .getOnlyChild () // STRING_KEY
3415
+ .getOnlyChild (); // GETPROP
3416
+ assertNode (getProp ).hasJSTypeThat ().isNumber ();
3417
+ Node thisNode = getProp .getOnlyChild ();
3418
+ assertNode (thisNode ).hasJSTypeThat ().isEqualTo (fooInstance );
3419
+
3420
+ testSame (
3421
+ lines (
3422
+ "class Foo {" , //
3423
+ " static baz = {" ,
3424
+ " e: this" ,
3425
+ " };" ,
3426
+ "}" ));
3427
+
3428
+ fooCtor = globalScope .getVar ("Foo" ).getType ().assertFunctionType ();
3429
+ thisNode =
3430
+ fooCtor
3431
+ .getPropertyNode ("baz" )
3432
+ .getOnlyChild () // OBJECTLIT
3433
+ .getOnlyChild () // STRING_KEY
3434
+ .getOnlyChild (); // THIS
3435
+ assertNode (thisNode ).hasJSTypeThat ().isEqualTo (fooCtor );
3436
+ }
3437
+
3438
+ @ Test
3439
+ public void testGetterInObjectLitInPublicField () {
3440
+ // Previously a bug caused getters & setters in object literals on the RHS of a field
3441
+ // declaration to be treated as if they belonged to the class.
3442
+ //
3443
+ // Make sure that `this` in an object literal getter or setter has the unknown type.
3444
+ testSame (
3445
+ lines (
3446
+ "class Foo {" , //
3447
+ " bar = {" ,
3448
+ " get baz() {" ,
3449
+ " X: this;" ,
3450
+ " }" ,
3451
+ " };" ,
3452
+ "}" ));
3453
+ Node thisNode = getLabeledStatement ("X" ).statementNode .getOnlyChild ();
3454
+ // We don't create unique types for object literals, so even though we know
3455
+ // the getter will (probably) only be called on this object, we just
3456
+ // use unknown for the type of `this`.
3457
+ assertNode (thisNode ).hasJSTypeThat ().isUnknown ();
3458
+
3459
+ testSame (
3460
+ lines (
3461
+ "class Foo {" , //
3462
+ " static bar = {" ,
3463
+ " /** @this {string} */" ,
3464
+ " get baz() { Y: this; }" ,
3465
+ " };" ,
3466
+ "}" ));
3467
+
3468
+ thisNode = getLabeledStatement ("Y" ).statementNode .getOnlyChild ();
3469
+ assertNode (thisNode ).hasJSTypeThat ().isString ();
3470
+ }
3471
+
3472
+ @ Test
3473
+ public void testMemberFunctionInObjectLitInPublicField () {
3474
+ // Previously a bug caused methods in object literals on the RHS of a field declaration to be
3475
+ // treated as if they were methods on the class.
3476
+ //
3477
+ // Make sure that `this` in an object literal method has the unknown type.
3478
+ testSame (
3479
+ lines (
3480
+ "class Foo {" , //
3481
+ " bar = {" ,
3482
+ " /** @this {number} */" ,
3483
+ " member() {" ,
3484
+ " X: this;" ,
3485
+ " }" ,
3486
+ " };" ,
3487
+ "}" ));
3488
+
3489
+ Node thisNode = getLabeledStatement ("X" ).statementNode .getOnlyChild ();
3490
+ assertNode (thisNode ).hasJSTypeThat ().isNumber ();
3491
+ }
3492
+
3394
3493
@ Test
3395
3494
public void testClassDeclarationWithDeprecatedField () {
3396
3495
testSame (
0 commit comments