Skip to content

Commit

Permalink
Handle redeclared private field in computed key
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell committed Apr 14, 2020
1 parent 27a09f1 commit 3a673dc
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 3 deletions.
20 changes: 17 additions & 3 deletions packages/babel-helper-create-class-features-plugin/src/fields.js
Expand Up @@ -86,21 +86,28 @@ const privateNameVisitor = {
const body = path.get("body.body");

const visiblePrivateNames = new Map(privateNamesMap);
const redeclared = [];
for (const prop of body) {
if (!prop.isPrivate()) continue;
visiblePrivateNames.delete(prop.node.key.id.name);
const { name } = prop.node.key.id;
visiblePrivateNames.delete(name);
redeclared.push(name);
}

// If the class doesn't redeclare any private fields, we can continue with
// our overall traversal.
if (visiblePrivateNames.size === privateNamesMap.size) {
if (!redeclared.length) {
return;
}

// This class redeclares some private field. We need to process the outer
// environment with access to all the outer privates, then we can process
// the inner environment with only the still-visible outer privates.
path.traverse(privateNameNestedVisitor, this);
path.get("superClass").traverse(privateNameVisitor, this);
path.get("body").traverse(privateNameNestedVisitor, {
...this,
redeclared,
});
path.traverse(privateNameVisitor, {
...this,
privateNamesMap: visiblePrivateNames,
Expand All @@ -115,6 +122,13 @@ const privateNameVisitor = {
// Traverses the outer portion of a class, without touching the class's inner
// scope, for private names.
const privateNameNestedVisitor = traverse.visitors.merge([
{
PrivateName(path) {
const { redeclared } = this;
const { name } = path.node.id;
if (redeclared.includes(name)) path.skip();
},
},
{
PrivateName: privateNameVisitor.PrivateName,
},
Expand Down
@@ -0,0 +1,14 @@
class Foo {
#foo = 1;

test() {
class Nested {
#foo = 2;

[this.#foo]() {
}
}

this.#foo;
}
}
@@ -0,0 +1,43 @@
var Foo = /*#__PURE__*/function () {
"use strict";

function Foo() {
babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _foo, {
writable: true,
value: 1
});
}

babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
var _babelHelpers$classPr;

_babelHelpers$classPr = babelHelpers.classPrivateFieldLooseBase(this, _foo2)[_foo2];

var Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
Object.defineProperty(this, _foo2, {
writable: true,
value: 2
});
}

babelHelpers.createClass(Nested, [{
key: _babelHelpers$classPr,
value: function () {}
}]);
return Nested;
}();

var _foo2 = babelHelpers.classPrivateFieldLooseKey("foo");

babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo];
}
}]);
return Foo;
}();

var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
@@ -0,0 +1,12 @@
class Foo {
#foo = 1;

test() {
class Nested {
[this.#foo]() {
}
}

this.#foo;
}
}
@@ -0,0 +1,35 @@
var Foo = /*#__PURE__*/function () {
"use strict";

function Foo() {
babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _foo, {
writable: true,
value: 1
});
}

babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
var _this = this;

var Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
}

babelHelpers.createClass(Nested, [{
key: babelHelpers.classPrivateFieldLooseBase(_this, _foo)[_foo],
value: function () {}
}]);
return Nested;
}();

babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo];
}
}]);
return Foo;
}();

var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
@@ -0,0 +1,14 @@
class Foo {
#foo = 1;

test() {
class Nested {
#foo = 2;

[this.#foo]() {
}
}

this.#foo;
}
}
@@ -0,0 +1,45 @@
var Foo = /*#__PURE__*/function () {
"use strict";

function Foo() {
babelHelpers.classCallCheck(this, Foo);

_foo.set(this, {
writable: true,
value: 1
});
}

babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
var _babelHelpers$classPr;

_babelHelpers$classPr = babelHelpers.classPrivateFieldGet(this, _foo2);

var Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);

_foo2.set(this, {
writable: true,
value: 2
});
}

babelHelpers.createClass(Nested, [{
key: _babelHelpers$classPr,
value: function () {}
}]);
return Nested;
}();

var _foo2 = new WeakMap();

babelHelpers.classPrivateFieldGet(this, _foo);
}
}]);
return Foo;
}();

var _foo = new WeakMap();
@@ -0,0 +1,12 @@
class Foo {
#foo = 1;

test() {
class Nested {
[this.#foo]() {
}
}

this.#foo;
}
}
@@ -0,0 +1,36 @@
var Foo = /*#__PURE__*/function () {
"use strict";

function Foo() {
babelHelpers.classCallCheck(this, Foo);

_foo.set(this, {
writable: true,
value: 1
});
}

babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
var _this = this;

var Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
}

babelHelpers.createClass(Nested, [{
key: babelHelpers.classPrivateFieldGet(_this, _foo),
value: function () {}
}]);
return Nested;
}();

babelHelpers.classPrivateFieldGet(this, _foo);
}
}]);
return Foo;
}();

var _foo = new WeakMap();

0 comments on commit 3a673dc

Please sign in to comment.