collections_Node.js.html 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSDoc: Source: collections/Node.js</title>
  6. <script src="scripts/prettify/prettify.js"> </script>
  7. <script src="scripts/prettify/lang-css.js"> </script>
  8. <!--[if lt IE 9]>
  9. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  10. <![endif]-->
  11. <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
  12. <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
  13. </head>
  14. <body>
  15. <div id="main">
  16. <h1 class="page-title">Source: collections/Node.js</h1>
  17. <section>
  18. <article>
  19. <pre class="prettyprint source linenums"><code>/*
  20. * Copyright (c) 2015-present, Facebook, Inc.
  21. * All rights reserved.
  22. *
  23. * This source code is licensed under the BSD-style license found in the
  24. * LICENSE file in the root directory of this source tree. An additional grant
  25. * of patent rights can be found in the PATENTS file in the same directory.
  26. *
  27. */
  28. 'use strict';
  29. var _ = require('lodash');
  30. var Collection = require('../Collection');
  31. var matchNode = require('../matchNode');
  32. var recast = require('recast');
  33. var Node = recast.types.namedTypes.Node;
  34. var types = recast.types.namedTypes;
  35. /**
  36. * @mixin
  37. */
  38. var traversalMethods = {
  39. /**
  40. * Find nodes of a specific type within the nodes of this collection.
  41. *
  42. * @param {type}
  43. * @param {filter}
  44. * @return {Collection}
  45. */
  46. find: function(type, filter) {
  47. var paths = [];
  48. var visitorMethodName = 'visit' + type;
  49. var visitor = {};
  50. function visit(path) {
  51. /*jshint validthis:true */
  52. if (!filter || matchNode(path.value, filter)) {
  53. paths.push(path);
  54. }
  55. this.traverse(path);
  56. }
  57. this.__paths.forEach(function(p, i) {
  58. var self = this;
  59. visitor[visitorMethodName] = function(path) {
  60. if (self.__paths[i] === path) {
  61. this.traverse(path);
  62. } else {
  63. return visit.call(this, path);
  64. }
  65. };
  66. recast.visit(p, visitor);
  67. }, this);
  68. return Collection.fromPaths(paths, this, type);
  69. },
  70. /**
  71. * Returns a collection containing the paths that create the scope of the
  72. * currently selected paths. Dedupes the paths.
  73. *
  74. * @return {Collection}
  75. */
  76. closestScope: function() {
  77. return this.map(path => path.scope &amp;&amp; path.scope.path);
  78. },
  79. /**
  80. * Traverse the AST up and finds the closest node of the provided type.
  81. *
  82. * @param {Collection}
  83. * @param {filter}
  84. * @return {Collection}
  85. */
  86. closest: function(type, filter) {
  87. return this.map(function(path) {
  88. var parent = path.parent;
  89. while (
  90. parent &amp;&amp;
  91. !(
  92. type.check(parent.value) &amp;&amp;
  93. (!filter || matchNode(parent.value, filter))
  94. )
  95. ) {
  96. parent = parent.parent;
  97. }
  98. return parent || null;
  99. });
  100. },
  101. /**
  102. * Finds the declaration for each selected path. Useful for member expressions
  103. * or JSXElements. Expects a callback function that maps each path to the name
  104. * to look for.
  105. *
  106. * If the callback returns a falsey value, the element is skipped.
  107. *
  108. * @param {function} nameGetter
  109. *
  110. * @return {Collection}
  111. */
  112. getVariableDeclarators: function(nameGetter) {
  113. return this.map(function(path) {
  114. /*jshint curly:false*/
  115. var scope = path.scope;
  116. if (!scope) return;
  117. var name = nameGetter.apply(path, arguments);
  118. if (!name) return;
  119. scope = scope.lookup(name);
  120. if (!scope) return;
  121. var bindings = scope.getBindings()[name];
  122. if (!bindings) return;
  123. var decl = Collection.fromPaths(bindings)
  124. .closest(types.VariableDeclarator);
  125. if (decl.length === 1) {
  126. return decl.paths()[0];
  127. }
  128. }, types.VariableDeclarator);
  129. },
  130. };
  131. function toArray(value) {
  132. return Array.isArray(value) ? value : [value];
  133. }
  134. /**
  135. * @mixin
  136. */
  137. var mutationMethods = {
  138. /**
  139. * Simply replaces the selected nodes with the provided node. If a function
  140. * is provided it is executed for every node and the node is replaced with the
  141. * functions return value.
  142. *
  143. * @param {Node|Array&lt;Node>|function} nodes
  144. * @return {Collection}
  145. */
  146. replaceWith: function(nodes) {
  147. return this.forEach(function(path, i) {
  148. var newNodes =
  149. (typeof nodes === 'function') ? nodes.call(path, path, i) : nodes;
  150. path.replace.apply(path, toArray(newNodes));
  151. });
  152. },
  153. /**
  154. * Inserts a new node before the current one.
  155. *
  156. * @param {Node|Array&lt;Node>|function} insert
  157. * @return {Collection}
  158. */
  159. insertBefore: function(insert) {
  160. return this.forEach(function(path, i) {
  161. var newNodes =
  162. (typeof insert === 'function') ? insert.call(path, path, i) : insert;
  163. path.insertBefore.apply(path, toArray(newNodes));
  164. });
  165. },
  166. /**
  167. * Inserts a new node after the current one.
  168. *
  169. * @param {Node|Array&lt;Node>|function} insert
  170. * @return {Collection}
  171. */
  172. insertAfter: function(insert) {
  173. return this.forEach(function(path, i) {
  174. var newNodes =
  175. (typeof insert === 'function') ? insert.call(path, path, i) : insert;
  176. path.insertAfter.apply(path, toArray(newNodes));
  177. });
  178. },
  179. remove: function() {
  180. return this.forEach(path => path.prune());
  181. }
  182. };
  183. function register() {
  184. Collection.registerMethods(traversalMethods, Node);
  185. Collection.registerMethods(mutationMethods, Node);
  186. Collection.setDefaultCollectionType(Node);
  187. }
  188. exports.register = _.once(register);
  189. </code></pre>
  190. </article>
  191. </section>
  192. </div>
  193. <nav>
  194. <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-jscodeshift.html">jscodeshift</a></li></ul><h3>Externals</h3><ul><li><a href="external-astTypes.html">astTypes</a></li></ul><h3>Classes</h3><ul><li><a href="Collection.html">Collection</a></li></ul><h3>Mixins</h3><ul><li><a href="globalMethods.html">globalMethods</a></li><li><a href="mutationMethods.html">mutationMethods</a></li><li><a href="transformMethods.html">transformMethods</a></li><li><a href="traversalMethods.html">traversalMethods</a></li></ul><h3>Global</h3><ul><li><a href="global.html#registerMethods">registerMethods</a></li></ul>
  195. </nav>
  196. <br class="clear">
  197. <footer>
  198. Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.1</a> on Wed Sep 21 2016 16:53:09 GMT-0400 (EDT)
  199. </footer>
  200. <script> prettyPrint(); </script>
  201. <script src="scripts/linenumber.js"> </script>
  202. </body>
  203. </html>