Skip to content

class-property transform leaks new.target in initializer to upper level #12737

@JLHwung

Description

@JLHwung

Bug Report

  • I would like to work on a fix!

Current behavior

(new C).Foo.p evaluates to C.

Input Code

class C {
  constructor() {
    this.Foo = class {
      static p = new.target
    }
  }
}

Expected behavior
(new C).Foo.p should evaluate to undefined.

Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command, .eslintrc)
See REPL configs

Environment
REPL

Possible Solution
When we are converting class properties into defineProperty calls that are appended to the class, we should replace new.target in class field initializers to undefined if it is associated to the class scope, otherwise new.target is leaked to the upper new.target values.

The replacing step can be inserted after super() is replaced in initializers:

const replaced = replaceThisContext(prop, ref, superRef, state, loose);

More test examples:

class C {
  constructor() {
    this.Foo = class {
      static p1 = class { constructor() { new.target } } // should not replace
      static p2 = new function () { new.target } // should not replace
      static p3 = () => { new.target } // should replace
    }
  }
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions