Class private properties (#7842)
* Update member-expression-to-functions 1. Babel using British spellings, so `memoise` 2. Provide a helper `AssignmentMemoiser` class, which will assign the memo'd value with the `n`th access. * Private properties! * Fixes * Tests * Update helper name * Fix privates that reference other privates * Don't extend a builtin * Rebase
This commit is contained in:
parent
70eb206c03
commit
27c39c512d
@ -26,7 +26,7 @@ const visitor = {
|
|||||||
|
|
||||||
// The helper requires three special methods on state: `get`, `set`, and
|
// The helper requires three special methods on state: `get`, `set`, and
|
||||||
// `call`.
|
// `call`.
|
||||||
// Optionally, a special `memoize` method may be defined, which gets
|
// Optionally, a special `memoise` method may be defined, which gets
|
||||||
// called if the member is in a self-referential update expression.
|
// called if the member is in a self-referential update expression.
|
||||||
// Everything else will be passed through as normal.
|
// Everything else will be passed through as normal.
|
||||||
const state = {
|
const state = {
|
||||||
@ -55,10 +55,10 @@ const state = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
memoize(memberPath) {
|
memoise(memberPath) {
|
||||||
const { node } = memberPath;
|
const { node } = memberPath;
|
||||||
if (node.computed) {
|
if (node.computed) {
|
||||||
MEMOIZED.set(node, ...);
|
MEMOISED.set(node, ...);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,39 @@
|
|||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
|
class AssignmentMemoiser {
|
||||||
|
constructor() {
|
||||||
|
this._map = new WeakMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
has(key) {
|
||||||
|
return this._map.has(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key) {
|
||||||
|
if (!this.has(key)) return;
|
||||||
|
|
||||||
|
const record = this._map.get(key);
|
||||||
|
const { value } = record;
|
||||||
|
|
||||||
|
record.count--;
|
||||||
|
if (record.count === 0) {
|
||||||
|
// The `count` access is the outermost function call (hopefully), so it
|
||||||
|
// does the assignment.
|
||||||
|
return t.assignmentExpression("=", value, key);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key, value, count) {
|
||||||
|
return this._map.set(key, { count, value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handle = {
|
const handle = {
|
||||||
|
memoise() {
|
||||||
|
// noop.
|
||||||
|
},
|
||||||
|
|
||||||
handle(member) {
|
handle(member) {
|
||||||
const { node, parent, parentPath } = member;
|
const { node, parent, parentPath } = member;
|
||||||
|
|
||||||
@ -9,11 +42,10 @@ const handle = {
|
|||||||
if (parentPath.isUpdateExpression({ argument: node })) {
|
if (parentPath.isUpdateExpression({ argument: node })) {
|
||||||
const { operator, prefix } = parent;
|
const { operator, prefix } = parent;
|
||||||
|
|
||||||
// Give the state handler a chance to memoize the member,
|
// Give the state handler a chance to memoise the member, since we'll
|
||||||
// since we'll reference it twice.
|
// reference it twice. The second access (the set) should do the memo
|
||||||
if (this.memoize) {
|
// assignment.
|
||||||
this.memoize(member);
|
this.memoise(member, 2);
|
||||||
}
|
|
||||||
|
|
||||||
const value = t.binaryExpression(
|
const value = t.binaryExpression(
|
||||||
operator[0],
|
operator[0],
|
||||||
@ -44,11 +76,10 @@ const handle = {
|
|||||||
let value = right;
|
let value = right;
|
||||||
|
|
||||||
if (operator !== "=") {
|
if (operator !== "=") {
|
||||||
// Give the state handler a chance to memoize the member,
|
// Give the state handler a chance to memoise the member, since we'll
|
||||||
// since we'll reference it twice.
|
// reference it twice. The second access (the set) should do the memo
|
||||||
if (this.memoize) {
|
// assignment.
|
||||||
this.memoize(member);
|
this.memoise(member, 2);
|
||||||
}
|
|
||||||
|
|
||||||
value = t.binaryExpression(
|
value = t.binaryExpression(
|
||||||
operator.slice(0, -1),
|
operator.slice(0, -1),
|
||||||
@ -79,11 +110,12 @@ const handle = {
|
|||||||
// it wishes to be transformed.
|
// it wishes to be transformed.
|
||||||
// Additionally, the caller must pass in a state object with at least
|
// Additionally, the caller must pass in a state object with at least
|
||||||
// get, set, and call methods.
|
// get, set, and call methods.
|
||||||
// Optionally, a memoize method may be defined on the state, which will be
|
// Optionally, a memoise method may be defined on the state, which will be
|
||||||
// called when the member is a self-referential update.
|
// called when the member is a self-referential update.
|
||||||
export default function memberExpressionToFunctions(path, visitor, state) {
|
export default function memberExpressionToFunctions(path, visitor, state) {
|
||||||
path.traverse(visitor, {
|
path.traverse(visitor, {
|
||||||
...state,
|
|
||||||
...handle,
|
...handle,
|
||||||
|
...state,
|
||||||
|
memoiser: new AssignmentMemoiser(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,9 +70,8 @@ const visitor = traverse.visitors.merge([
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const memoized = new WeakMap();
|
|
||||||
const specHandlers = {
|
const specHandlers = {
|
||||||
memoize(superMember) {
|
memoise(superMember, count) {
|
||||||
const { scope, node } = superMember;
|
const { scope, node } = superMember;
|
||||||
const { computed, property } = node;
|
const { computed, property } = node;
|
||||||
if (!computed) {
|
if (!computed) {
|
||||||
@ -84,44 +83,34 @@ const specHandlers = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memoized.set(property, memo);
|
this.memoiser.set(property, memo, count);
|
||||||
|
},
|
||||||
|
|
||||||
|
prop(superMember) {
|
||||||
|
const { computed, property } = superMember.node;
|
||||||
|
if (this.memoiser.has(property)) {
|
||||||
|
return t.cloneNode(this.memoiser.get(property));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (computed) {
|
||||||
|
return t.cloneNode(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.stringLiteral(property.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
get(superMember) {
|
get(superMember) {
|
||||||
const { computed, property } = superMember.node;
|
|
||||||
const thisExpr = t.thisExpression();
|
|
||||||
|
|
||||||
let prop;
|
|
||||||
if (computed && memoized.has(property)) {
|
|
||||||
prop = t.cloneNode(memoized.get(property));
|
|
||||||
} else {
|
|
||||||
prop = computed ? property : t.stringLiteral(property.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.callExpression(this.file.addHelper("get"), [
|
return t.callExpression(this.file.addHelper("get"), [
|
||||||
getPrototypeOfExpression(this.getObjectRef(), this.isStatic, this.file),
|
getPrototypeOfExpression(this.getObjectRef(), this.isStatic, this.file),
|
||||||
prop,
|
this.prop(superMember),
|
||||||
thisExpr,
|
t.thisExpression(),
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
set(superMember, value) {
|
set(superMember, value) {
|
||||||
const { computed, property } = superMember.node;
|
|
||||||
|
|
||||||
let prop;
|
|
||||||
if (computed && memoized.has(property)) {
|
|
||||||
prop = t.assignmentExpression(
|
|
||||||
"=",
|
|
||||||
t.cloneNode(memoized.get(property)),
|
|
||||||
property,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
prop = computed ? property : t.stringLiteral(property.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.callExpression(this.file.addHelper("set"), [
|
return t.callExpression(this.file.addHelper("set"), [
|
||||||
getPrototypeOfExpression(this.getObjectRef(), this.isStatic, this.file),
|
getPrototypeOfExpression(this.getObjectRef(), this.isStatic, this.file),
|
||||||
prop,
|
this.prop(superMember),
|
||||||
value,
|
value,
|
||||||
t.thisExpression(),
|
t.thisExpression(),
|
||||||
t.booleanLiteral(superMember.isInStrictMode()),
|
t.booleanLiteral(superMember.isInStrictMode()),
|
||||||
@ -134,12 +123,21 @@ const specHandlers = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const looseHandlers = {
|
const looseHandlers = {
|
||||||
memoize: specHandlers.memoize,
|
...specHandlers,
|
||||||
call: specHandlers.call,
|
|
||||||
|
prop(superMember) {
|
||||||
|
const { property } = superMember.node;
|
||||||
|
if (this.memoiser.has(property)) {
|
||||||
|
return t.cloneNode(this.memoiser.get(property));
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.cloneNode(property);
|
||||||
|
},
|
||||||
|
|
||||||
get(superMember) {
|
get(superMember) {
|
||||||
const { isStatic, superRef } = this;
|
const { isStatic, superRef } = this;
|
||||||
const { property, computed } = superMember.node;
|
const { computed } = superMember.node;
|
||||||
|
const prop = this.prop(superMember);
|
||||||
|
|
||||||
let object;
|
let object;
|
||||||
if (isStatic) {
|
if (isStatic) {
|
||||||
@ -155,29 +153,12 @@ const looseHandlers = {
|
|||||||
: t.memberExpression(t.identifier("Object"), t.identifier("prototype"));
|
: t.memberExpression(t.identifier("Object"), t.identifier("prototype"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let prop;
|
|
||||||
if (computed && memoized.has(property)) {
|
|
||||||
prop = t.cloneNode(memoized.get(property));
|
|
||||||
} else {
|
|
||||||
prop = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.memberExpression(object, prop, computed);
|
return t.memberExpression(object, prop, computed);
|
||||||
},
|
},
|
||||||
|
|
||||||
set(superMember, value) {
|
set(superMember, value) {
|
||||||
const { property, computed } = superMember.node;
|
const { computed } = superMember.node;
|
||||||
|
const prop = this.prop(superMember);
|
||||||
let prop;
|
|
||||||
if (computed && memoized.has(property)) {
|
|
||||||
prop = t.assignmentExpression(
|
|
||||||
"=",
|
|
||||||
t.cloneNode(memoized.get(property)),
|
|
||||||
property,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
prop = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.assignmentExpression(
|
return t.assignmentExpression(
|
||||||
"=",
|
"=",
|
||||||
|
|||||||
@ -967,3 +967,38 @@ helpers.applyDecoratedDescriptor = () => template.program.ast`
|
|||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
helpers.classPrivateFieldLooseKey = () => template.program.ast`
|
||||||
|
var id = 0;
|
||||||
|
export default function _classPrivateFieldKey(name) {
|
||||||
|
return "__private_" + (id++) + "_" + name;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
helpers.classPrivateFieldLooseBase = () => template.program.ast`
|
||||||
|
export default function _classPrivateFieldBase(receiver, privateKey) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {
|
||||||
|
throw new TypeError("attempted to use private field on non-instance");
|
||||||
|
}
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
helpers.classPrivateFieldGet = () => template.program.ast`
|
||||||
|
export default function _classPrivateFieldGet(receiver, privateMap) {
|
||||||
|
if (!privateMap.has(receiver)) {
|
||||||
|
throw new TypeError("attempted to get private field on non-instance");
|
||||||
|
}
|
||||||
|
return privateMap.get(receiver);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
helpers.classPrivateFieldSet = () => template.program.ast`
|
||||||
|
export default function _classPrivateFieldSet(receiver, privateMap, value) {
|
||||||
|
if (!privateMap.has(receiver)) {
|
||||||
|
throw new TypeError("attempted to set private field on non-instance");
|
||||||
|
}
|
||||||
|
privateMap.set(receiver, value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-function-name": "7.0.0-beta.47",
|
"@babel/helper-function-name": "7.0.0-beta.47",
|
||||||
|
"@babel/helper-member-expression-to-functions": "7.0.0-beta.47",
|
||||||
|
"@babel/helper-optimise-call-expression": "7.0.0-beta.47",
|
||||||
"@babel/helper-plugin-utils": "7.0.0-beta.47",
|
"@babel/helper-plugin-utils": "7.0.0-beta.47",
|
||||||
"@babel/helper-replace-supers": "7.0.0-beta.47",
|
"@babel/helper-replace-supers": "7.0.0-beta.47",
|
||||||
"@babel/plugin-syntax-class-properties": "7.0.0-beta.47"
|
"@babel/plugin-syntax-class-properties": "7.0.0-beta.47"
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import nameFunction from "@babel/helper-function-name";
|
|||||||
import syntaxClassProperties from "@babel/plugin-syntax-class-properties";
|
import syntaxClassProperties from "@babel/plugin-syntax-class-properties";
|
||||||
import { template, traverse, types as t } from "@babel/core";
|
import { template, traverse, types as t } from "@babel/core";
|
||||||
import { environmentVisitor } from "@babel/helper-replace-supers";
|
import { environmentVisitor } from "@babel/helper-replace-supers";
|
||||||
|
import memberExpressionToFunctions from "@babel/helper-member-expression-to-functions";
|
||||||
|
import optimiseCall from "@babel/helper-optimise-call-expression";
|
||||||
|
|
||||||
export default declare((api, options) => {
|
export default declare((api, options) => {
|
||||||
api.assertVersion(7);
|
api.assertVersion(7);
|
||||||
@ -51,36 +53,206 @@ export default declare((api, options) => {
|
|||||||
environmentVisitor,
|
environmentVisitor,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const buildClassPropertySpec = (
|
// Traverses the class scope, handling private name references. If an inner
|
||||||
ref,
|
// class redeclares the same private name, it will hand off traversal to the
|
||||||
{ key, value, computed },
|
// restricted visitor (which doesn't traverse the inner class's inner scope).
|
||||||
scope,
|
const privateNameVisitor = {
|
||||||
state,
|
PrivateName(path) {
|
||||||
) => {
|
const { name } = this;
|
||||||
|
const { node, parentPath } = path;
|
||||||
|
|
||||||
|
if (!parentPath.isMemberExpression({ property: node })) return;
|
||||||
|
if (node.id.name !== name) return;
|
||||||
|
this.handle(parentPath);
|
||||||
|
},
|
||||||
|
|
||||||
|
Class(path) {
|
||||||
|
const { name } = this;
|
||||||
|
const body = path.get("body.body");
|
||||||
|
|
||||||
|
for (const prop of body) {
|
||||||
|
if (!prop.isClassPrivateProperty()) continue;
|
||||||
|
if (prop.node.key.id.name !== name) continue;
|
||||||
|
|
||||||
|
// This class redeclares the private name.
|
||||||
|
// So, we can only evaluate the things in the outer scope.
|
||||||
|
path.traverse(privateNameInnerVisitor, this);
|
||||||
|
path.skip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Traverses the outer portion of a class, without touching the class's inner
|
||||||
|
// scope, for private names.
|
||||||
|
const privateNameInnerVisitor = traverse.visitors.merge([
|
||||||
|
{
|
||||||
|
PrivateName: privateNameVisitor.PrivateName,
|
||||||
|
},
|
||||||
|
environmentVisitor,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const privateNameHandlerSpec = {
|
||||||
|
memoise(member, count) {
|
||||||
|
const { scope } = member;
|
||||||
|
const { object } = member.node;
|
||||||
|
|
||||||
|
const memo = scope.maybeGenerateMemoised(object);
|
||||||
|
if (!memo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.memoiser.set(object, memo, count);
|
||||||
|
},
|
||||||
|
|
||||||
|
receiver(member) {
|
||||||
|
const { object } = member.node;
|
||||||
|
|
||||||
|
if (this.memoiser.has(object)) {
|
||||||
|
return t.cloneNode(this.memoiser.get(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.cloneNode(object);
|
||||||
|
},
|
||||||
|
|
||||||
|
get(member) {
|
||||||
|
const { map, file } = this;
|
||||||
|
|
||||||
|
return t.callExpression(file.addHelper("classPrivateFieldGet"), [
|
||||||
|
this.receiver(member),
|
||||||
|
t.cloneNode(map),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
set(member, value) {
|
||||||
|
const { map, file } = this;
|
||||||
|
|
||||||
|
return t.callExpression(file.addHelper("classPrivateFieldSet"), [
|
||||||
|
this.receiver(member),
|
||||||
|
t.cloneNode(map),
|
||||||
|
value,
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
call(member, args) {
|
||||||
|
// The first access (the get) should do the memo assignment.
|
||||||
|
this.memoise(member, 1);
|
||||||
|
|
||||||
|
return optimiseCall(this.get(member), this.receiver(member), args);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const privateNameHandlerLoose = {
|
||||||
|
handle(member) {
|
||||||
|
const { prop, file } = this;
|
||||||
|
const { object } = member.node;
|
||||||
|
|
||||||
|
member.replaceWith(
|
||||||
|
template.expression`BASE(REF, PROP)[PROP]`({
|
||||||
|
BASE: file.addHelper("classPrivateFieldLooseBase"),
|
||||||
|
REF: object,
|
||||||
|
PROP: prop,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function buildClassPropertySpec(ref, path, state) {
|
||||||
|
const { scope } = path;
|
||||||
|
const { key, value, computed } = path.node;
|
||||||
return t.expressionStatement(
|
return t.expressionStatement(
|
||||||
t.callExpression(state.addHelper("defineProperty"), [
|
t.callExpression(state.addHelper("defineProperty"), [
|
||||||
ref,
|
ref,
|
||||||
t.isIdentifier(key) && !computed ? t.stringLiteral(key.name) : key,
|
computed || t.isLiteral(key) ? key : t.stringLiteral(key.name),
|
||||||
value || scope.buildUndefinedNode(),
|
value || scope.buildUndefinedNode(),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
const buildClassPropertyLoose = (ref, { key, value, computed }, scope) => {
|
function buildClassPropertyLoose(ref, path) {
|
||||||
return template.statement`MEMBER = VALUE`({
|
const { scope } = path;
|
||||||
MEMBER: t.memberExpression(
|
const { key, value, computed } = path.node;
|
||||||
t.cloneNode(ref),
|
return t.expressionStatement(
|
||||||
key,
|
t.assignmentExpression(
|
||||||
computed || t.isLiteral(key),
|
"=",
|
||||||
|
t.memberExpression(ref, key, computed || t.isLiteral(key)),
|
||||||
|
value || scope.buildUndefinedNode(),
|
||||||
),
|
),
|
||||||
VALUE: value || scope.buildUndefinedNode(),
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildClassPrivatePropertySpec(ref, path, initNodes, state) {
|
||||||
|
const { parentPath, scope } = path;
|
||||||
|
const { name } = path.node.key.id;
|
||||||
|
|
||||||
|
const map = scope.generateUidIdentifier(name);
|
||||||
|
memberExpressionToFunctions(parentPath, privateNameVisitor, {
|
||||||
|
name,
|
||||||
|
map,
|
||||||
|
file: state,
|
||||||
|
...privateNameHandlerSpec,
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
initNodes.push(
|
||||||
|
template.statement`var MAP = new WeakMap();`({
|
||||||
|
MAP: map,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Must be late evaluated in case it references another private field.
|
||||||
|
return () =>
|
||||||
|
template.statement`MAP.set(REF, VALUE);`({
|
||||||
|
MAP: map,
|
||||||
|
REF: ref,
|
||||||
|
VALUE: path.node.value || scope.buildUndefinedNode(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildClassPrivatePropertyLoose(ref, path, initNodes, state) {
|
||||||
|
const { parentPath, scope } = path;
|
||||||
|
const { name } = path.node.key.id;
|
||||||
|
|
||||||
|
const prop = scope.generateUidIdentifier(name);
|
||||||
|
|
||||||
|
parentPath.traverse(privateNameVisitor, {
|
||||||
|
name,
|
||||||
|
prop,
|
||||||
|
file: state,
|
||||||
|
...privateNameHandlerLoose,
|
||||||
|
});
|
||||||
|
|
||||||
|
initNodes.push(
|
||||||
|
template.statement`var PROP = HELPER(NAME);`({
|
||||||
|
PROP: prop,
|
||||||
|
HELPER: state.addHelper("classPrivateFieldLooseKey"),
|
||||||
|
NAME: t.stringLiteral(name),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Must be late evaluated in case it references another private field.
|
||||||
|
return () =>
|
||||||
|
template.statement`
|
||||||
|
Object.defineProperty(REF, PROP, {
|
||||||
|
// configurable is false by default
|
||||||
|
// enumerable is false by default
|
||||||
|
writable: true,
|
||||||
|
value: VALUE
|
||||||
|
});
|
||||||
|
`({
|
||||||
|
REF: ref,
|
||||||
|
PROP: prop,
|
||||||
|
VALUE: path.node.value || scope.buildUndefinedNode(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const buildClassProperty = loose
|
const buildClassProperty = loose
|
||||||
? buildClassPropertyLoose
|
? buildClassPropertyLoose
|
||||||
: buildClassPropertySpec;
|
: buildClassPropertySpec;
|
||||||
|
|
||||||
|
const buildClassPrivateProperty = loose
|
||||||
|
? buildClassPrivatePropertyLoose
|
||||||
|
: buildClassPrivatePropertySpec;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
inherits: syntaxClassProperties,
|
inherits: syntaxClassProperties,
|
||||||
|
|
||||||
@ -90,14 +262,35 @@ export default declare((api, options) => {
|
|||||||
let constructor;
|
let constructor;
|
||||||
const props = [];
|
const props = [];
|
||||||
const computedPaths = [];
|
const computedPaths = [];
|
||||||
|
const privateNames = new Set();
|
||||||
const body = path.get("body");
|
const body = path.get("body");
|
||||||
|
|
||||||
for (const path of body.get("body")) {
|
for (const path of body.get("body")) {
|
||||||
if (path.node.computed) {
|
const { computed, decorators } = path.node;
|
||||||
|
if (computed) {
|
||||||
computedPaths.push(path);
|
computedPaths.push(path);
|
||||||
}
|
}
|
||||||
|
if (decorators && decorators.length > 0) {
|
||||||
|
throw path.buildCodeFrameError(
|
||||||
|
"Decorators transform is necessary.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (path.isClassProperty()) {
|
if (path.isClassPrivateProperty()) {
|
||||||
|
const { static: isStatic, key: { id: { name } } } = path.node;
|
||||||
|
|
||||||
|
if (isStatic) {
|
||||||
|
throw path.buildCodeFrameError(
|
||||||
|
"Static class fields are not spec'ed yet.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (privateNames.has(name)) {
|
||||||
|
throw path.buildCodeFrameError("Duplicate private field");
|
||||||
|
}
|
||||||
|
privateNames.add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.isProperty()) {
|
||||||
props.push(path);
|
props.push(path);
|
||||||
} else if (path.isClassMethod({ kind: "constructor" })) {
|
} else if (path.isClassMethod({ kind: "constructor" })) {
|
||||||
constructor = path;
|
constructor = path;
|
||||||
@ -141,22 +334,31 @@ export default declare((api, options) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform private props before publics.
|
||||||
|
const privateMaps = [];
|
||||||
|
const privateMapInits = [];
|
||||||
for (const prop of props) {
|
for (const prop of props) {
|
||||||
const propNode = prop.node;
|
if (prop.isPrivate()) {
|
||||||
if (propNode.decorators && propNode.decorators.length > 0) continue;
|
const inits = [];
|
||||||
|
privateMapInits.push(inits);
|
||||||
|
|
||||||
if (propNode.static) {
|
privateMaps.push(
|
||||||
staticNodes.push(
|
buildClassPrivateProperty(t.thisExpression(), prop, inits, state),
|
||||||
buildClassProperty(ref, propNode, path.scope, state),
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = 0;
|
||||||
|
for (const prop of props) {
|
||||||
|
if (prop.node.static) {
|
||||||
|
staticNodes.push(buildClassProperty(t.cloneNode(ref), prop, state));
|
||||||
|
} else if (prop.isPrivate()) {
|
||||||
|
instanceBody.push(privateMaps[p]());
|
||||||
|
staticNodes.push(...privateMapInits[p]);
|
||||||
|
p++;
|
||||||
} else {
|
} else {
|
||||||
instanceBody.push(
|
instanceBody.push(
|
||||||
buildClassProperty(
|
buildClassProperty(t.thisExpression(), prop, state),
|
||||||
t.thisExpression(),
|
|
||||||
propNode,
|
|
||||||
path.scope,
|
|
||||||
state,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,6 +422,10 @@ export default declare((api, options) => {
|
|||||||
path.insertBefore(computedNodes);
|
path.insertBefore(computedNodes);
|
||||||
path.insertAfter(staticNodes);
|
path.insertAfter(staticNodes);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
PrivateName(path) {
|
||||||
|
throw path.buildCodeFrameError(`Unknown PrivateName "${path}"`);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/input.js
vendored
Normal file
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/input.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class Foo {
|
||||||
|
#foo = 0;
|
||||||
|
|
||||||
|
test(other) {
|
||||||
|
this.#foo += 1;
|
||||||
|
this.#foo = 2;
|
||||||
|
other.obj.#foo += 1;
|
||||||
|
other.obj.#foo = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/output.js
vendored
Normal file
26
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/assignment/output.js
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _foo, {
|
||||||
|
writable: true,
|
||||||
|
value: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Foo, [{
|
||||||
|
key: "test",
|
||||||
|
value: function test(other) {
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo] += 1;
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo] = 2;
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo] += 1;
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo] = 2;
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Foo;
|
||||||
|
}();
|
||||||
|
|
||||||
|
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
|
||||||
15
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/exec.js
vendored
Normal file
15
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/exec.js
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
class Foo {
|
||||||
|
#foo = function() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
test(other) {
|
||||||
|
return [this.#foo(), other.#foo()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo;
|
||||||
|
const o = new Foo;
|
||||||
|
const test = f.test(o);
|
||||||
|
expect(test[0]).toBe(f);
|
||||||
|
expect(test[1]).toBe(o);
|
||||||
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/input.js
vendored
Normal file
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/input.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class Foo {
|
||||||
|
#foo = function() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
test(other) {
|
||||||
|
this.#foo();
|
||||||
|
other.obj.#foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
27
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/output.js
vendored
Normal file
27
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/call/output.js
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _foo, {
|
||||||
|
writable: true,
|
||||||
|
value: function () {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Foo, [{
|
||||||
|
key: "test",
|
||||||
|
value: function test(other) {
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo]();
|
||||||
|
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo]();
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Foo;
|
||||||
|
}();
|
||||||
|
|
||||||
|
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
|
||||||
73
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/exec.js
vendored
Normal file
73
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/exec.js
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
class Point {
|
||||||
|
#x;
|
||||||
|
#y;
|
||||||
|
|
||||||
|
constructor(x = 0, y = 0) {
|
||||||
|
this.#x = +x;
|
||||||
|
this.#y = +y;
|
||||||
|
}
|
||||||
|
|
||||||
|
get x() { return this.#x }
|
||||||
|
set x(value) { this.#x = +value }
|
||||||
|
|
||||||
|
get y() { return this.#y }
|
||||||
|
set y(value) { this.#y = +value }
|
||||||
|
|
||||||
|
equals(p) { return this.#x === p.#x && this.#y === p.#y }
|
||||||
|
|
||||||
|
toString() { return `Point<${ this.#x },${ this.#y }>` }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const p1 = new Point(1, 2);
|
||||||
|
const p2 = new Point(2, 3);
|
||||||
|
const p3 = new Point(1, 2);
|
||||||
|
|
||||||
|
expect(p1.x).toBe(1);
|
||||||
|
expect(p1.y).toBe(2);
|
||||||
|
expect(p2.x).toBe(2);
|
||||||
|
expect(p2.y).toBe(3);
|
||||||
|
expect(p3.x).toBe(1);
|
||||||
|
expect(p3.y).toBe(2);
|
||||||
|
|
||||||
|
expect(p1.equals(p1)).toBe(true)
|
||||||
|
expect(p1.equals(p2)).toBe(false)
|
||||||
|
expect(p1.equals(p3)).toBe(true)
|
||||||
|
expect(p2.equals(p1)).toBe(false)
|
||||||
|
expect(p2.equals(p2)).toBe(true)
|
||||||
|
expect(p2.equals(p3)).toBe(false)
|
||||||
|
expect(p3.equals(p1)).toBe(true)
|
||||||
|
expect(p3.equals(p2)).toBe(false)
|
||||||
|
expect(p3.equals(p3)).toBe(true)
|
||||||
|
|
||||||
|
expect(p1.toString()).toBe("Point<1,2>")
|
||||||
|
expect(p2.toString()).toBe("Point<2,3>")
|
||||||
|
expect(p3.toString()).toBe("Point<1,2>")
|
||||||
|
|
||||||
|
p1.x += 1;
|
||||||
|
p1.y = 3;
|
||||||
|
p2.x -= 1;
|
||||||
|
p2.y = 3;
|
||||||
|
p3.x = 0;
|
||||||
|
p3.y = 0;
|
||||||
|
|
||||||
|
expect(p1.x).toBe(2);
|
||||||
|
expect(p1.y).toBe(3);
|
||||||
|
expect(p2.x).toBe(1);
|
||||||
|
expect(p2.y).toBe(3);
|
||||||
|
expect(p3.x).toBe(0);
|
||||||
|
expect(p3.y).toBe(0);
|
||||||
|
|
||||||
|
expect(p1.equals(p1)).toBe(true)
|
||||||
|
expect(p1.equals(p2)).toBe(false)
|
||||||
|
expect(p1.equals(p3)).toBe(false)
|
||||||
|
expect(p2.equals(p1)).toBe(false)
|
||||||
|
expect(p2.equals(p2)).toBe(true)
|
||||||
|
expect(p2.equals(p3)).toBe(false)
|
||||||
|
expect(p3.equals(p1)).toBe(false)
|
||||||
|
expect(p3.equals(p2)).toBe(false)
|
||||||
|
expect(p3.equals(p3)).toBe(true)
|
||||||
|
|
||||||
|
expect(p1.toString()).toBe("Point<2,3>")
|
||||||
|
expect(p2.toString()).toBe("Point<1,3>")
|
||||||
|
expect(p3.toString()).toBe("Point<0,0>")
|
||||||
20
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/input.js
vendored
Normal file
20
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/input.js
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
class Point {
|
||||||
|
#x;
|
||||||
|
#y;
|
||||||
|
|
||||||
|
constructor(x = 0, y = 0) {
|
||||||
|
this.#x = +x;
|
||||||
|
this.#y = +y;
|
||||||
|
}
|
||||||
|
|
||||||
|
get x() { return this.#x }
|
||||||
|
set x(value) { this.#x = +value }
|
||||||
|
|
||||||
|
get y() { return this.#y }
|
||||||
|
set y(value) { this.#y = +value }
|
||||||
|
|
||||||
|
equals(p) { return this.#x === p.#x && this.#y === p.#y }
|
||||||
|
|
||||||
|
toString() { return `Point<${ this.#x },${ this.#y }>` }
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"minNodeVersion": "6.0.0"
|
||||||
|
}
|
||||||
52
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/output.js
vendored
Normal file
52
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/canonical/output.js
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
var Point =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Point(_x2 = 0, _y2 = 0) {
|
||||||
|
babelHelpers.classCallCheck(this, Point);
|
||||||
|
Object.defineProperty(this, _x, {
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
|
Object.defineProperty(this, _y, {
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _x)[_x] = +_x2;
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _y)[_y] = +_y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Point, [{
|
||||||
|
key: "equals",
|
||||||
|
value: function equals(p) {
|
||||||
|
return babelHelpers.classPrivateFieldLooseBase(this, _x)[_x] === babelHelpers.classPrivateFieldLooseBase(p, _x)[_x] && babelHelpers.classPrivateFieldLooseBase(this, _y)[_y] === babelHelpers.classPrivateFieldLooseBase(p, _y)[_y];
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "toString",
|
||||||
|
value: function toString() {
|
||||||
|
return `Point<${babelHelpers.classPrivateFieldLooseBase(this, _x)[_x]},${babelHelpers.classPrivateFieldLooseBase(this, _y)[_y]}>`;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "x",
|
||||||
|
get: function () {
|
||||||
|
return babelHelpers.classPrivateFieldLooseBase(this, _x)[_x];
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _x)[_x] = +value;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "y",
|
||||||
|
get: function () {
|
||||||
|
return babelHelpers.classPrivateFieldLooseBase(this, _y)[_y];
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _y)[_y] = +value;
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Point;
|
||||||
|
}();
|
||||||
|
|
||||||
|
var _x = babelHelpers.classPrivateFieldLooseKey("x");
|
||||||
|
|
||||||
|
var _y = babelHelpers.classPrivateFieldLooseKey("y");
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
#bar = foo;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
var foo = "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
test() {
|
||||||
|
return this.#bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo;
|
||||||
|
expect(f.test()).toBe(foo);
|
||||||
|
expect("bar" in f).toBe(false);
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
#bar = foo;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
var foo = "foo";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
var Foo = function Foo() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: foo
|
||||||
|
});
|
||||||
|
var _foo = "foo";
|
||||||
|
};
|
||||||
|
|
||||||
|
var _bar = babelHelpers.classPrivateFieldLooseKey("bar");
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
The << Software identified by reference to the Ecma Standard* ("Software)">> is protected by copyright and is being
|
||||||
|
made available under the "BSD License", included below. This Software may be subject to third party rights (rights
|
||||||
|
from parties other than Ecma International), including patent rights, and no licenses under such third party rights
|
||||||
|
are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA
|
||||||
|
CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR
|
||||||
|
INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*.
|
||||||
|
|
||||||
|
Copyright (C) 2012-2013 Ecma International
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
|
* Ecma International Standards hereafter means Ecma International Standards as well as Ecma Technical Reports
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
class C {
|
||||||
|
y = this.#x;
|
||||||
|
#x;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
new C();
|
||||||
|
}).toThrow();
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
class C {
|
||||||
|
y = this.#x;
|
||||||
|
#x;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
new C();
|
||||||
|
}).toThrow();
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
var C = function C() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, C);
|
||||||
|
this.y = babelHelpers.classPrivateFieldLooseBase(this, _x)[_x];
|
||||||
|
Object.defineProperty(this, _x, {
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _x = babelHelpers.classPrivateFieldLooseKey("x");
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
new C();
|
||||||
|
}).toThrow();
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
class Foo extends Bar {
|
||||||
|
#bar = "foo";
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
if (condition) {
|
||||||
|
super();
|
||||||
|
} else {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Bar) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
var _this;
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
|
||||||
|
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
|
||||||
|
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return babelHelpers.possibleConstructorReturn(_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.inherits(Foo, _Bar);
|
||||||
|
return Foo;
|
||||||
|
}(Bar);
|
||||||
|
|
||||||
|
var _bar = babelHelpers.classPrivateFieldLooseKey("bar");
|
||||||
22
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/exec.js
vendored
Normal file
22
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/exec.js
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
class Foo {
|
||||||
|
#prop = "foo";
|
||||||
|
|
||||||
|
foo() {
|
||||||
|
return this.#prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar extends Foo {
|
||||||
|
#prop = "bar";
|
||||||
|
|
||||||
|
bar() {
|
||||||
|
return this.#prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo;
|
||||||
|
expect(f.foo()).toBe("foo");
|
||||||
|
|
||||||
|
const b = new Bar;
|
||||||
|
expect(b.foo()).toBe("foo");
|
||||||
|
expect(b.bar()).toBe("bar");
|
||||||
7
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/input.js
vendored
Normal file
7
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/input.js
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class Foo {
|
||||||
|
#prop = "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar extends Foo {
|
||||||
|
#prop = "bar";
|
||||||
|
}
|
||||||
32
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/output.js
vendored
Normal file
32
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/derived/output.js
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
var Foo = function Foo() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _prop, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _prop = babelHelpers.classPrivateFieldLooseKey("prop");
|
||||||
|
|
||||||
|
var Bar =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Foo) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Bar(...args) {
|
||||||
|
var _temp, _this;
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Bar);
|
||||||
|
return babelHelpers.possibleConstructorReturn(_this, (_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Bar).call(this, ...args)), Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _prop2, {
|
||||||
|
writable: true,
|
||||||
|
value: "bar"
|
||||||
|
}), _temp));
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.inherits(Bar, _Foo);
|
||||||
|
return Bar;
|
||||||
|
}(Foo);
|
||||||
|
|
||||||
|
var _prop2 = babelHelpers.classPrivateFieldLooseKey("prop");
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
#bar = this;
|
||||||
|
#baz = foo;
|
||||||
|
|
||||||
|
constructor(foo) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
var Foo = function Foo(_foo) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: this
|
||||||
|
});
|
||||||
|
Object.defineProperty(this, _baz, {
|
||||||
|
writable: true,
|
||||||
|
value: foo
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _bar = babelHelpers.classPrivateFieldLooseKey("bar");
|
||||||
|
|
||||||
|
var _baz = babelHelpers.classPrivateFieldLooseKey("baz");
|
||||||
9
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/input.js
vendored
Normal file
9
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/input.js
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
class Child extends Parent {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
#scopedFunctionWithThis = () => {
|
||||||
|
this.name = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"presets": [["stage-0", { "decoratorsLegacy": true }], "es2015"]
|
||||||
|
}
|
||||||
24
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/output.js
vendored
Normal file
24
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/foobar/output.js
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
var Child =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Parent) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Child() {
|
||||||
|
var _this;
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Child);
|
||||||
|
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Child).call(this));
|
||||||
|
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _scopedFunctionWithThis, {
|
||||||
|
writable: true,
|
||||||
|
value: function value() {
|
||||||
|
_this.name = {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.inherits(Child, _Parent);
|
||||||
|
return Child;
|
||||||
|
}(Parent);
|
||||||
|
|
||||||
|
var _scopedFunctionWithThis = babelHelpers.classPrivateFieldLooseKey("scopedFunctionWithThis");
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
class Foo {
|
||||||
|
#bar;
|
||||||
|
|
||||||
|
test() {
|
||||||
|
return this.#bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(new Foo().test()).toBe(undefined);
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
class Foo {
|
||||||
|
#bar;
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
var Foo = function Foo() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _bar = babelHelpers.classPrivateFieldLooseKey("bar");
|
||||||
16
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/exec.js
vendored
Normal file
16
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/exec.js
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
class Foo {
|
||||||
|
#bar = "foo";
|
||||||
|
|
||||||
|
test() {
|
||||||
|
return this.#bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
static test(foo) {
|
||||||
|
return foo.#bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo();
|
||||||
|
expect(f.test()).toBe("foo");
|
||||||
|
expect(Foo.test(f)).toBe("foo");
|
||||||
|
expect("bar" in f).toBe(false);
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
class Foo {
|
||||||
|
#bar = "foo";
|
||||||
|
}
|
||||||
11
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/output.js
vendored
Normal file
11
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/instance/output.js
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
var Foo = function Foo() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _bar = babelHelpers.classPrivateFieldLooseKey("bar");
|
||||||
11
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/exec.js
vendored
Normal file
11
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/exec.js
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
class Foo {
|
||||||
|
#x = 0;
|
||||||
|
#y = this.#x + 1;
|
||||||
|
|
||||||
|
test() {
|
||||||
|
return this.#y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo();
|
||||||
|
expect(f.test()).toBe(1);
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
class Foo {
|
||||||
|
#x = 0;
|
||||||
|
#y = this.#x;
|
||||||
|
}
|
||||||
17
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/output.js
vendored
Normal file
17
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/multiple/output.js
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
var Foo = function Foo() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _x, {
|
||||||
|
writable: true,
|
||||||
|
value: 0
|
||||||
|
});
|
||||||
|
Object.defineProperty(this, _y, {
|
||||||
|
writable: true,
|
||||||
|
value: babelHelpers.classPrivateFieldLooseBase(this, _x)[_x]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _x = babelHelpers.classPrivateFieldLooseKey("x");
|
||||||
|
|
||||||
|
var _y = babelHelpers.classPrivateFieldLooseKey("y");
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
class Foo {
|
||||||
|
static #foo = "foo";
|
||||||
|
#bar = "bar";
|
||||||
|
|
||||||
|
static test() {
|
||||||
|
return Foo.#foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
test() {
|
||||||
|
return this.#bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo();
|
||||||
|
expect("foo" in Foo).toBe(false)
|
||||||
|
expect("bar" in f).toBe(false)
|
||||||
|
expect(Foo.test()).toBe("foo")
|
||||||
|
expect(f.test()).toBe("bar")
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Static class fields are not spec'ed yet."
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
var _foo, _bar;
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
constructor() {
|
||||||
|
Object.defineProperty(this, _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: "bar"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_foo = babelHelpers.classPrivateFieldKey("foo");
|
||||||
|
Object.defineProperty(Foo, _foo, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
});
|
||||||
|
_bar = babelHelpers.classPrivateFieldKey("bar");
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
export default param =>
|
||||||
|
class App {
|
||||||
|
static #props = {
|
||||||
|
prop1: 'prop1',
|
||||||
|
prop2: 'prop2'
|
||||||
|
}
|
||||||
|
|
||||||
|
getParam() {
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Static class fields are not spec'ed yet."
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
export default (param => {
|
||||||
|
var _props, _class, _temp;
|
||||||
|
|
||||||
|
return _temp = _class =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
function App() {
|
||||||
|
babelHelpers.classCallCheck(this, App);
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(App, [{
|
||||||
|
key: "getParam",
|
||||||
|
value: function getParam() {
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return App;
|
||||||
|
}(), _props = babelHelpers.classPrivateFieldKey("props"), Object.defineProperty(_class, _props, {
|
||||||
|
writable: true,
|
||||||
|
value: {
|
||||||
|
prop1: 'prop1',
|
||||||
|
prop2: 'prop2'
|
||||||
|
}
|
||||||
|
}), _temp;
|
||||||
|
});
|
||||||
3
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/options.json
vendored
Normal file
3
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["external-helpers",["proposal-class-properties", { "loose": true }], "transform-classes", "transform-block-scoping", "syntax-class-properties"]
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
class Outer {
|
||||||
|
#outer;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
class Test extends this.#outer {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
var Outer = function Outer() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Outer);
|
||||||
|
Object.defineProperty(this, _outer, {
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
|
|
||||||
|
var Test =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_babelHelpers$classPr) {
|
||||||
|
function Test() {
|
||||||
|
babelHelpers.classCallCheck(this, Test);
|
||||||
|
return babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Test).apply(this, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.inherits(Test, _babelHelpers$classPr);
|
||||||
|
return Test;
|
||||||
|
}(babelHelpers.classPrivateFieldLooseBase(this, _outer)[_outer]);
|
||||||
|
};
|
||||||
|
|
||||||
|
var _outer = babelHelpers.classPrivateFieldLooseKey("outer");
|
||||||
43
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/input.js
vendored
Normal file
43
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/reevaluated/input.js
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
function classFactory() {
|
||||||
|
return class Foo {
|
||||||
|
#foo = "foo";
|
||||||
|
static #bar = "bar";
|
||||||
|
|
||||||
|
instance() {
|
||||||
|
return this.#foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static() {
|
||||||
|
return Foo.#bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
static instance(inst) {
|
||||||
|
return inst.#foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static static() {
|
||||||
|
return Foo.#bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Foo1 = classFactory();
|
||||||
|
const Foo2 = classFactory();
|
||||||
|
|
||||||
|
const f1 = new Foo1;
|
||||||
|
const f2 = new Foo2;
|
||||||
|
|
||||||
|
expect(f1.instance()).toBe("foo");
|
||||||
|
expect(f1.static()).toBe("bar");
|
||||||
|
expect(f2.instance()).toBe("foo");
|
||||||
|
expect(f2.static()).toBe("bar");
|
||||||
|
|
||||||
|
expect(Foo1.instance(f1)).toBe("foo");
|
||||||
|
expect(Foo1.static()).toBe("bar");
|
||||||
|
expect(Foo2.instance(f2)).toBe("foo");
|
||||||
|
expect(Foo2.static()).toBe("bar");
|
||||||
|
|
||||||
|
assert.throws(() => f1.instance.call(f2));
|
||||||
|
assert.throws(() => f2.instance.call(f1));
|
||||||
|
assert.throws(() => Foo1.instance(f2));
|
||||||
|
assert.throws(() => Foo2.instance(f1));
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Static class fields are not spec'ed yet."
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
function classFactory() {
|
||||||
|
var _bar, _foo;
|
||||||
|
|
||||||
|
var Foo = function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _foo, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_bar = babelHelpers.classPrivateFieldKey("bar");
|
||||||
|
Object.defineProperty(Foo, _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: "bar"
|
||||||
|
});
|
||||||
|
_foo = babelHelpers.classPrivateFieldKey("foo");
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
class Foo {
|
||||||
|
one = this.#private;
|
||||||
|
#two = this.#private;
|
||||||
|
#private = 0;
|
||||||
|
three = this.#private;
|
||||||
|
#four = this.#private;
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
var Foo = function Foo() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
this.one = babelHelpers.classPrivateFieldLooseBase(this, _private)[_private];
|
||||||
|
Object.defineProperty(this, _two, {
|
||||||
|
writable: true,
|
||||||
|
value: babelHelpers.classPrivateFieldLooseBase(this, _private)[_private]
|
||||||
|
});
|
||||||
|
Object.defineProperty(this, _private, {
|
||||||
|
writable: true,
|
||||||
|
value: 0
|
||||||
|
});
|
||||||
|
this.three = babelHelpers.classPrivateFieldLooseBase(this, _private)[_private];
|
||||||
|
Object.defineProperty(this, _four, {
|
||||||
|
writable: true,
|
||||||
|
value: babelHelpers.classPrivateFieldLooseBase(this, _private)[_private]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _two = babelHelpers.classPrivateFieldLooseKey("two");
|
||||||
|
|
||||||
|
var _private = babelHelpers.classPrivateFieldLooseKey("private");
|
||||||
|
|
||||||
|
var _four = babelHelpers.classPrivateFieldLooseKey("four");
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
export class MyClass {
|
||||||
|
static #property = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class MyClass2 {
|
||||||
|
static #property = value;
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Static class fields are not spec'ed yet."
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
var _property, _property2;
|
||||||
|
|
||||||
|
export var MyClass = function MyClass() {
|
||||||
|
babelHelpers.classCallCheck(this, MyClass);
|
||||||
|
};
|
||||||
|
_property = babelHelpers.classPrivateFieldKey("property");
|
||||||
|
Object.defineProperty(MyClass, _property, {
|
||||||
|
writable: true,
|
||||||
|
value: value
|
||||||
|
});
|
||||||
|
|
||||||
|
var MyClass2 = function MyClass2() {
|
||||||
|
babelHelpers.classCallCheck(this, MyClass2);
|
||||||
|
};
|
||||||
|
|
||||||
|
_property2 = babelHelpers.classPrivateFieldKey("property");
|
||||||
|
Object.defineProperty(MyClass2, _property2, {
|
||||||
|
writable: true,
|
||||||
|
value: value
|
||||||
|
});
|
||||||
|
export { MyClass2 as default };
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
var Foo = class {
|
||||||
|
static #num = 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Static class fields are not spec'ed yet."
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
var _num, _class, _temp;
|
||||||
|
|
||||||
|
var Foo = (_temp = _class = function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
}, _num = babelHelpers.classPrivateFieldKey("num"), Object.defineProperty(_class, _num, {
|
||||||
|
writable: true,
|
||||||
|
value: 0
|
||||||
|
}), _temp);
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
class Base {
|
||||||
|
static #foo = 1;
|
||||||
|
|
||||||
|
static getThis() {
|
||||||
|
return this.#foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static updateThis(val) {
|
||||||
|
return this.#foo = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getClass() {
|
||||||
|
return Base.#foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static updateClass(val) {
|
||||||
|
return Base.#foo = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Sub1 extends Base {
|
||||||
|
static #foo = 2;
|
||||||
|
|
||||||
|
static update(val) {
|
||||||
|
return this.#foo = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Sub2 extends Base {
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(Base.getThis()).toBe(1);
|
||||||
|
expect(Base.getClass()).toBe(1);
|
||||||
|
assert.throws(() => Sub1.getThis());
|
||||||
|
expect(Sub1.getClass()).toBe(1);
|
||||||
|
assert.throws(() => Sub2.getThis());
|
||||||
|
expect(Sub2.getClass()).toBe(1);
|
||||||
|
|
||||||
|
expect(Sub1.update(3)).toBe(3);
|
||||||
|
expect(Base.getThis()).toBe(1);
|
||||||
|
expect(Base.getClass()).toBe(1);
|
||||||
|
assert.throws(() => Sub1.getThis());
|
||||||
|
expect(Sub1.getClass()).toBe(1);
|
||||||
|
assert.throws(() => Sub2.getThis());
|
||||||
|
expect(Sub2.getClass()).toBe(1);
|
||||||
|
|
||||||
|
expect(Base.updateThis(4)).toBe(4);
|
||||||
|
expect(Base.getThis()).toBe(4);
|
||||||
|
expect(Base.getClass()).toBe(4);
|
||||||
|
assert.throws(() => Sub1.getThis());
|
||||||
|
expect(Sub1.getClass()).toBe(4);
|
||||||
|
assert.throws(() => Sub2.getThis());
|
||||||
|
expect(Sub2.getClass()).toBe(4);
|
||||||
|
|
||||||
|
expect(Base.updateClass(5)).toBe(5);
|
||||||
|
expect(Base.getThis()).toBe(5);
|
||||||
|
expect(Base.getClass()).toBe(5);
|
||||||
|
assert.throws(() => Sub1.getThis());
|
||||||
|
expect(Sub1.getClass()).toBe(5);
|
||||||
|
assert.throws(() => Sub2.getThis());
|
||||||
|
expect(Sub2.getClass()).toBe(5);
|
||||||
|
|
||||||
|
assert.throws(() => Sub2.updateThis(6));
|
||||||
|
expect(Sub2.updateClass(7)).toBe(7);
|
||||||
|
expect(Base.getThis()).toBe(7);
|
||||||
|
expect(Base.getClass()).toBe(7);
|
||||||
|
assert.throws(() => Sub1.getThis());
|
||||||
|
expect(Sub1.getClass()).toBe(7);
|
||||||
|
assert.throws(() => Sub2.getThis());
|
||||||
|
expect(Sub2.getClass()).toBe(7);
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Static class fields are not spec'ed yet."
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
var _foo, _foo2;
|
||||||
|
|
||||||
|
var Base =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
function Base() {
|
||||||
|
babelHelpers.classCallCheck(this, Base);
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Base, null, [{
|
||||||
|
key: "m",
|
||||||
|
value: function m() {
|
||||||
|
return babelHelpers.classPrivateFieldBase(this, _foo)[_foo];
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Base;
|
||||||
|
}();
|
||||||
|
|
||||||
|
_foo = babelHelpers.classPrivateFieldKey("foo");
|
||||||
|
Object.defineProperty(Base, _foo, {
|
||||||
|
writable: true,
|
||||||
|
value: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
var Sub1 =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Base) {
|
||||||
|
babelHelpers.inherits(Sub1, _Base);
|
||||||
|
|
||||||
|
function Sub1() {
|
||||||
|
babelHelpers.classCallCheck(this, Sub1);
|
||||||
|
return babelHelpers.possibleConstructorReturn(this, (Sub1.__proto__ || Object.getPrototypeOf(Sub1)).apply(this, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sub1;
|
||||||
|
}(Base);
|
||||||
|
|
||||||
|
_foo2 = babelHelpers.classPrivateFieldKey("foo");
|
||||||
|
Object.defineProperty(Sub1, _foo2, {
|
||||||
|
writable: true,
|
||||||
|
value: 2
|
||||||
|
});
|
||||||
|
|
||||||
|
var Sub2 =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Base2) {
|
||||||
|
babelHelpers.inherits(Sub2, _Base2);
|
||||||
|
|
||||||
|
function Sub2() {
|
||||||
|
babelHelpers.classCallCheck(this, Sub2);
|
||||||
|
return babelHelpers.possibleConstructorReturn(this, (Sub2.__proto__ || Object.getPrototypeOf(Sub2)).apply(this, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sub2;
|
||||||
|
}(Base);
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
class Foo {
|
||||||
|
static #bar;
|
||||||
|
|
||||||
|
static test() {
|
||||||
|
return Foo.#bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
test() {
|
||||||
|
return Foo.#bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect("bar" in Foo).toBe(false)
|
||||||
|
expect(Foo.test()).toBe(undefined)
|
||||||
|
expect(Foo.test()).toBe(undefined)
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Static class fields are not spec'ed yet."
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
var _bar;
|
||||||
|
|
||||||
|
var Foo = function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
};
|
||||||
|
|
||||||
|
_bar = babelHelpers.classPrivateFieldKey("bar");
|
||||||
|
Object.defineProperty(Foo, _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: void 0
|
||||||
|
});
|
||||||
15
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js
vendored
Normal file
15
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/input.js
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
class Foo {
|
||||||
|
static #bar = "foo";
|
||||||
|
|
||||||
|
static test() {
|
||||||
|
return Foo.#bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
test() {
|
||||||
|
return Foo.#bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect("bar" in Foo).toBe(false)
|
||||||
|
expect(Foo.test()).toBe("foo")
|
||||||
|
expect(Foo.test()).toBe("foo")
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Static class fields are not spec'ed yet."
|
||||||
|
}
|
||||||
28
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js
vendored
Normal file
28
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/static/output.js
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
var _bar;
|
||||||
|
|
||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Foo, [{
|
||||||
|
key: "test",
|
||||||
|
value: function test() {
|
||||||
|
return babelHelpers.classPrivateFieldBase(Foo, _bar)[_bar];
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
key: "test",
|
||||||
|
value: function test() {
|
||||||
|
return babelHelpers.classPrivateFieldBase(Foo, _bar)[_bar];
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Foo;
|
||||||
|
}();
|
||||||
|
|
||||||
|
_bar = babelHelpers.classPrivateFieldKey("bar");
|
||||||
|
Object.defineProperty(Foo, _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
});
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
class Foo extends Bar {
|
||||||
|
#bar = "foo";
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
foo(super());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Bar) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
var _temp, _this;
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
foo((_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this)), Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
}), _temp));
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.inherits(Foo, _Bar);
|
||||||
|
return Foo;
|
||||||
|
}(Bar);
|
||||||
|
|
||||||
|
var _bar = babelHelpers.classPrivateFieldLooseKey("bar");
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
class Foo extends Bar {
|
||||||
|
#bar = "foo";
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Bar) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
var _this;
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
|
||||||
|
Object.defineProperty(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), _bar, {
|
||||||
|
writable: true,
|
||||||
|
value: "foo"
|
||||||
|
});
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.inherits(Foo, _Bar);
|
||||||
|
return Foo;
|
||||||
|
}(Bar);
|
||||||
|
|
||||||
|
var _bar = babelHelpers.classPrivateFieldLooseKey("bar");
|
||||||
27
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/exec.js
vendored
Normal file
27
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/exec.js
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
class Foo {
|
||||||
|
#foo = 0;
|
||||||
|
|
||||||
|
test(other) {
|
||||||
|
return [
|
||||||
|
this.#foo++,
|
||||||
|
this.#foo,
|
||||||
|
++this.#foo,
|
||||||
|
this.#foo,
|
||||||
|
other.obj.#foo++,
|
||||||
|
other.obj.#foo,
|
||||||
|
++other.obj.#foo,
|
||||||
|
other.obj.#foo,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo;
|
||||||
|
const results = f.test({ obj: f });
|
||||||
|
expect(results[0]).toBe(0);
|
||||||
|
expect(results[1]).toBe(1);
|
||||||
|
expect(results[2]).toBe(2);
|
||||||
|
expect(results[3]).toBe(2);
|
||||||
|
expect(results[4]).toBe(2);
|
||||||
|
expect(results[5]).toBe(3);
|
||||||
|
expect(results[6]).toBe(4);
|
||||||
|
expect(results[7]).toBe(4);
|
||||||
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/input.js
vendored
Normal file
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/input.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class Foo {
|
||||||
|
#foo = 0;
|
||||||
|
|
||||||
|
test(other) {
|
||||||
|
this.#foo++;
|
||||||
|
++this.#foo;
|
||||||
|
other.obj.#foo++;
|
||||||
|
++other.obj.#foo;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/output.js
vendored
Normal file
26
packages/babel-plugin-proposal-class-properties/test/fixtures/private-loose/update/output.js
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
Object.defineProperty(this, _foo, {
|
||||||
|
writable: true,
|
||||||
|
value: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Foo, [{
|
||||||
|
key: "test",
|
||||||
|
value: function test(other) {
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo]++;
|
||||||
|
++babelHelpers.classPrivateFieldLooseBase(this, _foo)[_foo];
|
||||||
|
babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo]++;
|
||||||
|
++babelHelpers.classPrivateFieldLooseBase(other.obj, _foo)[_foo];
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Foo;
|
||||||
|
}();
|
||||||
|
|
||||||
|
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
|
||||||
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/input.js
vendored
Normal file
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/input.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class Foo {
|
||||||
|
#foo = 0;
|
||||||
|
|
||||||
|
test(other) {
|
||||||
|
this.#foo += 1;
|
||||||
|
this.#foo = 2;
|
||||||
|
other.obj.#foo += 1;
|
||||||
|
other.obj.#foo = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/output.js
vendored
Normal file
26
packages/babel-plugin-proposal-class-properties/test/fixtures/private/assignment/output.js
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
|
||||||
|
_foo.set(this, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Foo, [{
|
||||||
|
key: "test",
|
||||||
|
value: function test(other) {
|
||||||
|
var _other$obj;
|
||||||
|
|
||||||
|
babelHelpers.classPrivateFieldSet(this, _foo, babelHelpers.classPrivateFieldGet(this, _foo) + 1);
|
||||||
|
babelHelpers.classPrivateFieldSet(this, _foo, 2);
|
||||||
|
babelHelpers.classPrivateFieldSet(_other$obj = other.obj, _foo, babelHelpers.classPrivateFieldGet(_other$obj, _foo) + 1);
|
||||||
|
babelHelpers.classPrivateFieldSet(other.obj, _foo, 2);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Foo;
|
||||||
|
}();
|
||||||
|
|
||||||
|
var _foo = new WeakMap();
|
||||||
15
packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/exec.js
vendored
Normal file
15
packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/exec.js
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
class Foo {
|
||||||
|
#foo = function() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
test(other) {
|
||||||
|
return [this.#foo(), other.#foo()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo;
|
||||||
|
const o = new Foo;
|
||||||
|
const test = f.test(o);
|
||||||
|
expect(test[0]).toBe(f);
|
||||||
|
expect(test[1]).toBe(o);
|
||||||
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/input.js
vendored
Normal file
10
packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/input.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class Foo {
|
||||||
|
#foo = function() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
test(other) {
|
||||||
|
this.#foo();
|
||||||
|
other.obj.#foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
26
packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/output.js
vendored
Normal file
26
packages/babel-plugin-proposal-class-properties/test/fixtures/private/call/output.js
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
|
||||||
|
_foo.set(this, function () {
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Foo, [{
|
||||||
|
key: "test",
|
||||||
|
value: function test(other) {
|
||||||
|
var _other$obj;
|
||||||
|
|
||||||
|
babelHelpers.classPrivateFieldGet(this, _foo).call(this);
|
||||||
|
babelHelpers.classPrivateFieldGet(_other$obj = other.obj, _foo).call(_other$obj);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Foo;
|
||||||
|
}();
|
||||||
|
|
||||||
|
var _foo = new WeakMap();
|
||||||
73
packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/exec.js
vendored
Normal file
73
packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/exec.js
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
class Point {
|
||||||
|
#x;
|
||||||
|
#y;
|
||||||
|
|
||||||
|
constructor(x = 0, y = 0) {
|
||||||
|
this.#x = +x;
|
||||||
|
this.#y = +y;
|
||||||
|
}
|
||||||
|
|
||||||
|
get x() { return this.#x }
|
||||||
|
set x(value) { this.#x = +value }
|
||||||
|
|
||||||
|
get y() { return this.#y }
|
||||||
|
set y(value) { this.#y = +value }
|
||||||
|
|
||||||
|
equals(p) { return this.#x === p.#x && this.#y === p.#y }
|
||||||
|
|
||||||
|
toString() { return `Point<${ this.#x },${ this.#y }>` }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const p1 = new Point(1, 2);
|
||||||
|
const p2 = new Point(2, 3);
|
||||||
|
const p3 = new Point(1, 2);
|
||||||
|
|
||||||
|
expect(p1.x).toBe(1);
|
||||||
|
expect(p1.y).toBe(2);
|
||||||
|
expect(p2.x).toBe(2);
|
||||||
|
expect(p2.y).toBe(3);
|
||||||
|
expect(p3.x).toBe(1);
|
||||||
|
expect(p3.y).toBe(2);
|
||||||
|
|
||||||
|
expect(p1.equals(p1)).toBe(true)
|
||||||
|
expect(p1.equals(p2)).toBe(false)
|
||||||
|
expect(p1.equals(p3)).toBe(true)
|
||||||
|
expect(p2.equals(p1)).toBe(false)
|
||||||
|
expect(p2.equals(p2)).toBe(true)
|
||||||
|
expect(p2.equals(p3)).toBe(false)
|
||||||
|
expect(p3.equals(p1)).toBe(true)
|
||||||
|
expect(p3.equals(p2)).toBe(false)
|
||||||
|
expect(p3.equals(p3)).toBe(true)
|
||||||
|
|
||||||
|
expect(p1.toString()).toBe("Point<1,2>")
|
||||||
|
expect(p2.toString()).toBe("Point<2,3>")
|
||||||
|
expect(p3.toString()).toBe("Point<1,2>")
|
||||||
|
|
||||||
|
p1.x += 1;
|
||||||
|
p1.y = 3;
|
||||||
|
p2.x -= 1;
|
||||||
|
p2.y = 3;
|
||||||
|
p3.x = 0;
|
||||||
|
p3.y = 0;
|
||||||
|
|
||||||
|
expect(p1.x).toBe(2);
|
||||||
|
expect(p1.y).toBe(3);
|
||||||
|
expect(p2.x).toBe(1);
|
||||||
|
expect(p2.y).toBe(3);
|
||||||
|
expect(p3.x).toBe(0);
|
||||||
|
expect(p3.y).toBe(0);
|
||||||
|
|
||||||
|
expect(p1.equals(p1)).toBe(true)
|
||||||
|
expect(p1.equals(p2)).toBe(false)
|
||||||
|
expect(p1.equals(p3)).toBe(false)
|
||||||
|
expect(p2.equals(p1)).toBe(false)
|
||||||
|
expect(p2.equals(p2)).toBe(true)
|
||||||
|
expect(p2.equals(p3)).toBe(false)
|
||||||
|
expect(p3.equals(p1)).toBe(false)
|
||||||
|
expect(p3.equals(p2)).toBe(false)
|
||||||
|
expect(p3.equals(p3)).toBe(true)
|
||||||
|
|
||||||
|
expect(p1.toString()).toBe("Point<2,3>")
|
||||||
|
expect(p2.toString()).toBe("Point<1,3>")
|
||||||
|
expect(p3.toString()).toBe("Point<0,0>")
|
||||||
20
packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/input.js
vendored
Normal file
20
packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/input.js
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
class Point {
|
||||||
|
#x;
|
||||||
|
#y;
|
||||||
|
|
||||||
|
constructor(x = 0, y = 0) {
|
||||||
|
this.#x = +x;
|
||||||
|
this.#y = +y;
|
||||||
|
}
|
||||||
|
|
||||||
|
get x() { return this.#x }
|
||||||
|
set x(value) { this.#x = +value }
|
||||||
|
|
||||||
|
get y() { return this.#y }
|
||||||
|
set y(value) { this.#y = +value }
|
||||||
|
|
||||||
|
equals(p) { return this.#x === p.#x && this.#y === p.#y }
|
||||||
|
|
||||||
|
toString() { return `Point<${ this.#x },${ this.#y }>` }
|
||||||
|
|
||||||
|
}
|
||||||
3
packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/options.json
vendored
Normal file
3
packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"minNodeVersion": "6.0.0"
|
||||||
|
}
|
||||||
49
packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/output.js
vendored
Normal file
49
packages/babel-plugin-proposal-class-properties/test/fixtures/private/canonical/output.js
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
var Point =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Point(_x2 = 0, _y2 = 0) {
|
||||||
|
babelHelpers.classCallCheck(this, Point);
|
||||||
|
|
||||||
|
_x.set(this, void 0);
|
||||||
|
|
||||||
|
_y.set(this, void 0);
|
||||||
|
|
||||||
|
babelHelpers.classPrivateFieldSet(this, _x, +_x2);
|
||||||
|
babelHelpers.classPrivateFieldSet(this, _y, +_y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.createClass(Point, [{
|
||||||
|
key: "equals",
|
||||||
|
value: function equals(p) {
|
||||||
|
return babelHelpers.classPrivateFieldGet(this, _x) === babelHelpers.classPrivateFieldGet(p, _x) && babelHelpers.classPrivateFieldGet(this, _y) === babelHelpers.classPrivateFieldGet(p, _y);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "toString",
|
||||||
|
value: function toString() {
|
||||||
|
return `Point<${babelHelpers.classPrivateFieldGet(this, _x)},${babelHelpers.classPrivateFieldGet(this, _y)}>`;
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "x",
|
||||||
|
get: function () {
|
||||||
|
return babelHelpers.classPrivateFieldGet(this, _x);
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
babelHelpers.classPrivateFieldSet(this, _x, +value);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "y",
|
||||||
|
get: function () {
|
||||||
|
return babelHelpers.classPrivateFieldGet(this, _y);
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
babelHelpers.classPrivateFieldSet(this, _y, +value);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return Point;
|
||||||
|
}();
|
||||||
|
|
||||||
|
var _x = new WeakMap();
|
||||||
|
|
||||||
|
var _y = new WeakMap();
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
#bar = foo;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
var foo = "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
test() {
|
||||||
|
return this.#bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo;
|
||||||
|
expect(f.test()).toBe(foo);
|
||||||
|
expect("bar" in f).toBe(false);
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
#bar = foo;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
var foo = "foo";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
var Foo = function Foo() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
|
||||||
|
_bar.set(this, foo);
|
||||||
|
|
||||||
|
var _foo = "foo";
|
||||||
|
};
|
||||||
|
|
||||||
|
var _bar = new WeakMap();
|
||||||
28
packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/LICENSE
vendored
Normal file
28
packages/babel-plugin-proposal-class-properties/test/fixtures/private/declaration-order/LICENSE
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
The << Software identified by reference to the Ecma Standard* ("Software)">> is protected by copyright and is being
|
||||||
|
made available under the "BSD License", included below. This Software may be subject to third party rights (rights
|
||||||
|
from parties other than Ecma International), including patent rights, and no licenses under such third party rights
|
||||||
|
are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA
|
||||||
|
CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR
|
||||||
|
INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS*.
|
||||||
|
|
||||||
|
Copyright (C) 2012-2013 Ecma International
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
|
* Ecma International Standards hereafter means Ecma International Standards as well as Ecma Technical Reports
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
class C {
|
||||||
|
y = this.#x;
|
||||||
|
#x;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
new C();
|
||||||
|
}).toThrow();
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
class C {
|
||||||
|
y = this.#x;
|
||||||
|
#x;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
new C();
|
||||||
|
}).toThrow();
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
var C = function C() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, C);
|
||||||
|
babelHelpers.defineProperty(this, "y", babelHelpers.classPrivateFieldGet(this, _x));
|
||||||
|
|
||||||
|
_x.set(this, void 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
var _x = new WeakMap();
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
new C();
|
||||||
|
}).toThrow();
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
class Foo extends Bar {
|
||||||
|
#bar = "foo";
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
if (condition) {
|
||||||
|
super();
|
||||||
|
} else {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
var Foo =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Bar) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Foo() {
|
||||||
|
var _this;
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
|
||||||
|
|
||||||
|
_bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), "foo");
|
||||||
|
} else {
|
||||||
|
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Foo).call(this));
|
||||||
|
|
||||||
|
_bar.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this))), "foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
return babelHelpers.possibleConstructorReturn(_this);
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.inherits(Foo, _Bar);
|
||||||
|
return Foo;
|
||||||
|
}(Bar);
|
||||||
|
|
||||||
|
var _bar = new WeakMap();
|
||||||
22
packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/exec.js
vendored
Normal file
22
packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/exec.js
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
class Foo {
|
||||||
|
#prop = "foo";
|
||||||
|
|
||||||
|
foo() {
|
||||||
|
return this.#prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar extends Foo {
|
||||||
|
#prop = "bar";
|
||||||
|
|
||||||
|
bar() {
|
||||||
|
return this.#prop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const f = new Foo;
|
||||||
|
expect(f.foo()).toBe("foo");
|
||||||
|
|
||||||
|
const b = new Bar;
|
||||||
|
expect(b.foo()).toBe("foo");
|
||||||
|
expect(b.bar()).toBe("bar");
|
||||||
7
packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/input.js
vendored
Normal file
7
packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/input.js
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class Foo {
|
||||||
|
#prop = "foo";
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar extends Foo {
|
||||||
|
#prop = "bar";
|
||||||
|
}
|
||||||
27
packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/output.js
vendored
Normal file
27
packages/babel-plugin-proposal-class-properties/test/fixtures/private/derived/output.js
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
var Foo = function Foo() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
|
||||||
|
_prop.set(this, "foo");
|
||||||
|
};
|
||||||
|
|
||||||
|
var _prop = new WeakMap();
|
||||||
|
|
||||||
|
var Bar =
|
||||||
|
/*#__PURE__*/
|
||||||
|
function (_Foo) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function Bar(...args) {
|
||||||
|
var _temp, _this;
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Bar);
|
||||||
|
return babelHelpers.possibleConstructorReturn(_this, (_temp = _this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Bar).call(this, ...args)), _prop2.set(babelHelpers.assertThisInitialized(babelHelpers.assertThisInitialized(_this)), "bar"), _temp));
|
||||||
|
}
|
||||||
|
|
||||||
|
babelHelpers.inherits(Bar, _Foo);
|
||||||
|
return Bar;
|
||||||
|
}(Foo);
|
||||||
|
|
||||||
|
var _prop2 = new WeakMap();
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
#bar = this;
|
||||||
|
#baz = foo;
|
||||||
|
|
||||||
|
constructor(foo) {
|
||||||
|
}
|
||||||
|
}
|
||||||
15
packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/output.js
vendored
Normal file
15
packages/babel-plugin-proposal-class-properties/test/fixtures/private/extracted-this/output.js
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
var foo = "bar";
|
||||||
|
|
||||||
|
var Foo = function Foo(_foo) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
babelHelpers.classCallCheck(this, Foo);
|
||||||
|
|
||||||
|
_bar.set(this, this);
|
||||||
|
|
||||||
|
_baz.set(this, foo);
|
||||||
|
};
|
||||||
|
|
||||||
|
var _bar = new WeakMap();
|
||||||
|
|
||||||
|
var _baz = new WeakMap();
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user