Hermes: Support new.target

Created on 4 Mar 2020  路  7Comments  路  Source: facebook/hermes

Currently on master (e13f095912599db76aeac537bb0e8efc7a2e11f9), new.target is not supported.

It will be great to support it in Hermes as some third party dependencies are relying on this internally.

Using Hermes will result in those errors:

Case 1

class CustomError extends Error {
  constructor(message) {
    super(message); // 'Error' breaks prototype chain here
    Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
  }
}
error: ')' expected at end of function call
    Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
                         ~~~~~~~~~~~~~~~~~^

Case 2

class CustomError extends Error {
  constructor(message) {
    console.log(new.target);
  }
}
error: invalid statement encountered.
class CustomError extends Error {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Emitted 1 errors. exiting.
bug

All 7 comments

We're working on adding support for class to Hermes, and new.target will be a part of that - both of these errors will stop happening.

This typically hasn't been an issue in other RN code to date because everyone tends to run Babel before JS code gets to Hermes. Is Babel's class transformation not being run on the code you've been seeing errors in?

I don't know Hermes well enough, but RN users tend to not run Babel by hands, we rely on Metro to do the transpilation and minification if needed. RN's packages are distributed as non-transformed ~ES2019.

Since class is not supported in Hermes, are you saying that we should manually run Babel transforms in order to enable Hermes? I wouldn't expect to do that as I would expect Metro/Hermes to do it for me. 馃

It looks like a transform should happen with new.target as class are transformed to ES5, but nothing happened.

Basically, if we add the following code to any React Native app with Hermes enabled, we'll have an error with Hermes:

class CustomError extends Error {
  constructor(message) {
    super(message); // 'Error' breaks prototype chain here
    Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
  }
}

Note that new.target isn鈥檛 a class feature, it works in normal functions too.

Unfortunately Babel doesn't support transpiling 'new.target' by default. It is not something that can be done reliably and efficiently by a transpiler.

A limited workaround is to replace new.target with this.constructor. I believe that there is an optional Babel plugin that does that.

We do have support for new.target in Hernes in an unpublished branch. I wonder I could reprioritize only that part.

Oops, sorry, this is actually a parser bug in Hermes.

We have a fix in progress (I feel bad for letting this slip through).

@tmikov Thanks for looking into this and landing a fix!

Don't feel bad for letting it slip, this is the first report, and it is now fixed. 馃帀

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Kikketer picture Kikketer  路  3Comments

thymikee picture thymikee  路  6Comments

swabbass picture swabbass  路  3Comments

NWU-NISL picture NWU-NISL  路  4Comments

mathiasbynens picture mathiasbynens  路  6Comments