Add private-property-in-object support (#11372)

https://github.com/tc39/proposal-private-fields-in-in

Co-Authored-By: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
Co-Authored-By: Huáng Jùnliàng <jlhwung@gmail.com>
This commit is contained in:
Justin Ridgewell 2020-05-18 15:10:14 -04:00 committed by Nicolò Ribaudo
parent 2d27cf819e
commit 7459038db8
90 changed files with 1949 additions and 83 deletions

View File

@ -1,9 +1,3 @@
{
"args": [
"src",
"--out-dir",
"lib",
"--copy-files",
"--verbose"
]
"args": ["src", "--out-dir", "lib", "--copy-files", "--verbose"]
}

View File

@ -1,9 +1,3 @@
{
"args": [
"src",
"--out-dir",
"lib",
"--copy-files",
"--verbose"
]
"args": ["src", "--out-dir", "lib", "--copy-files", "--verbose"]
}

View File

@ -1,3 +1,9 @@
{
"args": ["--out-file", "script2.js", "--no-comments", "--minified", "script.js"]
"args": [
"--out-file",
"script2.js",
"--no-comments",
"--minified",
"script.js"
]
}

View File

@ -5,6 +5,7 @@ export const FEATURES = Object.freeze({
fields: 1 << 1,
privateMethods: 1 << 2,
decorators: 1 << 3,
privateIn: 1 << 4,
});
// We can't use a symbol because this needs to always be the same, even if
@ -28,6 +29,39 @@ export function enableFeature(file, feature, loose) {
file.set(featuresKey, file.get(featuresKey) | feature);
if (loose) file.set(looseKey, file.get(looseKey) | feature);
}
if (
hasFeature(file, FEATURES.fields) &&
hasFeature(file, FEATURES.privateMethods) &&
isLoose(file, FEATURES.fields) !== isLoose(file, FEATURES.privateMethods)
) {
throw new Error(
"'loose' mode configuration must be the same for both @babel/plugin-proposal-class-properties " +
"and @babel/plugin-proposal-private-methods",
);
}
if (
hasFeature(file, FEATURES.fields) &&
hasFeature(file, FEATURES.privateIn) &&
isLoose(file, FEATURES.fields) !== isLoose(file, FEATURES.privateIn)
) {
throw new Error(
"'loose' mode configuration must be the same for both @babel/plugin-proposal-class-properties " +
"and @babel/plugin-proposal-private-property-in-object",
);
}
if (
hasFeature(file, FEATURES.privateMethods) &&
hasFeature(file, FEATURES.privateIn) &&
isLoose(file, FEATURES.privateMethods) !== isLoose(file, FEATURES.privateIn)
) {
throw new Error(
"'loose' mode configuration must be the same for both @babel/plugin-proposal-private-methods " +
"and @babel/plugin-proposal-private-property-in-object",
);
}
}
function hasFeature(file, feature) {
@ -69,14 +103,17 @@ export function verifyUsedFeatures(path, file) {
}
if (
hasFeature(file, FEATURES.privateMethods) &&
hasFeature(file, FEATURES.fields) &&
isLoose(file, FEATURES.privateMethods) !== isLoose(file, FEATURES.fields)
path.isPrivateName() &&
path.parentPath.isBinaryExpression({
operator: "in",
left: path.node,
})
) {
throw path.buildCodeFrameError(
"'loose' mode configuration must be the same for both @babel/plugin-proposal-class-properties " +
"and @babel/plugin-proposal-private-methods",
);
if (!hasFeature(file, FEATURES.privateIn)) {
throw path.buildCodeFrameError(
"Private property in checks are not enabled.",
);
}
}
if (path.isProperty()) {

View File

@ -70,69 +70,104 @@ export function buildPrivateNamesNodes(privateNamesMap, loose, state) {
// Traverses the class scope, handling private name references. If an inner
// class redeclares the same private name, it will hand off traversal to the
// restricted visitor (which doesn't traverse the inner class's inner scope).
const privateNameVisitor = {
function privateNameVisitorFactory(visitor) {
const privateNameVisitor = {
...visitor,
Class(path) {
const { privateNamesMap } = this;
const body = path.get("body.body");
const visiblePrivateNames = new Map(privateNamesMap);
const redeclared = [];
for (const prop of body) {
if (!prop.isPrivate()) continue;
const { name } = prop.node.key.id;
visiblePrivateNames.delete(name);
redeclared.push(name);
}
// If the class doesn't redeclare any private fields, we can continue with
// our overall traversal.
if (!redeclared.length) {
return;
}
// This class redeclares some private field. We need to process the outer
// environment with access to all the outer privates, then we can process
// the inner environment with only the still-visible outer privates.
path.get("body").traverse(nestedVisitor, {
...this,
redeclared,
});
path.traverse(privateNameVisitor, {
...this,
privateNamesMap: visiblePrivateNames,
});
// We'll eventually hit this class node again with the overall Class
// Features visitor, which'll process the redeclared privates.
path.skipKey("body");
},
};
// Traverses the outer portion of a class, without touching the class's inner
// scope, for private names.
const nestedVisitor = traverse.visitors.merge([
{
...visitor,
},
environmentVisitor,
]);
return privateNameVisitor;
}
const privateNameVisitor = privateNameVisitorFactory({
PrivateName(path) {
const { privateNamesMap } = this;
const { privateNamesMap, redeclared } = this;
const { node, parentPath } = path;
if (!parentPath.isMemberExpression({ property: node })) return;
if (!privateNamesMap.has(node.id.name)) return;
const { name } = node.id;
if (!privateNamesMap.has(name)) return;
if (redeclared && redeclared.includes(name)) return;
this.handle(parentPath);
},
});
Class(path) {
const { privateNamesMap } = this;
const body = path.get("body.body");
const privateInVisitor = privateNameVisitorFactory({
BinaryExpression(path) {
const { operator, left, right } = path.node;
if (operator !== "in") return;
if (!path.get("left").isPrivateName()) return;
const visiblePrivateNames = new Map(privateNamesMap);
const redeclared = [];
for (const prop of body) {
if (!prop.isPrivate()) continue;
const { name } = prop.node.key.id;
visiblePrivateNames.delete(name);
redeclared.push(name);
}
const { loose, privateNamesMap, redeclared } = this;
const { name } = left.id;
// If the class doesn't redeclare any private fields, we can continue with
// our overall traversal.
if (!redeclared.length) {
if (!privateNamesMap.has(name)) return;
if (redeclared && redeclared.includes(name)) return;
if (loose) {
const { id } = privateNamesMap.get(name);
path.replaceWith(template.expression.ast`
Object.prototype.hasOwnProperty.call(${right}, ${id})
`);
return;
}
// This class redeclares some private field. We need to process the outer
// environment with access to all the outer privates, then we can process
// the inner environment with only the still-visible outer privates.
path.get("body").traverse(privateNameNestedVisitor, {
...this,
redeclared,
});
path.traverse(privateNameVisitor, {
...this,
privateNamesMap: visiblePrivateNames,
});
const { id, static: isStatic } = privateNamesMap.get(name);
// We'll eventually hit this class node again with the overall Class
// Features visitor, which'll process the redeclared privates.
path.skipKey("body");
},
};
if (isStatic) {
path.replaceWith(template.expression.ast`${right} === ${this.classRef}`);
return;
}
// Traverses the outer portion of a class, without touching the class's inner
// scope, for private names.
const privateNameNestedVisitor = traverse.visitors.merge([
{
PrivateName(path) {
const { redeclared } = this;
const { name } = path.node.id;
if (redeclared.includes(name)) path.skip();
},
path.replaceWith(template.expression.ast`${id}.has(${right})`);
},
{
PrivateName: privateNameVisitor.PrivateName,
},
environmentVisitor,
]);
});
const privateNameHandlerSpec = {
memoise(member, count) {
@ -306,6 +341,12 @@ export function transformPrivateNamesUsage(
...privateNameHandlerSpec,
});
}
body.traverse(privateInVisitor, {
privateNamesMap,
classRef: ref,
file: state,
loose,
});
}
function buildPrivateFieldInitLoose(ref, prop, privateNamesMap) {

View File

@ -1,9 +1,7 @@
{
"presets": [
["typescript"]
],
"presets": [["typescript"]],
"plugins": [
["proposal-decorators", { "decoratorsBeforeExport": true }],
["proposal-class-properties"]
]
}
}

View File

@ -27,6 +27,7 @@ import {
isReservedWord,
isStrictReservedWord,
isStrictBindReservedWord,
isIdentifierStart,
} from "../util/identifier";
import type { Pos, Position } from "../util/location";
import * as charCodes from "charcodes";
@ -1148,6 +1149,26 @@ export default class ExpressionParser extends LValParser {
this.registerTopicReference();
return this.finishNode(node, "PipelinePrimaryTopicReference");
}
const nextCh = this.input.codePointAt(this.state.end);
if (isIdentifierStart(nextCh) || nextCh === charCodes.backslash) {
const start = this.state.start;
// $FlowIgnore It'll either parse a PrivateName or throw.
node = (this.parseMaybePrivateName(true): N.PrivateName);
if (this.match(tt._in)) {
this.expectPlugin("privateIn");
this.classScope.usePrivateName(node.id.name, node.start);
} else if (this.hasPlugin("privateIn")) {
this.raise(
this.state.start,
Errors.PrivateInExpectedIn,
node.id.name,
);
} else {
throw this.unexpected(start);
}
return node;
}
}
// fall through
default:

View File

@ -130,6 +130,8 @@ export const Errors = Object.freeze({
"Topic reference was used in a lexical context without topic binding",
PrimaryTopicRequiresSmartPipeline:
"Primary Topic Reference found but pipelineOperator not passed 'smart' for 'proposal' option.",
PrivateInExpectedIn:
"Private names are only allowed in property accesses (`obj.#%0`) or in `in` expressions (`#%0 in obj`)",
PrivateNameRedeclaration: "Duplicate private name #%0",
RecordExpressionBarIncorrectEndSyntaxType:
"Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'",

View File

@ -1,3 +1,3 @@
{
"throws": "Unexpected token, expected \";\" (1:12)"
}
}

View File

@ -1,5 +1,3 @@
{
"plugins": [
["pipelineOperator", { "proposal": "minimal" }]
]
"plugins": [["pipelineOperator", { "proposal": "minimal" }]]
}

View File

@ -0,0 +1,7 @@
class Point {
#x = 1;
#y = 2;
static isPoint(obj) {
return #x in obj && #y in obj;
}
}

View File

@ -0,0 +1,6 @@
{
"plugins": [
"classPrivateProperties"
],
"throws": "This experimental syntax requires enabling the parser plugin: 'privateIn' (5:14)"
}

View File

@ -1,4 +1,7 @@
{
"throws": "Unexpected token (3:3)",
"plugins": ["classProperties", "classPrivateMethods"]
}
"plugins": [
"classProperties",
"classPrivateMethods"
]
}

View File

@ -1,4 +1,6 @@
{
"throws": "Unexpected token (4:11)",
"plugins": ["classPrivateProperties"]
"plugins": [
"classPrivateProperties"
]
}

View File

@ -1,4 +1,11 @@
{
"plugins": [["pipelineOperator", { "proposal": "smart" }]],
"plugins": [
[
"pipelineOperator",
{
"proposal": "smart"
}
]
],
"throws": "Unexpected token (1:4)"
}
}

View File

@ -0,0 +1,6 @@
class Foo {
#x = 1;
test() {
#x + 1;
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["classPrivateProperties", "privateIn"]
}

View File

@ -0,0 +1,105 @@
{
"type": "File",
"start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"errors": [
"SyntaxError: Private names are only allowed in property accesses (`obj.#x`) or in `in` expressions (`#x in obj`) (4:7)"
],
"program": {
"type": "Program",
"start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":50,"loc":{"start":{"line":1,"column":10},"end":{"line":6,"column":1}},
"body": [
{
"type": "ClassPrivateProperty",
"start":14,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":9}},
"static": false,
"key": {
"type": "PrivateName",
"start":14,"end":16,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}},
"id": {
"type": "Identifier",
"start":15,"end":16,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"x"},
"name": "x"
}
},
"value": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":8}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
},
{
"type": "ClassMethod",
"start":24,"end":48,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}},
"static": false,
"key": {
"type": "Identifier",
"start":24,"end":28,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":6},"identifierName":"test"},
"name": "test"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":31,"end":48,"loc":{"start":{"line":3,"column":9},"end":{"line":5,"column":3}},
"body": [
{
"type": "ExpressionStatement",
"start":37,"end":44,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":11}},
"expression": {
"type": "BinaryExpression",
"start":37,"end":43,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":10}},
"left": {
"type": "PrivateName",
"start":37,"end":39,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":6}},
"id": {
"type": "Identifier",
"start":38,"end":39,"loc":{"start":{"line":4,"column":5},"end":{"line":4,"column":6},"identifierName":"x"},
"name": "x"
}
},
"operator": "+",
"right": {
"type": "NumericLiteral",
"start":42,"end":43,"loc":{"start":{"line":4,"column":9},"end":{"line":4,"column":10}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
}
],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,6 @@
class Foo {
#x = 1;
test() {
1 + #x;
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["classPrivateProperties", "privateIn"]
}

View File

@ -0,0 +1,105 @@
{
"type": "File",
"start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"errors": [
"SyntaxError: Private names are only allowed in property accesses (`obj.#x`) or in `in` expressions (`#x in obj`) (4:10)"
],
"program": {
"type": "Program",
"start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":50,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":50,"loc":{"start":{"line":1,"column":10},"end":{"line":6,"column":1}},
"body": [
{
"type": "ClassPrivateProperty",
"start":14,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":9}},
"static": false,
"key": {
"type": "PrivateName",
"start":14,"end":16,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}},
"id": {
"type": "Identifier",
"start":15,"end":16,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"x"},
"name": "x"
}
},
"value": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":8}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
},
{
"type": "ClassMethod",
"start":24,"end":48,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}},
"static": false,
"key": {
"type": "Identifier",
"start":24,"end":28,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":6},"identifierName":"test"},
"name": "test"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":31,"end":48,"loc":{"start":{"line":3,"column":9},"end":{"line":5,"column":3}},
"body": [
{
"type": "ExpressionStatement",
"start":37,"end":44,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":11}},
"expression": {
"type": "BinaryExpression",
"start":37,"end":43,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":10}},
"left": {
"type": "NumericLiteral",
"start":37,"end":38,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":5}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
},
"operator": "+",
"right": {
"type": "PrivateName",
"start":41,"end":43,"loc":{"start":{"line":4,"column":8},"end":{"line":4,"column":10}},
"id": {
"type": "Identifier",
"start":42,"end":43,"loc":{"start":{"line":4,"column":9},"end":{"line":4,"column":10},"identifierName":"x"},
"name": "x"
}
}
}
}
],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,6 @@
class Foo {
#x = 1;
test() {
#x;
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["classPrivateProperties", "privateIn"]
}

View File

@ -0,0 +1,91 @@
{
"type": "File",
"start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"errors": [
"SyntaxError: Private names are only allowed in property accesses (`obj.#x`) or in `in` expressions (`#x in obj`) (4:6)"
],
"program": {
"type": "Program",
"start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":46,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":46,"loc":{"start":{"line":1,"column":10},"end":{"line":6,"column":1}},
"body": [
{
"type": "ClassPrivateProperty",
"start":14,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":9}},
"static": false,
"key": {
"type": "PrivateName",
"start":14,"end":16,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}},
"id": {
"type": "Identifier",
"start":15,"end":16,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"x"},
"name": "x"
}
},
"value": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":8}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
},
{
"type": "ClassMethod",
"start":24,"end":44,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}},
"static": false,
"key": {
"type": "Identifier",
"start":24,"end":28,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":6},"identifierName":"test"},
"name": "test"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":31,"end":44,"loc":{"start":{"line":3,"column":9},"end":{"line":5,"column":3}},
"body": [
{
"type": "ExpressionStatement",
"start":37,"end":40,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":7}},
"expression": {
"type": "PrivateName",
"start":37,"end":39,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":6}},
"id": {
"type": "Identifier",
"start":38,"end":39,"loc":{"start":{"line":4,"column":5},"end":{"line":4,"column":6},"identifierName":"x"},
"name": "x"
}
}
}
],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,6 @@
class Foo {
#x = 1;
test() {
class X extends (#x in {}) {};
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["classPrivateProperties", "privateIn"]
}

View File

@ -0,0 +1,116 @@
{
"type": "File",
"start":0,"end":73,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"program": {
"type": "Program",
"start":0,"end":73,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":73,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":73,"loc":{"start":{"line":1,"column":10},"end":{"line":6,"column":1}},
"body": [
{
"type": "ClassPrivateProperty",
"start":14,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":9}},
"static": false,
"key": {
"type": "PrivateName",
"start":14,"end":16,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}},
"id": {
"type": "Identifier",
"start":15,"end":16,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"x"},
"name": "x"
}
},
"value": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":8}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
},
{
"type": "ClassMethod",
"start":24,"end":71,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}},
"static": false,
"key": {
"type": "Identifier",
"start":24,"end":28,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":6},"identifierName":"test"},
"name": "test"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":31,"end":71,"loc":{"start":{"line":3,"column":9},"end":{"line":5,"column":3}},
"body": [
{
"type": "ClassDeclaration",
"start":37,"end":66,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":33}},
"id": {
"type": "Identifier",
"start":43,"end":44,"loc":{"start":{"line":4,"column":10},"end":{"line":4,"column":11},"identifierName":"X"},
"name": "X"
},
"superClass": {
"type": "BinaryExpression",
"start":54,"end":62,"loc":{"start":{"line":4,"column":21},"end":{"line":4,"column":29}},
"left": {
"type": "PrivateName",
"start":54,"end":56,"loc":{"start":{"line":4,"column":21},"end":{"line":4,"column":23}},
"id": {
"type": "Identifier",
"start":55,"end":56,"loc":{"start":{"line":4,"column":22},"end":{"line":4,"column":23},"identifierName":"x"},
"name": "x"
}
},
"operator": "in",
"right": {
"type": "ObjectExpression",
"start":60,"end":62,"loc":{"start":{"line":4,"column":27},"end":{"line":4,"column":29}},
"properties": []
},
"extra": {
"parenthesized": true,
"parenStart": 53
}
},
"body": {
"type": "ClassBody",
"start":64,"end":66,"loc":{"start":{"line":4,"column":31},"end":{"line":4,"column":33}},
"body": []
}
},
{
"type": "EmptyStatement",
"start":66,"end":67,"loc":{"start":{"line":4,"column":33},"end":{"line":4,"column":34}}
}
],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,6 @@
class Foo {
#\u{61} = 1;
test() {
#\u{61} in {};
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["classPrivateProperties", "privateIn"]
}

View File

@ -0,0 +1,98 @@
{
"type": "File",
"start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"program": {
"type": "Program",
"start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":62,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":62,"loc":{"start":{"line":1,"column":10},"end":{"line":6,"column":1}},
"body": [
{
"type": "ClassPrivateProperty",
"start":14,"end":26,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":14}},
"static": false,
"key": {
"type": "PrivateName",
"start":14,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":9}},
"id": {
"type": "Identifier",
"start":15,"end":21,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":9},"identifierName":"a"},
"name": "a"
}
},
"value": {
"type": "NumericLiteral",
"start":24,"end":25,"loc":{"start":{"line":2,"column":12},"end":{"line":2,"column":13}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
},
{
"type": "ClassMethod",
"start":29,"end":60,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}},
"static": false,
"key": {
"type": "Identifier",
"start":29,"end":33,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":6},"identifierName":"test"},
"name": "test"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":36,"end":60,"loc":{"start":{"line":3,"column":9},"end":{"line":5,"column":3}},
"body": [
{
"type": "ExpressionStatement",
"start":42,"end":56,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":18}},
"expression": {
"type": "BinaryExpression",
"start":42,"end":55,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":17}},
"left": {
"type": "PrivateName",
"start":42,"end":49,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":11}},
"id": {
"type": "Identifier",
"start":43,"end":49,"loc":{"start":{"line":4,"column":5},"end":{"line":4,"column":11},"identifierName":"a"},
"name": "a"
}
},
"operator": "in",
"right": {
"type": "ObjectExpression",
"start":53,"end":55,"loc":{"start":{"line":4,"column":15},"end":{"line":4,"column":17}},
"properties": []
}
}
}
],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,6 @@
class Foo {
#x = 1;
test() {
(#x) in {};
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["classPrivateProperties", "privateIn"]
}

View File

@ -0,0 +1,105 @@
{
"type": "File",
"start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"errors": [
"SyntaxError: Private names are only allowed in property accesses (`obj.#x`) or in `in` expressions (`#x in obj`) (4:7)"
],
"program": {
"type": "Program",
"start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":54,"loc":{"start":{"line":1,"column":10},"end":{"line":6,"column":1}},
"body": [
{
"type": "ClassPrivateProperty",
"start":14,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":9}},
"static": false,
"key": {
"type": "PrivateName",
"start":14,"end":16,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}},
"id": {
"type": "Identifier",
"start":15,"end":16,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"x"},
"name": "x"
}
},
"value": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":8}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
},
{
"type": "ClassMethod",
"start":24,"end":52,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}},
"static": false,
"key": {
"type": "Identifier",
"start":24,"end":28,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":6},"identifierName":"test"},
"name": "test"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":31,"end":52,"loc":{"start":{"line":3,"column":9},"end":{"line":5,"column":3}},
"body": [
{
"type": "ExpressionStatement",
"start":37,"end":48,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":15}},
"expression": {
"type": "BinaryExpression",
"start":37,"end":47,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":14}},
"left": {
"type": "PrivateName",
"start":38,"end":40,"loc":{"start":{"line":4,"column":5},"end":{"line":4,"column":7}},
"id": {
"type": "Identifier",
"start":39,"end":40,"loc":{"start":{"line":4,"column":6},"end":{"line":4,"column":7},"identifierName":"x"},
"name": "x"
},
"extra": {
"parenthesized": true,
"parenStart": 37
}
},
"operator": "in",
"right": {
"type": "ObjectExpression",
"start":45,"end":47,"loc":{"start":{"line":4,"column":12},"end":{"line":4,"column":14}},
"properties": []
}
}
}
],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,5 @@
class Foo {
test() {
#x in {};
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["classPrivateProperties", "privateIn"]
}

View File

@ -0,0 +1,78 @@
{
"type": "File",
"start":0,"end":42,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
"errors": [
"SyntaxError: Private name #x is not defined (3:4)"
],
"program": {
"type": "Program",
"start":0,"end":42,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":42,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":42,"loc":{"start":{"line":1,"column":10},"end":{"line":5,"column":1}},
"body": [
{
"type": "ClassMethod",
"start":14,"end":40,"loc":{"start":{"line":2,"column":2},"end":{"line":4,"column":3}},
"static": false,
"key": {
"type": "Identifier",
"start":14,"end":18,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":6},"identifierName":"test"},
"name": "test"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":21,"end":40,"loc":{"start":{"line":2,"column":9},"end":{"line":4,"column":3}},
"body": [
{
"type": "ExpressionStatement",
"start":27,"end":36,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":13}},
"expression": {
"type": "BinaryExpression",
"start":27,"end":35,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":12}},
"left": {
"type": "PrivateName",
"start":27,"end":29,"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":6}},
"id": {
"type": "Identifier",
"start":28,"end":29,"loc":{"start":{"line":3,"column":5},"end":{"line":3,"column":6},"identifierName":"x"},
"name": "x"
}
},
"operator": "in",
"right": {
"type": "ObjectExpression",
"start":33,"end":35,"loc":{"start":{"line":3,"column":10},"end":{"line":3,"column":12}},
"properties": []
}
}
}
],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,6 @@
class Foo {
#x = 1;
test() {
#x in {};
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["classPrivateProperties", "privateIn"]
}

View File

@ -0,0 +1,98 @@
{
"type": "File",
"start":0,"end":52,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"program": {
"type": "Program",
"start":0,"end":52,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ClassDeclaration",
"start":0,"end":52,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":1}},
"id": {
"type": "Identifier",
"start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9},"identifierName":"Foo"},
"name": "Foo"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start":10,"end":52,"loc":{"start":{"line":1,"column":10},"end":{"line":6,"column":1}},
"body": [
{
"type": "ClassPrivateProperty",
"start":14,"end":21,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":9}},
"static": false,
"key": {
"type": "PrivateName",
"start":14,"end":16,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":4}},
"id": {
"type": "Identifier",
"start":15,"end":16,"loc":{"start":{"line":2,"column":3},"end":{"line":2,"column":4},"identifierName":"x"},
"name": "x"
}
},
"value": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":2,"column":7},"end":{"line":2,"column":8}},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
},
{
"type": "ClassMethod",
"start":24,"end":50,"loc":{"start":{"line":3,"column":2},"end":{"line":5,"column":3}},
"static": false,
"key": {
"type": "Identifier",
"start":24,"end":28,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":6},"identifierName":"test"},
"name": "test"
},
"computed": false,
"kind": "method",
"id": null,
"generator": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start":31,"end":50,"loc":{"start":{"line":3,"column":9},"end":{"line":5,"column":3}},
"body": [
{
"type": "ExpressionStatement",
"start":37,"end":46,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":13}},
"expression": {
"type": "BinaryExpression",
"start":37,"end":45,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":12}},
"left": {
"type": "PrivateName",
"start":37,"end":39,"loc":{"start":{"line":4,"column":4},"end":{"line":4,"column":6}},
"id": {
"type": "Identifier",
"start":38,"end":39,"loc":{"start":{"line":4,"column":5},"end":{"line":4,"column":6},"identifierName":"x"},
"name": "x"
}
},
"operator": "in",
"right": {
"type": "ObjectExpression",
"start":43,"end":45,"loc":{"start":{"line":4,"column":10},"end":{"line":4,"column":12}},
"properties": []
}
}
}
],
"directives": []
}
}
]
}
}
],
"directives": []
}
}

View File

@ -123,6 +123,7 @@ export type ParserPlugin =
'partialApplication' |
'pipelineOperator' |
'placeholders' |
'privateIn' |
'throwExpressions' |
'topLevelAwait' |
'typescript' |

View File

@ -0,0 +1,3 @@
src
test
*.log

View File

@ -0,0 +1,20 @@
# @babel/plugin-proposal-private-property-in-object
> This plugin transforms checks for a private property in an object
See our website [@babel/plugin-proposal-private-property-in-object](https://babeljs.io/docs/en/next/babel-plugin-proposal-private-property-in-object.html) for more information.
## Install
Using npm:
```sh
npm install --save-dev
@babel/plugin-proposal-private-property-in-object
```
or using yarn:
```sh
yarn add @babel/plugin-proposal-private-property-in-object --dev
```

View File

@ -0,0 +1,25 @@
{
"name": "@babel/plugin-proposal-private-property-in-object",
"version": "7.8.3",
"description": "This plugin transforms checks for a private property in an object",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-private-property-in-object",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"main": "lib/index.js",
"keywords": [
"babel-plugin"
],
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.8.3",
"@babel/helper-plugin-utils": "^7.8.3"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
},
"devDependencies": {
"@babel/core": "^7.8.3",
"@babel/helper-plugin-test-runner": "^7.8.3"
}
}

View File

@ -0,0 +1,22 @@
/* eslint-disable @babel/development/plugin-name */
import { declare } from "@babel/helper-plugin-utils";
import {
createClassFeaturePlugin,
FEATURES,
} from "@babel/helper-create-class-features-plugin";
export default declare((api, options) => {
api.assertVersion(7);
return createClassFeaturePlugin({
name: "proposal-class-properties",
feature: FEATURES.privateIn,
loose: options.loose,
manipulateOptions(opts, parserOpts) {
parserOpts.plugins.push("privateIn");
},
});
});

View File

@ -0,0 +1,7 @@
class Foo {
get #foo() {}
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,23 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _foo, {
get: _get_foo,
set: void 0
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
var _get_foo = function () {};

View File

@ -0,0 +1,7 @@
class Foo {
#foo = 1;
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,21 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _foo, {
writable: true,
value: 1
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");

View File

@ -0,0 +1,7 @@
class Foo {
#foo() {}
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,22 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _foo, {
value: _foo2
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
var _foo2 = function _foo2() {};

View File

@ -0,0 +1,12 @@
class Foo {
static #foo = "foo";
#bar = "bar";
static test() {
return #foo in Foo;
}
test() {
return #bar in this;
}
}

View File

@ -0,0 +1,8 @@
{
"plugins": [
["external-helpers", { "helperVersion": "7.100.0" }],
"proposal-private-property-in-object",
"proposal-class-properties",
"proposal-private-methods"
]
}

View File

@ -0,0 +1,24 @@
class Foo {
constructor() {
_bar.set(this, {
writable: true,
value: "bar"
});
}
static test() {
return Foo === Foo;
}
test() {
return _bar.has(this);
}
}
var _bar = new WeakMap();
var _foo = {
writable: true,
value: "foo"
};

View File

@ -0,0 +1,18 @@
class Foo {
#foo = 1;
#bar = 1;
test() {
class Nested {
#bar = 2;
test() {
#foo in this;
#bar in this;
}
}
#foo in this;
#bar in this;
}
}

View File

@ -0,0 +1,49 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _foo, {
writable: true,
value: 1
});
Object.defineProperty(this, _bar, {
writable: true,
value: 1
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
let Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
Object.defineProperty(this, _bar2, {
writable: true,
value: 2
});
}
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(this, _bar2);
}
}]);
return Nested;
}();
var _bar2 = babelHelpers.classPrivateFieldLooseKey("bar");
Object.prototype.hasOwnProperty.call(this, _foo);
Object.prototype.hasOwnProperty.call(this, _bar);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
var _bar = babelHelpers.classPrivateFieldLooseKey("bar");

View File

@ -0,0 +1,15 @@
class Foo {
#foo = 1;
test() {
class Nested {
#foo = 2;
test() {
#foo in this;
}
}
#foo in this;
}
}

View File

@ -0,0 +1,41 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _foo, {
writable: true,
value: 1
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
let Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
Object.defineProperty(this, _foo2, {
writable: true,
value: 2
});
}
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
Object.prototype.hasOwnProperty.call(this, _foo2);
}
}]);
return Nested;
}();
var _foo2 = babelHelpers.classPrivateFieldLooseKey("foo");
Object.prototype.hasOwnProperty.call(this, _foo);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");

View File

@ -0,0 +1,13 @@
class Foo {
#foo = 1;
test() {
class Nested {
test() {
#foo in this;
}
}
#foo in this;
}
}

View File

@ -0,0 +1,35 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
Object.defineProperty(this, _foo, {
writable: true,
value: 1
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
let Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
}
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
Object.prototype.hasOwnProperty.call(this, _foo);
}
}]);
return Nested;
}();
Object.prototype.hasOwnProperty.call(this, _foo);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");

View File

@ -0,0 +1,9 @@
{
"plugins": [
["external-helpers", { "helperVersion": "7.100.0" }],
["proposal-private-property-in-object", { "loose": true }],
["proposal-class-properties", { "loose": true }],
["proposal-private-methods", { "loose": true }],
"transform-classes"
]
}

View File

@ -0,0 +1,7 @@
class Foo {
static get #foo() {}
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,24 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
var _get_foo = function () {};
Object.defineProperty(Foo, _foo, {
get: _get_foo,
set: void 0
});

View File

@ -0,0 +1,7 @@
class Foo {
static #foo = 1;
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,22 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
Object.defineProperty(Foo, _foo, {
writable: true,
value: 1
});

View File

@ -0,0 +1,7 @@
class Foo {
static #foo() {}
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,23 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return Object.prototype.hasOwnProperty.call(other, _foo);
}
}]);
return Foo;
}();
var _foo = babelHelpers.classPrivateFieldLooseKey("foo");
var _foo2 = function _foo2() {};
Object.defineProperty(Foo, _foo, {
value: _foo2
});

View File

@ -0,0 +1,7 @@
class Foo {
get #foo() {}
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,24 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
_foo.set(this, {
get: _get_foo,
set: void 0
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return _foo.has(other);
}
}]);
return Foo;
}();
var _foo = new WeakMap();
var _get_foo = function () {};

View File

@ -0,0 +1,7 @@
class Foo {
#foo = 1;
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,22 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
_foo.set(this, {
writable: true,
value: 1
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return _foo.has(other);
}
}]);
return Foo;
}();
var _foo = new WeakMap();

View File

@ -0,0 +1,7 @@
class Foo {
#foo() {}
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,21 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
_foo.add(this);
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return _foo.has(other);
}
}]);
return Foo;
}();
var _foo = new WeakSet();
var _foo2 = function _foo2() {};

