Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class static private field destructure set #12917

Merged
merged 5 commits into from Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/release.yml
Expand Up @@ -49,7 +49,9 @@ jobs:
git config user.email "babel-bot@users.noreply.github.com"

- name: Create new version
run: yarn release-tool version -f @babel/standalone --yes patch
run: |
make new-version-checklist
yarn release-tool version -f @babel/standalone --yes patch

- name: Push to GitHub
id: push
Expand Down Expand Up @@ -167,5 +169,4 @@ jobs:

- name: Delete temporary branch from GitHub
if: needs.git-version.result == 'success'
run:
git push "https://babel-bot:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git" :${{ needs.git-version.outputs.branch }}
run: git push "https://babel-bot:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git" :${{ needs.git-version.outputs.branch }}
14 changes: 14 additions & 0 deletions Makefile
Expand Up @@ -195,7 +195,21 @@ prepublish:
$(MAKE) prepublish-build
IS_PUBLISH=true $(MAKE) test

new-version-checklist:
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@echo "!!!!!! !!!!!!"
@echo "!!!!!! Update classStaticPrivateFieldDestructureSet !!!!!!"
@echo "!!!!!! helper version in !!!!!!"
@echo "!!!!!! packages/babel-helpers/src/helpers.js !!!!!!"
@echo "!!!!!! packages/babel-helper-create-class-features-plugin/src/fields.js"
@echo "!!!!!! !!!!!!"
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
@exit 1
JLHwung marked this conversation as resolved.
Show resolved Hide resolved

new-version:
$(MAKE) new-version-checklist
git pull --rebase
$(YARN) release-tool version -f @babel/standalone

Expand Down
25 changes: 23 additions & 2 deletions packages/babel-helper-create-class-features-plugin/src/fields.js
Expand Up @@ -318,9 +318,30 @@ const privateNameHandlerSpec = {
},

