visitors.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. "use strict";
  2. exports.__esModule = true;
  3. var _typeof2 = require("babel-runtime/helpers/typeof");
  4. var _typeof3 = _interopRequireDefault(_typeof2);
  5. var _keys = require("babel-runtime/core-js/object/keys");
  6. var _keys2 = _interopRequireDefault(_keys);
  7. var _getIterator2 = require("babel-runtime/core-js/get-iterator");
  8. var _getIterator3 = _interopRequireDefault(_getIterator2);
  9. exports.explode = explode;
  10. exports.verify = verify;
  11. exports.merge = merge;
  12. var _virtualTypes = require("./path/lib/virtual-types");
  13. var virtualTypes = _interopRequireWildcard(_virtualTypes);
  14. var _babelMessages = require("babel-messages");
  15. var messages = _interopRequireWildcard(_babelMessages);
  16. var _babelTypes = require("babel-types");
  17. var t = _interopRequireWildcard(_babelTypes);
  18. var _clone = require("lodash/clone");
  19. var _clone2 = _interopRequireDefault(_clone);
  20. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  21. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  22. function explode(visitor) {
  23. if (visitor._exploded) return visitor;
  24. visitor._exploded = true;
  25. for (var nodeType in visitor) {
  26. if (shouldIgnoreKey(nodeType)) continue;
  27. var parts = nodeType.split("|");
  28. if (parts.length === 1) continue;
  29. var fns = visitor[nodeType];
  30. delete visitor[nodeType];
  31. for (var _iterator = parts, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, _getIterator3.default)(_iterator);;) {
  32. var _ref;
  33. if (_isArray) {
  34. if (_i >= _iterator.length) break;
  35. _ref = _iterator[_i++];
  36. } else {
  37. _i = _iterator.next();
  38. if (_i.done) break;
  39. _ref = _i.value;
  40. }
  41. var part = _ref;
  42. visitor[part] = fns;
  43. }
  44. }
  45. verify(visitor);
  46. delete visitor.__esModule;
  47. ensureEntranceObjects(visitor);
  48. ensureCallbackArrays(visitor);
  49. for (var _iterator2 = (0, _keys2.default)(visitor), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : (0, _getIterator3.default)(_iterator2);;) {
  50. var _ref2;
  51. if (_isArray2) {
  52. if (_i2 >= _iterator2.length) break;
  53. _ref2 = _iterator2[_i2++];
  54. } else {
  55. _i2 = _iterator2.next();
  56. if (_i2.done) break;
  57. _ref2 = _i2.value;
  58. }
  59. var _nodeType3 = _ref2;
  60. if (shouldIgnoreKey(_nodeType3)) continue;
  61. var wrapper = virtualTypes[_nodeType3];
  62. if (!wrapper) continue;
  63. var _fns2 = visitor[_nodeType3];
  64. for (var type in _fns2) {
  65. _fns2[type] = wrapCheck(wrapper, _fns2[type]);
  66. }
  67. delete visitor[_nodeType3];
  68. if (wrapper.types) {
  69. for (var _iterator4 = wrapper.types, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : (0, _getIterator3.default)(_iterator4);;) {
  70. var _ref4;
  71. if (_isArray4) {
  72. if (_i4 >= _iterator4.length) break;
  73. _ref4 = _iterator4[_i4++];
  74. } else {
  75. _i4 = _iterator4.next();
  76. if (_i4.done) break;
  77. _ref4 = _i4.value;
  78. }
  79. var _type = _ref4;
  80. if (visitor[_type]) {
  81. mergePair(visitor[_type], _fns2);
  82. } else {
  83. visitor[_type] = _fns2;
  84. }
  85. }
  86. } else {
  87. mergePair(visitor, _fns2);
  88. }
  89. }
  90. for (var _nodeType in visitor) {
  91. if (shouldIgnoreKey(_nodeType)) continue;
  92. var _fns = visitor[_nodeType];
  93. var aliases = t.FLIPPED_ALIAS_KEYS[_nodeType];
  94. var deprecratedKey = t.DEPRECATED_KEYS[_nodeType];
  95. if (deprecratedKey) {
  96. console.trace("Visitor defined for " + _nodeType + " but it has been renamed to " + deprecratedKey);
  97. aliases = [deprecratedKey];
  98. }
  99. if (!aliases) continue;
  100. delete visitor[_nodeType];
  101. for (var _iterator3 = aliases, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : (0, _getIterator3.default)(_iterator3);;) {
  102. var _ref3;
  103. if (_isArray3) {
  104. if (_i3 >= _iterator3.length) break;
  105. _ref3 = _iterator3[_i3++];
  106. } else {
  107. _i3 = _iterator3.next();
  108. if (_i3.done) break;
  109. _ref3 = _i3.value;
  110. }
  111. var alias = _ref3;
  112. var existing = visitor[alias];
  113. if (existing) {
  114. mergePair(existing, _fns);
  115. } else {
  116. visitor[alias] = (0, _clone2.default)(_fns);
  117. }
  118. }
  119. }
  120. for (var _nodeType2 in visitor) {
  121. if (shouldIgnoreKey(_nodeType2)) continue;
  122. ensureCallbackArrays(visitor[_nodeType2]);
  123. }
  124. return visitor;
  125. }
  126. function verify(visitor) {
  127. if (visitor._verified) return;
  128. if (typeof visitor === "function") {
  129. throw new Error(messages.get("traverseVerifyRootFunction"));
  130. }
  131. for (var nodeType in visitor) {
  132. if (nodeType === "enter" || nodeType === "exit") {
  133. validateVisitorMethods(nodeType, visitor[nodeType]);
  134. }
  135. if (shouldIgnoreKey(nodeType)) continue;
  136. if (t.TYPES.indexOf(nodeType) < 0) {
  137. throw new Error(messages.get("traverseVerifyNodeType", nodeType));
  138. }
  139. var visitors = visitor[nodeType];
  140. if ((typeof visitors === "undefined" ? "undefined" : (0, _typeof3.default)(visitors)) === "object") {
  141. for (var visitorKey in visitors) {
  142. if (visitorKey === "enter" || visitorKey === "exit") {
  143. validateVisitorMethods(nodeType + "." + visitorKey, visitors[visitorKey]);
  144. } else {
  145. throw new Error(messages.get("traverseVerifyVisitorProperty", nodeType, visitorKey));
  146. }
  147. }
  148. }
  149. }
  150. visitor._verified = true;
  151. }
  152. function validateVisitorMethods(path, val) {
  153. var fns = [].concat(val);
  154. for (var _iterator5 = fns, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : (0, _getIterator3.default)(_iterator5);;) {
  155. var _ref5;
  156. if (_isArray5) {
  157. if (_i5 >= _iterator5.length) break;
  158. _ref5 = _iterator5[_i5++];
  159. } else {
  160. _i5 = _iterator5.next();
  161. if (_i5.done) break;
  162. _ref5 = _i5.value;
  163. }
  164. var fn = _ref5;
  165. if (typeof fn !== "function") {
  166. throw new TypeError("Non-function found defined in " + path + " with type " + (typeof fn === "undefined" ? "undefined" : (0, _typeof3.default)(fn)));
  167. }
  168. }
  169. }
  170. function merge(visitors) {
  171. var states = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  172. var wrapper = arguments[2];
  173. var rootVisitor = {};
  174. for (var i = 0; i < visitors.length; i++) {
  175. var visitor = visitors[i];
  176. var state = states[i];
  177. explode(visitor);
  178. for (var type in visitor) {
  179. var visitorType = visitor[type];
  180. if (state || wrapper) {
  181. visitorType = wrapWithStateOrWrapper(visitorType, state, wrapper);
  182. }
  183. var nodeVisitor = rootVisitor[type] = rootVisitor[type] || {};
  184. mergePair(nodeVisitor, visitorType);
  185. }
  186. }
  187. return rootVisitor;
  188. }
  189. function wrapWithStateOrWrapper(oldVisitor, state, wrapper) {
  190. var newVisitor = {};
  191. var _loop = function _loop(key) {
  192. var fns = oldVisitor[key];
  193. if (!Array.isArray(fns)) return "continue";
  194. fns = fns.map(function (fn) {
  195. var newFn = fn;
  196. if (state) {
  197. newFn = function newFn(path) {
  198. return fn.call(state, path, state);
  199. };
  200. }
  201. if (wrapper) {
  202. newFn = wrapper(state.key, key, newFn);
  203. }
  204. return newFn;
  205. });
  206. newVisitor[key] = fns;
  207. };
  208. for (var key in oldVisitor) {
  209. var _ret = _loop(key);
  210. if (_ret === "continue") continue;
  211. }
  212. return newVisitor;
  213. }
  214. function ensureEntranceObjects(obj) {
  215. for (var key in obj) {
  216. if (shouldIgnoreKey(key)) continue;
  217. var fns = obj[key];
  218. if (typeof fns === "function") {
  219. obj[key] = { enter: fns };
  220. }
  221. }
  222. }
  223. function ensureCallbackArrays(obj) {
  224. if (obj.enter && !Array.isArray(obj.enter)) obj.enter = [obj.enter];
  225. if (obj.exit && !Array.isArray(obj.exit)) obj.exit = [obj.exit];
  226. }
  227. function wrapCheck(wrapper, fn) {
  228. var newFn = function newFn(path) {
  229. if (wrapper.checkPath(path)) {
  230. return fn.apply(this, arguments);
  231. }
  232. };
  233. newFn.toString = function () {
  234. return fn.toString();
  235. };
  236. return newFn;
  237. }
  238. function shouldIgnoreKey(key) {
  239. if (key[0] === "_") return true;
  240. if (key === "enter" || key === "exit" || key === "shouldSkip") return true;
  241. if (key === "blacklist" || key === "noScope" || key === "skipKeys") return true;
  242. return false;
  243. }
  244. function mergePair(dest, src) {
  245. for (var key in src) {
  246. dest[key] = [].concat(dest[key] || [], src[key]);
  247. }
  248. }