View File

@ -0,0 +1,12 @@
class Foo {
static #foo = "foo";
#bar = "bar";
static test() {
return #foo in Foo;
}
test() {
return #bar in this;
}
}

View File

@ -0,0 +1,8 @@
{
"plugins": [
["external-helpers", { "helperVersion": "7.100.0" }],
"proposal-private-property-in-object",
"proposal-class-properties",
"proposal-private-methods"
]
}

View File

@ -0,0 +1,24 @@
class Foo {
constructor() {
_bar.set(this, {
writable: true,
value: "bar"
});
}
static test() {
return Foo === Foo;
}
test() {
return _bar.has(this);
}
}
var _bar = new WeakMap();
var _foo = {
writable: true,
value: "foo"
};

View File

@ -0,0 +1,18 @@
class Foo {
#foo = 1;
#bar = 1;
test() {
class Nested {
#bar = 2;
test() {
#foo in this;
#bar in this;
}
}
#foo in this;
#bar in this;
}
}

View File

@ -0,0 +1,54 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
_foo.set(this, {
writable: true,
value: 1
});
_bar.set(this, {
writable: true,
value: 1
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
let Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
_bar2.set(this, {
writable: true,
value: 2
});
}
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
_foo.has(this);
_bar2.has(this);
}
}]);
return Nested;
}();
var _bar2 = new WeakMap();
_foo.has(this);
_bar.has(this);
}
}]);
return Foo;
}();
var _foo = new WeakMap();
var _bar = new WeakMap();

