visitors.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.explode = explode$1;
  6. exports.isExplodedVisitor = isExplodedVisitor;
  7. exports.merge = merge;
  8. exports.verify = verify$1;
  9. var virtualTypes = require("./path/lib/virtual-types.js");
  10. var virtualTypesValidators = require("./path/lib/virtual-types-validator.js");
  11. var _t = require("@babel/types");
  12. const {
  13. DEPRECATED_KEYS,
  14. DEPRECATED_ALIASES,
  15. FLIPPED_ALIAS_KEYS,
  16. TYPES,
  17. __internal__deprecationWarning: deprecationWarning
  18. } = _t;
  19. function isVirtualType(type) {
  20. return type in virtualTypes;
  21. }
  22. function isExplodedVisitor(visitor) {
  23. return visitor == null ? void 0 : visitor._exploded;
  24. }
  25. function explode$1(visitor) {
  26. if (isExplodedVisitor(visitor)) return visitor;
  27. visitor._exploded = true;
  28. for (const nodeType of Object.keys(visitor)) {
  29. if (shouldIgnoreKey(nodeType)) continue;
  30. const parts = nodeType.split("|");
  31. if (parts.length === 1) continue;
  32. const fns = visitor[nodeType];
  33. delete visitor[nodeType];
  34. for (const part of parts) {
  35. visitor[part] = fns;
  36. }
  37. }
  38. verify$1(visitor);
  39. delete visitor.__esModule;
  40. ensureEntranceObjects(visitor);
  41. ensureCallbackArrays(visitor);
  42. for (const nodeType of Object.keys(visitor)) {
  43. if (shouldIgnoreKey(nodeType)) continue;
  44. if (!isVirtualType(nodeType)) continue;
  45. const fns = visitor[nodeType];
  46. for (const type of Object.keys(fns)) {
  47. fns[type] = wrapCheck(nodeType, fns[type]);
  48. }
  49. delete visitor[nodeType];
  50. const types = virtualTypes[nodeType];
  51. if (types !== null) {
  52. for (const type of types) {
  53. if (visitor[type]) {
  54. mergePair(visitor[type], fns);
  55. } else {
  56. visitor[type] = fns;
  57. }
  58. }
  59. } else {
  60. mergePair(visitor, fns);
  61. }
  62. }
  63. for (const nodeType of Object.keys(visitor)) {
  64. if (shouldIgnoreKey(nodeType)) continue;
  65. let aliases = FLIPPED_ALIAS_KEYS[nodeType];
  66. if (nodeType in DEPRECATED_KEYS) {
  67. const deprecatedKey = DEPRECATED_KEYS[nodeType];
  68. deprecationWarning(nodeType, deprecatedKey, "Visitor ");
  69. aliases = [deprecatedKey];
  70. } else if (nodeType in DEPRECATED_ALIASES) {
  71. const deprecatedAlias = DEPRECATED_ALIASES[nodeType];
  72. deprecationWarning(nodeType, deprecatedAlias, "Visitor ");
  73. aliases = FLIPPED_ALIAS_KEYS[deprecatedAlias];
  74. }
  75. if (!aliases) continue;
  76. const fns = visitor[nodeType];
  77. delete visitor[nodeType];
  78. for (const alias of aliases) {
  79. const existing = visitor[alias];
  80. if (existing) {
  81. mergePair(existing, fns);
  82. } else {
  83. visitor[alias] = Object.assign({}, fns);
  84. }
  85. }
  86. }
  87. for (const nodeType of Object.keys(visitor)) {
  88. if (shouldIgnoreKey(nodeType)) continue;
  89. ensureCallbackArrays(visitor[nodeType]);
  90. }
  91. return visitor;
  92. }
  93. function verify$1(visitor) {
  94. if (visitor._verified) return;
  95. if (typeof visitor === "function") {
  96. throw new Error("You passed `traverse()` a function when it expected a visitor object, " + "are you sure you didn't mean `{ enter: Function }`?");
  97. }
  98. for (const nodeType of Object.keys(visitor)) {
  99. if (nodeType === "enter" || nodeType === "exit") {
  100. validateVisitorMethods(nodeType, visitor[nodeType]);
  101. }
  102. if (shouldIgnoreKey(nodeType)) continue;
  103. if (TYPES.indexOf(nodeType) < 0) {
  104. throw new Error(`You gave us a visitor for the node type ${nodeType} but it's not a valid type`);
  105. }
  106. const visitors = visitor[nodeType];
  107. if (typeof visitors === "object") {
  108. for (const visitorKey of Object.keys(visitors)) {
  109. if (visitorKey === "enter" || visitorKey === "exit") {
  110. validateVisitorMethods(`${nodeType}.${visitorKey}`, visitors[visitorKey]);
  111. } else {
  112. throw new Error("You passed `traverse()` a visitor object with the property " + `${nodeType} that has the invalid property ${visitorKey}`);
  113. }
  114. }
  115. }
  116. }
  117. visitor._verified = true;
  118. }
  119. function validateVisitorMethods(path, val) {
  120. const fns = [].concat(val);
  121. for (const fn of fns) {
  122. if (typeof fn !== "function") {
  123. throw new TypeError(`Non-function found defined in ${path} with type ${typeof fn}`);
  124. }
  125. }
  126. }
  127. function merge(visitors, states = [], wrapper) {
  128. const mergedVisitor = {};
  129. for (let i = 0; i < visitors.length; i++) {
  130. const visitor = explode$1(visitors[i]);
  131. const state = states[i];
  132. let topVisitor = visitor;
  133. if (state || wrapper) {
  134. topVisitor = wrapWithStateOrWrapper(topVisitor, state, wrapper);
  135. }
  136. mergePair(mergedVisitor, topVisitor);
  137. for (const key of Object.keys(visitor)) {
  138. if (shouldIgnoreKey(key)) continue;
  139. let typeVisitor = visitor[key];
  140. if (state || wrapper) {
  141. typeVisitor = wrapWithStateOrWrapper(typeVisitor, state, wrapper);
  142. }
  143. const nodeVisitor = mergedVisitor[key] || (mergedVisitor[key] = {});
  144. mergePair(nodeVisitor, typeVisitor);
  145. }
  146. }
  147. ;
  148. return mergedVisitor;
  149. }
  150. function wrapWithStateOrWrapper(oldVisitor, state, wrapper) {
  151. const newVisitor = {};
  152. for (const phase of ["enter", "exit"]) {
  153. let fns = oldVisitor[phase];
  154. if (!Array.isArray(fns)) continue;
  155. fns = fns.map(function (fn) {
  156. let newFn = fn;
  157. if (state) {
  158. newFn = function (path) {
  159. fn.call(state, path, state);
  160. };
  161. }
  162. if (wrapper) {
  163. newFn = wrapper(state == null ? void 0 : state.key, phase, newFn);
  164. }
  165. if (newFn !== fn) {
  166. newFn.toString = () => fn.toString();
  167. }
  168. return newFn;
  169. });
  170. newVisitor[phase] = fns;
  171. }
  172. return newVisitor;
  173. }
  174. function ensureEntranceObjects(obj) {
  175. for (const key of Object.keys(obj)) {
  176. if (shouldIgnoreKey(key)) continue;
  177. const fns = obj[key];
  178. if (typeof fns === "function") {
  179. obj[key] = {
  180. enter: fns
  181. };
  182. }
  183. }
  184. }
  185. function ensureCallbackArrays(obj) {
  186. if (obj.enter && !Array.isArray(obj.enter)) obj.enter = [obj.enter];
  187. if (obj.exit && !Array.isArray(obj.exit)) obj.exit = [obj.exit];
  188. }
  189. function wrapCheck(nodeType, fn) {
  190. const fnKey = `is${nodeType}`;
  191. const validator = virtualTypesValidators[fnKey];
  192. const newFn = function (path) {
  193. if (validator.call(path)) {
  194. return fn.apply(this, arguments);
  195. }
  196. };
  197. newFn.toString = () => fn.toString();
  198. return newFn;
  199. }
  200. function shouldIgnoreKey(key) {
  201. if (key[0] === "_") return true;
  202. if (key === "enter" || key === "exit" || key === "shouldSkip") return true;
  203. if (key === "denylist" || key === "noScope" || key === "skipKeys") {
  204. return true;
  205. }
  206. {
  207. if (key === "blacklist") {
  208. return true;
  209. }
  210. }
  211. return false;
  212. }
  213. function mergePair(dest, src) {
  214. for (const phase of ["enter", "exit"]) {
  215. if (!src[phase]) continue;
  216. dest[phase] = [].concat(dest[phase] || [], src[phase]);
  217. }
  218. }
  219. //# sourceMappingURL=visitors.js.map