Flow enums parsing (#10344)

* Flow enums parsing

* Parse exporting enums

* Enums parsing remove lookahead, other improvements

* Enums: add EnumBody and EnumMember aliases, change boolean members to use BooleaLiteral value

* Fix enum member init flow type, now that boolean members have a BooleanLiteral value

* Flow enums: use contextual utils, change members length checks to use logic operators, remove reserved word logic modification

* Flow enums: remove unnecessary code in generator, fix error message
This commit is contained in:
George Zahariev
2019-10-29 14:55:12 -07:00
committed by Nicolò Ribaudo
parent 4b3a19ea9f
commit ec3345bb57
92 changed files with 3213 additions and 5 deletions

View File

@@ -584,6 +584,39 @@ export function assertVoidTypeAnnotation(
): void {
assert("VoidTypeAnnotation", node, opts);
}
export function assertEnumDeclaration(node: Object, opts?: Object = {}): void {
assert("EnumDeclaration", node, opts);
}
export function assertEnumBooleanBody(node: Object, opts?: Object = {}): void {
assert("EnumBooleanBody", node, opts);
}
export function assertEnumNumberBody(node: Object, opts?: Object = {}): void {
assert("EnumNumberBody", node, opts);
}
export function assertEnumStringBody(node: Object, opts?: Object = {}): void {
assert("EnumStringBody", node, opts);
}
export function assertEnumSymbolBody(node: Object, opts?: Object = {}): void {
assert("EnumSymbolBody", node, opts);
}
export function assertEnumBooleanMember(
node: Object,
opts?: Object = {},
): void {
assert("EnumBooleanMember", node, opts);
}
export function assertEnumNumberMember(node: Object, opts?: Object = {}): void {
assert("EnumNumberMember", node, opts);
}
export function assertEnumStringMember(node: Object, opts?: Object = {}): void {
assert("EnumStringMember", node, opts);
}
export function assertEnumDefaultedMember(
node: Object,
opts?: Object = {},
): void {
assert("EnumDefaultedMember", node, opts);
}
export function assertJSXAttribute(node: Object, opts?: Object = {}): void {
assert("JSXAttribute", node, opts);
}
@@ -1139,6 +1172,12 @@ export function assertFlowDeclaration(node: Object, opts?: Object = {}): void {
export function assertFlowPredicate(node: Object, opts?: Object = {}): void {
assert("FlowPredicate", node, opts);
}
export function assertEnumBody(node: Object, opts?: Object = {}): void {
assert("EnumBody", node, opts);
}
export function assertEnumMember(node: Object, opts?: Object = {}): void {
assert("EnumMember", node, opts);
}
export function assertJSX(node: Object, opts?: Object = {}): void {
assert("JSX", node, opts);
}

View File

@@ -517,6 +517,42 @@ export function VoidTypeAnnotation(...args: Array<any>): Object {
return builder("VoidTypeAnnotation", ...args);
}
export { VoidTypeAnnotation as voidTypeAnnotation };
export function EnumDeclaration(...args: Array<any>): Object {
return builder("EnumDeclaration", ...args);
}
export { EnumDeclaration as enumDeclaration };
export function EnumBooleanBody(...args: Array<any>): Object {
return builder("EnumBooleanBody", ...args);
}
export { EnumBooleanBody as enumBooleanBody };
export function EnumNumberBody(...args: Array<any>): Object {
return builder("EnumNumberBody", ...args);
}
export { EnumNumberBody as enumNumberBody };
export function EnumStringBody(...args: Array<any>): Object {
return builder("EnumStringBody", ...args);
}
export { EnumStringBody as enumStringBody };
export function EnumSymbolBody(...args: Array<any>): Object {
return builder("EnumSymbolBody", ...args);
}
export { EnumSymbolBody as enumSymbolBody };
export function EnumBooleanMember(...args: Array<any>): Object {
return builder("EnumBooleanMember", ...args);
}
export { EnumBooleanMember as enumBooleanMember };
export function EnumNumberMember(...args: Array<any>): Object {
return builder("EnumNumberMember", ...args);
}
export { EnumNumberMember as enumNumberMember };
export function EnumStringMember(...args: Array<any>): Object {
return builder("EnumStringMember", ...args);
}
export { EnumStringMember as enumStringMember };
export function EnumDefaultedMember(...args: Array<any>): Object {
return builder("EnumDefaultedMember", ...args);
}
export { EnumDefaultedMember as enumDefaultedMember };
export function JSXAttribute(...args: Array<any>): Object {
return builder("JSXAttribute", ...args);
}

View File

@@ -45,6 +45,8 @@ export const FLOWBASEANNOTATION_TYPES =
FLIPPED_ALIAS_KEYS["FlowBaseAnnotation"];
export const FLOWDECLARATION_TYPES = FLIPPED_ALIAS_KEYS["FlowDeclaration"];
export const FLOWPREDICATE_TYPES = FLIPPED_ALIAS_KEYS["FlowPredicate"];
export const ENUMBODY_TYPES = FLIPPED_ALIAS_KEYS["EnumBody"];
export const ENUMMEMBER_TYPES = FLIPPED_ALIAS_KEYS["EnumMember"];
export const JSX_TYPES = FLIPPED_ALIAS_KEYS["JSX"];
export const PRIVATE_TYPES = FLIPPED_ALIAS_KEYS["Private"];
export const TSTYPEELEMENT_TYPES = FLIPPED_ALIAS_KEYS["TSTypeElement"];

View File

@@ -4,6 +4,7 @@ import defineType, {
assertOneOf,
assertValueType,
validate,
validateArrayOfType,
validateOptional,
validateOptionalType,
validateType,
@@ -464,3 +465,88 @@ defineType("Variance", {
defineType("VoidTypeAnnotation", {
aliases: ["Flow", "FlowType", "FlowBaseAnnotation"],
});
// Enums
defineType("EnumDeclaration", {
alises: ["Declaration"],
visitor: ["id", "body"],
fields: {
id: validateType("Identifier"),
body: validateType([
"EnumBooleanBody",
"EnumNumberBody",
"EnumStringBody",
"EnumSymbolBody",
]),
},
});
defineType("EnumBooleanBody", {
aliases: ["EnumBody"],
visitor: ["members"],
fields: {
explicit: validate(assertValueType("boolean")),
members: validateArrayOfType("EnumBooleanMember"),
},
});
defineType("EnumNumberBody", {
aliases: ["EnumBody"],
visitor: ["members"],
fields: {
explicit: validate(assertValueType("boolean")),
members: validateArrayOfType("EnumNumberMember"),
},
});
defineType("EnumStringBody", {
aliases: ["EnumBody"],
visitor: ["members"],
fields: {
explicit: validate(assertValueType("boolean")),
members: validateArrayOfType(["EnumStringMember", "EnumDefaultedMember"]),
},
});
defineType("EnumSymbolBody", {
aliases: ["EnumBody"],
visitor: ["members"],
fields: {
members: validateArrayOfType("EnumDefaultedMember"),
},
});
defineType("EnumBooleanMember", {
aliases: ["EnumMember"],
visitor: ["id"],
fields: {
id: validateType("Identifier"),
init: validateType("BooleanLiteral"),
},
});
defineType("EnumNumberMember", {
aliases: ["EnumMember"],
visitor: ["id", "init"],
fields: {
id: validateType("Identifier"),
init: validateType("NumericLiteral"),
},
});
defineType("EnumStringMember", {
aliases: ["EnumMember"],
visitor: ["id", "init"],
fields: {
id: validateType("Identifier"),
init: validateType("StringLiteral"),
},
});
defineType("EnumDefaultedMember", {
aliases: ["EnumMember"],
visitor: ["id"],
fields: {
id: validateType("Identifier"),
},
});

View File

@@ -1866,6 +1866,132 @@ export function isVoidTypeAnnotation(node: ?Object, opts?: Object): boolean {
return false;
}
export function isEnumDeclaration(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumDeclaration") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumBooleanBody(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumBooleanBody") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumNumberBody(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumNumberBody") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumStringBody(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumStringBody") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumSymbolBody(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumSymbolBody") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumBooleanMember(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumBooleanMember") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumNumberMember(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumNumberMember") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumStringMember(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumStringMember") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumDefaultedMember(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (nodeType === "EnumDefaultedMember") {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isJSXAttribute(node: ?Object, opts?: Object): boolean {
if (!node) return false;
@@ -4276,6 +4402,46 @@ export function isFlowPredicate(node: ?Object, opts?: Object): boolean {
return false;
}
export function isEnumBody(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (
nodeType === "EnumBody" ||
"EnumBooleanBody" === nodeType ||
"EnumNumberBody" === nodeType ||
"EnumStringBody" === nodeType ||
"EnumSymbolBody" === nodeType
) {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isEnumMember(node: ?Object, opts?: Object): boolean {
if (!node) return false;
const nodeType = node.type;
if (
nodeType === "EnumMember" ||
"EnumBooleanMember" === nodeType ||
"EnumNumberMember" === nodeType ||
"EnumStringMember" === nodeType ||
"EnumDefaultedMember" === nodeType
) {
if (typeof opts === "undefined") {
return true;
} else {
return shallowEqual(node, opts);
}
}
return false;
}
export function isJSX(node: ?Object, opts?: Object): boolean {
if (!node) return false;