View File

@ -0,0 +1,15 @@
class Foo {
#foo = 1;
test() {
class Nested {
#foo = 2;
test() {
#foo in this;
}
}
#foo in this;
}
}

View File

@ -0,0 +1,43 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
_foo.set(this, {
writable: true,
value: 1
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
let Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
_foo2.set(this, {
writable: true,
value: 2
});
}
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
_foo2.has(this);
}
}]);
return Nested;
}();
var _foo2 = new WeakMap();
_foo.has(this);
}
}]);
return Foo;
}();
var _foo = new WeakMap();

View File

@ -0,0 +1,13 @@
class Foo {
#foo = 1;
test() {
class Nested {
test() {
#foo in this;
}
}
#foo in this;
}
}

View File

@ -0,0 +1,36 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
_foo.set(this, {
writable: true,
value: 1
});
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test() {
let Nested = /*#__PURE__*/function () {
function Nested() {
babelHelpers.classCallCheck(this, Nested);
}
babelHelpers.createClass(Nested, [{
key: "test",
value: function test() {
_foo.has(this);
}
}]);
return Nested;
}();
_foo.has(this);
}
}]);
return Foo;
}();
var _foo = new WeakMap();

View File

@ -0,0 +1,9 @@
{
"plugins": [
["external-helpers", { "helperVersion": "7.100.0" }],
"proposal-private-property-in-object",
"proposal-class-properties",
"proposal-private-methods",
"transform-classes"
]
}

