From c6e68c732543894024e60b24cf2328fed02e938a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Mon, 9 May 2022 14:20:10 -0400 Subject: [PATCH] @babel/types builder improvements (#14519) * improve deprecated builders generation * generate builders instead of dynamically doing it * use default parameters in builder function arguments * fix deprecated builders * optimize: use shorthand if applicable * Mark BaseNode properties as optional They are generated by `@babel/parser` but not returned from types builder * chore: improve types * revert cloneNode changes * fix: assign optional value when default is non-null * optimize: skip validateNode when builder keys are empty * fix: set default value of objectTypeAnnotation.indexers/callProperties/internalSlots to [] null has been excluded by validate: arrayOfType * remove unused builder * fix deprecated types builder typings * simplify builders * return validated in validateNode * merge intermediate node declaration * review comments Co-authored-by: Bogdan Savluk --- .../src/transformer-2021-12.ts | 4 +- .../scripts/generators/ast-types.js | 12 +- .../scripts/generators/builders.js | 67 +- .../src/ast-types/generated/index.ts | 18 +- packages/babel-types/src/builders/builder.ts | 37 - .../src/builders/generated/index.ts | 1775 +++++++++++++---- .../babel-types/src/builders/validateNode.ts | 12 + packages/babel-types/src/definitions/flow.ts | 6 +- .../__snapshots__/templateElement.js.snap | 2 +- .../builders/typescript/tsTypeParameter.js | 2 +- 10 files changed, 1452 insertions(+), 483 deletions(-) delete mode 100644 packages/babel-types/src/builders/builder.ts create mode 100644 packages/babel-types/src/builders/validateNode.ts diff --git a/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts b/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts index 84ddad225725..ed478e3ebee6 100644 --- a/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts +++ b/packages/babel-plugin-proposal-decorators/src/transformer-2021-12.ts @@ -4,7 +4,7 @@ import syntaxDecorators from "@babel/plugin-syntax-decorators"; import ReplaceSupers from "@babel/helper-replace-supers"; import splitExportDeclaration from "@babel/helper-split-export-declaration"; import * as charCodes from "charcodes"; -import type { PluginAPI, PluginObject } from "@babel/core"; +import type { PluginAPI, PluginObject, PluginPass } from "@babel/core"; import type { Options } from ".."; type ClassDecoratableElement = @@ -482,7 +482,7 @@ function maybeSequenceExpression(exprs: t.Expression[]) { function transformClass( path: NodePath, - state: any, + state: PluginPass, constantSuper: boolean, ): NodePath { const body = path.get("body.body"); diff --git a/packages/babel-types/scripts/generators/ast-types.js b/packages/babel-types/scripts/generators/ast-types.js index 3bf42869f127..49b67bba38a8 100644 --- a/packages/babel-types/scripts/generators/ast-types.js +++ b/packages/babel-types/scripts/generators/ast-types.js @@ -36,13 +36,13 @@ export interface SourceLocation { } interface BaseNode { - leadingComments: ReadonlyArray | null; - innerComments: ReadonlyArray | null; - trailingComments: ReadonlyArray | null; - start: number | null; - end: number | null; - loc: SourceLocation | null; type: Node["type"]; + leadingComments?: ReadonlyArray | null; + innerComments?: ReadonlyArray | null; + trailingComments?: ReadonlyArray | null; + start?: number | null; + end?: number | null; + loc?: SourceLocation | null; range?: [number, number]; extra?: Record; } diff --git a/packages/babel-types/scripts/generators/builders.js b/packages/babel-types/scripts/generators/builders.js index 13e772eb43d0..0576b8b72eca 100644 --- a/packages/babel-types/scripts/generators/builders.js +++ b/packages/babel-types/scripts/generators/builders.js @@ -51,20 +51,23 @@ function generateBuilderArgs(type) { } if (builderNames.includes(fieldName)) { + const field = definitions.NODE_FIELDS[type][fieldName]; + const def = JSON.stringify(field.default); const bindingIdentifierName = t.toBindingIdentifierName(fieldName); + let arg; if (areAllRemainingFieldsNullable(fieldName, builderNames, fields)) { - args.push( - `${bindingIdentifierName}${ - isNullable(field) ? "?:" : ":" - } ${typeAnnotation}` - ); + arg = `${bindingIdentifierName}${ + isNullable(field) && !def ? "?:" : ":" + } ${typeAnnotation}`; } else { - args.push( - `${bindingIdentifierName}: ${typeAnnotation}${ - isNullable(field) ? " | undefined" : "" - }` - ); + arg = `${bindingIdentifierName}: ${typeAnnotation}${ + isNullable(field) ? " | undefined" : "" + }`; } + if (def !== "null" || isNullable(field)) { + arg += `= ${def}`; + } + args.push(arg); } }); @@ -82,11 +85,8 @@ function generateLowercaseBuilders() { * This file is auto-generated! Do not modify it directly. * To re-generate run 'make build' */ -import builder from "../builder"; +import validateNode from "../validateNode"; import type * as t from "../.."; - -/* eslint-disable @typescript-eslint/no-unused-vars */ - `; const reservedNames = new Set(["super", "import"]); @@ -96,11 +96,39 @@ import type * as t from "../.."; const formatedBuilderNameLocal = reservedNames.has(formatedBuilderName) ? `_${formatedBuilderName}` : formatedBuilderName; + + const fieldNames = sortFieldNames( + Object.keys(definitions.NODE_FIELDS[type]), + type + ); + const builderNames = definitions.BUILDER_KEYS[type]; + const objectFields = [["type", JSON.stringify(type)]]; + fieldNames.forEach(fieldName => { + const field = definitions.NODE_FIELDS[type][fieldName]; + if (builderNames.includes(fieldName)) { + const bindingIdentifierName = t.toBindingIdentifierName(fieldName); + objectFields.push([fieldName, bindingIdentifierName]); + } else if (!field.optional) { + const def = JSON.stringify(field.default); + objectFields.push([fieldName, def]); + } + }); + output += `${ formatedBuilderNameLocal === formatedBuilderName ? "export " : "" - }function ${formatedBuilderNameLocal}(${defArgs.join( - ", " - )}): t.${type} { return builder.apply("${type}", arguments); }\n`; + }function ${formatedBuilderNameLocal}(${defArgs.join(", ")}): t.${type} {`; + + const nodeObjectExpression = `{\n${objectFields + .map(([k, v]) => (k === v ? ` ${k},` : ` ${k}: ${v},`)) + .join("\n")}\n }`; + + if (builderNames.length > 0) { + output += `\n return validateNode(${nodeObjectExpression});`; + } else { + output += `\n return ${nodeObjectExpression};`; + } + output += `\n}\n`; + if (formatedBuilderNameLocal !== formatedBuilderName) { output += `export { ${formatedBuilderNameLocal} as ${formatedBuilderName} };\n`; } @@ -118,10 +146,11 @@ import type * as t from "../.."; Object.keys(definitions.DEPRECATED_KEYS).forEach(type => { const newType = definitions.DEPRECATED_KEYS[type]; const formatedBuilderName = formatBuilderName(type); + const formatedNewBuilderName = formatBuilderName(newType); output += `/** @deprecated */ -function ${type}(${generateBuilderArgs(newType).join(", ")}): t.${type} { +function ${type}(${generateBuilderArgs(newType).join(", ")}) { console.trace("The node type ${type} has been renamed to ${newType}"); - return builder.apply("${type}", arguments); + return ${formatedNewBuilderName}(${t.BUILDER_KEYS[newType].join(", ")}); } export { ${type} as ${formatedBuilderName} };\n`; // This is needed for backwards compatibility. diff --git a/packages/babel-types/src/ast-types/generated/index.ts b/packages/babel-types/src/ast-types/generated/index.ts index c29254a26672..82c9b2fd6bf0 100644 --- a/packages/babel-types/src/ast-types/generated/index.ts +++ b/packages/babel-types/src/ast-types/generated/index.ts @@ -32,13 +32,13 @@ export interface SourceLocation { } interface BaseNode { - leadingComments: ReadonlyArray | null; - innerComments: ReadonlyArray | null; - trailingComments: ReadonlyArray | null; - start: number | null; - end: number | null; - loc: SourceLocation | null; type: Node["type"]; + leadingComments?: ReadonlyArray | null; + innerComments?: ReadonlyArray | null; + trailingComments?: ReadonlyArray | null; + start?: number | null; + end?: number | null; + loc?: SourceLocation | null; range?: [number, number]; extra?: Record; } @@ -1253,9 +1253,9 @@ export interface NumberTypeAnnotation extends BaseNode { export interface ObjectTypeAnnotation extends BaseNode { type: "ObjectTypeAnnotation"; properties: Array; - indexers?: Array | null; - callProperties?: Array | null; - internalSlots?: Array | null; + indexers?: Array; + callProperties?: Array; + internalSlots?: Array; exact: boolean; inexact?: boolean | null; } diff --git a/packages/babel-types/src/builders/builder.ts b/packages/babel-types/src/builders/builder.ts deleted file mode 100644 index 26ae3ffda4a9..000000000000 --- a/packages/babel-types/src/builders/builder.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { NODE_FIELDS, BUILDER_KEYS } from "../definitions"; -import validate from "../validators/validate"; -import type * as t from ".."; - -export default function builder(this: T["type"]): T { - const type = this; - const keys = BUILDER_KEYS[type]; - const countArgs = arguments.length; - if (countArgs > keys.length) { - throw new Error( - `${type}: Too many arguments passed. Received ${countArgs} but can receive no more than ${keys.length}`, - ); - } - - const node = { type }; - - for (let i = 0; i < keys.length; ++i) { - const key = keys[i]; - const field = NODE_FIELDS[type][key]; - - let arg; - if (i < countArgs) arg = arguments[i]; - if (arg === undefined) { - arg = Array.isArray(field.default) ? [] : field.default; - } - - node[key] = arg; - } - - // (assume all enumerable properties are own) - // eslint-disable-next-line guard-for-in - for (const key in node) { - validate(node as t.Node, key, node[key]); - } - - return node as T; -} diff --git a/packages/babel-types/src/builders/generated/index.ts b/packages/babel-types/src/builders/generated/index.ts index e0573e9d6bf2..c837d08c24bb 100644 --- a/packages/babel-types/src/builders/generated/index.ts +++ b/packages/babel-types/src/builders/generated/index.ts @@ -2,22 +2,27 @@ * This file is auto-generated! Do not modify it directly. * To re-generate run 'make build' */ -import builder from "../builder"; +import validateNode from "../validateNode"; import type * as t from "../.."; - -/* eslint-disable @typescript-eslint/no-unused-vars */ - export function arrayExpression( - elements?: Array, + elements: Array = [], ): t.ArrayExpression { - return builder.apply("ArrayExpression", arguments); + return validateNode({ + type: "ArrayExpression", + elements, + }); } export function assignmentExpression( operator: string, left: t.LVal, right: t.Expression, ): t.AssignmentExpression { - return builder.apply("AssignmentExpression", arguments); + return validateNode({ + type: "AssignmentExpression", + operator, + left, + right, + }); } export function binaryExpression( operator: @@ -47,25 +52,48 @@ export function binaryExpression( left: t.Expression | t.PrivateName, right: t.Expression, ): t.BinaryExpression { - return builder.apply("BinaryExpression", arguments); + return validateNode({ + type: "BinaryExpression", + operator, + left, + right, + }); } export function interpreterDirective(value: string): t.InterpreterDirective { - return builder.apply("InterpreterDirective", arguments); + return validateNode({ + type: "InterpreterDirective", + value, + }); } export function directive(value: t.DirectiveLiteral): t.Directive { - return builder.apply("Directive", arguments); + return validateNode({ + type: "Directive", + value, + }); } export function directiveLiteral(value: string): t.DirectiveLiteral { - return builder.apply("DirectiveLiteral", arguments); + return validateNode({ + type: "DirectiveLiteral", + value, + }); } export function blockStatement( body: Array, - directives?: Array, + directives: Array = [], ): t.BlockStatement { - return builder.apply("BlockStatement", arguments); -} -export function breakStatement(label?: t.Identifier | null): t.BreakStatement { - return builder.apply("BreakStatement", arguments); + return validateNode({ + type: "BlockStatement", + body, + directives, + }); +} +export function breakStatement( + label: t.Identifier | null = null, +): t.BreakStatement { + return validateNode({ + type: "BreakStatement", + label, + }); } export function callExpression( callee: t.Expression | t.V8IntrinsicIdentifier, @@ -73,131 +101,231 @@ export function callExpression( t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder >, ): t.CallExpression { - return builder.apply("CallExpression", arguments); + return validateNode({ + type: "CallExpression", + callee, + arguments: _arguments, + }); } export function catchClause( - param: t.Identifier | t.ArrayPattern | t.ObjectPattern | null | undefined, + param: + | t.Identifier + | t.ArrayPattern + | t.ObjectPattern + | null + | undefined = null, body: t.BlockStatement, ): t.CatchClause { - return builder.apply("CatchClause", arguments); + return validateNode({ + type: "CatchClause", + param, + body, + }); } export function conditionalExpression( test: t.Expression, consequent: t.Expression, alternate: t.Expression, ): t.ConditionalExpression { - return builder.apply("ConditionalExpression", arguments); + return validateNode({ + type: "ConditionalExpression", + test, + consequent, + alternate, + }); } export function continueStatement( - label?: t.Identifier | null, + label: t.Identifier | null = null, ): t.ContinueStatement { - return builder.apply("ContinueStatement", arguments); + return validateNode({ + type: "ContinueStatement", + label, + }); } export function debuggerStatement(): t.DebuggerStatement { - return builder.apply("DebuggerStatement", arguments); + return { + type: "DebuggerStatement", + }; } export function doWhileStatement( test: t.Expression, body: t.Statement, ): t.DoWhileStatement { - return builder.apply("DoWhileStatement", arguments); + return validateNode({ + type: "DoWhileStatement", + test, + body, + }); } export function emptyStatement(): t.EmptyStatement { - return builder.apply("EmptyStatement", arguments); + return { + type: "EmptyStatement", + }; } export function expressionStatement( expression: t.Expression, ): t.ExpressionStatement { - return builder.apply("ExpressionStatement", arguments); + return validateNode({ + type: "ExpressionStatement", + expression, + }); } export function file( program: t.Program, - comments?: Array | null, - tokens?: Array | null, + comments: Array | null = null, + tokens: Array | null = null, ): t.File { - return builder.apply("File", arguments); + return validateNode({ + type: "File", + program, + comments, + tokens, + }); } export function forInStatement( left: t.VariableDeclaration | t.LVal, right: t.Expression, body: t.Statement, ): t.ForInStatement { - return builder.apply("ForInStatement", arguments); + return validateNode({ + type: "ForInStatement", + left, + right, + body, + }); } export function forStatement( - init: t.VariableDeclaration | t.Expression | null | undefined, - test: t.Expression | null | undefined, - update: t.Expression | null | undefined, + init: t.VariableDeclaration | t.Expression | null | undefined = null, + test: t.Expression | null | undefined = null, + update: t.Expression | null | undefined = null, body: t.Statement, ): t.ForStatement { - return builder.apply("ForStatement", arguments); + return validateNode({ + type: "ForStatement", + init, + test, + update, + body, + }); } export function functionDeclaration( - id: t.Identifier | null | undefined, + id: t.Identifier | null | undefined = null, params: Array, body: t.BlockStatement, - generator?: boolean, - async?: boolean, + generator: boolean = false, + async: boolean = false, ): t.FunctionDeclaration { - return builder.apply("FunctionDeclaration", arguments); + return validateNode({ + type: "FunctionDeclaration", + id, + params, + body, + generator, + async, + }); } export function functionExpression( - id: t.Identifier | null | undefined, + id: t.Identifier | null | undefined = null, params: Array, body: t.BlockStatement, - generator?: boolean, - async?: boolean, + generator: boolean = false, + async: boolean = false, ): t.FunctionExpression { - return builder.apply("FunctionExpression", arguments); + return validateNode({ + type: "FunctionExpression", + id, + params, + body, + generator, + async, + }); } export function identifier(name: string): t.Identifier { - return builder.apply("Identifier", arguments); + return validateNode({ + type: "Identifier", + name, + }); } export function ifStatement( test: t.Expression, consequent: t.Statement, - alternate?: t.Statement | null, + alternate: t.Statement | null = null, ): t.IfStatement { - return builder.apply("IfStatement", arguments); + return validateNode({ + type: "IfStatement", + test, + consequent, + alternate, + }); } export function labeledStatement( label: t.Identifier, body: t.Statement, ): t.LabeledStatement { - return builder.apply("LabeledStatement", arguments); + return validateNode({ + type: "LabeledStatement", + label, + body, + }); } export function stringLiteral(value: string): t.StringLiteral { - return builder.apply("StringLiteral", arguments); + return validateNode({ + type: "StringLiteral", + value, + }); } export function numericLiteral(value: number): t.NumericLiteral { - return builder.apply("NumericLiteral", arguments); + return validateNode({ + type: "NumericLiteral", + value, + }); } export function nullLiteral(): t.NullLiteral { - return builder.apply("NullLiteral", arguments); + return { + type: "NullLiteral", + }; } export function booleanLiteral(value: boolean): t.BooleanLiteral { - return builder.apply("BooleanLiteral", arguments); + return validateNode({ + type: "BooleanLiteral", + value, + }); } export function regExpLiteral( pattern: string, - flags?: string, + flags: string = "", ): t.RegExpLiteral { - return builder.apply("RegExpLiteral", arguments); + return validateNode({ + type: "RegExpLiteral", + pattern, + flags, + }); } export function logicalExpression( operator: "||" | "&&" | "??", left: t.Expression, right: t.Expression, ): t.LogicalExpression { - return builder.apply("LogicalExpression", arguments); + return validateNode({ + type: "LogicalExpression", + operator, + left, + right, + }); } export function memberExpression( object: t.Expression, property: t.Expression | t.Identifier | t.PrivateName, - computed?: boolean, - optional?: true | false | null, + computed: boolean = false, + optional: true | false | null = null, ): t.MemberExpression { - return builder.apply("MemberExpression", arguments); + return validateNode({ + type: "MemberExpression", + object, + property, + computed, + optional, + }); } export function newExpression( callee: t.Expression | t.V8IntrinsicIdentifier, @@ -205,121 +333,207 @@ export function newExpression( t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder >, ): t.NewExpression { - return builder.apply("NewExpression", arguments); + return validateNode({ + type: "NewExpression", + callee, + arguments: _arguments, + }); } export function program( body: Array, - directives?: Array, - sourceType?: "script" | "module", - interpreter?: t.InterpreterDirective | null, + directives: Array = [], + sourceType: "script" | "module" = "script", + interpreter: t.InterpreterDirective | null = null, ): t.Program { - return builder.apply("Program", arguments); + return validateNode({ + type: "Program", + body, + directives, + sourceType, + interpreter, + sourceFile: null, + }); } export function objectExpression( properties: Array, ): t.ObjectExpression { - return builder.apply("ObjectExpression", arguments); + return validateNode({ + type: "ObjectExpression", + properties, + }); } export function objectMethod( - kind: "method" | "get" | "set" | undefined, + kind: "method" | "get" | "set" | undefined = "method", key: t.Expression | t.Identifier | t.StringLiteral | t.NumericLiteral, params: Array, body: t.BlockStatement, - computed?: boolean, - generator?: boolean, - async?: boolean, + computed: boolean = false, + generator: boolean = false, + async: boolean = false, ): t.ObjectMethod { - return builder.apply("ObjectMethod", arguments); + return validateNode({ + type: "ObjectMethod", + kind, + key, + params, + body, + computed, + generator, + async, + }); } export function objectProperty( key: t.Expression | t.Identifier | t.StringLiteral | t.NumericLiteral, value: t.Expression | t.PatternLike, - computed?: boolean, - shorthand?: boolean, - decorators?: Array | null, + computed: boolean = false, + shorthand: boolean = false, + decorators: Array | null = null, ): t.ObjectProperty { - return builder.apply("ObjectProperty", arguments); + return validateNode({ + type: "ObjectProperty", + key, + value, + computed, + shorthand, + decorators, + }); } export function restElement(argument: t.LVal): t.RestElement { - return builder.apply("RestElement", arguments); + return validateNode({ + type: "RestElement", + argument, + }); } export function returnStatement( - argument?: t.Expression | null, + argument: t.Expression | null = null, ): t.ReturnStatement { - return builder.apply("ReturnStatement", arguments); + return validateNode({ + type: "ReturnStatement", + argument, + }); } export function sequenceExpression( expressions: Array, ): t.SequenceExpression { - return builder.apply("SequenceExpression", arguments); + return validateNode({ + type: "SequenceExpression", + expressions, + }); } export function parenthesizedExpression( expression: t.Expression, ): t.ParenthesizedExpression { - return builder.apply("ParenthesizedExpression", arguments); + return validateNode({ + type: "ParenthesizedExpression", + expression, + }); } export function switchCase( - test: t.Expression | null | undefined, + test: t.Expression | null | undefined = null, consequent: Array, ): t.SwitchCase { - return builder.apply("SwitchCase", arguments); + return validateNode({ + type: "SwitchCase", + test, + consequent, + }); } export function switchStatement( discriminant: t.Expression, cases: Array, ): t.SwitchStatement { - return builder.apply("SwitchStatement", arguments); + return validateNode({ + type: "SwitchStatement", + discriminant, + cases, + }); } export function thisExpression(): t.ThisExpression { - return builder.apply("ThisExpression", arguments); + return { + type: "ThisExpression", + }; } export function throwStatement(argument: t.Expression): t.ThrowStatement { - return builder.apply("ThrowStatement", arguments); + return validateNode({ + type: "ThrowStatement", + argument, + }); } export function tryStatement( block: t.BlockStatement, - handler?: t.CatchClause | null, - finalizer?: t.BlockStatement | null, + handler: t.CatchClause | null = null, + finalizer: t.BlockStatement | null = null, ): t.TryStatement { - return builder.apply("TryStatement", arguments); + return validateNode({ + type: "TryStatement", + block, + handler, + finalizer, + }); } export function unaryExpression( operator: "void" | "throw" | "delete" | "!" | "+" | "-" | "~" | "typeof", argument: t.Expression, - prefix?: boolean, + prefix: boolean = true, ): t.UnaryExpression { - return builder.apply("UnaryExpression", arguments); + return validateNode({ + type: "UnaryExpression", + operator, + argument, + prefix, + }); } export function updateExpression( operator: "++" | "--", argument: t.Expression, - prefix?: boolean, + prefix: boolean = false, ): t.UpdateExpression { - return builder.apply("UpdateExpression", arguments); + return validateNode({ + type: "UpdateExpression", + operator, + argument, + prefix, + }); } export function variableDeclaration( kind: "var" | "let" | "const", declarations: Array, ): t.VariableDeclaration { - return builder.apply("VariableDeclaration", arguments); + return validateNode({ + type: "VariableDeclaration", + kind, + declarations, + }); } export function variableDeclarator( id: t.LVal, - init?: t.Expression | null, + init: t.Expression | null = null, ): t.VariableDeclarator { - return builder.apply("VariableDeclarator", arguments); + return validateNode({ + type: "VariableDeclarator", + id, + init, + }); } export function whileStatement( test: t.Expression, body: t.Statement, ): t.WhileStatement { - return builder.apply("WhileStatement", arguments); + return validateNode({ + type: "WhileStatement", + test, + body, + }); } export function withStatement( object: t.Expression, body: t.Statement, ): t.WithStatement { - return builder.apply("WithStatement", arguments); + return validateNode({ + type: "WithStatement", + object, + body, + }); } export function assignmentPattern( left: @@ -332,19 +546,32 @@ export function assignmentPattern( | t.TSNonNullExpression, right: t.Expression, ): t.AssignmentPattern { - return builder.apply("AssignmentPattern", arguments); + return validateNode({ + type: "AssignmentPattern", + left, + right, + }); } export function arrayPattern( elements: Array, ): t.ArrayPattern { - return builder.apply("ArrayPattern", arguments); + return validateNode({ + type: "ArrayPattern", + elements, + }); } export function arrowFunctionExpression( params: Array, body: t.BlockStatement | t.Expression, - async?: boolean, + async: boolean = false, ): t.ArrowFunctionExpression { - return builder.apply("ArrowFunctionExpression", arguments); + return validateNode({ + type: "ArrowFunctionExpression", + params, + body, + async, + expression: null, + }); } export function classBody( body: Array< @@ -358,28 +585,46 @@ export function classBody( | t.StaticBlock >, ): t.ClassBody { - return builder.apply("ClassBody", arguments); + return validateNode({ + type: "ClassBody", + body, + }); } export function classExpression( - id: t.Identifier | null | undefined, - superClass: t.Expression | null | undefined, + id: t.Identifier | null | undefined = null, + superClass: t.Expression | null | undefined = null, body: t.ClassBody, - decorators?: Array | null, + decorators: Array | null = null, ): t.ClassExpression { - return builder.apply("ClassExpression", arguments); + return validateNode({ + type: "ClassExpression", + id, + superClass, + body, + decorators, + }); } export function classDeclaration( id: t.Identifier, - superClass: t.Expression | null | undefined, + superClass: t.Expression | null | undefined = null, body: t.ClassBody, - decorators?: Array | null, + decorators: Array | null = null, ): t.ClassDeclaration { - return builder.apply("ClassDeclaration", arguments); + return validateNode({ + type: "ClassDeclaration", + id, + superClass, + body, + decorators, + }); } export function exportAllDeclaration( source: t.StringLiteral, ): t.ExportAllDeclaration { - return builder.apply("ExportAllDeclaration", arguments); + return validateNode({ + type: "ExportAllDeclaration", + source, + }); } export function exportDefaultDeclaration( declaration: @@ -388,30 +633,48 @@ export function exportDefaultDeclaration( | t.ClassDeclaration | t.Expression, ): t.ExportDefaultDeclaration { - return builder.apply("ExportDefaultDeclaration", arguments); + return validateNode({ + type: "ExportDefaultDeclaration", + declaration, + }); } export function exportNamedDeclaration( - declaration?: t.Declaration | null, - specifiers?: Array< + declaration: t.Declaration | null = null, + specifiers: Array< t.ExportSpecifier | t.ExportDefaultSpecifier | t.ExportNamespaceSpecifier - >, - source?: t.StringLiteral | null, + > = [], + source: t.StringLiteral | null = null, ): t.ExportNamedDeclaration { - return builder.apply("ExportNamedDeclaration", arguments); + return validateNode({ + type: "ExportNamedDeclaration", + declaration, + specifiers, + source, + }); } export function exportSpecifier( local: t.Identifier, exported: t.Identifier | t.StringLiteral, ): t.ExportSpecifier { - return builder.apply("ExportSpecifier", arguments); + return validateNode({ + type: "ExportSpecifier", + local, + exported, + }); } export function forOfStatement( left: t.VariableDeclaration | t.LVal, right: t.Expression, body: t.Statement, - _await?: boolean, + _await: boolean = false, ): t.ForOfStatement { - return builder.apply("ForOfStatement", arguments); + return validateNode({ + type: "ForOfStatement", + left, + right, + body, + await: _await, + }); } export function importDeclaration( specifiers: Array< @@ -419,102 +682,171 @@ export function importDeclaration( >, source: t.StringLiteral, ): t.ImportDeclaration { - return builder.apply("ImportDeclaration", arguments); + return validateNode({ + type: "ImportDeclaration", + specifiers, + source, + }); } export function importDefaultSpecifier( local: t.Identifier, ): t.ImportDefaultSpecifier { - return builder.apply("ImportDefaultSpecifier", arguments); + return validateNode({ + type: "ImportDefaultSpecifier", + local, + }); } export function importNamespaceSpecifier( local: t.Identifier, ): t.ImportNamespaceSpecifier { - return builder.apply("ImportNamespaceSpecifier", arguments); + return validateNode({ + type: "ImportNamespaceSpecifier", + local, + }); } export function importSpecifier( local: t.Identifier, imported: t.Identifier | t.StringLiteral, ): t.ImportSpecifier { - return builder.apply("ImportSpecifier", arguments); + return validateNode({ + type: "ImportSpecifier", + local, + imported, + }); } export function metaProperty( meta: t.Identifier, property: t.Identifier, ): t.MetaProperty { - return builder.apply("MetaProperty", arguments); + return validateNode({ + type: "MetaProperty", + meta, + property, + }); } export function classMethod( - kind: "get" | "set" | "method" | "constructor" | undefined, + kind: "get" | "set" | "method" | "constructor" | undefined = "method", key: t.Identifier | t.StringLiteral | t.NumericLiteral | t.Expression, params: Array< t.Identifier | t.Pattern | t.RestElement | t.TSParameterProperty >, body: t.BlockStatement, - computed?: boolean, - _static?: boolean, - generator?: boolean, - async?: boolean, + computed: boolean = false, + _static: boolean = false, + generator: boolean = false, + async: boolean = false, ): t.ClassMethod { - return builder.apply("ClassMethod", arguments); + return validateNode({ + type: "ClassMethod", + kind, + key, + params, + body, + computed, + static: _static, + generator, + async, + }); } export function objectPattern( properties: Array, ): t.ObjectPattern { - return builder.apply("ObjectPattern", arguments); + return validateNode({ + type: "ObjectPattern", + properties, + }); } export function spreadElement(argument: t.Expression): t.SpreadElement { - return builder.apply("SpreadElement", arguments); + return validateNode({ + type: "SpreadElement", + argument, + }); } function _super(): t.Super { - return builder.apply("Super", arguments); + return { + type: "Super", + }; } export { _super as super }; export function taggedTemplateExpression( tag: t.Expression, quasi: t.TemplateLiteral, ): t.TaggedTemplateExpression { - return builder.apply("TaggedTemplateExpression", arguments); + return validateNode({ + type: "TaggedTemplateExpression", + tag, + quasi, + }); } export function templateElement( value: { raw: string; cooked?: string }, - tail?: boolean, + tail: boolean = false, ): t.TemplateElement { - return builder.apply("TemplateElement", arguments); + return validateNode({ + type: "TemplateElement", + value, + tail, + }); } export function templateLiteral( quasis: Array, expressions: Array, ): t.TemplateLiteral { - return builder.apply("TemplateLiteral", arguments); + return validateNode({ + type: "TemplateLiteral", + quasis, + expressions, + }); } export function yieldExpression( - argument?: t.Expression | null, - delegate?: boolean, + argument: t.Expression | null = null, + delegate: boolean = false, ): t.YieldExpression { - return builder.apply("YieldExpression", arguments); + return validateNode({ + type: "YieldExpression", + argument, + delegate, + }); } export function awaitExpression(argument: t.Expression): t.AwaitExpression { - return builder.apply("AwaitExpression", arguments); + return validateNode({ + type: "AwaitExpression", + argument, + }); } function _import(): t.Import { - return builder.apply("Import", arguments); + return { + type: "Import", + }; } export { _import as import }; export function bigIntLiteral(value: string): t.BigIntLiteral { - return builder.apply("BigIntLiteral", arguments); + return validateNode({ + type: "BigIntLiteral", + value, + }); } export function exportNamespaceSpecifier( exported: t.Identifier, ): t.ExportNamespaceSpecifier { - return builder.apply("ExportNamespaceSpecifier", arguments); + return validateNode({ + type: "ExportNamespaceSpecifier", + exported, + }); } export function optionalMemberExpression( object: t.Expression, property: t.Expression | t.Identifier, - computed: boolean | undefined, + computed: boolean | undefined = false, optional: boolean, ): t.OptionalMemberExpression { - return builder.apply("OptionalMemberExpression", arguments); + return validateNode({ + type: "OptionalMemberExpression", + object, + property, + computed, + optional, + }); } export function optionalCallExpression( callee: t.Expression, @@ -523,17 +855,30 @@ export function optionalCallExpression( >, optional: boolean, ): t.OptionalCallExpression { - return builder.apply("OptionalCallExpression", arguments); + return validateNode({ + type: "OptionalCallExpression", + callee, + arguments: _arguments, + optional, + }); } export function classProperty( key: t.Identifier | t.StringLiteral | t.NumericLiteral | t.Expression, - value?: t.Expression | null, - typeAnnotation?: t.TypeAnnotation | t.TSTypeAnnotation | t.Noop | null, - decorators?: Array | null, - computed?: boolean, - _static?: boolean, + value: t.Expression | null = null, + typeAnnotation: t.TypeAnnotation | t.TSTypeAnnotation | t.Noop | null = null, + decorators: Array | null = null, + computed: boolean = false, + _static: boolean = false, ): t.ClassProperty { - return builder.apply("ClassProperty", arguments); + return validateNode({ + type: "ClassProperty", + key, + value, + typeAnnotation, + decorators, + computed, + static: _static, + }); } export function classAccessorProperty( key: @@ -542,205 +887,351 @@ export function classAccessorProperty( | t.NumericLiteral | t.Expression | t.PrivateName, - value?: t.Expression | null, - typeAnnotation?: t.TypeAnnotation | t.TSTypeAnnotation | t.Noop | null, - decorators?: Array | null, - computed?: boolean, - _static?: boolean, + value: t.Expression | null = null, + typeAnnotation: t.TypeAnnotation | t.TSTypeAnnotation | t.Noop | null = null, + decorators: Array | null = null, + computed: boolean = false, + _static: boolean = false, ): t.ClassAccessorProperty { - return builder.apply("ClassAccessorProperty", arguments); + return validateNode({ + type: "ClassAccessorProperty", + key, + value, + typeAnnotation, + decorators, + computed, + static: _static, + }); } export function classPrivateProperty( key: t.PrivateName, - value: t.Expression | null | undefined, - decorators: Array | null | undefined, + value: t.Expression | null | undefined = null, + decorators: Array | null | undefined = null, _static: any, ): t.ClassPrivateProperty { - return builder.apply("ClassPrivateProperty", arguments); + return validateNode({ + type: "ClassPrivateProperty", + key, + value, + decorators, + static: _static, + }); } export function classPrivateMethod( - kind: "get" | "set" | "method" | "constructor" | undefined, + kind: "get" | "set" | "method" | "constructor" | undefined = "method", key: t.PrivateName, params: Array< t.Identifier | t.Pattern | t.RestElement | t.TSParameterProperty >, body: t.BlockStatement, - _static?: boolean, + _static: boolean = false, ): t.ClassPrivateMethod { - return builder.apply("ClassPrivateMethod", arguments); + return validateNode({ + type: "ClassPrivateMethod", + kind, + key, + params, + body, + static: _static, + }); } export function privateName(id: t.Identifier): t.PrivateName { - return builder.apply("PrivateName", arguments); + return validateNode({ + type: "PrivateName", + id, + }); } export function staticBlock(body: Array): t.StaticBlock { - return builder.apply("StaticBlock", arguments); + return validateNode({ + type: "StaticBlock", + body, + }); } export function anyTypeAnnotation(): t.AnyTypeAnnotation { - return builder.apply("AnyTypeAnnotation", arguments); + return { + type: "AnyTypeAnnotation", + }; } export function arrayTypeAnnotation( elementType: t.FlowType, ): t.ArrayTypeAnnotation { - return builder.apply("ArrayTypeAnnotation", arguments); + return validateNode({ + type: "ArrayTypeAnnotation", + elementType, + }); } export function booleanTypeAnnotation(): t.BooleanTypeAnnotation { - return builder.apply("BooleanTypeAnnotation", arguments); + return { + type: "BooleanTypeAnnotation", + }; } export function booleanLiteralTypeAnnotation( value: boolean, ): t.BooleanLiteralTypeAnnotation { - return builder.apply("BooleanLiteralTypeAnnotation", arguments); + return validateNode({ + type: "BooleanLiteralTypeAnnotation", + value, + }); } export function nullLiteralTypeAnnotation(): t.NullLiteralTypeAnnotation { - return builder.apply("NullLiteralTypeAnnotation", arguments); + return { + type: "NullLiteralTypeAnnotation", + }; } export function classImplements( id: t.Identifier, - typeParameters?: t.TypeParameterInstantiation | null, + typeParameters: t.TypeParameterInstantiation | null = null, ): t.ClassImplements { - return builder.apply("ClassImplements", arguments); + return validateNode({ + type: "ClassImplements", + id, + typeParameters, + }); } export function declareClass( id: t.Identifier, - typeParameters: t.TypeParameterDeclaration | null | undefined, - _extends: Array | null | undefined, + typeParameters: t.TypeParameterDeclaration | null | undefined = null, + _extends: Array | null | undefined = null, body: t.ObjectTypeAnnotation, ): t.DeclareClass { - return builder.apply("DeclareClass", arguments); + return validateNode({ + type: "DeclareClass", + id, + typeParameters, + extends: _extends, + body, + }); } export function declareFunction(id: t.Identifier): t.DeclareFunction { - return builder.apply("DeclareFunction", arguments); + return validateNode({ + type: "DeclareFunction", + id, + }); } export function declareInterface( id: t.Identifier, - typeParameters: t.TypeParameterDeclaration | null | undefined, - _extends: Array | null | undefined, + typeParameters: t.TypeParameterDeclaration | null | undefined = null, + _extends: Array | null | undefined = null, body: t.ObjectTypeAnnotation, ): t.DeclareInterface { - return builder.apply("DeclareInterface", arguments); + return validateNode({ + type: "DeclareInterface", + id, + typeParameters, + extends: _extends, + body, + }); } export function declareModule( id: t.Identifier | t.StringLiteral, body: t.BlockStatement, - kind?: "CommonJS" | "ES" | null, + kind: "CommonJS" | "ES" | null = null, ): t.DeclareModule { - return builder.apply("DeclareModule", arguments); + return validateNode({ + type: "DeclareModule", + id, + body, + kind, + }); } export function declareModuleExports( typeAnnotation: t.TypeAnnotation, ): t.DeclareModuleExports { - return builder.apply("DeclareModuleExports", arguments); + return validateNode({ + type: "DeclareModuleExports", + typeAnnotation, + }); } export function declareTypeAlias( id: t.Identifier, - typeParameters: t.TypeParameterDeclaration | null | undefined, + typeParameters: t.TypeParameterDeclaration | null | undefined = null, right: t.FlowType, ): t.DeclareTypeAlias { - return builder.apply("DeclareTypeAlias", arguments); + return validateNode({ + type: "DeclareTypeAlias", + id, + typeParameters, + right, + }); } export function declareOpaqueType( id: t.Identifier, - typeParameters?: t.TypeParameterDeclaration | null, - supertype?: t.FlowType | null, + typeParameters: t.TypeParameterDeclaration | null = null, + supertype: t.FlowType | null = null, ): t.DeclareOpaqueType { - return builder.apply("DeclareOpaqueType", arguments); + return validateNode({ + type: "DeclareOpaqueType", + id, + typeParameters, + supertype, + }); } export function declareVariable(id: t.Identifier): t.DeclareVariable { - return builder.apply("DeclareVariable", arguments); + return validateNode({ + type: "DeclareVariable", + id, + }); } export function declareExportDeclaration( - declaration?: t.Flow | null, - specifiers?: Array | null, - source?: t.StringLiteral | null, + declaration: t.Flow | null = null, + specifiers: Array< + t.ExportSpecifier | t.ExportNamespaceSpecifier + > | null = null, + source: t.StringLiteral | null = null, ): t.DeclareExportDeclaration { - return builder.apply("DeclareExportDeclaration", arguments); + return validateNode({ + type: "DeclareExportDeclaration", + declaration, + specifiers, + source, + }); } export function declareExportAllDeclaration( source: t.StringLiteral, ): t.DeclareExportAllDeclaration { - return builder.apply("DeclareExportAllDeclaration", arguments); + return validateNode({ + type: "DeclareExportAllDeclaration", + source, + }); } export function declaredPredicate(value: t.Flow): t.DeclaredPredicate { - return builder.apply("DeclaredPredicate", arguments); + return validateNode({ + type: "DeclaredPredicate", + value, + }); } export function existsTypeAnnotation(): t.ExistsTypeAnnotation { - return builder.apply("ExistsTypeAnnotation", arguments); + return { + type: "ExistsTypeAnnotation", + }; } export function functionTypeAnnotation( - typeParameters: t.TypeParameterDeclaration | null | undefined, + typeParameters: t.TypeParameterDeclaration | null | undefined = null, params: Array, - rest: t.FunctionTypeParam | null | undefined, + rest: t.FunctionTypeParam | null | undefined = null, returnType: t.FlowType, ): t.FunctionTypeAnnotation { - return builder.apply("FunctionTypeAnnotation", arguments); + return validateNode({ + type: "FunctionTypeAnnotation", + typeParameters, + params, + rest, + returnType, + }); } export function functionTypeParam( - name: t.Identifier | null | undefined, + name: t.Identifier | null | undefined = null, typeAnnotation: t.FlowType, ): t.FunctionTypeParam { - return builder.apply("FunctionTypeParam", arguments); + return validateNode({ + type: "FunctionTypeParam", + name, + typeAnnotation, + }); } export function genericTypeAnnotation( id: t.Identifier | t.QualifiedTypeIdentifier, - typeParameters?: t.TypeParameterInstantiation | null, + typeParameters: t.TypeParameterInstantiation | null = null, ): t.GenericTypeAnnotation { - return builder.apply("GenericTypeAnnotation", arguments); + return validateNode({ + type: "GenericTypeAnnotation", + id, + typeParameters, + }); } export function inferredPredicate(): t.InferredPredicate { - return builder.apply("InferredPredicate", arguments); + return { + type: "InferredPredicate", + }; } export function interfaceExtends( id: t.Identifier | t.QualifiedTypeIdentifier, - typeParameters?: t.TypeParameterInstantiation | null, + typeParameters: t.TypeParameterInstantiation | null = null, ): t.InterfaceExtends { - return builder.apply("InterfaceExtends", arguments); + return validateNode({ + type: "InterfaceExtends", + id, + typeParameters, + }); } export function interfaceDeclaration( id: t.Identifier, - typeParameters: t.TypeParameterDeclaration | null | undefined, - _extends: Array | null | undefined, + typeParameters: t.TypeParameterDeclaration | null | undefined = null, + _extends: Array | null | undefined = null, body: t.ObjectTypeAnnotation, ): t.InterfaceDeclaration { - return builder.apply("InterfaceDeclaration", arguments); + return validateNode({ + type: "InterfaceDeclaration", + id, + typeParameters, + extends: _extends, + body, + }); } export function interfaceTypeAnnotation( - _extends: Array | null | undefined, + _extends: Array | null | undefined = null, body: t.ObjectTypeAnnotation, ): t.InterfaceTypeAnnotation { - return builder.apply("InterfaceTypeAnnotation", arguments); + return validateNode({ + type: "InterfaceTypeAnnotation", + extends: _extends, + body, + }); } export function intersectionTypeAnnotation( types: Array, ): t.IntersectionTypeAnnotation { - return builder.apply("IntersectionTypeAnnotation", arguments); + return validateNode({ + type: "IntersectionTypeAnnotation", + types, + }); } export function mixedTypeAnnotation(): t.MixedTypeAnnotation { - return builder.apply("MixedTypeAnnotation", arguments); + return { + type: "MixedTypeAnnotation", + }; } export function emptyTypeAnnotation(): t.EmptyTypeAnnotation { - return builder.apply("EmptyTypeAnnotation", arguments); + return { + type: "EmptyTypeAnnotation", + }; } export function nullableTypeAnnotation( typeAnnotation: t.FlowType, ): t.NullableTypeAnnotation { - return builder.apply("NullableTypeAnnotation", arguments); + return validateNode({ + type: "NullableTypeAnnotation", + typeAnnotation, + }); } export function numberLiteralTypeAnnotation( value: number, ): t.NumberLiteralTypeAnnotation { - return builder.apply("NumberLiteralTypeAnnotation", arguments); + return validateNode({ + type: "NumberLiteralTypeAnnotation", + value, + }); } export function numberTypeAnnotation(): t.NumberTypeAnnotation { - return builder.apply("NumberTypeAnnotation", arguments); + return { + type: "NumberTypeAnnotation", + }; } export function objectTypeAnnotation( properties: Array, - indexers?: Array | null, - callProperties?: Array | null, - internalSlots?: Array | null, - exact?: boolean, + indexers: Array = [], + callProperties: Array = [], + internalSlots: Array = [], + exact: boolean = false, ): t.ObjectTypeAnnotation { - return builder.apply("ObjectTypeAnnotation", arguments); + return validateNode({ + type: "ObjectTypeAnnotation", + properties, + indexers, + callProperties, + internalSlots, + exact, + }); } export function objectTypeInternalSlot( id: t.Identifier, @@ -749,114 +1240,202 @@ export function objectTypeInternalSlot( _static: boolean, method: boolean, ): t.ObjectTypeInternalSlot { - return builder.apply("ObjectTypeInternalSlot", arguments); + return validateNode({ + type: "ObjectTypeInternalSlot", + id, + value, + optional, + static: _static, + method, + }); } export function objectTypeCallProperty( value: t.FlowType, ): t.ObjectTypeCallProperty { - return builder.apply("ObjectTypeCallProperty", arguments); + return validateNode({ + type: "ObjectTypeCallProperty", + value, + static: null, + }); } export function objectTypeIndexer( - id: t.Identifier | null | undefined, + id: t.Identifier | null | undefined = null, key: t.FlowType, value: t.FlowType, - variance?: t.Variance | null, + variance: t.Variance | null = null, ): t.ObjectTypeIndexer { - return builder.apply("ObjectTypeIndexer", arguments); + return validateNode({ + type: "ObjectTypeIndexer", + id, + key, + value, + variance, + static: null, + }); } export function objectTypeProperty( key: t.Identifier | t.StringLiteral, value: t.FlowType, - variance?: t.Variance | null, + variance: t.Variance | null = null, ): t.ObjectTypeProperty { - return builder.apply("ObjectTypeProperty", arguments); + return validateNode({ + type: "ObjectTypeProperty", + key, + value, + variance, + kind: null, + method: null, + optional: null, + proto: null, + static: null, + }); } export function objectTypeSpreadProperty( argument: t.FlowType, ): t.ObjectTypeSpreadProperty { - return builder.apply("ObjectTypeSpreadProperty", arguments); + return validateNode({ + type: "ObjectTypeSpreadProperty", + argument, + }); } export function opaqueType( id: t.Identifier, - typeParameters: t.TypeParameterDeclaration | null | undefined, - supertype: t.FlowType | null | undefined, + typeParameters: t.TypeParameterDeclaration | null | undefined = null, + supertype: t.FlowType | null | undefined = null, impltype: t.FlowType, ): t.OpaqueType { - return builder.apply("OpaqueType", arguments); + return validateNode({ + type: "OpaqueType", + id, + typeParameters, + supertype, + impltype, + }); } export function qualifiedTypeIdentifier( id: t.Identifier, qualification: t.Identifier | t.QualifiedTypeIdentifier, ): t.QualifiedTypeIdentifier { - return builder.apply("QualifiedTypeIdentifier", arguments); + return validateNode({ + type: "QualifiedTypeIdentifier", + id, + qualification, + }); } export function stringLiteralTypeAnnotation( value: string, ): t.StringLiteralTypeAnnotation { - return builder.apply("StringLiteralTypeAnnotation", arguments); + return validateNode({ + type: "StringLiteralTypeAnnotation", + value, + }); } export function stringTypeAnnotation(): t.StringTypeAnnotation { - return builder.apply("StringTypeAnnotation", arguments); + return { + type: "StringTypeAnnotation", + }; } export function symbolTypeAnnotation(): t.SymbolTypeAnnotation { - return builder.apply("SymbolTypeAnnotation", arguments); + return { + type: "SymbolTypeAnnotation", + }; } export function thisTypeAnnotation(): t.ThisTypeAnnotation { - return builder.apply("ThisTypeAnnotation", arguments); + return { + type: "ThisTypeAnnotation", + }; } export function tupleTypeAnnotation( types: Array, ): t.TupleTypeAnnotation { - return builder.apply("TupleTypeAnnotation", arguments); + return validateNode({ + type: "TupleTypeAnnotation", + types, + }); } export function typeofTypeAnnotation( argument: t.FlowType, ): t.TypeofTypeAnnotation { - return builder.apply("TypeofTypeAnnotation", arguments); + return validateNode({ + type: "TypeofTypeAnnotation", + argument, + }); } export function typeAlias( id: t.Identifier, - typeParameters: t.TypeParameterDeclaration | null | undefined, + typeParameters: t.TypeParameterDeclaration | null | undefined = null, right: t.FlowType, ): t.TypeAlias { - return builder.apply("TypeAlias", arguments); + return validateNode({ + type: "TypeAlias", + id, + typeParameters, + right, + }); } export function typeAnnotation(typeAnnotation: t.FlowType): t.TypeAnnotation { - return builder.apply("TypeAnnotation", arguments); + return validateNode({ + type: "TypeAnnotation", + typeAnnotation, + }); } export function typeCastExpression( expression: t.Expression, typeAnnotation: t.TypeAnnotation, ): t.TypeCastExpression { - return builder.apply("TypeCastExpression", arguments); + return validateNode({ + type: "TypeCastExpression", + expression, + typeAnnotation, + }); } export function typeParameter( - bound?: t.TypeAnnotation | null, - _default?: t.FlowType | null, - variance?: t.Variance | null, + bound: t.TypeAnnotation | null = null, + _default: t.FlowType | null = null, + variance: t.Variance | null = null, ): t.TypeParameter { - return builder.apply("TypeParameter", arguments); + return validateNode({ + type: "TypeParameter", + bound, + default: _default, + variance, + name: null, + }); } export function typeParameterDeclaration( params: Array, ): t.TypeParameterDeclaration { - return builder.apply("TypeParameterDeclaration", arguments); + return validateNode({ + type: "TypeParameterDeclaration", + params, + }); } export function typeParameterInstantiation( params: Array, ): t.TypeParameterInstantiation { - return builder.apply("TypeParameterInstantiation", arguments); + return validateNode({ + type: "TypeParameterInstantiation", + params, + }); } export function unionTypeAnnotation( types: Array, ): t.UnionTypeAnnotation { - return builder.apply("UnionTypeAnnotation", arguments); + return validateNode({ + type: "UnionTypeAnnotation", + types, + }); } export function variance(kind: "minus" | "plus"): t.Variance { - return builder.apply("Variance", arguments); + return validateNode({ + type: "Variance", + kind, + }); } export function voidTypeAnnotation(): t.VoidTypeAnnotation { - return builder.apply("VoidTypeAnnotation", arguments); + return { + type: "VoidTypeAnnotation", + }; } export function enumDeclaration( id: t.Identifier, @@ -866,79 +1445,133 @@ export function enumDeclaration( | t.EnumStringBody | t.EnumSymbolBody, ): t.EnumDeclaration { - return builder.apply("EnumDeclaration", arguments); + return validateNode({ + type: "EnumDeclaration", + id, + body, + }); } export function enumBooleanBody( members: Array, ): t.EnumBooleanBody { - return builder.apply("EnumBooleanBody", arguments); + return validateNode({ + type: "EnumBooleanBody", + members, + explicitType: null, + hasUnknownMembers: null, + }); } export function enumNumberBody( members: Array, ): t.EnumNumberBody { - return builder.apply("EnumNumberBody", arguments); + return validateNode({ + type: "EnumNumberBody", + members, + explicitType: null, + hasUnknownMembers: null, + }); } export function enumStringBody( members: Array, ): t.EnumStringBody { - return builder.apply("EnumStringBody", arguments); + return validateNode({ + type: "EnumStringBody", + members, + explicitType: null, + hasUnknownMembers: null, + }); } export function enumSymbolBody( members: Array, ): t.EnumSymbolBody { - return builder.apply("EnumSymbolBody", arguments); + return validateNode({ + type: "EnumSymbolBody", + members, + hasUnknownMembers: null, + }); } export function enumBooleanMember(id: t.Identifier): t.EnumBooleanMember { - return builder.apply("EnumBooleanMember", arguments); + return validateNode({ + type: "EnumBooleanMember", + id, + init: null, + }); } export function enumNumberMember( id: t.Identifier, init: t.NumericLiteral, ): t.EnumNumberMember { - return builder.apply("EnumNumberMember", arguments); + return validateNode({ + type: "EnumNumberMember", + id, + init, + }); } export function enumStringMember( id: t.Identifier, init: t.StringLiteral, ): t.EnumStringMember { - return builder.apply("EnumStringMember", arguments); + return validateNode({ + type: "EnumStringMember", + id, + init, + }); } export function enumDefaultedMember(id: t.Identifier): t.EnumDefaultedMember { - return builder.apply("EnumDefaultedMember", arguments); + return validateNode({ + type: "EnumDefaultedMember", + id, + }); } export function indexedAccessType( objectType: t.FlowType, indexType: t.FlowType, ): t.IndexedAccessType { - return builder.apply("IndexedAccessType", arguments); + return validateNode({ + type: "IndexedAccessType", + objectType, + indexType, + }); } export function optionalIndexedAccessType( objectType: t.FlowType, indexType: t.FlowType, ): t.OptionalIndexedAccessType { - return builder.apply("OptionalIndexedAccessType", arguments); + return validateNode({ + type: "OptionalIndexedAccessType", + objectType, + indexType, + optional: null, + }); } export function jsxAttribute( name: t.JSXIdentifier | t.JSXNamespacedName, - value?: + value: | t.JSXElement | t.JSXFragment | t.StringLiteral | t.JSXExpressionContainer - | null, + | null = null, ): t.JSXAttribute { - return builder.apply("JSXAttribute", arguments); + return validateNode({ + type: "JSXAttribute", + name, + value, + }); } export { jsxAttribute as jSXAttribute }; export function jsxClosingElement( name: t.JSXIdentifier | t.JSXMemberExpression | t.JSXNamespacedName, ): t.JSXClosingElement { - return builder.apply("JSXClosingElement", arguments); + return validateNode({ + type: "JSXClosingElement", + name, + }); } export { jsxClosingElement as jSXClosingElement }; export function jsxElement( openingElement: t.JSXOpeningElement, - closingElement: t.JSXClosingElement | null | undefined, + closingElement: t.JSXClosingElement | null | undefined = null, children: Array< | t.JSXText | t.JSXExpressionContainer @@ -946,59 +1579,95 @@ export function jsxElement( | t.JSXElement | t.JSXFragment >, - selfClosing?: boolean | null, + selfClosing: boolean | null = null, ): t.JSXElement { - return builder.apply("JSXElement", arguments); + return validateNode({ + type: "JSXElement", + openingElement, + closingElement, + children, + selfClosing, + }); } export { jsxElement as jSXElement }; export function jsxEmptyExpression(): t.JSXEmptyExpression { - return builder.apply("JSXEmptyExpression", arguments); + return { + type: "JSXEmptyExpression", + }; } export { jsxEmptyExpression as jSXEmptyExpression }; export function jsxExpressionContainer( expression: t.Expression | t.JSXEmptyExpression, ): t.JSXExpressionContainer { - return builder.apply("JSXExpressionContainer", arguments); + return validateNode({ + type: "JSXExpressionContainer", + expression, + }); } export { jsxExpressionContainer as jSXExpressionContainer }; export function jsxSpreadChild(expression: t.Expression): t.JSXSpreadChild { - return builder.apply("JSXSpreadChild", arguments); + return validateNode({ + type: "JSXSpreadChild", + expression, + }); } export { jsxSpreadChild as jSXSpreadChild }; export function jsxIdentifier(name: string): t.JSXIdentifier { - return builder.apply("JSXIdentifier", arguments); + return validateNode({ + type: "JSXIdentifier", + name, + }); } export { jsxIdentifier as jSXIdentifier }; export function jsxMemberExpression( object: t.JSXMemberExpression | t.JSXIdentifier, property: t.JSXIdentifier, ): t.JSXMemberExpression { - return builder.apply("JSXMemberExpression", arguments); + return validateNode({ + type: "JSXMemberExpression", + object, + property, + }); } export { jsxMemberExpression as jSXMemberExpression }; export function jsxNamespacedName( namespace: t.JSXIdentifier, name: t.JSXIdentifier, ): t.JSXNamespacedName { - return builder.apply("JSXNamespacedName", arguments); + return validateNode({ + type: "JSXNamespacedName", + namespace, + name, + }); } export { jsxNamespacedName as jSXNamespacedName }; export function jsxOpeningElement( name: t.JSXIdentifier | t.JSXMemberExpression | t.JSXNamespacedName, attributes: Array, - selfClosing?: boolean, + selfClosing: boolean = false, ): t.JSXOpeningElement { - return builder.apply("JSXOpeningElement", arguments); + return validateNode({ + type: "JSXOpeningElement", + name, + attributes, + selfClosing, + }); } export { jsxOpeningElement as jSXOpeningElement }; export function jsxSpreadAttribute( argument: t.Expression, ): t.JSXSpreadAttribute { - return builder.apply("JSXSpreadAttribute", arguments); + return validateNode({ + type: "JSXSpreadAttribute", + argument, + }); } export { jsxSpreadAttribute as jSXSpreadAttribute }; export function jsxText(value: string): t.JSXText { - return builder.apply("JSXText", arguments); + return validateNode({ + type: "JSXText", + value, + }); } export { jsxText as jSXText }; export function jsxFragment( @@ -1012,19 +1681,30 @@ export function jsxFragment( | t.JSXFragment >, ): t.JSXFragment { - return builder.apply("JSXFragment", arguments); + return validateNode({ + type: "JSXFragment", + openingFragment, + closingFragment, + children, + }); } export { jsxFragment as jSXFragment }; export function jsxOpeningFragment(): t.JSXOpeningFragment { - return builder.apply("JSXOpeningFragment", arguments); + return { + type: "JSXOpeningFragment", + }; } export { jsxOpeningFragment as jSXOpeningFragment }; export function jsxClosingFragment(): t.JSXClosingFragment { - return builder.apply("JSXClosingFragment", arguments); + return { + type: "JSXClosingFragment", + }; } export { jsxClosingFragment as jSXClosingFragment }; export function noop(): t.Noop { - return builder.apply("Noop", arguments); + return { + type: "Noop", + }; } export function placeholder( expectedNode: @@ -1038,279 +1718,459 @@ export function placeholder( | "Pattern", name: t.Identifier, ): t.Placeholder { - return builder.apply("Placeholder", arguments); + return validateNode({ + type: "Placeholder", + expectedNode, + name, + }); } export function v8IntrinsicIdentifier(name: string): t.V8IntrinsicIdentifier { - return builder.apply("V8IntrinsicIdentifier", arguments); + return validateNode({ + type: "V8IntrinsicIdentifier", + name, + }); } export function argumentPlaceholder(): t.ArgumentPlaceholder { - return builder.apply("ArgumentPlaceholder", arguments); + return { + type: "ArgumentPlaceholder", + }; } export function bindExpression( object: t.Expression, callee: t.Expression, ): t.BindExpression { - return builder.apply("BindExpression", arguments); + return validateNode({ + type: "BindExpression", + object, + callee, + }); } export function importAttribute( key: t.Identifier | t.StringLiteral, value: t.StringLiteral, ): t.ImportAttribute { - return builder.apply("ImportAttribute", arguments); + return validateNode({ + type: "ImportAttribute", + key, + value, + }); } export function decorator(expression: t.Expression): t.Decorator { - return builder.apply("Decorator", arguments); + return validateNode({ + type: "Decorator", + expression, + }); } export function doExpression( body: t.BlockStatement, - async?: boolean, + async: boolean = false, ): t.DoExpression { - return builder.apply("DoExpression", arguments); + return validateNode({ + type: "DoExpression", + body, + async, + }); } export function exportDefaultSpecifier( exported: t.Identifier, ): t.ExportDefaultSpecifier { - return builder.apply("ExportDefaultSpecifier", arguments); + return validateNode({ + type: "ExportDefaultSpecifier", + exported, + }); } export function recordExpression( properties: Array, ): t.RecordExpression { - return builder.apply("RecordExpression", arguments); + return validateNode({ + type: "RecordExpression", + properties, + }); } export function tupleExpression( - elements?: Array, + elements: Array = [], ): t.TupleExpression { - return builder.apply("TupleExpression", arguments); + return validateNode({ + type: "TupleExpression", + elements, + }); } export function decimalLiteral(value: string): t.DecimalLiteral { - return builder.apply("DecimalLiteral", arguments); + return validateNode({ + type: "DecimalLiteral", + value, + }); } export function moduleExpression(body: t.Program): t.ModuleExpression { - return builder.apply("ModuleExpression", arguments); + return validateNode({ + type: "ModuleExpression", + body, + }); } export function topicReference(): t.TopicReference { - return builder.apply("TopicReference", arguments); + return { + type: "TopicReference", + }; } export function pipelineTopicExpression( expression: t.Expression, ): t.PipelineTopicExpression { - return builder.apply("PipelineTopicExpression", arguments); + return validateNode({ + type: "PipelineTopicExpression", + expression, + }); } export function pipelineBareFunction( callee: t.Expression, ): t.PipelineBareFunction { - return builder.apply("PipelineBareFunction", arguments); + return validateNode({ + type: "PipelineBareFunction", + callee, + }); } export function pipelinePrimaryTopicReference(): t.PipelinePrimaryTopicReference { - return builder.apply("PipelinePrimaryTopicReference", arguments); + return { + type: "PipelinePrimaryTopicReference", + }; } export function tsParameterProperty( parameter: t.Identifier | t.AssignmentPattern, ): t.TSParameterProperty { - return builder.apply("TSParameterProperty", arguments); + return validateNode({ + type: "TSParameterProperty", + parameter, + }); } export { tsParameterProperty as tSParameterProperty }; export function tsDeclareFunction( - id: t.Identifier | null | undefined, - typeParameters: t.TSTypeParameterDeclaration | t.Noop | null | undefined, + id: t.Identifier | null | undefined = null, + typeParameters: + | t.TSTypeParameterDeclaration + | t.Noop + | null + | undefined = null, params: Array, - returnType?: t.TSTypeAnnotation | t.Noop | null, + returnType: t.TSTypeAnnotation | t.Noop | null = null, ): t.TSDeclareFunction { - return builder.apply("TSDeclareFunction", arguments); + return validateNode({ + type: "TSDeclareFunction", + id, + typeParameters, + params, + returnType, + }); } export { tsDeclareFunction as tSDeclareFunction }; export function tsDeclareMethod( - decorators: Array | null | undefined, + decorators: Array | null | undefined = null, key: t.Identifier | t.StringLiteral | t.NumericLiteral | t.Expression, - typeParameters: t.TSTypeParameterDeclaration | t.Noop | null | undefined, + typeParameters: + | t.TSTypeParameterDeclaration + | t.Noop + | null + | undefined = null, params: Array< t.Identifier | t.Pattern | t.RestElement | t.TSParameterProperty >, - returnType?: t.TSTypeAnnotation | t.Noop | null, + returnType: t.TSTypeAnnotation | t.Noop | null = null, ): t.TSDeclareMethod { - return builder.apply("TSDeclareMethod", arguments); + return validateNode({ + type: "TSDeclareMethod", + decorators, + key, + typeParameters, + params, + returnType, + }); } export { tsDeclareMethod as tSDeclareMethod }; export function tsQualifiedName( left: t.TSEntityName, right: t.Identifier, ): t.TSQualifiedName { - return builder.apply("TSQualifiedName", arguments); + return validateNode({ + type: "TSQualifiedName", + left, + right, + }); } export { tsQualifiedName as tSQualifiedName }; export function tsCallSignatureDeclaration( - typeParameters: t.TSTypeParameterDeclaration | null | undefined, + typeParameters: t.TSTypeParameterDeclaration | null | undefined = null, parameters: Array, - typeAnnotation?: t.TSTypeAnnotation | null, + typeAnnotation: t.TSTypeAnnotation | null = null, ): t.TSCallSignatureDeclaration { - return builder.apply("TSCallSignatureDeclaration", arguments); + return validateNode({ + type: "TSCallSignatureDeclaration", + typeParameters, + parameters, + typeAnnotation, + }); } export { tsCallSignatureDeclaration as tSCallSignatureDeclaration }; export function tsConstructSignatureDeclaration( - typeParameters: t.TSTypeParameterDeclaration | null | undefined, + typeParameters: t.TSTypeParameterDeclaration | null | undefined = null, parameters: Array, - typeAnnotation?: t.TSTypeAnnotation | null, + typeAnnotation: t.TSTypeAnnotation | null = null, ): t.TSConstructSignatureDeclaration { - return builder.apply("TSConstructSignatureDeclaration", arguments); + return validateNode({ + type: "TSConstructSignatureDeclaration", + typeParameters, + parameters, + typeAnnotation, + }); } export { tsConstructSignatureDeclaration as tSConstructSignatureDeclaration }; export function tsPropertySignature( key: t.Expression, - typeAnnotation?: t.TSTypeAnnotation | null, - initializer?: t.Expression | null, + typeAnnotation: t.TSTypeAnnotation | null = null, + initializer: t.Expression | null = null, ): t.TSPropertySignature { - return builder.apply("TSPropertySignature", arguments); + return validateNode({ + type: "TSPropertySignature", + key, + typeAnnotation, + initializer, + kind: null, + }); } export { tsPropertySignature as tSPropertySignature }; export function tsMethodSignature( key: t.Expression, - typeParameters: t.TSTypeParameterDeclaration | null | undefined, + typeParameters: t.TSTypeParameterDeclaration | null | undefined = null, parameters: Array, - typeAnnotation?: t.TSTypeAnnotation | null, + typeAnnotation: t.TSTypeAnnotation | null = null, ): t.TSMethodSignature { - return builder.apply("TSMethodSignature", arguments); + return validateNode({ + type: "TSMethodSignature", + key, + typeParameters, + parameters, + typeAnnotation, + kind: null, + }); } export { tsMethodSignature as tSMethodSignature }; export function tsIndexSignature( parameters: Array, - typeAnnotation?: t.TSTypeAnnotation | null, + typeAnnotation: t.TSTypeAnnotation | null = null, ): t.TSIndexSignature { - return builder.apply("TSIndexSignature", arguments); + return validateNode({ + type: "TSIndexSignature", + parameters, + typeAnnotation, + }); } export { tsIndexSignature as tSIndexSignature }; export function tsAnyKeyword(): t.TSAnyKeyword { - return builder.apply("TSAnyKeyword", arguments); + return { + type: "TSAnyKeyword", + }; } export { tsAnyKeyword as tSAnyKeyword }; export function tsBooleanKeyword(): t.TSBooleanKeyword { - return builder.apply("TSBooleanKeyword", arguments); + return { + type: "TSBooleanKeyword", + }; } export { tsBooleanKeyword as tSBooleanKeyword }; export function tsBigIntKeyword(): t.TSBigIntKeyword { - return builder.apply("TSBigIntKeyword", arguments); + return { + type: "TSBigIntKeyword", + }; } export { tsBigIntKeyword as tSBigIntKeyword }; export function tsIntrinsicKeyword(): t.TSIntrinsicKeyword { - return builder.apply("TSIntrinsicKeyword", arguments); + return { + type: "TSIntrinsicKeyword", + }; } export { tsIntrinsicKeyword as tSIntrinsicKeyword }; export function tsNeverKeyword(): t.TSNeverKeyword { - return builder.apply("TSNeverKeyword", arguments); + return { + type: "TSNeverKeyword", + }; } export { tsNeverKeyword as tSNeverKeyword }; export function tsNullKeyword(): t.TSNullKeyword { - return builder.apply("TSNullKeyword", arguments); + return { + type: "TSNullKeyword", + }; } export { tsNullKeyword as tSNullKeyword }; export function tsNumberKeyword(): t.TSNumberKeyword { - return builder.apply("TSNumberKeyword", arguments); + return { + type: "TSNumberKeyword", + }; } export { tsNumberKeyword as tSNumberKeyword }; export function tsObjectKeyword(): t.TSObjectKeyword { - return builder.apply("TSObjectKeyword", arguments); + return { + type: "TSObjectKeyword", + }; } export { tsObjectKeyword as tSObjectKeyword }; export function tsStringKeyword(): t.TSStringKeyword { - return builder.apply("TSStringKeyword", arguments); + return { + type: "TSStringKeyword", + }; } export { tsStringKeyword as tSStringKeyword }; export function tsSymbolKeyword(): t.TSSymbolKeyword { - return builder.apply("TSSymbolKeyword", arguments); + return { + type: "TSSymbolKeyword", + }; } export { tsSymbolKeyword as tSSymbolKeyword }; export function tsUndefinedKeyword(): t.TSUndefinedKeyword { - return builder.apply("TSUndefinedKeyword", arguments); + return { + type: "TSUndefinedKeyword", + }; } export { tsUndefinedKeyword as tSUndefinedKeyword }; export function tsUnknownKeyword(): t.TSUnknownKeyword { - return builder.apply("TSUnknownKeyword", arguments); + return { + type: "TSUnknownKeyword", + }; } export { tsUnknownKeyword as tSUnknownKeyword }; export function tsVoidKeyword(): t.TSVoidKeyword { - return builder.apply("TSVoidKeyword", arguments); + return { + type: "TSVoidKeyword", + }; } export { tsVoidKeyword as tSVoidKeyword }; export function tsThisType(): t.TSThisType { - return builder.apply("TSThisType", arguments); + return { + type: "TSThisType", + }; } export { tsThisType as tSThisType }; export function tsFunctionType( - typeParameters: t.TSTypeParameterDeclaration | null | undefined, + typeParameters: t.TSTypeParameterDeclaration | null | undefined = null, parameters: Array, - typeAnnotation?: t.TSTypeAnnotation | null, + typeAnnotation: t.TSTypeAnnotation | null = null, ): t.TSFunctionType { - return builder.apply("TSFunctionType", arguments); + return validateNode({ + type: "TSFunctionType", + typeParameters, + parameters, + typeAnnotation, + }); } export { tsFunctionType as tSFunctionType }; export function tsConstructorType( - typeParameters: t.TSTypeParameterDeclaration | null | undefined, + typeParameters: t.TSTypeParameterDeclaration | null | undefined = null, parameters: Array, - typeAnnotation?: t.TSTypeAnnotation | null, + typeAnnotation: t.TSTypeAnnotation | null = null, ): t.TSConstructorType { - return builder.apply("TSConstructorType", arguments); + return validateNode({ + type: "TSConstructorType", + typeParameters, + parameters, + typeAnnotation, + }); } export { tsConstructorType as tSConstructorType }; export function tsTypeReference( typeName: t.TSEntityName, - typeParameters?: t.TSTypeParameterInstantiation | null, + typeParameters: t.TSTypeParameterInstantiation | null = null, ): t.TSTypeReference { - return builder.apply("TSTypeReference", arguments); + return validateNode({ + type: "TSTypeReference", + typeName, + typeParameters, + }); } export { tsTypeReference as tSTypeReference }; export function tsTypePredicate( parameterName: t.Identifier | t.TSThisType, - typeAnnotation?: t.TSTypeAnnotation | null, - asserts?: boolean | null, + typeAnnotation: t.TSTypeAnnotation | null = null, + asserts: boolean | null = null, ): t.TSTypePredicate { - return builder.apply("TSTypePredicate", arguments); + return validateNode({ + type: "TSTypePredicate", + parameterName, + typeAnnotation, + asserts, + }); } export { tsTypePredicate as tSTypePredicate }; export function tsTypeQuery( exprName: t.TSEntityName | t.TSImportType, ): t.TSTypeQuery { - return builder.apply("TSTypeQuery", arguments); + return validateNode({ + type: "TSTypeQuery", + exprName, + }); } export { tsTypeQuery as tSTypeQuery }; export function tsTypeLiteral( members: Array, ): t.TSTypeLiteral { - return builder.apply("TSTypeLiteral", arguments); + return validateNode({ + type: "TSTypeLiteral", + members, + }); } export { tsTypeLiteral as tSTypeLiteral }; export function tsArrayType(elementType: t.TSType): t.TSArrayType { - return builder.apply("TSArrayType", arguments); + return validateNode({ + type: "TSArrayType", + elementType, + }); } export { tsArrayType as tSArrayType }; export function tsTupleType( elementTypes: Array, ): t.TSTupleType { - return builder.apply("TSTupleType", arguments); + return validateNode({ + type: "TSTupleType", + elementTypes, + }); } export { tsTupleType as tSTupleType }; export function tsOptionalType(typeAnnotation: t.TSType): t.TSOptionalType { - return builder.apply("TSOptionalType", arguments); + return validateNode({ + type: "TSOptionalType", + typeAnnotation, + }); } export { tsOptionalType as tSOptionalType }; export function tsRestType(typeAnnotation: t.TSType): t.TSRestType { - return builder.apply("TSRestType", arguments); + return validateNode({ + type: "TSRestType", + typeAnnotation, + }); } export { tsRestType as tSRestType }; export function tsNamedTupleMember( label: t.Identifier, elementType: t.TSType, - optional?: boolean, + optional: boolean = false, ): t.TSNamedTupleMember { - return builder.apply("TSNamedTupleMember", arguments); + return validateNode({ + type: "TSNamedTupleMember", + label, + elementType, + optional, + }); } export { tsNamedTupleMember as tSNamedTupleMember }; export function tsUnionType(types: Array): t.TSUnionType { - return builder.apply("TSUnionType", arguments); + return validateNode({ + type: "TSUnionType", + types, + }); } export { tsUnionType as tSUnionType }; export function tsIntersectionType( types: Array, ): t.TSIntersectionType { - return builder.apply("TSIntersectionType", arguments); + return validateNode({ + type: "TSIntersectionType", + types, + }); } export { tsIntersectionType as tSIntersectionType }; export function tsConditionalType( @@ -1319,36 +2179,61 @@ export function tsConditionalType( trueType: t.TSType, falseType: t.TSType, ): t.TSConditionalType { - return builder.apply("TSConditionalType", arguments); + return validateNode({ + type: "TSConditionalType", + checkType, + extendsType, + trueType, + falseType, + }); } export { tsConditionalType as tSConditionalType }; export function tsInferType(typeParameter: t.TSTypeParameter): t.TSInferType { - return builder.apply("TSInferType", arguments); + return validateNode({ + type: "TSInferType", + typeParameter, + }); } export { tsInferType as tSInferType }; export function tsParenthesizedType( typeAnnotation: t.TSType, ): t.TSParenthesizedType { - return builder.apply("TSParenthesizedType", arguments); + return validateNode({ + type: "TSParenthesizedType", + typeAnnotation, + }); } export { tsParenthesizedType as tSParenthesizedType }; export function tsTypeOperator(typeAnnotation: t.TSType): t.TSTypeOperator { - return builder.apply("TSTypeOperator", arguments); + return validateNode({ + type: "TSTypeOperator", + typeAnnotation, + operator: null, + }); } export { tsTypeOperator as tSTypeOperator }; export function tsIndexedAccessType( objectType: t.TSType, indexType: t.TSType, ): t.TSIndexedAccessType { - return builder.apply("TSIndexedAccessType", arguments); + return validateNode({ + type: "TSIndexedAccessType", + objectType, + indexType, + }); } export { tsIndexedAccessType as tSIndexedAccessType }; export function tsMappedType( typeParameter: t.TSTypeParameter, - typeAnnotation?: t.TSType | null, - nameType?: t.TSType | null, + typeAnnotation: t.TSType | null = null, + nameType: t.TSType | null = null, ): t.TSMappedType { - return builder.apply("TSMappedType", arguments); + return validateNode({ + type: "TSMappedType", + typeParameter, + typeAnnotation, + nameType, + }); } export { tsMappedType as tSMappedType }; export function tsLiteralType( @@ -1359,166 +2244,246 @@ export function tsLiteralType( | t.BigIntLiteral | t.UnaryExpression, ): t.TSLiteralType { - return builder.apply("TSLiteralType", arguments); + return validateNode({ + type: "TSLiteralType", + literal, + }); } export { tsLiteralType as tSLiteralType }; export function tsExpressionWithTypeArguments( expression: t.TSEntityName, - typeParameters?: t.TSTypeParameterInstantiation | null, + typeParameters: t.TSTypeParameterInstantiation | null = null, ): t.TSExpressionWithTypeArguments { - return builder.apply("TSExpressionWithTypeArguments", arguments); + return validateNode({ + type: "TSExpressionWithTypeArguments", + expression, + typeParameters, + }); } export { tsExpressionWithTypeArguments as tSExpressionWithTypeArguments }; export function tsInterfaceDeclaration( id: t.Identifier, - typeParameters: t.TSTypeParameterDeclaration | null | undefined, - _extends: Array | null | undefined, + typeParameters: t.TSTypeParameterDeclaration | null | undefined = null, + _extends: Array | null | undefined = null, body: t.TSInterfaceBody, ): t.TSInterfaceDeclaration { - return builder.apply("TSInterfaceDeclaration", arguments); + return validateNode({ + type: "TSInterfaceDeclaration", + id, + typeParameters, + extends: _extends, + body, + }); } export { tsInterfaceDeclaration as tSInterfaceDeclaration }; export function tsInterfaceBody( body: Array, ): t.TSInterfaceBody { - return builder.apply("TSInterfaceBody", arguments); + return validateNode({ + type: "TSInterfaceBody", + body, + }); } export { tsInterfaceBody as tSInterfaceBody }; export function tsTypeAliasDeclaration( id: t.Identifier, - typeParameters: t.TSTypeParameterDeclaration | null | undefined, + typeParameters: t.TSTypeParameterDeclaration | null | undefined = null, typeAnnotation: t.TSType, ): t.TSTypeAliasDeclaration { - return builder.apply("TSTypeAliasDeclaration", arguments); + return validateNode({ + type: "TSTypeAliasDeclaration", + id, + typeParameters, + typeAnnotation, + }); } export { tsTypeAliasDeclaration as tSTypeAliasDeclaration }; export function tsAsExpression( expression: t.Expression, typeAnnotation: t.TSType, ): t.TSAsExpression { - return builder.apply("TSAsExpression", arguments); + return validateNode({ + type: "TSAsExpression", + expression, + typeAnnotation, + }); } export { tsAsExpression as tSAsExpression }; export function tsTypeAssertion( typeAnnotation: t.TSType, expression: t.Expression, ): t.TSTypeAssertion { - return builder.apply("TSTypeAssertion", arguments); + return validateNode({ + type: "TSTypeAssertion", + typeAnnotation, + expression, + }); } export { tsTypeAssertion as tSTypeAssertion }; export function tsEnumDeclaration( id: t.Identifier, members: Array, ): t.TSEnumDeclaration { - return builder.apply("TSEnumDeclaration", arguments); + return validateNode({ + type: "TSEnumDeclaration", + id, + members, + }); } export { tsEnumDeclaration as tSEnumDeclaration }; export function tsEnumMember( id: t.Identifier | t.StringLiteral, - initializer?: t.Expression | null, + initializer: t.Expression | null = null, ): t.TSEnumMember { - return builder.apply("TSEnumMember", arguments); + return validateNode({ + type: "TSEnumMember", + id, + initializer, + }); } export { tsEnumMember as tSEnumMember }; export function tsModuleDeclaration( id: t.Identifier | t.StringLiteral, body: t.TSModuleBlock | t.TSModuleDeclaration, ): t.TSModuleDeclaration { - return builder.apply("TSModuleDeclaration", arguments); + return validateNode({ + type: "TSModuleDeclaration", + id, + body, + }); } export { tsModuleDeclaration as tSModuleDeclaration }; export function tsModuleBlock(body: Array): t.TSModuleBlock { - return builder.apply("TSModuleBlock", arguments); + return validateNode({ + type: "TSModuleBlock", + body, + }); } export { tsModuleBlock as tSModuleBlock }; export function tsImportType( argument: t.StringLiteral, - qualifier?: t.TSEntityName | null, - typeParameters?: t.TSTypeParameterInstantiation | null, + qualifier: t.TSEntityName | null = null, + typeParameters: t.TSTypeParameterInstantiation | null = null, ): t.TSImportType { - return builder.apply("TSImportType", arguments); + return validateNode({ + type: "TSImportType", + argument, + qualifier, + typeParameters, + }); } export { tsImportType as tSImportType }; export function tsImportEqualsDeclaration( id: t.Identifier, moduleReference: t.TSEntityName | t.TSExternalModuleReference, ): t.TSImportEqualsDeclaration { - return builder.apply("TSImportEqualsDeclaration", arguments); + return validateNode({ + type: "TSImportEqualsDeclaration", + id, + moduleReference, + isExport: null, + }); } export { tsImportEqualsDeclaration as tSImportEqualsDeclaration }; export function tsExternalModuleReference( expression: t.StringLiteral, ): t.TSExternalModuleReference { - return builder.apply("TSExternalModuleReference", arguments); + return validateNode({ + type: "TSExternalModuleReference", + expression, + }); } export { tsExternalModuleReference as tSExternalModuleReference }; export function tsNonNullExpression( expression: t.Expression, ): t.TSNonNullExpression { - return builder.apply("TSNonNullExpression", arguments); + return validateNode({ + type: "TSNonNullExpression", + expression, + }); } export { tsNonNullExpression as tSNonNullExpression }; export function tsExportAssignment( expression: t.Expression, ): t.TSExportAssignment { - return builder.apply("TSExportAssignment", arguments); + return validateNode({ + type: "TSExportAssignment", + expression, + }); } export { tsExportAssignment as tSExportAssignment }; export function tsNamespaceExportDeclaration( id: t.Identifier, ): t.TSNamespaceExportDeclaration { - return builder.apply("TSNamespaceExportDeclaration", arguments); + return validateNode({ + type: "TSNamespaceExportDeclaration", + id, + }); } export { tsNamespaceExportDeclaration as tSNamespaceExportDeclaration }; export function tsTypeAnnotation(typeAnnotation: t.TSType): t.TSTypeAnnotation { - return builder.apply("TSTypeAnnotation", arguments); + return validateNode({ + type: "TSTypeAnnotation", + typeAnnotation, + }); } export { tsTypeAnnotation as tSTypeAnnotation }; export function tsTypeParameterInstantiation( params: Array, ): t.TSTypeParameterInstantiation { - return builder.apply("TSTypeParameterInstantiation", arguments); + return validateNode({ + type: "TSTypeParameterInstantiation", + params, + }); } export { tsTypeParameterInstantiation as tSTypeParameterInstantiation }; export function tsTypeParameterDeclaration( params: Array, ): t.TSTypeParameterDeclaration { - return builder.apply("TSTypeParameterDeclaration", arguments); + return validateNode({ + type: "TSTypeParameterDeclaration", + params, + }); } export { tsTypeParameterDeclaration as tSTypeParameterDeclaration }; export function tsTypeParameter( - constraint: t.TSType | null | undefined, - _default: t.TSType | null | undefined, + constraint: t.TSType | null | undefined = null, + _default: t.TSType | null | undefined = null, name: string, ): t.TSTypeParameter { - return builder.apply("TSTypeParameter", arguments); + return validateNode({ + type: "TSTypeParameter", + constraint, + default: _default, + name, + }); } export { tsTypeParameter as tSTypeParameter }; /** @deprecated */ -function NumberLiteral(value: number): t.NumberLiteral { +function NumberLiteral(value: number) { console.trace( "The node type NumberLiteral has been renamed to NumericLiteral", ); - return builder.apply("NumberLiteral", arguments); + return numericLiteral(value); } export { NumberLiteral as numberLiteral }; /** @deprecated */ -function RegexLiteral(pattern: string, flags?: string): t.RegexLiteral { +function RegexLiteral(pattern: string, flags: string = "") { console.trace("The node type RegexLiteral has been renamed to RegExpLiteral"); - return builder.apply("RegexLiteral", arguments); + return regExpLiteral(pattern, flags); } export { RegexLiteral as regexLiteral }; /** @deprecated */ -function RestProperty(argument: t.LVal): t.RestProperty { +function RestProperty(argument: t.LVal) { console.trace("The node type RestProperty has been renamed to RestElement"); - return builder.apply("RestProperty", arguments); + return restElement(argument); } export { RestProperty as restProperty }; /** @deprecated */ -function SpreadProperty(argument: t.Expression): t.SpreadProperty { +function SpreadProperty(argument: t.Expression) { console.trace( "The node type SpreadProperty has been renamed to SpreadElement", ); - return builder.apply("SpreadProperty", arguments); + return spreadElement(argument); } export { SpreadProperty as spreadProperty }; diff --git a/packages/babel-types/src/builders/validateNode.ts b/packages/babel-types/src/builders/validateNode.ts new file mode 100644 index 000000000000..aa6bbd0889b0 --- /dev/null +++ b/packages/babel-types/src/builders/validateNode.ts @@ -0,0 +1,12 @@ +import validate from "../validators/validate"; +import type * as t from ".."; +import { BUILDER_KEYS } from ".."; + +export default function validateNode(node: N) { + // todo: because keys not in BUILDER_KEYS are not validated - this actually allows invalid nodes in some cases + const keys = BUILDER_KEYS[node.type]; + for (const key of keys) { + validate(node, key, node[key]); + } + return node; +} diff --git a/packages/babel-types/src/definitions/flow.ts b/packages/babel-types/src/definitions/flow.ts index 13b6b2dfa641..a51e0c91fd06 100644 --- a/packages/babel-types/src/definitions/flow.ts +++ b/packages/babel-types/src/definitions/flow.ts @@ -275,17 +275,17 @@ defineType("ObjectTypeAnnotation", { indexers: { validate: arrayOfType("ObjectTypeIndexer"), optional: process.env.BABEL_8_BREAKING ? false : true, - default: process.env.BABEL_8_BREAKING ? [] : undefined, + default: [], }, callProperties: { validate: arrayOfType("ObjectTypeCallProperty"), optional: process.env.BABEL_8_BREAKING ? false : true, - default: process.env.BABEL_8_BREAKING ? [] : undefined, + default: [], }, internalSlots: { validate: arrayOfType("ObjectTypeInternalSlot"), optional: process.env.BABEL_8_BREAKING ? false : true, - default: process.env.BABEL_8_BREAKING ? [] : undefined, + default: [], }, exact: { validate: assertValueType("boolean"), diff --git a/packages/babel-types/test/builders/es2015/__snapshots__/templateElement.js.snap b/packages/babel-types/test/builders/es2015/__snapshots__/templateElement.js.snap index 2915dd37948f..9c78963dc5f5 100644 --- a/packages/babel-types/test/builders/es2015/__snapshots__/templateElement.js.snap +++ b/packages/babel-types/test/builders/es2015/__snapshots__/templateElement.js.snap @@ -92,4 +92,4 @@ Expected 1 quasis but got 2" exports[`builders es2015 templateLiteral should validate 5`] = `"Property quasis expected type of array but got object"`; -exports[`builders es2015 templateLiteral should validate 6`] = `"Property expressions expected type of array but got null"`; +exports[`builders es2015 templateLiteral should validate 6`] = `"Property expressions expected type of array but got undefined"`; diff --git a/packages/babel-types/test/builders/typescript/tsTypeParameter.js b/packages/babel-types/test/builders/typescript/tsTypeParameter.js index e11753dec266..41870be9de3a 100644 --- a/packages/babel-types/test/builders/typescript/tsTypeParameter.js +++ b/packages/babel-types/test/builders/typescript/tsTypeParameter.js @@ -32,7 +32,7 @@ describe("builders", function () { ); }).toThrow( !process.env.BABEL_8_BREAKING - ? "Property name expected type of string but got null" + ? "Property name expected type of string but got undefined" : 'Property name of TSTypeParameter expected node to be of a type ["Identifier"] but instead got undefined', ); });