New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: Tagged template with strict private field/method tag has incorrect receiver #13366
Comments
If it is the first time that you contribute to Babel, follow these steps: (you need to have
|
Can i take this? 🙂 |
@sag1v: Sure |
@nicolas-marien / @jridgewell |
There are a few needed , which will live in the following directories: Class fields:
Private method:
Private accessor:
You can look at the other fixtures in these directories to see an example of the |
EDIT Please Ignore, i was using a wrong nodeJS version @jridgewell Thanks! yarn jest private-methods The error is:
I was following these steps, without steps 7 and 8 of creating new tests and updating any code. |
Is it possible that you changed your Node.js version after running |
Yep, i'm using nvm and i guess a new terminal session picked a lower version. |
@nicolo-ribaudo / @jridgewell
when i run
I reckon the fix is something like the following: // packages/babel-helper-member-expression-to-functions/src/index.ts
-465 // MEMBER -> _get(MEMBER)
-466 member.replaceWith(this.get(member));
+465 if (t.isTaggedTemplateExpression(parent)) {
+466 // MEMBER -> _get(MEMBER).bind(this)
+467 member.replaceWith(this.boundGet(member));
+468 } else {
+469 // MEMBER -> _get(MEMBER)
+470 member.replaceWith(this.get(member));
+471 }
And it does pass the exec tests i added (currently only 2 exec and 2 inputs):
And
I have doubts regarding these tests, i'm not sure this is the way to write them. |
For (1), we should probably update the For (2), your class Foo {
static #tag() {
return this;
}
static getReceiver() {
return this.#tag``;
}
}
expect(Foo.getReceiver()).toBe(Foo); Also please yes, open a draft PR so we can discuss there 🙏 |
@nicolo-ribaudo Thanks, i will try that I'm a bit confused then, if tests inside I guess for this PR i only need |
This is the draft |
The difference is that |
Ok so |
Yup, right |
💻
How are you using Babel?
Programmatic API (
babel.transform
,babel.parse
)Input code
While scanning the recent esbuild commits, I noticed evanw/esbuild@f66b586. Essentially, Tagged Template Literals are a special form of function invocation, and we need to preserve the
this
receiver when invoking:REPL
Configuration file name
babel.config.json
Configuration
Current and expected behavior
Currently, the
this.#tag
is transformed into_classPrivateMethodGet(this, _tag, _tag2)
. The return value from_classPrivateMethodGet
(which is_tag2
, the transformed#tag
method) is then invoked via Tagged Template:In this case, the receiver is
undefined
, which fails the assertion.Environment
Babel v7.14.1
Possible solution
When we're transforming a private access in the
tag
of a Tagged Template Literal, we need to bind the value to the correct receiver:Where this is done is a bit confusing. Transforming is done via
transformPrivateNamesUsage
, which calls an abstractmemberExpressionToFunctions
transformer.memberExpressionToFunctions
will call several "handler" functions, which are defined in privateNameHandlerSpec.Currently, the
this.#tag`template literal`
is invoking theget
handler. This fails to preserve thethis
receiver once transformed. Luckily, there's a similar handler calledboundGet
which will preserve the receiver.We actually just need to fix the
memberExpressionToFunctions
implementation to detect when theget
is happening inside a Tagged Template'stag
. In this case, we need to callboundGet
instead ofget
. Specifically this line:babel/packages/babel-helper-member-expression-to-functions/src/index.ts
Lines 465 to 466 in b1f57e5
We'll also need
Additional context
This also needs to be applied when transforming a private field, not just a private method:
The text was updated successfully, but these errors were encountered: