flow.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. "use strict";
  2. const t = require("../../packages/babel-types");
  3. const utils = require("./utils");
  4. const NODE_PREFIX = "BabelNode";
  5. let code = `// NOTE: This file is autogenerated. Do not modify.
  6. // See scripts/generators/flow.js for script used.
  7. declare class ${NODE_PREFIX}Comment {
  8. value: string;
  9. start: number;
  10. end: number;
  11. loc: ${NODE_PREFIX}SourceLocation;
  12. }
  13. declare class ${NODE_PREFIX}BlockComment extends ${NODE_PREFIX}Comment {
  14. type: "BlockComment";
  15. }
  16. declare class ${NODE_PREFIX}LineComment extends ${NODE_PREFIX}Comment {
  17. type: "LineComment";
  18. }
  19. declare class ${NODE_PREFIX}SourceLocation {
  20. start: {
  21. line: number;
  22. column: number;
  23. };
  24. end: {
  25. line: number;
  26. column: number;
  27. };
  28. }
  29. declare class ${NODE_PREFIX} {
  30. leadingComments?: Array<${NODE_PREFIX}Comment>;
  31. innerComments?: Array<${NODE_PREFIX}Comment>;
  32. trailingComments?: Array<${NODE_PREFIX}Comment>;
  33. start: ?number;
  34. end: ?number;
  35. loc: ?${NODE_PREFIX}SourceLocation;
  36. }\n\n`;
  37. //
  38. const lines = [];
  39. for (const type in t.NODE_FIELDS) {
  40. const fields = t.NODE_FIELDS[type];
  41. const struct = ['type: "' + type + '";'];
  42. const args = [];
  43. Object.keys(t.NODE_FIELDS[type])
  44. .sort((fieldA, fieldB) => {
  45. const indexA = t.BUILDER_KEYS[type].indexOf(fieldA);
  46. const indexB = t.BUILDER_KEYS[type].indexOf(fieldB);
  47. if (indexA === indexB) return fieldA < fieldB ? -1 : 1;
  48. if (indexA === -1) return 1;
  49. if (indexB === -1) return -1;
  50. return indexA - indexB;
  51. })
  52. .forEach(fieldName => {
  53. const field = fields[fieldName];
  54. let suffix = "";
  55. if (field.optional || field.default != null) suffix += "?";
  56. let typeAnnotation = "any";
  57. const validate = field.validate;
  58. if (validate) {
  59. typeAnnotation = utils.stringifyValidator(validate, NODE_PREFIX);
  60. }
  61. if (typeAnnotation) {
  62. suffix += ": " + typeAnnotation;
  63. }
  64. args.push(t.toBindingIdentifierName(fieldName) + suffix);
  65. if (t.isValidIdentifier(fieldName)) {
  66. struct.push(fieldName + suffix + ";");
  67. }
  68. });
  69. code += `declare class ${NODE_PREFIX}${type} extends ${NODE_PREFIX} {
  70. ${struct.join("\n ").trim()}
  71. }\n\n`;
  72. // Flow chokes on super() and import() :/
  73. if (type !== "Super" && type !== "Import") {
  74. lines.push(
  75. `declare function ${utils.toFunctionName(type)}(${args.join(
  76. ", "
  77. )}): ${NODE_PREFIX}${type};`
  78. );
  79. }
  80. }
  81. for (let i = 0; i < t.TYPES.length; i++) {
  82. let decl = `declare function is${
  83. t.TYPES[i]
  84. }(node: Object, opts?: ?Object): boolean`;
  85. if (t.NODE_FIELDS[t.TYPES[i]]) {
  86. decl += ` %checks (node instanceof ${NODE_PREFIX}${t.TYPES[i]})`;
  87. }
  88. lines.push(decl);
  89. }
  90. lines.push(
  91. `declare function validate(n: BabelNode, key: string, value: mixed): void;`,
  92. `declare function clone<T>(n: T): T;`,
  93. `declare function cloneDeep<T>(n: T): T;`,
  94. `declare function removeProperties<T>(n: T, opts: ?{}): void;`,
  95. `declare function removePropertiesDeep<T>(n: T, opts: ?{}): T;`,
  96. `declare type TraversalAncestors = Array<{
  97. node: BabelNode,
  98. key: string,
  99. index?: number,
  100. }>;
  101. declare type TraversalHandler<T> = (BabelNode, TraversalAncestors, T) => void;
  102. declare type TraversalHandlers<T> = {
  103. enter?: TraversalHandler<T>,
  104. exit?: TraversalHandler<T>,
  105. };`.replace(/(^|\n) {2}/g, "$1"),
  106. // eslint-disable-next-line
  107. `declare function traverse<T>(n: BabelNode, TraversalHandler<T> | TraversalHandlers<T>, state?: T): void;`
  108. );
  109. for (const type in t.FLIPPED_ALIAS_KEYS) {
  110. const types = t.FLIPPED_ALIAS_KEYS[type];
  111. code += `type ${NODE_PREFIX}${type} = ${types
  112. .map(type => `${NODE_PREFIX}${type}`)
  113. .join(" | ")};\n`;
  114. }
  115. code += `\ndeclare module "@babel/types" {
  116. ${lines
  117. .join("\n")
  118. .replace(/\n/g, "\n ")
  119. .trim()}
  120. }\n`;
  121. //
  122. process.stdout.write(code);