diff --git a/scripts/generate-interfaces.js b/scripts/generate-interfaces.js new file mode 100644 index 0000000000..5ec8d3c829 --- /dev/null +++ b/scripts/generate-interfaces.js @@ -0,0 +1,117 @@ +var fs = require("fs"); +var t = require("../packages/babel-types"); + +var NODE_PREFIX = "BabelNode"; + +var code = `// NOTE: This file is autogenerated. Do not modify. +// See scripts/generate-interfaces.js for script used. + +declare class ${NODE_PREFIX}Comment { + value: string; + start: number; + end: number; + loc: ${NODE_PREFIX}SourceLocation; +} + +declare class ${NODE_PREFIX}BlockComment extends ${NODE_PREFIX}Comment { + type: "BlockComment"; +} + +declare class ${NODE_PREFIX}LineComment extends ${NODE_PREFIX}Comment { + type: "LineComment"; +} + +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`; + +// + +var lines = []; + +for (var type in t.NODE_FIELDS) { + var fields = t.NODE_FIELDS[type]; + + var struct = ['type: "' + type + '";']; + var args = []; + + for (var fieldName in fields) { + var field = fields[fieldName]; + + var suffix = ""; + if (field.optional || field.default != null) suffix += "?"; + + var typeAnnotation = "any"; + + var validate = field.validate; + if (validate) { + if (validate.oneOf) { + typeAnnotation = validate.oneOf.map(function (val) { + return JSON.stringify(val); + }).join(" | "); + } + + if (validate.type) { + typeAnnotation = validate.type; + + if (typeAnnotation === "array") { + typeAnnotation = "Array"; + } + } + + if (validate.oneOfNodeTypes) { + var types = validate.oneOfNodeTypes.map(type => `${NODE_PREFIX}${type}`); + typeAnnotation = types.join(" | "); + if (suffix === "?") typeAnnotation = "?" + typeAnnotation; + } + } + + if (typeAnnotation) { + suffix += ": " + typeAnnotation; + } + + args.push(t.toBindingIdentifierName(fieldName) + suffix); + if (!t.isValidIdentifier(fieldName)) continue; + struct.push(fieldName + suffix + ";"); + } + + code += `declare class ${NODE_PREFIX}${type} extends ${NODE_PREFIX} { + ${struct.join("\n ").trim()} +}\n\n`; + + lines.push(`declare function ${type[0].toLowerCase() + type.slice(1)}(${args.join(", ")}): ${NODE_PREFIX}${type};`); +} + +for (var i = 0; i < t.TYPES.length; i++) { + lines.push(`declare function is${t.TYPES[i]}(node: Object, opts?: Object): boolean;`); +} + +for (var type in t.FLIPPED_ALIAS_KEYS) { + var 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`; + +// + +fs.writeFileSync(__dirname + "/../lib/types.js", code);