1 | import t from "../../lib/index.js";
|
---|
2 | import stringifyValidator from "../utils/stringifyValidator.js";
|
---|
3 | import toFunctionName from "../utils/toFunctionName.js";
|
---|
4 |
|
---|
5 | const NODE_PREFIX = "BabelNode";
|
---|
6 |
|
---|
7 | let code = `// NOTE: This file is autogenerated. Do not modify.
|
---|
8 | // See packages/babel-types/scripts/generators/flow.js for script used.
|
---|
9 |
|
---|
10 | declare class ${NODE_PREFIX}Comment {
|
---|
11 | value: string;
|
---|
12 | start: number;
|
---|
13 | end: number;
|
---|
14 | loc: ${NODE_PREFIX}SourceLocation;
|
---|
15 | }
|
---|
16 |
|
---|
17 | declare class ${NODE_PREFIX}CommentBlock extends ${NODE_PREFIX}Comment {
|
---|
18 | type: "CommentBlock";
|
---|
19 | }
|
---|
20 |
|
---|
21 | declare class ${NODE_PREFIX}CommentLine extends ${NODE_PREFIX}Comment {
|
---|
22 | type: "CommentLine";
|
---|
23 | }
|
---|
24 |
|
---|
25 | declare class ${NODE_PREFIX}SourceLocation {
|
---|
26 | start: {
|
---|
27 | line: number;
|
---|
28 | column: number;
|
---|
29 | };
|
---|
30 |
|
---|
31 | end: {
|
---|
32 | line: number;
|
---|
33 | column: number;
|
---|
34 | };
|
---|
35 | }
|
---|
36 |
|
---|
37 | declare class ${NODE_PREFIX} {
|
---|
38 | leadingComments?: Array<${NODE_PREFIX}Comment>;
|
---|
39 | innerComments?: Array<${NODE_PREFIX}Comment>;
|
---|
40 | trailingComments?: Array<${NODE_PREFIX}Comment>;
|
---|
41 | start: ?number;
|
---|
42 | end: ?number;
|
---|
43 | loc: ?${NODE_PREFIX}SourceLocation;
|
---|
44 | extra?: { [string]: mixed };
|
---|
45 | }\n\n`;
|
---|
46 |
|
---|
47 | //
|
---|
48 |
|
---|
49 | const lines = [];
|
---|
50 |
|
---|
51 | for (const type in t.NODE_FIELDS) {
|
---|
52 | const fields = t.NODE_FIELDS[type];
|
---|
53 |
|
---|
54 | const struct = ['type: "' + type + '";'];
|
---|
55 | const args = [];
|
---|
56 | const builderNames = t.BUILDER_KEYS[type];
|
---|
57 |
|
---|
58 | Object.keys(t.NODE_FIELDS[type])
|
---|
59 | .sort((fieldA, fieldB) => {
|
---|
60 | const indexA = t.BUILDER_KEYS[type].indexOf(fieldA);
|
---|
61 | const indexB = t.BUILDER_KEYS[type].indexOf(fieldB);
|
---|
62 | if (indexA === indexB) return fieldA < fieldB ? -1 : 1;
|
---|
63 | if (indexA === -1) return 1;
|
---|
64 | if (indexB === -1) return -1;
|
---|
65 | return indexA - indexB;
|
---|
66 | })
|
---|
67 | .forEach(fieldName => {
|
---|
68 | const field = fields[fieldName];
|
---|
69 |
|
---|
70 | let suffix = "";
|
---|
71 | if (field.optional || field.default != null) suffix += "?";
|
---|
72 |
|
---|
73 | let typeAnnotation = "any";
|
---|
74 |
|
---|
75 | const validate = field.validate;
|
---|
76 | if (validate) {
|
---|
77 | typeAnnotation = stringifyValidator(validate, NODE_PREFIX);
|
---|
78 | }
|
---|
79 |
|
---|
80 | if (typeAnnotation) {
|
---|
81 | suffix += ": " + typeAnnotation;
|
---|
82 | }
|
---|
83 | if (builderNames.includes(fieldName)) {
|
---|
84 | args.push(t.toBindingIdentifierName(fieldName) + suffix);
|
---|
85 | }
|
---|
86 |
|
---|
87 | if (t.isValidIdentifier(fieldName)) {
|
---|
88 | struct.push(fieldName + suffix + ";");
|
---|
89 | }
|
---|
90 | });
|
---|
91 |
|
---|
92 | code += `declare class ${NODE_PREFIX}${type} extends ${NODE_PREFIX} {
|
---|
93 | ${struct.join("\n ").trim()}
|
---|
94 | }\n\n`;
|
---|
95 |
|
---|
96 | // Flow chokes on super() and import() :/
|
---|
97 | if (type !== "Super" && type !== "Import") {
|
---|
98 | lines.push(
|
---|
99 | `declare export function ${toFunctionName(type)}(${args.join(
|
---|
100 | ", "
|
---|
101 | )}): ${NODE_PREFIX}${type};`
|
---|
102 | );
|
---|
103 | } else {
|
---|
104 | const functionName = toFunctionName(type);
|
---|
105 | lines.push(
|
---|
106 | `declare function _${functionName}(${args.join(
|
---|
107 | ", "
|
---|
108 | )}): ${NODE_PREFIX}${type};`,
|
---|
109 | `declare export { _${functionName} as ${functionName} }`
|
---|
110 | );
|
---|
111 | }
|
---|
112 | }
|
---|
113 |
|
---|
114 | for (const typeName of t.TYPES) {
|
---|
115 | const isDeprecated = !!t.DEPRECATED_KEYS[typeName];
|
---|
116 | const realName = isDeprecated ? t.DEPRECATED_KEYS[typeName] : typeName;
|
---|
117 |
|
---|
118 | let decl = `declare export function is${typeName}(node: ?Object, opts?: ?Object): boolean`;
|
---|
119 | if (t.NODE_FIELDS[realName]) {
|
---|
120 | decl += ` %checks (node instanceof ${NODE_PREFIX}${realName})`;
|
---|
121 | }
|
---|
122 | lines.push(decl);
|
---|
123 |
|
---|
124 | lines.push(
|
---|
125 | `declare export function assert${typeName}(node: ?Object, opts?: ?Object): void`
|
---|
126 | );
|
---|
127 | }
|
---|
128 |
|
---|
129 | lines.push(
|
---|
130 | `declare export var VISITOR_KEYS: { [type: string]: string[] }`,
|
---|
131 |
|
---|
132 | // assert/
|
---|
133 | `declare export function assertNode(obj: any): void`,
|
---|
134 |
|
---|
135 | // builders/
|
---|
136 | // eslint-disable-next-line max-len
|
---|
137 | `declare export function createTypeAnnotationBasedOnTypeof(type: 'string' | 'number' | 'undefined' | 'boolean' | 'function' | 'object' | 'symbol'): ${NODE_PREFIX}TypeAnnotation`,
|
---|
138 | // eslint-disable-next-line max-len
|
---|
139 | `declare export function createUnionTypeAnnotation(types: Array<${NODE_PREFIX}FlowType>): ${NODE_PREFIX}UnionTypeAnnotation`,
|
---|
140 | // eslint-disable-next-line max-len
|
---|
141 | `declare export function createFlowUnionType(types: Array<${NODE_PREFIX}FlowType>): ${NODE_PREFIX}UnionTypeAnnotation`,
|
---|
142 | // this smells like "internal API"
|
---|
143 | // eslint-disable-next-line max-len
|
---|
144 | `declare export function buildChildren(node: { children: Array<${NODE_PREFIX}JSXText | ${NODE_PREFIX}JSXExpressionContainer | ${NODE_PREFIX}JSXSpreadChild | ${NODE_PREFIX}JSXElement | ${NODE_PREFIX}JSXFragment | ${NODE_PREFIX}JSXEmptyExpression> }): Array<${NODE_PREFIX}JSXText | ${NODE_PREFIX}JSXExpressionContainer | ${NODE_PREFIX}JSXSpreadChild | ${NODE_PREFIX}JSXElement | ${NODE_PREFIX}JSXFragment>`,
|
---|
145 |
|
---|
146 | // clone/
|
---|
147 | `declare export function clone<T>(n: T): T;`,
|
---|
148 | `declare export function cloneDeep<T>(n: T): T;`,
|
---|
149 | `declare export function cloneDeepWithoutLoc<T>(n: T): T;`,
|
---|
150 | `declare export function cloneNode<T>(n: T, deep?: boolean, withoutLoc?: boolean): T;`,
|
---|
151 | `declare export function cloneWithoutLoc<T>(n: T): T;`,
|
---|
152 |
|
---|
153 | // comments/
|
---|
154 | `declare type CommentTypeShorthand = 'leading' | 'inner' | 'trailing'`,
|
---|
155 | // eslint-disable-next-line max-len
|
---|
156 | `declare export function addComment<T: BabelNode>(node: T, type: CommentTypeShorthand, content: string, line?: boolean): T`,
|
---|
157 | // eslint-disable-next-line max-len
|
---|
158 | `declare export function addComments<T: BabelNode>(node: T, type: CommentTypeShorthand, comments: Array<Comment>): T`,
|
---|
159 | `declare export function inheritInnerComments(node: BabelNode, parent: BabelNode): void`,
|
---|
160 | `declare export function inheritLeadingComments(node: BabelNode, parent: BabelNode): void`,
|
---|
161 | `declare export function inheritsComments<T: BabelNode>(node: T, parent: BabelNode): void`,
|
---|
162 | `declare export function inheritTrailingComments(node: BabelNode, parent: BabelNode): void`,
|
---|
163 | `declare export function removeComments<T: BabelNode>(node: T): T`,
|
---|
164 |
|
---|
165 | // converters/
|
---|
166 | `declare export function ensureBlock(node: ${NODE_PREFIX}, key: string): ${NODE_PREFIX}BlockStatement`,
|
---|
167 | `declare export function toBindingIdentifierName(name?: ?string): string`,
|
---|
168 | // eslint-disable-next-line max-len
|
---|
169 | `declare export function toBlock(node: ${NODE_PREFIX}Statement | ${NODE_PREFIX}Expression, parent?: ${NODE_PREFIX}Function | null): ${NODE_PREFIX}BlockStatement`,
|
---|
170 | // eslint-disable-next-line max-len
|
---|
171 | `declare export function toComputedKey(node: ${NODE_PREFIX}Method | ${NODE_PREFIX}Property, key?: ${NODE_PREFIX}Expression | ${NODE_PREFIX}Identifier): ${NODE_PREFIX}Expression`,
|
---|
172 | // eslint-disable-next-line max-len
|
---|
173 | `declare export function toExpression(node: ${NODE_PREFIX}ExpressionStatement | ${NODE_PREFIX}Expression | ${NODE_PREFIX}Class | ${NODE_PREFIX}Function): ${NODE_PREFIX}Expression`,
|
---|
174 | `declare export function toIdentifier(name?: ?string): string`,
|
---|
175 | // eslint-disable-next-line max-len
|
---|
176 | `declare export function toKeyAlias(node: ${NODE_PREFIX}Method | ${NODE_PREFIX}Property, key?: ${NODE_PREFIX}): string`,
|
---|
177 | // toSequenceExpression relies on types that aren't declared in flow
|
---|
178 | // eslint-disable-next-line max-len
|
---|
179 | `declare export function toStatement(node: ${NODE_PREFIX}Statement | ${NODE_PREFIX}Class | ${NODE_PREFIX}Function | ${NODE_PREFIX}AssignmentExpression, ignore?: boolean): ${NODE_PREFIX}Statement | void`,
|
---|
180 | `declare export function valueToNode(value: any): ${NODE_PREFIX}Expression`,
|
---|
181 |
|
---|
182 | // modifications/
|
---|
183 | // eslint-disable-next-line max-len
|
---|
184 | `declare export function removeTypeDuplicates(types: Array<${NODE_PREFIX}FlowType>): Array<${NODE_PREFIX}FlowType>`,
|
---|
185 | // eslint-disable-next-line max-len
|
---|
186 | `declare export function appendToMemberExpression(member: ${NODE_PREFIX}MemberExpression, append: ${NODE_PREFIX}, computed?: boolean): ${NODE_PREFIX}MemberExpression`,
|
---|
187 | // eslint-disable-next-line max-len
|
---|
188 | `declare export function inherits<T: BabelNode>(child: T, parent: ${NODE_PREFIX} | null | void): T`,
|
---|
189 | // eslint-disable-next-line max-len
|
---|
190 | `declare export function prependToMemberExpression(member: ${NODE_PREFIX}MemberExpression, prepend: ${NODE_PREFIX}Expression): ${NODE_PREFIX}MemberExpression`,
|
---|
191 | `declare export function removeProperties<T>(n: T, opts: ?{}): void;`,
|
---|
192 | `declare export function removePropertiesDeep<T>(n: T, opts: ?{}): T;`,
|
---|
193 |
|
---|
194 | // retrievers/
|
---|
195 | // eslint-disable-next-line max-len
|
---|
196 | `declare export var getBindingIdentifiers: {
|
---|
197 | (node: ${NODE_PREFIX}, duplicates?: boolean, outerOnly?: boolean): { [key: string]: ${NODE_PREFIX}Identifier | Array<${NODE_PREFIX}Identifier> },
|
---|
198 | keys: { [type: string]: string[] }
|
---|
199 | }`,
|
---|
200 | // eslint-disable-next-line max-len
|
---|
201 | `declare export function getOuterBindingIdentifiers(node: BabelNode, duplicates?: boolean): { [key: string]: ${NODE_PREFIX}Identifier | Array<${NODE_PREFIX}Identifier> }`,
|
---|
202 |
|
---|
203 | // traverse/
|
---|
204 | `declare type TraversalAncestors = Array<{
|
---|
205 | node: BabelNode,
|
---|
206 | key: string,
|
---|
207 | index?: number,
|
---|
208 | }>;
|
---|
209 | declare type TraversalHandler<T> = (BabelNode, TraversalAncestors, T) => void;
|
---|
210 | declare type TraversalHandlers<T> = {
|
---|
211 | enter?: TraversalHandler<T>,
|
---|
212 | exit?: TraversalHandler<T>,
|
---|
213 | };`.replace(/(^|\n) {2}/g, "$1"),
|
---|
214 | // eslint-disable-next-line
|
---|
215 | `declare export function traverse<T>(n: BabelNode, TraversalHandler<T> | TraversalHandlers<T>, state?: T): void;`,
|
---|
216 | `declare export function traverseFast<T>(n: BabelNode, h: TraversalHandler<T>, state?: T): void;`,
|
---|
217 |
|
---|
218 | // utils/
|
---|
219 | // cleanJSXElementLiteralChild is not exported
|
---|
220 | // inherit is not exported
|
---|
221 | `declare export function shallowEqual(actual: Object, expected: Object): boolean`,
|
---|
222 |
|
---|
223 | // validators/
|
---|
224 | // eslint-disable-next-line max-len
|
---|
225 | `declare export function buildMatchMemberExpression(match: string, allowPartial?: boolean): (?BabelNode) => boolean`,
|
---|
226 | `declare export function is(type: string, n: BabelNode, opts: Object): boolean;`,
|
---|
227 | `declare export function isBinding(node: BabelNode, parent: BabelNode, grandparent?: BabelNode): boolean`,
|
---|
228 | `declare export function isBlockScoped(node: BabelNode): boolean`,
|
---|
229 | `declare export function isImmutable(node: BabelNode): boolean`,
|
---|
230 | `declare export function isLet(node: BabelNode): boolean`,
|
---|
231 | `declare export function isNode(node: ?Object): boolean`,
|
---|
232 | `declare export function isNodesEquivalent(a: any, b: any): boolean`,
|
---|
233 | `declare export function isPlaceholderType(placeholderType: string, targetType: string): boolean`,
|
---|
234 | `declare export function isReferenced(node: BabelNode, parent: BabelNode, grandparent?: BabelNode): boolean`,
|
---|
235 | `declare export function isScope(node: BabelNode, parent: BabelNode): boolean`,
|
---|
236 | `declare export function isSpecifierDefault(specifier: BabelNodeModuleSpecifier): boolean`,
|
---|
237 | `declare export function isType(nodetype: ?string, targetType: string): boolean`,
|
---|
238 | `declare export function isValidES3Identifier(name: string): boolean`,
|
---|
239 | `declare export function isValidES3Identifier(name: string): boolean`,
|
---|
240 | `declare export function isValidIdentifier(name: string): boolean`,
|
---|
241 | `declare export function isVar(node: BabelNode): boolean`,
|
---|
242 | // eslint-disable-next-line max-len
|
---|
243 | `declare export function matchesPattern(node: ?BabelNode, match: string | Array<string>, allowPartial?: boolean): boolean`,
|
---|
244 | `declare export function validate(n: BabelNode, key: string, value: mixed): void;`
|
---|
245 | );
|
---|
246 |
|
---|
247 | for (const type in t.FLIPPED_ALIAS_KEYS) {
|
---|
248 | const types = t.FLIPPED_ALIAS_KEYS[type];
|
---|
249 | code += `type ${NODE_PREFIX}${type} = ${types
|
---|
250 | .map(type => `${NODE_PREFIX}${type}`)
|
---|
251 | .join(" | ")};\n`;
|
---|
252 | }
|
---|
253 |
|
---|
254 | code += `\ndeclare module "@babel/types" {
|
---|
255 | ${lines.join("\n").replace(/\n/g, "\n ").trim()}
|
---|
256 | }\n`;
|
---|
257 |
|
---|
258 | //
|
---|
259 |
|
---|
260 | process.stdout.write(code);
|
---|