destructureSet(member) {
const { privateNamesMap, file } = this;
const { classRef, privateNamesMap, file } = this;
const { name } = member.node.property.id;
const { id } = privateNamesMap.get(name);
const { id, static: isStatic } = privateNamesMap.get(name);
if (isStatic) {
try {
// classStaticPrivateFieldDestructureSet was introduced in 7.99.0
// eslint-disable-next-line no-var
var helper = file.addHelper("classStaticPrivateFieldDestructureSet");
} catch {
throw new Error(
"Babel can not transpile `[C.#p] = [0]` with @babel/helpers < 7.99.0, \n" +
"please update @babel/helpers to the latest version.",
);
}
return t.memberExpression(
t.callExpression(helper, [
this.receiver(member),
t.cloneNode(classRef),
t.cloneNode(id),
]),
t.identifier("value"),
);
}

return t.memberExpression(
t.callExpression(file.addHelper("classPrivateFieldDestructureSet"), [
this.receiver(member),
Expand Down
153 changes: 91 additions & 62 deletions packages/babel-helpers/src/helpers.js
Expand Up @@ -1299,24 +1299,90 @@ helpers.classPrivateFieldLooseBase = helper("7.0.0-beta.0")`
`;

helpers.classPrivateFieldGet = helper("7.0.0-beta.0")`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to bump the version because it's functionally equivalent, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Refactoring internals helpers should not bump minimal required helper version as long as the interface is not changed.

import classApplyDescriptorGet from "classApplyDescriptorGet";
import classExtractFieldDescriptor from "classExtractFieldDescriptor";
export default function _classPrivateFieldGet(receiver, privateMap) {
var descriptor = privateMap.get(receiver);
if (!descriptor) {
throw new TypeError("attempted to get private field on non-instance");
var descriptor = classExtractFieldDescriptor(receiver, privateMap, "get");
return classApplyDescriptorGet(receiver, descriptor);
}
`;

helpers.classPrivateFieldSet = helper("7.0.0-beta.0")`
import classApplyDescriptorSet from "classApplyDescriptorSet";
import classExtractFieldDescriptor from "classExtractFieldDescriptor";
export default function _classPrivateFieldSet(receiver, privateMap, value) {
var descriptor = classExtractFieldDescriptor(receiver, privateMap, "set");
classApplyDescriptorSet(receiver, descriptor, value);
return value;
}
`;

helpers.classPrivateFieldDestructureSet = helper("7.4.4")`
import classApplyDescriptorDestructureSet from "classApplyDescriptorDestructureSet";
import classExtractFieldDescriptor from "classExtractFieldDescriptor";
export default function _classPrivateFieldDestructureSet(receiver, privateMap) {
var descriptor = classExtractFieldDescriptor(receiver, privateMap, "set");
return classApplyDescriptorDestructureSet(receiver, descriptor);
}
`;

helpers.classExtractFieldDescriptor = helper("7.99.0")`
export default function _classExtractFieldDescriptor(receiver, privateMap, action) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to " + action + " private field on non-instance");
}
return privateMap.get(receiver);
}
`;

helpers.classStaticPrivateFieldSpecGet = helper("7.0.2")`
import classApplyDescriptorGet from "classApplyDescriptorGet";
import classCheckPrivateStaticAccess from "classCheckPrivateStaticAccess";
import classCheckPrivateStaticFieldDescriptor from "classCheckPrivateStaticFieldDescriptor";
export default function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) {
classCheckPrivateStaticAccess(receiver, classConstructor);
classCheckPrivateStaticFieldDescriptor(descriptor, "get");
return classApplyDescriptorGet(receiver, descriptor);
}
`;

helpers.classStaticPrivateFieldSpecSet = helper("7.0.2")`
import classApplyDescriptorSet from "classApplyDescriptorSet";
import classCheckPrivateStaticAccess from "classCheckPrivateStaticAccess";
import classCheckPrivateStaticFieldDescriptor from "classCheckPrivateStaticFieldDescriptor";
export default function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) {
classCheckPrivateStaticAccess(receiver, classConstructor);
classCheckPrivateStaticFieldDescriptor(descriptor, "set");
classApplyDescriptorSet(receiver, descriptor, value);
return value;
}
`;

helpers.classStaticPrivateMethodGet = helper("7.3.2")`
import classCheckPrivateStaticAccess from "classCheckPrivateStaticAccess";
export default function _classStaticPrivateMethodGet(receiver, classConstructor, method) {
classCheckPrivateStaticAccess(receiver, classConstructor);
return method;
}
`;

helpers.classStaticPrivateMethodSet = helper("7.3.2")`
export default function _classStaticPrivateMethodSet() {
throw new TypeError("attempted to set read only static private field");
}
`;

helpers.classApplyDescriptorGet = helper("7.99.0")`
export default function _classApplyDescriptorGet(receiver, descriptor) {
if (descriptor.get) {
return descriptor.get.call(receiver);
}
return descriptor.value;
}
`;

helpers.classPrivateFieldSet = helper("7.0.0-beta.0")`
export default function _classPrivateFieldSet(receiver, privateMap, value) {
var descriptor = privateMap.get(receiver);
if (!descriptor) {
throw new TypeError("attempted to set private field on non-instance");
}
helpers.classApplyDescriptorSet = helper("7.99.0")`
export default function _classApplyDescriptorSet(receiver, descriptor, value) {
if (descriptor.set) {
descriptor.set.call(receiver, value);
} else {
Expand All @@ -1326,23 +1392,13 @@ helpers.classPrivateFieldSet = helper("7.0.0-beta.0")`
// class bodies.
throw new TypeError("attempted to set read only private field");
}

descriptor.value = value;
}

return value;
}
`;

helpers.classPrivateFieldDestructureSet = helper("7.4.4")`
export default function _classPrivateFieldDestructureSet(receiver, privateMap) {
if (privateMap === undefined) {
throw new TypeError("attempted to set private static field before its declaration");
}
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to set private field on non-instance");
}
var descriptor = privateMap.get(receiver);
helpers.classApplyDescriptorDestructureSet = helper("7.99.0")`
export default function _classApplyDescriptorDestructureSet(receiver, descriptor) {
if (descriptor.set) {
if (!("__destrObj" in descriptor)) {
descriptor.__destrObj = {
Expand All @@ -1365,57 +1421,30 @@ helpers.classPrivateFieldDestructureSet = helper("7.4.4")`
}
`;

helpers.classStaticPrivateFieldSpecGet = helper("7.0.2")`
export default function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) {
if (receiver !== classConstructor) {
throw new TypeError("Private static access of wrong provenance");
}
if (descriptor === undefined) {
throw new TypeError("attempted to get private static field before its declaration");
}
if (descriptor.get) {
return descriptor.get.call(receiver);
}
return descriptor.value;
helpers.classStaticPrivateFieldDestructureSet = helper("7.99.0")`
import classApplyDescriptorDestructureSet from "classApplyDescriptorDestructureSet";
import classCheckPrivateStaticAccess from "classCheckPrivateStaticAccess";
import classCheckPrivateStaticFieldDescriptor from "classCheckPrivateStaticFieldDescriptor";
export default function _classStaticPrivateFieldDestructureSet(receiver, classConstructor, descriptor) {
classCheckPrivateStaticAccess(receiver, classConstructor);
classCheckPrivateStaticFieldDescriptor(descriptor, "set");
return classApplyDescriptorDestructureSet(receiver, descriptor);
}
`;

helpers.classStaticPrivateFieldSpecSet = helper("7.0.2")`
export default function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) {
helpers.classCheckPrivateStaticAccess = helper("7.99.0")`
export default function _classCheckPrivateStaticAccess(receiver, classConstructor) {
if (receiver !== classConstructor) {
throw new TypeError("Private static access of wrong provenance");
}
if (descriptor === undefined) {
throw new TypeError("attempted to set private static field before its declaration");
}
if (descriptor.set) {
descriptor.set.call(receiver, value);
} else {
if (!descriptor.writable) {
// This should only throw in strict mode, but class bodies are
// always strict and private fields can only be used inside
// class bodies.
throw new TypeError("attempted to set read only private field");
}
descriptor.value = value;
}

return value;
}
`;

helpers.classStaticPrivateMethodGet = helper("7.3.2")`
export default function _classStaticPrivateMethodGet(receiver, classConstructor, method) {
if (receiver !== classConstructor) {
throw new TypeError("Private static access of wrong provenance");
helpers.classCheckPrivateStaticFieldDescriptor = helper("7.99.0")`
export default function _classCheckPrivateStaticFieldDescriptor(descriptor, action) {
if (descriptor === undefined) {
throw new TypeError("attempted to " + action + " private static field before its declaration");
}
return method;
}
`;

helpers.classStaticPrivateMethodSet = helper("7.3.2")`
export default function _classStaticPrivateMethodSet() {
throw new TypeError("attempted to set read only static private field");
}
`;

Expand Down
@@ -0,0 +1,14 @@
class Foo {
static #client

constructor(props) {
;([Foo.#client] = props);
}

getClient() {
return Foo.#client;
}
}

const foo = new Foo(['bar']);
expect(foo.getClient()).toBe('bar');
@@ -0,0 +1,7 @@
class Foo {
static #client

constructor(props) {
([Foo.#client] = props);
}
}
@@ -0,0 +1,13 @@
var _client = babelHelpers.classPrivateFieldLooseKey("client");

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

babelHelpers.classCallCheck(this, Foo);
[babelHelpers.classPrivateFieldLooseBase(Foo, _client)[_client]] = props;
};

Object.defineProperty(Foo, _client, {
writable: true,
value: void 0
});
@@ -0,0 +1,14 @@
class Foo {
static #client

constructor(props) {
;({ client: Foo.#client } = props)
}

getClient() {
return Foo.#client;
}
}

const foo = new Foo({ client: 'bar' });
expect(foo.getClient()).toBe('bar');
@@ -0,0 +1,7 @@
class Foo {
static #client

constructor(props) {
({ client: Foo.#client } = props)
}
}
@@ -0,0 +1,15 @@
var _client = babelHelpers.classPrivateFieldLooseKey("client");

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

babelHelpers.classCallCheck(this, Foo);
({
client: babelHelpers.classPrivateFieldLooseBase(Foo, _client)[_client]
} = props);
};

Object.defineProperty(Foo, _client, {
writable: true,
value: void 0
});
@@ -0,0 +1,14 @@
class Foo {
static #client

constructor(props) {
;([Foo.#client] = props);
}

getClient() {
return Foo.#client;
}
}

const foo = new Foo(['bar']);
expect(foo.getClient()).toBe('bar');
@@ -0,0 +1,7 @@
class Foo {
static #client

constructor(props) {
([Foo.#client] = props);
}
}
@@ -0,0 +1,11 @@
var Foo = function Foo(props) {
"use strict";

babelHelpers.classCallCheck(this, Foo);
[babelHelpers.classStaticPrivateFieldDestructureSet(Foo, Foo, _client).value] = props;
};

var _client = {
writable: true,
value: void 0
};
@@ -0,0 +1,14 @@
class Foo {
static #client

constructor(props) {
;({ client: Foo.#client } = props)
}

getClient() {
return Foo.#client;
}
}

const foo = new Foo({ client: 'bar' });
expect(foo.getClient()).toBe('bar');