Private Properties phase 1 (#7666)
* Private Properties phase 1 Co-authored-by: CodingItWrong * Private fields are optional * Docs update
This commit is contained in:
parent
01f4c2368e
commit
43040a4181
@ -117,6 +117,21 @@ export function ClassProperty(node: Object) {
|
|||||||
this.semicolon();
|
this.semicolon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function ClassPrivateProperty(node: Object) {
|
||||||
|
if (node.static) {
|
||||||
|
this.word("static");
|
||||||
|
this.space();
|
||||||
|
}
|
||||||
|
this.print(node.key, node);
|
||||||
|
if (node.value) {
|
||||||
|
this.space();
|
||||||
|
this.token("=");
|
||||||
|
this.space();
|
||||||
|
this.print(node.value, node);
|
||||||
|
}
|
||||||
|
this.semicolon();
|
||||||
|
}
|
||||||
|
|
||||||
export function ClassMethod(node: Object) {
|
export function ClassMethod(node: Object) {
|
||||||
this._classMethodHead(node);
|
this._classMethodHead(node);
|
||||||
this.space();
|
this.space();
|
||||||
|
|||||||
@ -254,3 +254,8 @@ export function MetaProperty(node: Object) {
|
|||||||
this.token(".");
|
this.token(".");
|
||||||
this.print(node.property, node);
|
this.print(node.property, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function PrivateName(node: Object) {
|
||||||
|
this.token("#");
|
||||||
|
this.print(node.id, node);
|
||||||
|
}
|
||||||
|
|||||||
@ -26,6 +26,11 @@ class Foo {
|
|||||||
async;
|
async;
|
||||||
foo; bar;
|
foo; bar;
|
||||||
foo = 0; bar = 1;
|
foo = 0; bar = 1;
|
||||||
|
|
||||||
|
#foo;
|
||||||
|
#foo = 1;
|
||||||
|
static #foo;
|
||||||
|
static #foo = Foo.#foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
class A1 {
|
class A1 {
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
{ "plugins": ["classProperties"] }
|
{ "plugins": ["classProperties", "classPrivateProperties"] }
|
||||||
|
|||||||
@ -26,6 +26,10 @@ class Foo {
|
|||||||
bar;
|
bar;
|
||||||
foo = 0;
|
foo = 0;
|
||||||
bar = 1;
|
bar = 1;
|
||||||
|
#foo;
|
||||||
|
#foo = 1;
|
||||||
|
static #foo;
|
||||||
|
static #foo = Foo.#foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
class A1 {
|
class A1 {
|
||||||
@ -65,4 +69,4 @@ class A6 {
|
|||||||
class A7 {
|
class A7 {
|
||||||
static get static() {}
|
static get static() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@ export function push(
|
|||||||
key = t.toComputedKey(node, node.key);
|
key = t.toComputedKey(node, node.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.isObjectProperty(node) || t.isClassProperty(node)) {
|
if (t.isProperty(node)) {
|
||||||
value = node.value;
|
value = node.value;
|
||||||
} else if (t.isObjectMethod(node) || t.isClassMethod(node)) {
|
} else if (t.isObjectMethod(node) || t.isClassMethod(node)) {
|
||||||
value = t.functionExpression(
|
value = t.functionExpression(
|
||||||
@ -131,15 +131,12 @@ export function toClassObject(mutatorMap: Object): Object {
|
|||||||
const propNode = t.objectProperty(map._key, mapNode, map._computed);
|
const propNode = t.objectProperty(map._key, mapNode, map._computed);
|
||||||
|
|
||||||
Object.keys(map).forEach(function(key) {
|
Object.keys(map).forEach(function(key) {
|
||||||
let node = map[key];
|
const node = map[key];
|
||||||
if (key[0] === "_") return;
|
if (key[0] === "_") return;
|
||||||
|
|
||||||
const inheritNode = node;
|
|
||||||
if (t.isClassMethod(node) || t.isClassProperty(node)) node = node.value;
|
|
||||||
|
|
||||||
const prop = t.objectProperty(t.identifier(key), node);
|
const prop = t.objectProperty(t.identifier(key), node);
|
||||||
t.inheritsComments(prop, inheritNode);
|
t.inheritsComments(prop, node);
|
||||||
t.removeComments(inheritNode);
|
t.removeComments(node);
|
||||||
|
|
||||||
mapNode.properties.push(prop);
|
mapNode.properties.push(prop);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export default declare(api => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
manipulateOptions(opts, parserOpts) {
|
manipulateOptions(opts, parserOpts) {
|
||||||
parserOpts.plugins.push("classProperties");
|
parserOpts.plugins.push("classProperties", "classPrivateProperties");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -46,7 +46,7 @@ const memberExpressionOptimisationVisitor = {
|
|||||||
path.skip();
|
path.skip();
|
||||||
},
|
},
|
||||||
|
|
||||||
"Function|ClassProperty": function(path, state) {
|
Function(path, state) {
|
||||||
// Detect whether any reference to rest is contained in nested functions to
|
// Detect whether any reference to rest is contained in nested functions to
|
||||||
// determine if deopt is necessary.
|
// determine if deopt is necessary.
|
||||||
const oldNoOptimise = state.noOptimise;
|
const oldNoOptimise = state.noOptimise;
|
||||||
|
|||||||
@ -33,4 +33,4 @@ var innerclassproperties = (...args) => (
|
|||||||
static args = args;
|
static args = args;
|
||||||
args = args;
|
args = args;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
class AnchorLink extends Component {
|
class AnchorLink extends Component {
|
||||||
render() {
|
render() {
|
||||||
const _props = this.props,
|
const _this$props = this.props,
|
||||||
isExternal = _props.isExternal,
|
isExternal = _this$props.isExternal,
|
||||||
children = _props.children;
|
children = _this$props.children;
|
||||||
|
|
||||||
if (isExternal) {
|
if (isExternal) {
|
||||||
return <a>{children}</a>;
|
return <a>{children}</a>;
|
||||||
|
|||||||
@ -163,12 +163,13 @@ function hoistFunctionEnvironment(
|
|||||||
specCompliant = false,
|
specCompliant = false,
|
||||||
allowInsertArrow = true,
|
allowInsertArrow = true,
|
||||||
) {
|
) {
|
||||||
const thisEnvFn = fnPath.findParent(
|
const thisEnvFn = fnPath.findParent(p => {
|
||||||
p =>
|
return (
|
||||||
(p.isFunction() && !p.isArrowFunctionExpression()) ||
|
(p.isFunction() && !p.isArrowFunctionExpression()) ||
|
||||||
p.isProgram() ||
|
p.isProgram() ||
|
||||||
p.isClassProperty({ static: false }),
|
p.isClassProperty({ static: false })
|
||||||
);
|
);
|
||||||
|
});
|
||||||
const inConstructor = thisEnvFn && thisEnvFn.node.kind === "constructor";
|
const inConstructor = thisEnvFn && thisEnvFn.node.kind === "constructor";
|
||||||
|
|
||||||
if (thisEnvFn.isClassProperty()) {
|
if (thisEnvFn.isClassProperty()) {
|
||||||
|
|||||||
@ -36,6 +36,10 @@ function gatherNodeParts(node: Object, parts: Array) {
|
|||||||
for (const prop of (node.properties: Array)) {
|
for (const prop of (node.properties: Array)) {
|
||||||
gatherNodeParts(prop.key || prop.argument, parts);
|
gatherNodeParts(prop.key || prop.argument, parts);
|
||||||
}
|
}
|
||||||
|
} else if (t.isPrivateName(node)) {
|
||||||
|
gatherNodeParts(node.id, parts);
|
||||||
|
} else if (t.isThisExpression(node)) {
|
||||||
|
parts.push("this");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,7 +626,7 @@ export default class Scope {
|
|||||||
if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
|
if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
|
||||||
if (node.kind === "get" || node.kind === "set") return false;
|
if (node.kind === "get" || node.kind === "set") return false;
|
||||||
return true;
|
return true;
|
||||||
} else if (t.isClassProperty(node) || t.isObjectProperty(node)) {
|
} else if (t.isProperty(node)) {
|
||||||
if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
|
if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
|
||||||
return this.isPure(node.value, constantsOnly);
|
return this.isPure(node.value, constantsOnly);
|
||||||
} else if (t.isUnaryExpression(node)) {
|
} else if (t.isUnaryExpression(node)) {
|
||||||
|
|||||||
@ -256,7 +256,7 @@ t.classBody(body)
|
|||||||
|
|
||||||
See also `t.isClassBody(node, opts)` and `t.assertClassBody(node, opts)`.
|
See also `t.isClassBody(node, opts)` and `t.assertClassBody(node, opts)`.
|
||||||
|
|
||||||
- `body`: `Array<ClassMethod | ClassProperty | TSDeclareMethod | TSIndexSignature>` (required)
|
- `body`: `Array<ClassMethod | ClassProperty | ClassPrivateProperty | TSDeclareMethod | TSIndexSignature>` (required)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -343,6 +343,20 @@ Aliases: `Function`, `Scopable`, `BlockParent`, `FunctionParent`, `Method`
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### classPrivateProperty
|
||||||
|
```javascript
|
||||||
|
t.classPrivateProperty(key, value)
|
||||||
|
```
|
||||||
|
|
||||||
|
See also `t.isClassPrivateProperty(node, opts)` and `t.assertClassPrivateProperty(node, opts)`.
|
||||||
|
|
||||||
|
Aliases: `Property`, `Private`
|
||||||
|
|
||||||
|
- `key`: `PrivateName` (required)
|
||||||
|
- `value`: `Expression` (default: `null`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### classProperty
|
### classProperty
|
||||||
```javascript
|
```javascript
|
||||||
t.classProperty(key, value, typeAnnotation, decorators, computed)
|
t.classProperty(key, value, typeAnnotation, decorators, computed)
|
||||||
@ -1636,6 +1650,19 @@ Aliases: `Expression`, `ExpressionWrapper`
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### privateName
|
||||||
|
```javascript
|
||||||
|
t.privateName(id)
|
||||||
|
```
|
||||||
|
|
||||||
|
See also `t.isPrivateName(node, opts)` and `t.assertPrivateName(node, opts)`.
|
||||||
|
|
||||||
|
Aliases: `Private`
|
||||||
|
|
||||||
|
- `id`: `Identifier` (required)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### program
|
### program
|
||||||
```javascript
|
```javascript
|
||||||
t.program(body, directives, sourceType)
|
t.program(body, directives, sourceType)
|
||||||
|
|||||||
@ -663,6 +663,12 @@ export function assertOptionalCallExpression(
|
|||||||
): void {
|
): void {
|
||||||
assert("OptionalCallExpression", node, opts);
|
assert("OptionalCallExpression", node, opts);
|
||||||
}
|
}
|
||||||
|
export function assertClassPrivateProperty(
|
||||||
|
node: Object,
|
||||||
|
opts?: Object = {},
|
||||||
|
): void {
|
||||||
|
assert("ClassPrivateProperty", node, opts);
|
||||||
|
}
|
||||||
export function assertImport(node: Object, opts?: Object = {}): void {
|
export function assertImport(node: Object, opts?: Object = {}): void {
|
||||||
assert("Import", node, opts);
|
assert("Import", node, opts);
|
||||||
}
|
}
|
||||||
@ -684,6 +690,9 @@ export function assertExportNamespaceSpecifier(
|
|||||||
): void {
|
): void {
|
||||||
assert("ExportNamespaceSpecifier", node, opts);
|
assert("ExportNamespaceSpecifier", node, opts);
|
||||||
}
|
}
|
||||||
|
export function assertPrivateName(node: Object, opts?: Object = {}): void {
|
||||||
|
assert("PrivateName", node, opts);
|
||||||
|
}
|
||||||
export function assertTSParameterProperty(
|
export function assertTSParameterProperty(
|
||||||
node: Object,
|
node: Object,
|
||||||
opts?: Object = {},
|
opts?: Object = {},
|
||||||
@ -1059,6 +1068,9 @@ export function assertFlowPredicate(node: Object, opts?: Object = {}): void {
|
|||||||
export function assertJSX(node: Object, opts?: Object = {}): void {
|
export function assertJSX(node: Object, opts?: Object = {}): void {
|
||||||
assert("JSX", node, opts);
|
assert("JSX", node, opts);
|
||||||
}
|
}
|
||||||
|
export function assertPrivate(node: Object, opts?: Object = {}): void {
|
||||||
|
assert("Private", node, opts);
|
||||||
|
}
|
||||||
export function assertTSTypeElement(node: Object, opts?: Object = {}): void {
|
export function assertTSTypeElement(node: Object, opts?: Object = {}): void {
|
||||||
assert("TSTypeElement", node, opts);
|
assert("TSTypeElement", node, opts);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -604,6 +604,10 @@ export function OptionalCallExpression(...args: Array<any>): Object {
|
|||||||
return builder("OptionalCallExpression", ...args);
|
return builder("OptionalCallExpression", ...args);
|
||||||
}
|
}
|
||||||
export { OptionalCallExpression as optionalCallExpression };
|
export { OptionalCallExpression as optionalCallExpression };
|
||||||
|
export function ClassPrivateProperty(...args: Array<any>): Object {
|
||||||
|
return builder("ClassPrivateProperty", ...args);
|
||||||
|
}
|
||||||
|
export { ClassPrivateProperty as classPrivateProperty };
|
||||||
export function Import(...args: Array<any>): Object {
|
export function Import(...args: Array<any>): Object {
|
||||||
return builder("Import", ...args);
|
return builder("Import", ...args);
|
||||||
}
|
}
|
||||||
@ -624,6 +628,10 @@ export function ExportNamespaceSpecifier(...args: Array<any>): Object {
|
|||||||
return builder("ExportNamespaceSpecifier", ...args);
|
return builder("ExportNamespaceSpecifier", ...args);
|
||||||
}
|
}
|
||||||
export { ExportNamespaceSpecifier as exportNamespaceSpecifier };
|
export { ExportNamespaceSpecifier as exportNamespaceSpecifier };
|
||||||
|
export function PrivateName(...args: Array<any>): Object {
|
||||||
|
return builder("PrivateName", ...args);
|
||||||
|
}
|
||||||
|
export { PrivateName as privateName };
|
||||||
export function TSParameterProperty(...args: Array<any>): Object {
|
export function TSParameterProperty(...args: Array<any>): Object {
|
||||||
return builder("TSParameterProperty", ...args);
|
return builder("TSParameterProperty", ...args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,5 +46,6 @@ export const FLOWBASEANNOTATION_TYPES =
|
|||||||
export const FLOWDECLARATION_TYPES = FLIPPED_ALIAS_KEYS["FlowDeclaration"];
|
export const FLOWDECLARATION_TYPES = FLIPPED_ALIAS_KEYS["FlowDeclaration"];
|
||||||
export const FLOWPREDICATE_TYPES = FLIPPED_ALIAS_KEYS["FlowPredicate"];
|
export const FLOWPREDICATE_TYPES = FLIPPED_ALIAS_KEYS["FlowPredicate"];
|
||||||
export const JSX_TYPES = FLIPPED_ALIAS_KEYS["JSX"];
|
export const JSX_TYPES = FLIPPED_ALIAS_KEYS["JSX"];
|
||||||
|
export const PRIVATE_TYPES = FLIPPED_ALIAS_KEYS["Private"];
|
||||||
export const TSTYPEELEMENT_TYPES = FLIPPED_ALIAS_KEYS["TSTypeElement"];
|
export const TSTYPEELEMENT_TYPES = FLIPPED_ALIAS_KEYS["TSTypeElement"];
|
||||||
export const TSTYPE_TYPES = FLIPPED_ALIAS_KEYS["TSType"];
|
export const TSTYPE_TYPES = FLIPPED_ALIAS_KEYS["TSType"];
|
||||||
|
|||||||
@ -503,7 +503,7 @@ defineType("MemberExpression", {
|
|||||||
},
|
},
|
||||||
property: {
|
property: {
|
||||||
validate: (function() {
|
validate: (function() {
|
||||||
const normal = assertNodeType("Identifier");
|
const normal = assertNodeType("Identifier", "PrivateName");
|
||||||
const computed = assertNodeType("Expression");
|
const computed = assertNodeType("Expression");
|
||||||
|
|
||||||
return function(node, key, val) {
|
return function(node, key, val) {
|
||||||
|
|||||||
@ -88,6 +88,7 @@ defineType("ClassBody", {
|
|||||||
assertNodeType(
|
assertNodeType(
|
||||||
"ClassMethod",
|
"ClassMethod",
|
||||||
"ClassProperty",
|
"ClassProperty",
|
||||||
|
"ClassPrivateProperty",
|
||||||
"TSDeclareMethod",
|
"TSDeclareMethod",
|
||||||
"TSIndexSignature",
|
"TSIndexSignature",
|
||||||
),
|
),
|
||||||
|
|||||||
@ -115,6 +115,21 @@ defineType("OptionalCallExpression", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
defineType("ClassPrivateProperty", {
|
||||||
|
visitor: ["key", "value"],
|
||||||
|
builder: ["key", "value"],
|
||||||
|
aliases: ["Property", "Private"],
|
||||||
|
fields: {
|
||||||
|
key: {
|
||||||
|
validate: assertNodeType("PrivateName"),
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
validate: assertNodeType("Expression"),
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
defineType("Import", {
|
defineType("Import", {
|
||||||
aliases: ["Expression"],
|
aliases: ["Expression"],
|
||||||
});
|
});
|
||||||
@ -157,3 +172,13 @@ defineType("ExportNamespaceSpecifier", {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
defineType("PrivateName", {
|
||||||
|
visitor: ["id"],
|
||||||
|
aliases: ["Private"],
|
||||||
|
fields: {
|
||||||
|
id: {
|
||||||
|
validate: assertNodeType("Identifier"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@ -494,6 +494,9 @@ export function isOptionalMemberExpression(
|
|||||||
export function isOptionalCallExpression(node: Object, opts?: Object): boolean {
|
export function isOptionalCallExpression(node: Object, opts?: Object): boolean {
|
||||||
return is("OptionalCallExpression", node, opts);
|
return is("OptionalCallExpression", node, opts);
|
||||||
}
|
}
|
||||||
|
export function isClassPrivateProperty(node: Object, opts?: Object): boolean {
|
||||||
|
return is("ClassPrivateProperty", node, opts);
|
||||||
|
}
|
||||||
export function isImport(node: Object, opts?: Object): boolean {
|
export function isImport(node: Object, opts?: Object): boolean {
|
||||||
return is("Import", node, opts);
|
return is("Import", node, opts);
|
||||||
}
|
}
|
||||||
@ -512,6 +515,9 @@ export function isExportNamespaceSpecifier(
|
|||||||
): boolean {
|
): boolean {
|
||||||
return is("ExportNamespaceSpecifier", node, opts);
|
return is("ExportNamespaceSpecifier", node, opts);
|
||||||
}
|
}
|
||||||
|
export function isPrivateName(node: Object, opts?: Object): boolean {
|
||||||
|
return is("PrivateName", node, opts);
|
||||||
|
}
|
||||||
export function isTSParameterProperty(node: Object, opts?: Object): boolean {
|
export function isTSParameterProperty(node: Object, opts?: Object): boolean {
|
||||||
return is("TSParameterProperty", node, opts);
|
return is("TSParameterProperty", node, opts);
|
||||||
}
|
}
|
||||||
@ -821,6 +827,9 @@ export function isFlowPredicate(node: Object, opts?: Object): boolean {
|
|||||||
export function isJSX(node: Object, opts?: Object): boolean {
|
export function isJSX(node: Object, opts?: Object): boolean {
|
||||||
return is("JSX", node, opts);
|
return is("JSX", node, opts);
|
||||||
}
|
}
|
||||||
|
export function isPrivate(node: Object, opts?: Object): boolean {
|
||||||
|
return is("Private", node, opts);
|
||||||
|
}
|
||||||
export function isTSTypeElement(node: Object, opts?: Object): boolean {
|
export function isTSTypeElement(node: Object, opts?: Object): boolean {
|
||||||
return is("TSTypeElement", node, opts);
|
return is("TSTypeElement", node, opts);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -76,8 +76,9 @@ export default function isReferenced(node: Object, parent: Object): boolean {
|
|||||||
// yes: class { [NODE] = value; }
|
// yes: class { [NODE] = value; }
|
||||||
// yes: class { key = NODE; }
|
// yes: class { key = NODE; }
|
||||||
case "ClassProperty":
|
case "ClassProperty":
|
||||||
|
case "ClassPrivateProperty":
|
||||||
if (parent.key === node) {
|
if (parent.key === node) {
|
||||||
return parent.computed;
|
return !!parent.computed;
|
||||||
} else {
|
} else {
|
||||||
return parent.value === node;
|
return parent.value === node;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user