[@babel/types] Moved generators related to babel-types into the babel-types package directory. (#9245)
This commit is contained in:
committed by
Nicolò Ribaudo
parent
46e3f6df1f
commit
778a61a3c2
@@ -1,116 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const util = require("util");
|
||||
const utils = require("./utils");
|
||||
|
||||
const types = require("../../packages/babel-types");
|
||||
|
||||
const readme = [
|
||||
`# @babel/types
|
||||
|
||||
> This module contains methods for building ASTs manually and for checking the types of AST nodes.
|
||||
|
||||
## Install
|
||||
|
||||
\`\`\`sh
|
||||
npm install --save-dev @babel/types
|
||||
\`\`\`
|
||||
|
||||
## API`,
|
||||
];
|
||||
|
||||
const customTypes = {
|
||||
ClassMethod: {
|
||||
key: "if computed then `Expression` else `Identifier | Literal`",
|
||||
},
|
||||
Identifier: {
|
||||
name: "`string`",
|
||||
},
|
||||
MemberExpression: {
|
||||
property: "if computed then `Expression` else `Identifier`",
|
||||
},
|
||||
ObjectMethod: {
|
||||
key: "if computed then `Expression` else `Identifier | Literal`",
|
||||
},
|
||||
ObjectProperty: {
|
||||
key: "if computed then `Expression` else `Identifier | Literal`",
|
||||
},
|
||||
};
|
||||
Object.keys(types.BUILDER_KEYS)
|
||||
.sort()
|
||||
.forEach(function(key) {
|
||||
readme.push("### " + key[0].toLowerCase() + key.substr(1));
|
||||
readme.push("```javascript");
|
||||
readme.push(
|
||||
"t." +
|
||||
utils.toFunctionName(key) +
|
||||
"(" +
|
||||
types.BUILDER_KEYS[key].join(", ") +
|
||||
")"
|
||||
);
|
||||
readme.push("```");
|
||||
readme.push("");
|
||||
readme.push(
|
||||
"See also `t.is" +
|
||||
key +
|
||||
"(node, opts)` and `t.assert" +
|
||||
key +
|
||||
"(node, opts)`."
|
||||
);
|
||||
readme.push("");
|
||||
if (types.ALIAS_KEYS[key] && types.ALIAS_KEYS[key].length) {
|
||||
readme.push(
|
||||
"Aliases: " +
|
||||
types.ALIAS_KEYS[key]
|
||||
.map(function(key) {
|
||||
return "`" + key + "`";
|
||||
})
|
||||
.join(", ")
|
||||
);
|
||||
readme.push("");
|
||||
}
|
||||
Object.keys(types.NODE_FIELDS[key])
|
||||
.sort(function(fieldA, fieldB) {
|
||||
const indexA = types.BUILDER_KEYS[key].indexOf(fieldA);
|
||||
const indexB = types.BUILDER_KEYS[key].indexOf(fieldB);
|
||||
if (indexA === indexB) return fieldA < fieldB ? -1 : 1;
|
||||
if (indexA === -1) return 1;
|
||||
if (indexB === -1) return -1;
|
||||
return indexA - indexB;
|
||||
})
|
||||
.forEach(function(field) {
|
||||
const defaultValue = types.NODE_FIELDS[key][field].default;
|
||||
const fieldDescription = ["`" + field + "`"];
|
||||
const validator = types.NODE_FIELDS[key][field].validate;
|
||||
if (customTypes[key] && customTypes[key][field]) {
|
||||
fieldDescription.push(`: ${customTypes[key][field]}`);
|
||||
} else if (validator) {
|
||||
try {
|
||||
fieldDescription.push(
|
||||
": `" + utils.stringifyValidator(validator, "") + "`"
|
||||
);
|
||||
} catch (ex) {
|
||||
if (ex.code === "UNEXPECTED_VALIDATOR_TYPE") {
|
||||
console.log(
|
||||
"Unrecognised validator type for " + key + "." + field
|
||||
);
|
||||
console.dir(ex.validator, { depth: 10, colors: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (defaultValue !== null || types.NODE_FIELDS[key][field].optional) {
|
||||
fieldDescription.push(
|
||||
" (default: `" + util.inspect(defaultValue) + "`)"
|
||||
);
|
||||
} else {
|
||||
fieldDescription.push(" (required)");
|
||||
}
|
||||
readme.push(" - " + fieldDescription.join(""));
|
||||
});
|
||||
|
||||
readme.push("");
|
||||
readme.push("---");
|
||||
readme.push("");
|
||||
});
|
||||
|
||||
process.stdout.write(readme.join("\n"));
|
||||
@@ -1,152 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const t = require("../../packages/babel-types");
|
||||
const utils = require("./utils");
|
||||
|
||||
const NODE_PREFIX = "BabelNode";
|
||||
|
||||
let code = `// NOTE: This file is autogenerated. Do not modify.
|
||||
// See scripts/generators/flow.js for script used.
|
||||
|
||||
declare class ${NODE_PREFIX}Comment {
|
||||
value: string;
|
||||
start: number;
|
||||
end: number;
|
||||
loc: ${NODE_PREFIX}SourceLocation;
|
||||
}
|
||||
|
||||
declare class ${NODE_PREFIX}CommentBlock extends ${NODE_PREFIX}Comment {
|
||||
type: "CommentBlock";
|
||||
}
|
||||
|
||||
declare class ${NODE_PREFIX}CommentLine extends ${NODE_PREFIX}Comment {
|
||||
type: "CommentLine";
|
||||
}
|
||||
|
||||
declare class ${NODE_PREFIX}SourceLocation {
|
||||
start: {
|
||||
line: number;
|
||||
column: number;
|
||||
};
|
||||
|
||||
end: {
|
||||
line: number;
|
||||
column: number;
|
||||
};
|
||||
}
|
||||
|
||||
declare class ${NODE_PREFIX} {
|
||||
leadingComments?: Array<${NODE_PREFIX}Comment>;
|
||||
innerComments?: Array<${NODE_PREFIX}Comment>;
|
||||
trailingComments?: Array<${NODE_PREFIX}Comment>;
|
||||
start: ?number;
|
||||
end: ?number;
|
||||
loc: ?${NODE_PREFIX}SourceLocation;
|
||||
}\n\n`;
|
||||
|
||||
//
|
||||
|
||||
const lines = [];
|
||||
|
||||
for (const type in t.NODE_FIELDS) {
|
||||
const fields = t.NODE_FIELDS[type];
|
||||
|
||||
const struct = ['type: "' + type + '";'];
|
||||
const args = [];
|
||||
|
||||
Object.keys(t.NODE_FIELDS[type])
|
||||
.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;
|
||||
})
|
||||
.forEach(fieldName => {
|
||||
const field = fields[fieldName];
|
||||
|
||||
let suffix = "";
|
||||
if (field.optional || field.default != null) suffix += "?";
|
||||
|
||||
let typeAnnotation = "any";
|
||||
|
||||
const validate = field.validate;
|
||||
if (validate) {
|
||||
typeAnnotation = utils.stringifyValidator(validate, NODE_PREFIX);
|
||||
}
|
||||
|
||||
if (typeAnnotation) {
|
||||
suffix += ": " + typeAnnotation;
|
||||
}
|
||||
|
||||
args.push(t.toBindingIdentifierName(fieldName) + suffix);
|
||||
|
||||
if (t.isValidIdentifier(fieldName)) {
|
||||
struct.push(fieldName + suffix + ";");
|
||||
}
|
||||
});
|
||||
|
||||
code += `declare class ${NODE_PREFIX}${type} extends ${NODE_PREFIX} {
|
||||
${struct.join("\n ").trim()}
|
||||
}\n\n`;
|
||||
|
||||
// Flow chokes on super() and import() :/
|
||||
if (type !== "Super" && type !== "Import") {
|
||||
lines.push(
|
||||
`declare function ${utils.toFunctionName(type)}(${args.join(
|
||||
", "
|
||||
)}): ${NODE_PREFIX}${type};`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < t.TYPES.length; i++) {
|
||||
let decl = `declare function is${
|
||||
t.TYPES[i]
|
||||
}(node: Object, opts?: ?Object): boolean`;
|
||||
|
||||
if (t.NODE_FIELDS[t.TYPES[i]]) {
|
||||
decl += ` %checks (node instanceof ${NODE_PREFIX}${t.TYPES[i]})`;
|
||||
}
|
||||
|
||||
lines.push(decl);
|
||||
}
|
||||
|
||||
lines.push(
|
||||
`declare function validate(n: BabelNode, key: string, value: mixed): void;`,
|
||||
`declare function clone<T>(n: T): T;`,
|
||||
`declare function cloneDeep<T>(n: T): T;`,
|
||||
`declare function removeProperties<T>(n: T, opts: ?{}): void;`,
|
||||
`declare function removePropertiesDeep<T>(n: T, opts: ?{}): T;`,
|
||||
`declare type TraversalAncestors = Array<{
|
||||
node: BabelNode,
|
||||
key: string,
|
||||
index?: number,
|
||||
}>;
|
||||
declare type TraversalHandler<T> = (BabelNode, TraversalAncestors, T) => void;
|
||||
declare type TraversalHandlers<T> = {
|
||||
enter?: TraversalHandler<T>,
|
||||
exit?: TraversalHandler<T>,
|
||||
};`.replace(/(^|\n) {2}/g, "$1"),
|
||||
// eslint-disable-next-line
|
||||
`declare function traverse<T>(n: BabelNode, TraversalHandler<T> | TraversalHandlers<T>, state?: T): void;`
|
||||
);
|
||||
|
||||
for (const type in t.FLIPPED_ALIAS_KEYS) {
|
||||
const types = t.FLIPPED_ALIAS_KEYS[type];
|
||||
code += `type ${NODE_PREFIX}${type} = ${types
|
||||
.map(type => `${NODE_PREFIX}${type}`)
|
||||
.join(" | ")};\n`;
|
||||
}
|
||||
|
||||
code += `\ndeclare module "@babel/types" {
|
||||
${lines
|
||||
.join("\n")
|
||||
.replace(/\n/g, "\n ")
|
||||
.trim()}
|
||||
}\n`;
|
||||
|
||||
//
|
||||
|
||||
process.stdout.write(code);
|
||||
@@ -1,201 +0,0 @@
|
||||
"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: "CommentBlock" | "CommentLine";
|
||||
}
|
||||
|
||||
export interface CommentBlock extends BaseComment {
|
||||
type: "CommentBlock";
|
||||
}
|
||||
|
||||
export interface CommentLine extends BaseComment {
|
||||
type: "CommentLine";
|
||||
}
|
||||
|
||||
export type Comment = CommentBlock | CommentLine;
|
||||
|
||||
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" : ""
|
||||
}`
|
||||
);
|
||||
}
|
||||
|
||||
const alphaNumeric = /^\w+$/;
|
||||
|
||||
if (t.isValidIdentifier(fieldName) || alphaNumeric.test(fieldName)) {
|
||||
struct.push(`${fieldName}: ${typeAnnotation};`);
|
||||
} else {
|
||||
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 if (t.FLIPPED_ALIAS_KEYS[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 += "\n";
|
||||
|
||||
code += "export interface Aliases {\n";
|
||||
for (const type in t.FLIPPED_ALIAS_KEYS) {
|
||||
code += ` ${type}: ${type};\n`;
|
||||
}
|
||||
code += "}\n\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;
|
||||
});
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
exports.stringifyValidator = function stringifyValidator(
|
||||
validator,
|
||||
nodePrefix
|
||||
) {
|
||||
if (validator === undefined) {
|
||||
return "any";
|
||||
}
|
||||
|
||||
if (validator.each) {
|
||||
return `Array<${stringifyValidator(validator.each, nodePrefix)}>`;
|
||||
}
|
||||
|
||||
if (validator.chainOf) {
|
||||
return stringifyValidator(validator.chainOf[1], nodePrefix);
|
||||
}
|
||||
|
||||
if (validator.oneOf) {
|
||||
return validator.oneOf.map(JSON.stringify).join(" | ");
|
||||
}
|
||||
|
||||
if (validator.oneOfNodeTypes) {
|
||||
return validator.oneOfNodeTypes.map(_ => nodePrefix + _).join(" | ");
|
||||
}
|
||||
|
||||
if (validator.oneOfNodeOrValueTypes) {
|
||||
return validator.oneOfNodeOrValueTypes
|
||||
.map(_ => {
|
||||
return isValueType(_) ? _ : nodePrefix + _;
|
||||
})
|
||||
.join(" | ");
|
||||
}
|
||||
|
||||
if (validator.type) {
|
||||
return validator.type;
|
||||
}
|
||||
|
||||
return ["any"];
|
||||
};
|
||||
|
||||
exports.toFunctionName = function toFunctionName(typeName) {
|
||||
const _ = typeName.replace(/^TS/, "ts").replace(/^JSX/, "jsx");
|
||||
return _.slice(0, 1).toLowerCase() + _.slice(1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Heuristic to decide whether or not the given type is a value type (eg. "null")
|
||||
* or a Node type (eg. "Expression").
|
||||
*/
|
||||
function isValueType(type) {
|
||||
return type.charAt(0).toLowerCase() === type.charAt(0);
|
||||
}
|
||||
Reference in New Issue
Block a user