Private class methods stage 3 (#8654)

* Add private method syntax support

* Add private method spec support

* Add private method loose support

* Throw error if static private method is used

* Add more isStatic & isMethod checks

* Remove `writable:false` from private method inits

`writable` is false by default.

* Add private method func obj equality check

* Throw if private accessor is used

* Add check for fields === private method loose mode

* Throw buildCodeFrameErrors instead of Errors

* Move obj destructuring inside for loop

* Remove "computed" from ClassPrivateMethod type def
This commit is contained in:
Tim McClure
2018-11-28 19:20:09 -05:00
committed by Justin Ridgewell
parent 6e39b58f8a
commit 0859535b62
40 changed files with 745 additions and 37 deletions

View File

@@ -687,6 +687,12 @@ export function assertClassPrivateProperty(
): void {
assert("ClassPrivateProperty", node, opts);
}
export function assertClassPrivateMethod(
node: Object,
opts?: Object = {},
): void {
assert("ClassPrivateMethod", node, opts);
}
export function assertImport(node: Object, opts?: Object = {}): void {
assert("Import", node, opts);
}

View File

@@ -620,6 +620,10 @@ export function ClassPrivateProperty(...args: Array<any>): Object {
return builder("ClassPrivateProperty", ...args);
}
export { ClassPrivateProperty as classPrivateProperty };
export function ClassPrivateMethod(...args: Array<any>): Object {
return builder("ClassPrivateMethod", ...args);
}
export { ClassPrivateMethod as classPrivateMethod };
export function Import(...args: Array<any>): Object {
return builder("Import", ...args);
}

View File

@@ -87,6 +87,7 @@ defineType("ClassBody", {
assertEach(
assertNodeType(
"ClassMethod",
"ClassPrivateMethod",
"ClassProperty",
"ClassPrivateProperty",
"TSDeclareMethod",

View File

@@ -5,7 +5,10 @@ import defineType, {
assertValueType,
chain,
} from "./utils";
import { classMethodOrPropertyCommon } from "./es2015";
import {
classMethodOrPropertyCommon,
classMethodOrDeclareMethodCommon,
} from "./es2015";
defineType("AwaitExpression", {
builder: ["argument"],
@@ -131,6 +134,28 @@ defineType("ClassPrivateProperty", {
},
});
defineType("ClassPrivateMethod", {
builder: ["kind", "key", "params", "body", "static"],
visitor: [
"key",
"params",
"body",
"decorators",
"returnType",
"typeParameters",
],
aliases: ["Method", "Private", "Function"],
fields: {
...classMethodOrDeclareMethodCommon,
key: {
validate: assertNodeType("PrivateName"),
},
body: {
validate: assertNodeType("BlockStatement"),
},
},
});
defineType("Import", {
aliases: ["Expression"],
});

View File

@@ -2159,6 +2159,20 @@ export function isClassPrivateProperty(node: Object, opts?: Object): boolean {
return false;
}
export function isClassPrivateMethod(node: Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "ClassPrivateMethod") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isImport(node: Object, opts?: Object): boolean {
if (!node) return false;
@@ -3492,7 +3506,8 @@ export function isFunction(node: Object, opts?: Object): boolean {
"FunctionExpression" === nodeType ||
"ObjectMethod" === nodeType ||
"ArrowFunctionExpression" === nodeType ||
"ClassMethod" === nodeType
"ClassMethod" === nodeType ||
"ClassPrivateMethod" === nodeType
) {
if (typeof opts === "undefined") {
return true;
@@ -3737,7 +3752,8 @@ export function isMethod(node: Object, opts?: Object): boolean {
if (
nodeType === "Method" ||
"ObjectMethod" === nodeType ||
"ClassMethod" === nodeType
"ClassMethod" === nodeType ||
"ClassPrivateMethod" === nodeType
) {
if (typeof opts === "undefined") {
return true;
@@ -4119,6 +4135,7 @@ export function isPrivate(node: Object, opts?: Object): boolean {
if (
nodeType === "Private" ||
"ClassPrivateProperty" === nodeType ||
"ClassPrivateMethod" === nodeType ||
"PrivateName" === nodeType
) {
if (typeof opts === "undefined") {

View File

@@ -46,6 +46,7 @@ export default function isReferenced(node: Object, parent: Object): boolean {
// no: class { NODE() {} }
// yes: class { [NODE]() {} }
case "ClassMethod":
case "ClassPrivateMethod":
case "ObjectMethod":
if (parent.key === node) {
return !!parent.computed;