diff --git a/packages/babel-helper-create-class-features-plugin/src/fields.js b/packages/babel-helper-create-class-features-plugin/src/fields.js index e29ff33776..80e1ec1b40 100644 --- a/packages/babel-helper-create-class-features-plugin/src/fields.js +++ b/packages/babel-helper-create-class-features-plugin/src/fields.js @@ -501,10 +501,9 @@ function replaceThisContext(path, ref, superRef, file, loose) { file, getObjectRef() { state.needsClassRef = true; - return ref; + return path.node.static ? ref : t.thisExpression(); }, }); - replacer.isStatic = true; replacer.replace(); if (path.isProperty()) { path.traverse(thisContextVisitor, state); @@ -532,7 +531,7 @@ export function buildFieldsInitNodes( const isField = prop.isProperty(); const isMethod = !isField; - if (isStatic) { + if (isStatic || (isMethod && isPrivate)) { const replaced = replaceThisContext(prop, ref, superRef, state, loose); needsClassRef = needsClassRef || replaced; } diff --git a/packages/babel-helper-replace-supers/src/index.js b/packages/babel-helper-replace-supers/src/index.js index 89b7cc70d0..2e445c0c76 100644 --- a/packages/babel-helper-replace-supers/src/index.js +++ b/packages/babel-helper-replace-supers/src/index.js @@ -15,11 +15,12 @@ import * as t from "@babel/types"; * * helpers.getPrototypeOf(CLASS.prototype) */ -function getPrototypeOfExpression(objectRef, isStatic, file) { +function getPrototypeOfExpression(objectRef, isStatic, file, isPrivateMethod) { objectRef = t.cloneNode(objectRef); - const targetRef = isStatic - ? objectRef - : t.memberExpression(objectRef, t.identifier("prototype")); + const targetRef = + isStatic || isPrivateMethod + ? objectRef + : t.memberExpression(objectRef, t.identifier("prototype")); return t.callExpression(file.addHelper("getPrototypeOf"), [targetRef]); } @@ -98,7 +99,12 @@ const specHandlers = { get(superMember) { return t.callExpression(this.file.addHelper("get"), [ - getPrototypeOfExpression(this.getObjectRef(), this.isStatic, this.file), + getPrototypeOfExpression( + this.getObjectRef(), + this.isStatic, + this.file, + this.isPrivateMethod, + ), this.prop(superMember), t.thisExpression(), ]); @@ -106,7 +112,12 @@ const specHandlers = { set(superMember, value) { return t.callExpression(this.file.addHelper("set"), [ - getPrototypeOfExpression(this.getObjectRef(), this.isStatic, this.file), + getPrototypeOfExpression( + this.getObjectRef(), + this.isStatic, + this.file, + this.isPrivateMethod, + ), this.prop(superMember), value, t.thisExpression(), @@ -170,8 +181,8 @@ export default class ReplaceSupers { const path = opts.methodPath; this.methodPath = path; - this.isStatic = - path.isClassMethod({ static: true }) || path.isObjectMethod(); + this.isStatic = path.isObjectMethod() || path.node.static; + this.isPrivateMethod = path.isPrivate() && path.isMethod(); this.file = opts.file; this.superRef = opts.superRef; @@ -202,6 +213,7 @@ export default class ReplaceSupers { memberExpressionToFunctions(this.methodPath, visitor, { file: this.file, isStatic: this.isStatic, + isPrivateMethod: this.isPrivateMethod, getObjectRef: this.getObjectRef.bind(this), superRef: this.superRef, ...handler, diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/exec.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/exec.js new file mode 100644 index 0000000000..9fcc52c264 --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/exec.js @@ -0,0 +1,17 @@ +class Base { + superMethod() { + return 1017; + } +} + +class Sub extends Base { + #privateMethod() { + return super.superMethod(); + } + + publicMethod() { + return this.#privateMethod(); + } +} + +expect((new Sub()).publicMethod()).toEqual(1017); \ No newline at end of file diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/input.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/input.js new file mode 100644 index 0000000000..57879b021e --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/input.js @@ -0,0 +1,15 @@ +class Base { + superMethod() { + return 1017; + } +} + +class Sub extends Base { + #privateMethod() { + return super.superMethod(); + } + + publicMethod() { + return this.#privateMethod(); + } +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/output.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/output.js new file mode 100644 index 0000000000..b245ccca9f --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method-loose/super/output.js @@ -0,0 +1,26 @@ +class Base { + superMethod() { + return 1017; + } + +} + +class Sub extends Base { + constructor(...args) { + super(...args); + Object.defineProperty(this, _privateMethod, { + value: _privateMethod2 + }); + } + + publicMethod() { + return babelHelpers.classPrivateFieldLooseBase(this, _privateMethod)[_privateMethod](); + } + +} + +var _privateMethod = babelHelpers.classPrivateFieldLooseKey("privateMethod"); + +var _privateMethod2 = function _privateMethod2() { + return Base.prototype.superMethod.call(this); +}; diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/exec.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/exec.js new file mode 100644 index 0000000000..9fcc52c264 --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/exec.js @@ -0,0 +1,17 @@ +class Base { + superMethod() { + return 1017; + } +} + +class Sub extends Base { + #privateMethod() { + return super.superMethod(); + } + + publicMethod() { + return this.#privateMethod(); + } +} + +expect((new Sub()).publicMethod()).toEqual(1017); \ No newline at end of file diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/input.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/input.js new file mode 100644 index 0000000000..57879b021e --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/input.js @@ -0,0 +1,15 @@ +class Base { + superMethod() { + return 1017; + } +} + +class Sub extends Base { + #privateMethod() { + return super.superMethod(); + } + + publicMethod() { + return this.#privateMethod(); + } +} \ No newline at end of file diff --git a/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/output.js b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/output.js new file mode 100644 index 0000000000..63878e0e22 --- /dev/null +++ b/packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/super/output.js @@ -0,0 +1,25 @@ +class Base { + superMethod() { + return 1017; + } + +} + +class Sub extends Base { + constructor(...args) { + super(...args); + + _privateMethod.add(this); + } + + publicMethod() { + return babelHelpers.classPrivateMethodGet(this, _privateMethod, _privateMethod2).call(this); + } + +} + +var _privateMethod = new WeakSet(); + +var _privateMethod2 = function _privateMethod2() { + return babelHelpers.get(babelHelpers.getPrototypeOf(this), "superMethod", this).call(this); +};