From 4208099f5b3d95076ea58f029be155f26132d88b Mon Sep 17 00:00:00 2001 From: Boris Cherny Date: Sat, 30 Dec 2017 13:26:01 -0800 Subject: [PATCH] Add validators for Flow AST node fields (#7107) --- packages/babel-generator/test/index.js | 4 +- packages/babel-types/README.md | 212 +++++++++------- .../src/asserts/generated/index.js | 3 + .../src/constants/generated/index.js | 1 + packages/babel-types/src/definitions/flow.js | 240 ++++++++++-------- .../babel-types/src/definitions/typescript.js | 40 +-- packages/babel-types/src/definitions/utils.js | 59 ++++- .../src/validators/generated/index.js | 3 + 8 files changed, 314 insertions(+), 248 deletions(-) diff --git a/packages/babel-generator/test/index.js b/packages/babel-generator/test/index.js index 40bbf8c12e..99b5955222 100644 --- a/packages/babel-generator/test/index.js +++ b/packages/babel-generator/test/index.js @@ -335,7 +335,7 @@ describe("programmatic generation", function() { t.objectTypeIndexer( t.identifier("key"), t.anyTypeAnnotation(), - t.identifier("Test"), + t.numberTypeAnnotation(), ), ], ); @@ -345,7 +345,7 @@ describe("programmatic generation", function() { assert.equal( output, `{ - [key: any]: Test + [key: any]: number }`, ); }); diff --git a/packages/babel-types/README.md b/packages/babel-types/README.md index 5e8d650c86..a9267f1b5c 100644 --- a/packages/babel-types/README.md +++ b/packages/babel-types/README.md @@ -19,7 +19,7 @@ t.anyTypeAnnotation() See also `t.isAnyTypeAnnotation(node, opts)` and `t.assertAnyTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- @@ -59,9 +59,9 @@ t.arrayTypeAnnotation(elementType) See also `t.isArrayTypeAnnotation(node, opts)` and `t.assertArrayTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `elementType` (required) + - `elementType`: `FlowType` (required) --- @@ -191,8 +191,9 @@ t.booleanLiteralTypeAnnotation() See also `t.isBooleanLiteralTypeAnnotation(node, opts)` and `t.assertBooleanLiteralTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` + - `value`: `boolean` (default: `null`) --- @@ -203,7 +204,7 @@ t.booleanTypeAnnotation() See also `t.isBooleanTypeAnnotation(node, opts)` and `t.assertBooleanTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- @@ -313,8 +314,8 @@ See also `t.isClassImplements(node, opts)` and `t.assertClassImplements(node, op Aliases: `Flow` - - `id` (required) - - `typeParameters` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterInstantiation` (default: `null`) --- @@ -416,10 +417,11 @@ See also `t.isDeclareClass(node, opts)` and `t.assertDeclareClass(node, opts)`. Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) - - `typeParameters` (required) - - `extends` (required) - - `body` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterInstantiation` (default: `null`) + - `extends`: `Array` (default: `null`) + - `body`: `ObjectTypeAnnotation` (required) + - `mixins`: `Array` (default: `null`) --- @@ -432,7 +434,8 @@ See also `t.isDeclareExportAllDeclaration(node, opts)` and `t.assertDeclareExpor Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `source` (required) + - `source`: `StringLiteral` (required) + - `exportKind`: `[ 'type', 'value' ]` (default: `null`) --- @@ -445,9 +448,10 @@ See also `t.isDeclareExportDeclaration(node, opts)` and `t.assertDeclareExportDe Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `declaration` (required) - - `specifiers` (required) - - `source` (required) + - `declaration`: `Flow` (default: `null`) + - `specifiers`: `Array` (default: `null`) + - `source`: `StringLiteral` (default: `null`) + - `default`: `boolean` (default: `null`) --- @@ -460,7 +464,8 @@ See also `t.isDeclareFunction(node, opts)` and `t.assertDeclareFunction(node, op Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) + - `id`: `Identifier` (required) + - `predicate`: `DeclaredPredicate` (default: `null`) --- @@ -473,24 +478,26 @@ See also `t.isDeclareInterface(node, opts)` and `t.assertDeclareInterface(node, Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) - - `typeParameters` (required) - - `extends` (required) - - `body` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterDeclaration` (default: `null`) + - `extends`: `InterfaceExtends` (default: `null`) + - `body`: `ObjectTypeAnnotation` (required) + - `mixins`: `Array` (default: `null`) --- ### declareModule ```javascript -t.declareModule(id, body) +t.declareModule(id, body, kind) ``` See also `t.isDeclareModule(node, opts)` and `t.assertDeclareModule(node, opts)`. Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) - - `body` (required) + - `id`: `Identifier | StringLiteral` (required) + - `body`: `BlockStatement` (required) + - `kind`: `'CommonJS' | 'ES'` (default: `null`) --- @@ -503,7 +510,7 @@ See also `t.isDeclareModuleExports(node, opts)` and `t.assertDeclareModuleExport Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `typeAnnotation` (required) + - `typeAnnotation`: `TypeAnnotation` (required) --- @@ -516,9 +523,9 @@ See also `t.isDeclareOpaqueType(node, opts)` and `t.assertDeclareOpaqueType(node Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) - - `typeParameters` (required) - - `supertype` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterDeclaration` (default: `null`) + - `supertype`: `FlowType` (default: `null`) --- @@ -531,9 +538,9 @@ See also `t.isDeclareTypeAlias(node, opts)` and `t.assertDeclareTypeAlias(node, Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) - - `typeParameters` (required) - - `right` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterDeclaration` (default: `null`) + - `right`: `FlowType` (required) --- @@ -546,7 +553,7 @@ See also `t.isDeclareVariable(node, opts)` and `t.assertDeclareVariable(node, op Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) + - `id`: `Identifier` (required) --- @@ -559,7 +566,7 @@ See also `t.isDeclaredPredicate(node, opts)` and `t.assertDeclaredPredicate(node Aliases: `Flow`, `FlowPredicate` - - `value` (required) + - `value`: `Flow` (required) --- @@ -642,7 +649,7 @@ t.emptyTypeAnnotation() See also `t.isEmptyTypeAnnotation(node, opts)` and `t.assertEmptyTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- @@ -654,7 +661,7 @@ t.existsTypeAnnotation() See also `t.isExistsTypeAnnotation(node, opts)` and `t.assertExistsTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` --- @@ -859,12 +866,12 @@ t.functionTypeAnnotation(typeParameters, params, rest, returnType) See also `t.isFunctionTypeAnnotation(node, opts)` and `t.assertFunctionTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `typeParameters` (required) - - `params` (required) - - `rest` (required) - - `returnType` (required) + - `typeParameters`: `TypeParameterDeclaration` (default: `null`) + - `params`: `Array` (required) + - `rest`: `FunctionTypeParam` (default: `null`) + - `returnType`: `FlowType` (required) --- @@ -877,8 +884,9 @@ See also `t.isFunctionTypeParam(node, opts)` and `t.assertFunctionTypeParam(node Aliases: `Flow` - - `name` (required) - - `typeAnnotation` (required) + - `name`: `Identifier` (default: `null`) + - `typeAnnotation`: `FlowType` (required) + - `optional`: `boolean` (default: `null`) --- @@ -889,10 +897,10 @@ t.genericTypeAnnotation(id, typeParameters) See also `t.isGenericTypeAnnotation(node, opts)` and `t.assertGenericTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `id` (required) - - `typeParameters` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterInstantiation` (default: `null`) --- @@ -1015,10 +1023,11 @@ See also `t.isInterfaceDeclaration(node, opts)` and `t.assertInterfaceDeclaratio Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) - - `typeParameters` (required) - - `extends` (required) - - `body` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterDeclaration` (default: `null`) + - `extends`: `Array` (required) + - `body`: `ObjectTypeAnnotation` (required) + - `mixins`: `Array` (default: `null`) --- @@ -1031,8 +1040,8 @@ See also `t.isInterfaceExtends(node, opts)` and `t.assertInterfaceExtends(node, Aliases: `Flow` - - `id` (required) - - `typeParameters` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterInstantiation` (default: `null`) --- @@ -1043,9 +1052,9 @@ t.intersectionTypeAnnotation(types) See also `t.isIntersectionTypeAnnotation(node, opts)` and `t.assertIntersectionTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `types` (required) + - `types`: `Array` (required) --- @@ -1317,7 +1326,7 @@ t.mixedTypeAnnotation() See also `t.isMixedTypeAnnotation(node, opts)` and `t.assertMixedTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- @@ -1367,7 +1376,7 @@ t.nullLiteralTypeAnnotation() See also `t.isNullLiteralTypeAnnotation(node, opts)` and `t.assertNullLiteralTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- @@ -1379,9 +1388,9 @@ t.nullableTypeAnnotation(typeAnnotation) See also `t.isNullableTypeAnnotation(node, opts)` and `t.assertNullableTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `typeAnnotation` (required) + - `typeAnnotation`: `FlowType` (required) --- @@ -1392,8 +1401,9 @@ t.numberLiteralTypeAnnotation() See also `t.isNumberLiteralTypeAnnotation(node, opts)` and `t.assertNumberLiteralTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` + - `value`: `number` (default: `null`) --- @@ -1404,7 +1414,7 @@ t.numberTypeAnnotation() See also `t.isNumberTypeAnnotation(node, opts)` and `t.assertNumberTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- @@ -1496,11 +1506,12 @@ t.objectTypeAnnotation(properties, indexers, callProperties) See also `t.isObjectTypeAnnotation(node, opts)` and `t.assertObjectTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `properties` (required) - - `indexers` (required) - - `callProperties` (required) + - `properties`: `Array` (required) + - `indexers`: `Array` (default: `null`) + - `callProperties`: `Array` (default: `null`) + - `exact`: `boolean` (default: `null`) --- @@ -1513,36 +1524,43 @@ See also `t.isObjectTypeCallProperty(node, opts)` and `t.assertObjectTypeCallPro Aliases: `Flow`, `UserWhitespacable` - - `value` (required) + - `value`: `FlowType` (required) + - `static`: `boolean` (default: `null`) --- ### objectTypeIndexer ```javascript -t.objectTypeIndexer(id, key, value) +t.objectTypeIndexer(id, key, value, variance) ``` See also `t.isObjectTypeIndexer(node, opts)` and `t.assertObjectTypeIndexer(node, opts)`. Aliases: `Flow`, `UserWhitespacable` - - `id` (required) - - `key` (required) - - `value` (required) + - `id`: `Identifier` (default: `null`) + - `key`: `FlowType` (required) + - `value`: `FlowType` (required) + - `variance`: `Variance` (default: `null`) + - `static`: `boolean` (default: `null`) --- ### objectTypeProperty ```javascript -t.objectTypeProperty(key, value) +t.objectTypeProperty(key, value, variance) ``` See also `t.isObjectTypeProperty(node, opts)` and `t.assertObjectTypeProperty(node, opts)`. Aliases: `Flow`, `UserWhitespacable` - - `key` (required) - - `value` (required) + - `key`: `Identifier` (required) + - `value`: `FlowType` (required) + - `variance`: `Variance` (default: `null`) + - `kind`: `'init' | 'get' | 'set'` (default: `null`) + - `optional`: `boolean` (default: `null`) + - `static`: `boolean` (default: `null`) --- @@ -1555,7 +1573,7 @@ See also `t.isObjectTypeSpreadProperty(node, opts)` and `t.assertObjectTypeSprea Aliases: `Flow`, `UserWhitespacable` - - `argument` (required) + - `argument`: `FlowType` (required) --- @@ -1568,10 +1586,10 @@ See also `t.isOpaqueType(node, opts)` and `t.assertOpaqueType(node, opts)`. Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) - - `typeParameters` (required) - - `supertype` (required) - - `impltype` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterDeclaration` (default: `null`) + - `supertype`: `FlowType` (default: `null`) + - `impltype`: `FlowType` (required) --- @@ -1613,8 +1631,8 @@ See also `t.isQualifiedTypeIdentifier(node, opts)` and `t.assertQualifiedTypeIde Aliases: `Flow` - - `id` (required) - - `qualification` (required) + - `id`: `Identifier` (required) + - `qualification`: `Identifier | QualifiedTypeIdentifier` (required) --- @@ -1706,8 +1724,9 @@ t.stringLiteralTypeAnnotation() See also `t.isStringLiteralTypeAnnotation(node, opts)` and `t.assertStringLiteralTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` + - `value`: `string` (default: `null`) --- @@ -1718,7 +1737,7 @@ t.stringTypeAnnotation() See also `t.isStringTypeAnnotation(node, opts)` and `t.assertStringTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- @@ -2564,7 +2583,7 @@ t.thisTypeAnnotation() See also `t.isThisTypeAnnotation(node, opts)` and `t.assertThisTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- @@ -2604,9 +2623,9 @@ t.tupleTypeAnnotation(types) See also `t.isTupleTypeAnnotation(node, opts)` and `t.assertTupleTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `types` (required) + - `types`: `Array` (required) --- @@ -2619,9 +2638,9 @@ See also `t.isTypeAlias(node, opts)` and `t.assertTypeAlias(node, opts)`. Aliases: `Flow`, `FlowDeclaration`, `Statement`, `Declaration` - - `id` (required) - - `typeParameters` (required) - - `right` (required) + - `id`: `Identifier` (required) + - `typeParameters`: `TypeParameterDeclaration` (default: `null`) + - `right`: `FlowType` (required) --- @@ -2634,7 +2653,7 @@ See also `t.isTypeAnnotation(node, opts)` and `t.assertTypeAnnotation(node, opts Aliases: `Flow` - - `typeAnnotation`: `Flow` (required) + - `typeAnnotation`: `FlowType` (required) --- @@ -2647,14 +2666,14 @@ See also `t.isTypeCastExpression(node, opts)` and `t.assertTypeCastExpression(no Aliases: `Flow`, `ExpressionWrapper`, `Expression` - - `expression` (required) - - `typeAnnotation` (required) + - `expression`: `Expression` (required) + - `typeAnnotation`: `TypeAnnotation` (required) --- ### typeParameter ```javascript -t.typeParameter(bound, default) +t.typeParameter(bound, default, variance) ``` See also `t.isTypeParameter(node, opts)` and `t.assertTypeParameter(node, opts)`. @@ -2662,7 +2681,8 @@ See also `t.isTypeParameter(node, opts)` and `t.assertTypeParameter(node, opts)` Aliases: `Flow` - `bound`: `TypeAnnotation` (default: `null`) - - `default`: `Flow` (default: `null`) + - `default`: `FlowType` (default: `null`) + - `variance`: `Variance` (default: `null`) - `name`: `string` (default: `null`) --- @@ -2689,7 +2709,7 @@ See also `t.isTypeParameterInstantiation(node, opts)` and `t.assertTypeParameter Aliases: `Flow` - - `params`: `Array` (required) + - `params`: `Array` (required) --- @@ -2700,9 +2720,9 @@ t.typeofTypeAnnotation(argument) See also `t.isTypeofTypeAnnotation(node, opts)` and `t.assertTypeofTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `argument` (required) + - `argument`: `FlowType` (required) --- @@ -2728,9 +2748,9 @@ t.unionTypeAnnotation(types) See also `t.isUnionTypeAnnotation(node, opts)` and `t.assertUnionTypeAnnotation(node, opts)`. -Aliases: `Flow` +Aliases: `Flow`, `FlowType` - - `types` (required) + - `types`: `Array` (required) --- @@ -2783,7 +2803,7 @@ t.voidTypeAnnotation() See also `t.isVoidTypeAnnotation(node, opts)` and `t.assertVoidTypeAnnotation(node, opts)`. -Aliases: `Flow`, `FlowBaseAnnotation` +Aliases: `Flow`, `FlowType`, `FlowBaseAnnotation` --- diff --git a/packages/babel-types/src/asserts/generated/index.js b/packages/babel-types/src/asserts/generated/index.js index 4abf598a6a..29949f58fe 100644 --- a/packages/babel-types/src/asserts/generated/index.js +++ b/packages/babel-types/src/asserts/generated/index.js @@ -1017,6 +1017,9 @@ export function assertModuleSpecifier(node: Object, opts?: Object = {}): void { export function assertFlow(node: Object, opts?: Object = {}): void { assert("Flow", node, opts); } +export function assertFlowType(node: Object, opts?: Object = {}): void { + assert("FlowType", node, opts); +} export function assertFlowBaseAnnotation( node: Object, opts?: Object = {}, diff --git a/packages/babel-types/src/constants/generated/index.js b/packages/babel-types/src/constants/generated/index.js index 793d436c99..ea64f77d1e 100644 --- a/packages/babel-types/src/constants/generated/index.js +++ b/packages/babel-types/src/constants/generated/index.js @@ -40,6 +40,7 @@ export const MODULEDECLARATION_TYPES = FLIPPED_ALIAS_KEYS["ModuleDeclaration"]; export const EXPORTDECLARATION_TYPES = FLIPPED_ALIAS_KEYS["ExportDeclaration"]; export const MODULESPECIFIER_TYPES = FLIPPED_ALIAS_KEYS["ModuleSpecifier"]; export const FLOW_TYPES = FLIPPED_ALIAS_KEYS["Flow"]; +export const FLOWTYPE_TYPES = FLIPPED_ALIAS_KEYS["FlowType"]; export const FLOWBASEANNOTATION_TYPES = FLIPPED_ALIAS_KEYS["FlowBaseAnnotation"]; export const FLOWDECLARATION_TYPES = FLIPPED_ALIAS_KEYS["FlowDeclaration"]; diff --git a/packages/babel-types/src/definitions/flow.js b/packages/babel-types/src/definitions/flow.js index f165ec346e..264ff9f5ba 100644 --- a/packages/babel-types/src/definitions/flow.js +++ b/packages/babel-types/src/definitions/flow.js @@ -1,48 +1,47 @@ // @flow import defineType, { - assertEach, - assertNodeType, + arrayOfType, + assertOneOf, assertValueType, - chain, + validate, + validateOptional, + validateOptionalType, + validateType, } from "./utils"; defineType("AnyTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], - fields: { - // todo - }, + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); defineType("ArrayTypeAnnotation", { visitor: ["elementType"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + elementType: validateType("FlowType"), }, }); defineType("BooleanTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], - fields: { - // todo - }, + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); defineType("BooleanLiteralTypeAnnotation", { - aliases: ["Flow"], - fields: {}, + aliases: ["Flow", "FlowType"], + fields: { + value: validate(assertValueType("boolean")), + }, }); defineType("NullLiteralTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], - fields: {}, + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); defineType("ClassImplements", { visitor: ["id", "typeParameters"], aliases: ["Flow"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterInstantiation"), }, }); @@ -50,7 +49,11 @@ defineType("DeclareClass", { visitor: ["id", "typeParameters", "extends", "body"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterInstantiation"), + extends: validateOptional(arrayOfType("InterfaceExtends")), + mixins: validateOptional(arrayOfType("InterfaceExtends")), + body: validateType("ObjectTypeAnnotation"), }, }); @@ -58,7 +61,8 @@ defineType("DeclareFunction", { visitor: ["id"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), + predicate: validateOptionalType("DeclaredPredicate"), }, }); @@ -66,15 +70,22 @@ defineType("DeclareInterface", { visitor: ["id", "typeParameters", "extends", "body"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterDeclaration"), + extends: validateOptionalType("InterfaceExtends"), + mixins: validateOptional(arrayOfType("Flow")), + body: validateType("ObjectTypeAnnotation"), }, }); defineType("DeclareModule", { + builder: ["id", "body", "kind"], visitor: ["id", "body"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType(["Identifier", "StringLiteral"]), + body: validateType("BlockStatement"), + kind: validateOptional(assertOneOf("CommonJS", "ES")), }, }); @@ -82,7 +93,7 @@ defineType("DeclareModuleExports", { visitor: ["typeAnnotation"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + typeAnnotation: validateType("TypeAnnotation"), }, }); @@ -90,7 +101,9 @@ defineType("DeclareTypeAlias", { visitor: ["id", "typeParameters", "right"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterDeclaration"), + right: validateType("FlowType"), }, }); @@ -98,7 +111,9 @@ defineType("DeclareOpaqueType", { visitor: ["id", "typeParameters", "supertype"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterDeclaration"), + supertype: validateOptionalType("FlowType"), }, }); @@ -106,7 +121,7 @@ defineType("DeclareVariable", { visitor: ["id"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), }, }); @@ -114,7 +129,12 @@ defineType("DeclareExportDeclaration", { visitor: ["declaration", "specifiers", "source"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + declaration: validateOptionalType("Flow"), + specifiers: validateOptional( + arrayOfType(["ExportSpecifier", "ExportNamespaceSpecifier"]), + ), + source: validateOptionalType("StringLiteral"), + default: validateOptional(assertValueType("boolean")), }, }); @@ -122,7 +142,8 @@ defineType("DeclareExportAllDeclaration", { visitor: ["source"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + source: validateType("StringLiteral"), + exportKind: validateOptional(assertOneOf(["type", "value"])), }, }); @@ -130,19 +151,22 @@ defineType("DeclaredPredicate", { visitor: ["value"], aliases: ["Flow", "FlowPredicate"], fields: { - // todo + value: validateType("Flow"), }, }); defineType("ExistsTypeAnnotation", { - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], }); defineType("FunctionTypeAnnotation", { visitor: ["typeParameters", "params", "rest", "returnType"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + typeParameters: validateOptionalType("TypeParameterDeclaration"), + params: validate(arrayOfType("FunctionTypeParam")), + rest: validateOptionalType("FunctionTypeParam"), + returnType: validateType("FlowType"), }, }); @@ -150,30 +174,31 @@ defineType("FunctionTypeParam", { visitor: ["name", "typeAnnotation"], aliases: ["Flow"], fields: { - // todo + name: validateOptionalType("Identifier"), + typeAnnotation: validateType("FlowType"), + optional: validateOptional(assertValueType("boolean")), }, }); defineType("GenericTypeAnnotation", { visitor: ["id", "typeParameters"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterInstantiation"), }, }); defineType("InferredPredicate", { aliases: ["Flow", "FlowPredicate"], - fields: { - // todo - }, }); defineType("InterfaceExtends", { visitor: ["id", "typeParameters"], aliases: ["Flow"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterInstantiation"), }, }); @@ -181,53 +206,59 @@ defineType("InterfaceDeclaration", { visitor: ["id", "typeParameters", "extends", "body"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterDeclaration"), + extends: validate(arrayOfType("InterfaceExtends")), + mixins: validate(arrayOfType("InterfaceExtends")), + body: validateType("ObjectTypeAnnotation"), }, }); defineType("IntersectionTypeAnnotation", { visitor: ["types"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + types: validate(arrayOfType("FlowType")), }, }); defineType("MixedTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); defineType("EmptyTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); defineType("NullableTypeAnnotation", { visitor: ["typeAnnotation"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + typeAnnotation: validateType("FlowType"), }, }); defineType("NumberLiteralTypeAnnotation", { - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + value: validate(assertValueType("number")), }, }); defineType("NumberTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], - fields: { - // todo - }, + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); defineType("ObjectTypeAnnotation", { visitor: ["properties", "indexers", "callProperties"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + properties: validate( + arrayOfType(["ObjectTypeProperty", "ObjectTypeSpreadProperty"]), + ), + indexers: validateOptional(arrayOfType("ObjectTypeIndexer")), + callProperties: validateOptional(arrayOfType("ObjectTypeCallProperty")), + exact: validate(assertValueType("boolean")), }, }); @@ -235,23 +266,33 @@ defineType("ObjectTypeCallProperty", { visitor: ["value"], aliases: ["Flow", "UserWhitespacable"], fields: { - // todo + value: validateType("FlowType"), + static: validate(assertValueType("boolean")), }, }); defineType("ObjectTypeIndexer", { - visitor: ["id", "key", "value"], + visitor: ["id", "key", "value", "variance"], aliases: ["Flow", "UserWhitespacable"], fields: { - // todo + id: validateOptionalType("Identifier"), + key: validateType("FlowType"), + value: validateType("FlowType"), + static: validate(assertValueType("boolean")), + variance: validateOptionalType("Variance"), }, }); defineType("ObjectTypeProperty", { - visitor: ["key", "value"], + visitor: ["key", "value", "variance"], aliases: ["Flow", "UserWhitespacable"], fields: { - // todo + key: validateType("Identifier"), + value: validateType("FlowType"), + kind: validate(assertOneOf("init", "get", "set")), + static: validate(assertValueType("boolean")), + optional: validate(assertValueType("boolean")), + variance: validateOptionalType("Variance"), }, }); @@ -259,7 +300,7 @@ defineType("ObjectTypeSpreadProperty", { visitor: ["argument"], aliases: ["Flow", "UserWhitespacable"], fields: { - // todo + argument: validateType("FlowType"), }, }); @@ -267,7 +308,10 @@ defineType("OpaqueType", { visitor: ["id", "typeParameters", "supertype", "impltype"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterDeclaration"), + supertype: validateOptionalType("FlowType"), + impltype: validateType("FlowType"), }, }); @@ -275,42 +319,39 @@ defineType("QualifiedTypeIdentifier", { visitor: ["id", "qualification"], aliases: ["Flow"], fields: { - // todo + id: validateType("Identifier"), + qualification: validateType(["Identifier", "QualifiedTypeIdentifier"]), }, }); defineType("StringLiteralTypeAnnotation", { - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + value: validate(assertValueType("string")), }, }); defineType("StringTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], - fields: { - // todo - }, + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); defineType("ThisTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], - fields: {}, + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); defineType("TupleTypeAnnotation", { visitor: ["types"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + types: validate(arrayOfType("FlowType")), }, }); defineType("TypeofTypeAnnotation", { visitor: ["argument"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + argument: validateType("FlowType"), }, }); @@ -318,7 +359,9 @@ defineType("TypeAlias", { visitor: ["id", "typeParameters", "right"], aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], fields: { - // todo + id: validateType("Identifier"), + typeParameters: validateOptionalType("TypeParameterDeclaration"), + right: validateType("FlowType"), }, }); @@ -326,9 +369,7 @@ defineType("TypeAnnotation", { aliases: ["Flow"], visitor: ["typeAnnotation"], fields: { - typeAnnotation: { - validate: assertNodeType("Flow"), - }, + typeAnnotation: validateType("FlowType"), }, }); @@ -336,25 +377,19 @@ defineType("TypeCastExpression", { visitor: ["expression", "typeAnnotation"], aliases: ["Flow", "ExpressionWrapper", "Expression"], fields: { - // todo + expression: validateType("Expression"), + typeAnnotation: validateType("TypeAnnotation"), }, }); defineType("TypeParameter", { aliases: ["Flow"], - visitor: ["bound", "default"], + visitor: ["bound", "default", "variance"], fields: { - name: { - validate: assertValueType("string"), - }, - bound: { - validate: assertNodeType("TypeAnnotation"), - optional: true, - }, - default: { - validate: assertNodeType("Flow"), - optional: true, - }, + name: validate(assertValueType("string")), + bound: validateOptionalType("TypeAnnotation"), + default: validateOptionalType("FlowType"), + variance: validateOptionalType("Variance"), }, }); @@ -362,12 +397,7 @@ defineType("TypeParameterDeclaration", { aliases: ["Flow"], visitor: ["params"], fields: { - params: { - validate: chain( - assertValueType("array"), - assertEach(assertNodeType("TypeParameter")), - ), - }, + params: validate(arrayOfType("TypeParameter")), }, }); @@ -375,26 +405,18 @@ defineType("TypeParameterInstantiation", { aliases: ["Flow"], visitor: ["params"], fields: { - params: { - validate: chain( - assertValueType("array"), - assertEach(assertNodeType("Flow")), - ), - }, + params: validate(arrayOfType("FlowType")), }, }); defineType("UnionTypeAnnotation", { visitor: ["types"], - aliases: ["Flow"], + aliases: ["Flow", "FlowType"], fields: { - // todo + types: validate(arrayOfType("FlowType")), }, }); defineType("VoidTypeAnnotation", { - aliases: ["Flow", "FlowBaseAnnotation"], - fields: { - // todo - }, + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"], }); diff --git a/packages/babel-types/src/definitions/typescript.js b/packages/babel-types/src/definitions/typescript.js index 796a4e1d24..8f4ff25bda 100644 --- a/packages/babel-types/src/definitions/typescript.js +++ b/packages/babel-types/src/definitions/typescript.js @@ -1,50 +1,22 @@ // @flow import defineType, { + arrayOfType, assertEach, assertNodeType, assertOneOf, assertValueType, chain, + validate, + validateArrayOfType, + validateOptional, + validateOptionalType, + validateType, } from "./utils"; import { functionDeclarationCommon } from "./core"; import { classMethodOrDeclareMethodCommon } from "./es2015"; const bool = assertValueType("boolean"); -function validate(validate) { - return { validate }; -} - -function typeIs(typeName) { - return typeof typeName === "string" - ? assertNodeType(typeName) - : assertNodeType(...typeName); -} - -function validateType(name) { - return validate(typeIs(name)); -} - -function validateOptional(validate) { - return { validate, optional: true }; -} - -function validateOptionalType(typeName) { - return { validate: typeIs(typeName), optional: true }; -} - -function arrayOf(elementType) { - return chain(assertValueType("array"), assertEach(elementType)); -} - -function arrayOfType(nodeTypeName) { - return arrayOf(typeIs(nodeTypeName)); -} - -function validateArrayOfType(nodeTypeName) { - return validate(arrayOfType(nodeTypeName)); -} - const tSFunctionTypeAnnotationCommon = { returnType: { validate: assertNodeType("TSTypeAnnotation", "Noop"), diff --git a/packages/babel-types/src/definitions/utils.js b/packages/babel-types/src/definitions/utils.js index 75aa6841d6..4fc52eef84 100644 --- a/packages/babel-types/src/definitions/utils.js +++ b/packages/babel-types/src/definitions/utils.js @@ -20,7 +20,52 @@ function getType(val) { } } -export function assertEach(callback: Function): Function { +// TODO: Import and use Node instead of any +opaque type Validator = (any, string, any) => void; + +type FieldOptions = { + default?: boolean, + optional?: boolean, + validate?: Validator, +}; + +export function validate(validate: Validator): FieldOptions { + return { validate }; +} + +export function typeIs(typeName: string | string[]) { + return typeof typeName === "string" + ? assertNodeType(typeName) + : assertNodeType(...typeName); +} + +export function validateType(typeName: string | string[]) { + return validate(typeIs(typeName)); +} + +export function validateOptional(validate: Validator): FieldOptions { + return { validate, optional: true }; +} + +export function validateOptionalType( + typeName: string | string[], +): FieldOptions { + return { validate: typeIs(typeName), optional: true }; +} + +export function arrayOf(elementType: Validator): Validator { + return chain(assertValueType("array"), assertEach(elementType)); +} + +export function arrayOfType(typeName: string | string[]) { + return arrayOf(typeIs(typeName)); +} + +export function validateArrayOfType(typeName: string | string[]) { + return validate(arrayOfType(typeName)); +} + +export function assertEach(callback: Validator): Validator { function validator(node, key, val) { if (!Array.isArray(val)) return; @@ -32,7 +77,7 @@ export function assertEach(callback: Function): Function { return validator; } -export function assertOneOf(...values: Array): Function { +export function assertOneOf(...values: Array): Validator { function validate(node: Object, key: string, val: any) { if (values.indexOf(val) < 0) { throw new TypeError( @@ -48,7 +93,7 @@ export function assertOneOf(...values: Array): Function { return validate; } -export function assertNodeType(...types: Array): Function { +export function assertNodeType(...types: Array): Validator { function validate(node, key, val) { let valid = false; @@ -74,7 +119,7 @@ export function assertNodeType(...types: Array): Function { return validate; } -export function assertNodeOrValueType(...types: Array): Function { +export function assertNodeOrValueType(...types: Array): Validator { function validate(node, key, val) { let valid = false; @@ -100,7 +145,7 @@ export function assertNodeOrValueType(...types: Array): Function { return validate; } -export function assertValueType(type: string): Function { +export function assertValueType(type: string): Validator { function validate(node, key, val) { const valid = getType(val) === type; @@ -116,7 +161,7 @@ export function assertValueType(type: string): Function { return validate; } -export function chain(...fns: Array): Function { +export function chain(...fns: Array): Validator { function validate(...args) { for (const fn of fns) { fn(...args); @@ -130,7 +175,7 @@ export default function defineType( type: string, opts: { fields?: { - [string]: {| validate?: Function, default?: any, optional?: boolean |}, + [string]: FieldOptions, }, visitor?: Array, aliases?: Array, diff --git a/packages/babel-types/src/validators/generated/index.js b/packages/babel-types/src/validators/generated/index.js index bae197505a..ef11ea0629 100644 --- a/packages/babel-types/src/validators/generated/index.js +++ b/packages/babel-types/src/validators/generated/index.js @@ -788,6 +788,9 @@ export function isModuleSpecifier(node: Object, opts?: Object): boolean { export function isFlow(node: Object, opts?: Object): boolean { return is("Flow", node, opts); } +export function isFlowType(node: Object, opts?: Object): boolean { + return is("FlowType", node, opts); +} export function isFlowBaseAnnotation(node: Object, opts?: Object): boolean { return is("FlowBaseAnnotation", node, opts); }