Skip to content

Commit

Permalink
Fix the support of arguments in private get/set method (#16307)
Browse files Browse the repository at this point in the history
* fix arguments

* Update packages/babel-plugin-transform-private-methods/test/fixtures/accessors/arguments/exec.js

Co-authored-by: Nicol貌 Ribaudo <nicolo.ribaudo@gmail.com>

* review

* fix types

---------

Co-authored-by: Nicol貌 Ribaudo <nicolo.ribaudo@gmail.com>
  • Loading branch information
liuxingbaoyu and nicolo-ribaudo committed Feb 27, 2024
1 parent d7cd8e9 commit f370fb4
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 4 deletions.
28 changes: 24 additions & 4 deletions packages/babel-helper-create-class-features-plugin/src/fields.ts
Expand Up @@ -1312,11 +1312,25 @@ function buildPrivateMethodDeclaration(
(isGetter || isSetter) &&
!privateFieldsAsProperties
) {
const thisArg = prop.get("body").scope.generateUidIdentifier("this");
// eslint-disable-next-line @typescript-eslint/no-use-before-define
prop.traverse(thisContextVisitor, {
const scope = prop.get("body").scope;
const thisArg = scope.generateUidIdentifier("this");
const state: ReplaceThisState = {
thisRef: thisArg,
});
argumentsPath: [],
};
// eslint-disable-next-line @typescript-eslint/no-use-before-define
prop.traverse(thisContextVisitor, state);
if (state.argumentsPath.length) {
const argumentsId = scope.generateUidIdentifier("arguments");
scope.push({
id: argumentsId,
init: template.expression.ast`[].slice.call(arguments, 1)`,
});
for (const path of state.argumentsPath) {
path.replaceWith(t.cloneNode(argumentsId));
}
}

params.unshift(t.cloneNode(thisArg));
}

Expand Down Expand Up @@ -1357,12 +1371,18 @@ type ReplaceThisState = {
thisRef: t.Identifier;
needsClassRef?: boolean;
innerBinding?: t.Identifier | null;
argumentsPath?: NodePath<t.Identifier>[];
};

type ReplaceInnerBindingReferenceState = ReplaceThisState;

const thisContextVisitor = traverse.visitors.merge<ReplaceThisState>([
{
Identifier(path, state) {
if (state.argumentsPath && path.node.name === "arguments") {
state.argumentsPath.push(path);
}
},
UnaryExpression(path) {
// Replace `delete this` with `true`
const { node } = path;
Expand Down
@@ -0,0 +1,33 @@
class Cl {
#privateField = "top secret string";

constructor() {
this.publicField = "not secret string";
}

get #privateFieldValue() {
expect(arguments.length).toBe(0);
return this.#privateField;
}

set #privateFieldValue(newValue) {
expect(arguments.length).toBe(1);
this.#privateField = newValue;
}

publicGetPrivateField() {
return this.#privateFieldValue;
}

publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
}

const cl = new Cl();

expect(cl.publicGetPrivateField()).toEqual("top secret string");

cl.publicSetPrivateField("new secret string");
expect(cl.publicGetPrivateField()).toEqual("new secret string");

@@ -0,0 +1,25 @@
class Cl {
#privateField = "top secret string";

constructor() {
this.publicField = "not secret string";
}

get #privateFieldValue() {
expect(arguments.length).toBe(0);
return this.#privateField;
}

set #privateFieldValue(newValue) {
expect(arguments.length).toBe(1);
this.#privateField = newValue;
}

publicGetPrivateField() {
return this.#privateFieldValue;
}

publicSetPrivateField(newValue) {
this.#privateFieldValue = newValue;
}
}
@@ -0,0 +1,25 @@
var _privateField = /*#__PURE__*/new WeakMap();
var _Cl_brand = /*#__PURE__*/new WeakSet();
class Cl {
constructor() {
babelHelpers.classPrivateMethodInitSpec(this, _Cl_brand);
babelHelpers.classPrivateFieldInitSpec(this, _privateField, "top secret string");
this.publicField = "not secret string";
}
publicGetPrivateField() {
return babelHelpers.classPrivateGetter(_Cl_brand, this, _get_privateFieldValue);
}
publicSetPrivateField(newValue) {
babelHelpers.classPrivateSetter(_Cl_brand, _set_privateFieldValue, this, newValue);
}
}
function _get_privateFieldValue(_this) {
var _arguments = [].slice.call(arguments, 1);
expect(_arguments.length).toBe(0);
return babelHelpers.classPrivateFieldGet2(_privateField, _this);
}
function _set_privateFieldValue(_this2, newValue) {
var _arguments2 = [].slice.call(arguments, 1);
expect(_arguments2.length).toBe(1);
babelHelpers.classPrivateFieldSet2(_privateField, _this2, newValue);
}

0 comments on commit f370fb4

Please sign in to comment.