123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- "use strict";
- const t = require("../../packages/babel-types");
- const utils = require("./utils");
- let code = `// NOTE: This file is autogenerated. Do not modify.
- // See scripts/generators/typescript.js for script used.
- interface BaseComment {
- value: string;
- start: number;
- end: number;
- loc: SourceLocation;
- type: "BlockComment" | "LineComment";
- }
- export interface BlockComment extends BaseComment {
- type: "BlockComment";
- }
- export interface LineComment extends BaseComment {
- type: "LineComment";
- }
- export type Comment = BlockComment | LineComment;
- export interface SourceLocation {
- start: {
- line: number;
- column: number;
- };
- end: {
- line: number;
- column: number;
- };
- }
- interface BaseNode {
- leadingComments: ReadonlyArray<Comment> | null;
- innerComments: ReadonlyArray<Comment> | null;
- trailingComments: ReadonlyArray<Comment> | null;
- start: number | null;
- end: number | null;
- loc: SourceLocation | null;
- type: Node["type"];
- }
- export type Node = ${t.TYPES.sort().join(" | ")};\n\n`;
- //
- const lines = [];
- for (const type in t.NODE_FIELDS) {
- const fields = t.NODE_FIELDS[type];
- const fieldNames = sortFieldNames(Object.keys(t.NODE_FIELDS[type]), type);
- const struct = ['type: "' + type + '";'];
- const args = [];
- fieldNames.forEach(fieldName => {
- const field = fields[fieldName];
- let typeAnnotation = utils.stringifyValidator(field.validate, "");
- if (isNullable(field) && !hasDefault(field)) {
- typeAnnotation += " | null";
- }
- if (areAllRemainingFieldsNullable(fieldName, fieldNames, fields)) {
- args.push(
- `${t.toBindingIdentifierName(fieldName)}${
- isNullable(field) ? "?:" : ":"
- } ${typeAnnotation}`
- );
- } else {
- args.push(
- `${t.toBindingIdentifierName(fieldName)}: ${typeAnnotation}${
- isNullable(field) ? " | undefined" : ""
- }`
- );
- }
- if (t.isValidIdentifier(fieldName)) {
- struct.push(`${fieldName}: ${typeAnnotation};`);
- }
- });
- code += `export interface ${type} extends BaseNode {
- ${struct.join("\n ").trim()}
- }\n\n`;
- // super and import are reserved words in JavaScript
- if (type !== "Super" && type !== "Import") {
- lines.push(
- `export function ${utils.toFunctionName(type)}(${args.join(
- ", "
- )}): ${type};`
- );
- }
- }
- for (let i = 0; i < t.TYPES.length; i++) {
- let decl = `export function is${
- t.TYPES[i]
- }(node: object, opts?: object | null): `;
- if (t.NODE_FIELDS[t.TYPES[i]]) {
- decl += `node is ${t.TYPES[i]};`;
- } else {
- decl += `boolean;`;
- }
- lines.push(decl);
- }
- lines.push(
- `export function validate(n: Node, key: string, value: any): void;`,
- `export function clone<T extends Node>(n: T): T;`,
- `export function cloneDeep<T extends Node>(n: T): T;`,
- `export function removeProperties(
- n: Node,
- opts?: { preserveComments: boolean } | null
- ): void;`,
- `export function removePropertiesDeep<T extends Node>(
- n: T,
- opts?: { preserveComments: boolean } | null
- ): T;`,
- `export type TraversalAncestors = ReadonlyArray<{
- node: Node,
- key: string,
- index?: number,
- }>;
- export type TraversalHandler<T> = (node: Node, parent: TraversalAncestors, type: T) => void;
- export type TraversalHandlers<T> = {
- enter?: TraversalHandler<T>,
- exit?: TraversalHandler<T>,
- };`.replace(/(^|\n) {2}/g, "$1"),
- // eslint-disable-next-line
- `export function traverse<T>(n: Node, h: TraversalHandler<T> | TraversalHandlers<T>, state?: T): void;`
- );
- for (const type in t.DEPRECATED_KEYS) {
- code += `/**
- * @deprecated Use \`${t.DEPRECATED_KEYS[type]}\`
- */
- export type ${type} = ${t.DEPRECATED_KEYS[type]};\n
- `;
- }
- for (const type in t.FLIPPED_ALIAS_KEYS) {
- const types = t.FLIPPED_ALIAS_KEYS[type];
- code += `export type ${type} = ${types
- .map(type => `${type}`)
- .join(" | ")};\n`;
- }
- code += lines.join("\n") + "\n";
- //
- process.stdout.write(code);
- //
- function areAllRemainingFieldsNullable(fieldName, fieldNames, fields) {
- const index = fieldNames.indexOf(fieldName);
- return fieldNames.slice(index).every(_ => isNullable(fields[_]));
- }
- function hasDefault(field) {
- return field.default != null;
- }
- function isNullable(field) {
- return field.optional || hasDefault(field);
- }
- function sortFieldNames(fields, type) {
- return fields.sort((fieldA, fieldB) => {
- const indexA = t.BUILDER_KEYS[type].indexOf(fieldA);
- const indexB = t.BUILDER_KEYS[type].indexOf(fieldB);
- if (indexA === indexB) return fieldA < fieldB ? -1 : 1;
- if (indexA === -1) return 1;
- if (indexB === -1) return -1;
- return indexA - indexB;
- });
- }
|