Skip to content

Commit

Permalink
fix: reference to class expression in private method (#13429)
Browse files Browse the repository at this point in the history
Co-authored-by: Henry Zhu <hi@henryzoo.com>
Co-authored-by: Federico Ciardi <fed.ciardi@gmail.com>
Co-authored-by: Nicol貌 Ribaudo <nicolo.ribaudo@gmail.com>
  • Loading branch information
4 people committed Jun 14, 2021
1 parent 69f423b commit 903b600
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 3 deletions.
25 changes: 24 additions & 1 deletion packages/babel-helper-create-class-features-plugin/src/fields.ts
Expand Up @@ -669,15 +669,31 @@ const thisContextVisitor = traverse.visitors.merge([
environmentVisitor,
]);

const innerReferencesVisitor = {
ReferencedIdentifier(path, state) {
if (
path.scope.bindingIdentifierEquals(path.node.name, state.innerBinding)
) {
state.needsClassRef = true;
path.node.name = state.classRef.name;
}
},
};

function replaceThisContext(
path,
ref,
getSuperRef,
file,
isStaticBlock,
constantSuper,
innerBindingRef,
) {
const state = { classRef: ref, needsClassRef: false };
const state = {
classRef: ref,
needsClassRef: false,
innerBinding: innerBindingRef,
};

const replacer = new ReplaceSupers({
methodPath: path,
Expand All @@ -696,6 +712,11 @@ function replaceThisContext(
if (isStaticBlock || path.isProperty()) {
path.traverse(thisContextVisitor, state);
}

if (state.classRef?.name && state.classRef.name !== innerBindingRef?.name) {
path.traverse(innerReferencesVisitor, state);
}

return state.needsClassRef;
}

Expand All @@ -708,6 +729,7 @@ export function buildFieldsInitNodes(
setPublicClassFields,
privateFieldsAsProperties,
constantSuper,
innerBindingRef,
) {
let needsClassRef = false;
let injectSuperRef;
Expand Down Expand Up @@ -743,6 +765,7 @@ export function buildFieldsInitNodes(
state,
isStaticBlock,
constantSuper,
innerBindingRef,
);
needsClassRef = needsClassRef || replaced;
}
Expand Down
Expand Up @@ -168,9 +168,9 @@ export function createClassFeaturePlugin({

if (!props.length && !isDecorated) return;

const innerBinding = path.node.id;
let ref;

if (path.isClassExpression() || !path.node.id) {
if (!innerBinding || path.isClassExpression()) {
nameFunction(path);
ref = path.scope.generateUidIdentifier("class");
} else {
Expand Down Expand Up @@ -220,6 +220,7 @@ export function createClassFeaturePlugin({
setPublicClassFields ?? loose,
privateFieldsAsProperties ?? loose,
constantSuper ?? loose,
innerBinding,
));
}

Expand Down
@@ -0,0 +1,15 @@
const f = class Foo {
static #x = Foo;
static y = Foo;

static extract() {
return {
x: Foo.#x,
y: Foo.y,
}
}
};

const { x, y } = f.extract();
expect(x).toBe(f)
expect(y).toBe(f)
@@ -0,0 +1,4 @@
const f = class Foo {
static #x = Foo;
static y = Foo;
}
@@ -0,0 +1,3 @@
{
"plugins": ["proposal-class-properties", "transform-block-scoping"]
}
@@ -0,0 +1,6 @@
var _class, _temp, _x;

var f = (_temp = _class = class Foo {}, _x = {
writable: true,
value: _class
}, babelHelpers.defineProperty(_class, "y", _class), _temp);
@@ -0,0 +1,31 @@
const f = class Foo {
static #bar() {
return Foo;
}

static #method() {
return function inner() {
return Foo;
};
}
static #method_shadowed() {
new Foo();
return function inner() {
let Foo = 3;
return Foo;
}
}

static extract() {
return {
bar: Foo.#bar,
method: Foo.#method,
method_shadowed: Foo.#method_shadowed
}
}
};

const { bar, method, method_shadowed } = f.extract();
expect(bar()).toBe(f)
expect(method()()).toBe(f)
expect(method_shadowed()()).toBe(3)
@@ -0,0 +1,18 @@
const f = class Foo {
static #bar() {
return Foo;
}

static #method() {
return function inner() {
return Foo;
};
}
static #method_shadowed() {
new Foo();
return function inner() {
let Foo = 3;
return Foo;
}
}
}
@@ -0,0 +1,3 @@
{
"plugins": ["proposal-class-properties", "transform-block-scoping"]
}
@@ -0,0 +1,21 @@
var _class;

var f = _class = class Foo {};

function _bar() {
return _class;
}

function _method() {
return function inner() {
return _class;
};
}

function _method_shadowed() {
new _class();
return function inner() {
var Foo = 3;
return Foo;
};
}

0 comments on commit 903b600

Please sign in to comment.