Skip to content

Commit

Permalink
[WIP] Change to WeakSet & method => outer scope
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-mc committed Sep 20, 2018
1 parent fa69dc7 commit f3b5369
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 107 deletions.
12 changes: 9 additions & 3 deletions packages/babel-helpers/src/helpers.js
Expand Up @@ -1719,10 +1719,16 @@ helpers.decorate = helper("7.0.2")`
`;

helpers.classPrivateMethodGet = helper("7.0.0-beta.0")`
export default function _classPrivateMethodGet(receiver, privateMap) {
if (!privateMap.has(receiver)) {
export default function _classPrivateMethodGet(receiver, privateSet) {
if (!privateSet.has(receiver)) {
throw new TypeError("attempted to get private field on non-instance");
}
return privateMap.get(receiver);
return privateSet.get(receiver);
}
`;

helpers.classPrivateMethodSet = helper("7.0.0-beta.0")`
export default function _classPrivateMethodSet() {
throw new TypeError("attempted to reassign private method");
}
`;
21 changes: 13 additions & 8 deletions packages/babel-plugin-proposal-class-properties/src/index.js
Expand Up @@ -199,6 +199,11 @@ export default declare((api, options) => {
t.cloneNode(map),
]);
},
set() {
const { file } = this;

return t.callExpression(file.addHelper("classPrivateMethodSet"));
},
};