View File

@ -0,0 +1,7 @@
class Foo {
static get #foo() {}
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,22 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return other === Foo;
}
}]);
return Foo;
}();
var _get_foo = function () {};
var _foo = {
get: _get_foo,
set: void 0
};

View File

@ -0,0 +1,7 @@
class Foo {
static #foo = 1;
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,20 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return other === Foo;
}
}]);
return Foo;
}();
var _foo = {
writable: true,
value: 1
};

View File

@ -0,0 +1,7 @@
class Foo {
static #foo() {}
test(other) {
return #foo in other;
}
}

View File

@ -0,0 +1,17 @@
let Foo = /*#__PURE__*/function () {
"use strict";
function Foo() {
babelHelpers.classCallCheck(this, Foo);
}
babelHelpers.createClass(Foo, [{
key: "test",
value: function test(other) {
return other === Foo;
}
}]);
return Foo;
}();
var _foo = function _foo() {};

View File

@ -0,0 +1,3 @@
import runner from "@babel/helper-plugin-test-runner";
runner(__dirname);

View File

@ -80,7 +80,15 @@ defineType("BinaryExpression", {
validate: assertOneOf(...BINARY_OPERATORS),
},
left: {
validate: assertNodeType("Expression"),
validate: (function() {
const expression = assertNodeType("Expression");
const inOp = assertNodeType("Expression", "PrivateName");
return function(node, key, val) {
const validator = node.operator === "in" ? inOp : expression;
validator(node, key, val);
};
})(),
},
right: {
validate: assertNodeType("Expression"),