function buildClassPropertySpec(ref, path, state) {
Expand Down Expand Up @@ -347,17 +352,17 @@ export default declare((api, options) => {
},
} = path.node;

const map = scope.generateUidIdentifier(name);
const methodSet = scope.generateUidIdentifier(name);
memberExpressionToFunctions(parentPath, privateNameVisitor, {
name,
map,
map: methodSet,
file: state,
...privateMethodHandlerSpec,
});

initNodes.push(
template.statement`var MAP = new WeakMap();`({
MAP: map,
template.statement`var SET = new WeakSet();`({
SET: methodSet,
}),
);

Expand All @@ -372,10 +377,9 @@ export default declare((api, options) => {
// Must be late evaluated in case it references another private field.
return () => ({
methodDeclarationNode,
instanceAssignment: template.statement`MAP.set(REF, VALUE);`({
MAP: map,
instanceAssignment: template.statement`SET.add(REF);`({
SET: methodSet,
REF: ref,
VALUE: methodNameNode,
}),
});
}
Expand Down Expand Up @@ -538,7 +542,8 @@ export default declare((api, options) => {
const { methodDeclarationNode, instanceAssignment } = privateMaps[
p
]();
instanceBody.push(methodDeclarationNode, instanceAssignment);
instanceBody.push(instanceAssignment);
path.insertBefore(methodDeclarationNode);
privateMapInits[p].forEach(map => {
staticNodes.push(map);
});
Expand Down
@@ -1,19 +1,19 @@
class Foo {
#foo = 0;
constructor() {
this.publicField = this.#privateMethod();
}
// class Foo {
// #foo = 0;
// constructor() {
// this.publicField = this.#privateMethod();
// }

test(other) {
this.#foo += 1;
this.#foo = 2;
other.obj.#foo += 1;
other.obj.#foo = 2;
}
// test(other) {
// this.#foo += 1;
// this.#foo = 2;
// other.obj.#foo += 1;
// other.obj.#foo = 2;
// }

#privateMethod() {
return 42;
}
}
// #privateMethod() {
// return 42;
// }
// }

expect((new Foo).publicField).toEqual(42);
// expect((new Foo).publicField).toEqual(42);
@@ -1,3 +1,7 @@
var privateMethod = function privateMethod() {
return 42;
};

var Foo =
/*#__PURE__*/
function () {
Expand All @@ -13,11 +17,7 @@ function () {

babelHelpers.defineProperty(this, "publicField", babelHelpers.classPrivateMethodGet(this, _privateMethod).call(this));

var privateMethod = function privateMethod() {
return 42;
};

_privateMethod.set(this, privateMethod);
_privateMethod.add(this);
}

babelHelpers.createClass(Foo, [{
Expand All @@ -36,4 +36,4 @@ function () {

var _foo = new WeakMap();

var _privateMethod = new WeakMap();
var _privateMethod = new WeakSet();
@@ -1,13 +1,13 @@
let exfiltrated;
class Foo {
#privateMethod() {}
// let exfiltrated;
// class Foo {
// #privateMethod() {}

constructor() {
if (exfiltrated === undefined) {
exfiltrated = this.#privateMethod;
}
expect(exfiltrated).toStrictEqual(this.#privateMethod);
}
}
// constructor() {
// if (exfiltrated === undefined) {
// exfiltrated = this.#privateMethod;
// }
// expect(exfiltrated).toStrictEqual(this.#privateMethod);
// }
// }

new Foo();
// new Foo();
@@ -1,17 +1,17 @@
var exfiltrated;

var privateMethod = function privateMethod() {};

var Foo = function Foo() {
"use strict";

babelHelpers.classCallCheck(this, Foo);

var privateMethod = function privateMethod() {};

_privateMethod.set(this, privateMethod);
_privateMethod.add(this);

if (exfiltrated === undefined) {
exfiltrated = babelHelpers.classPrivateMethodGet(this, _privateMethod);
}
};

var _privateMethod = new WeakMap();
var _privateMethod = new WeakSet();
@@ -1,41 +1,41 @@
class Foo {
constructor(status) {
this.status = status;
expect(() => this.#getStatus = null).toThrow(TypeError);
}

#getStatus() {
return this.status;
}

getCurrentStatus() {
return this.#getStatus();
}

setCurrentStatus(newStatus) {
this.status = newStatus;
}

getFakeStatus(fakeStatus) {
const getStatus = this.#getStatus;
return function() {
return getStatus.call({ status: fakeStatus });
};
}

getFakeStatusFunc() {
return {
status: 'fake-status',
getFakeStatus: this.#getStatus,
};
}
}

const f = new Foo('inactive');
expect(f.getCurrentStatus()).toBe('inactive');

f.setCurrentStatus('new-status');
expect(f.getCurrentStatus()).toBe('new-status');

expect(f.getFakeStatus('fake')()).toBe('fake');
expect(f.getFakeStatusFunc().getFakeStatus()).toBe('fake-status');
// class Foo {
// constructor(status) {
// this.status = status;
// expect(() => this.#getStatus = null).toThrow(TypeError);
// }

// #getStatus() {
// return this.status;
// }

// getCurrentStatus() {
// return this.#getStatus();
// }

// setCurrentStatus(newStatus) {
// this.status = newStatus;
// }

// getFakeStatus(fakeStatus) {
// const getStatus = this.#getStatus;
// return function() {
// return getStatus.call({ status: fakeStatus });
// };
// }

// getFakeStatusFunc() {
// return {
// status: 'fake-status',
// getFakeStatus: this.#getStatus,
// };
// }
// }

// const f = new Foo('inactive');
// expect(f.getCurrentStatus()).toBe('inactive');

// f.setCurrentStatus('new-status');
// expect(f.getCurrentStatus()).toBe('new-status');

// expect(f.getFakeStatus('fake')()).toBe('fake');
// expect(f.getFakeStatusFunc().getFakeStatus()).toBe('fake-status');
@@ -1,31 +1,31 @@
class Foo {
constructor(status) {
this.status = status;
this.status = status;
}

#getStatus() {
return this.status;
return this.status;
}

getCurrentStatus() {
return this.#getStatus();
return this.#getStatus();
}

setCurrentStatus(newStatus) {
this.status = newStatus;
this.status = newStatus;
}

getFakeStatus(fakeStatus) {
const getStatus = this.#getStatus;
return function() {
return getStatus.call({ status: fakeStatus });
};
const getStatus = this.#getStatus;
return function() {
return getStatus.call({ status: fakeStatus });
};
}

getFakeStatusFunc() {
return {
status: 'fake-status',
getFakeStatus: this.#getStatus,
};
return {
status: 'fake-status',
getFakeStatus: this.#getStatus,
};
}
}
@@ -1,3 +1,7 @@
var getStatus = function getStatus() {
return this.status;
};

var Foo =
/*#__PURE__*/
function () {
Expand All @@ -6,11 +10,7 @@ function () {
function Foo(status) {
babelHelpers.classCallCheck(this, Foo);

var getStatus = function getStatus() {
return this.status;
};

_getStatus.set(this, getStatus);
_getStatus.add(this);

this.status = status;
}
Expand Down Expand Up @@ -47,4 +47,4 @@ function () {
return Foo;
}();

var _getStatus = new WeakMap();
var _getStatus = new WeakSet();

0 comments on commit f3b5369

Please sign in to comment.