105 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| 
 | |
| Object.defineProperty(exports, "__esModule", {
 | |
|   value: true
 | |
| });
 | |
| exports.traverse = traverse;
 | |
| 
 | |
| var _nodePath = require("./node-path");
 | |
| 
 | |
| var _nodes = require("./nodes");
 | |
| 
 | |
| // recursively walks the AST starting at the given node. The callback is invoked for
 | |
| // and object that has a 'type' property.
 | |
| function walk(context, callback) {
 | |
|   var stop = false;
 | |
| 
 | |
|   function innerWalk(context, callback) {
 | |
|     if (stop) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     var node = context.node;
 | |
| 
 | |
|     if (node === undefined) {
 | |
|       console.warn("traversing with an empty context");
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (node._deleted === true) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     var path = (0, _nodePath.createPath)(context);
 | |
|     callback(node.type, path);
 | |
| 
 | |
|     if (path.shouldStop) {
 | |
|       stop = true;
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     Object.keys(node).forEach(function (prop) {
 | |
|       var value = node[prop];
 | |
| 
 | |
|       if (value === null || value === undefined) {
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       var valueAsArray = Array.isArray(value) ? value : [value];
 | |
|       valueAsArray.forEach(function (childNode) {
 | |
|         if (typeof childNode.type === "string") {
 | |
|           var childContext = {
 | |
|             node: childNode,
 | |
|             parentKey: prop,
 | |
|             parentPath: path,
 | |
|             shouldStop: false,
 | |
|             inList: Array.isArray(value)
 | |
|           };
 | |
|           innerWalk(childContext, callback);
 | |
|         }
 | |
|       });
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   innerWalk(context, callback);
 | |
| }
 | |
| 
 | |
| var noop = function noop() {};
 | |
| 
 | |
| function traverse(node, visitors) {
 | |
|   var before = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop;
 | |
|   var after = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : noop;
 | |
|   Object.keys(visitors).forEach(function (visitor) {
 | |
|     if (!_nodes.nodeAndUnionTypes.includes(visitor)) {
 | |
|       throw new Error("Unexpected visitor ".concat(visitor));
 | |
|     }
 | |
|   });
 | |
|   var context = {
 | |
|     node: node,
 | |
|     inList: false,
 | |
|     shouldStop: false,
 | |
|     parentPath: null,
 | |
|     parentKey: null
 | |
|   };
 | |
|   walk(context, function (type, path) {
 | |
|     if (typeof visitors[type] === "function") {
 | |
|       before(type, path);
 | |
|       visitors[type](path);
 | |
|       after(type, path);
 | |
|     }
 | |
| 
 | |
|     var unionTypes = _nodes.unionTypesMap[type];
 | |
| 
 | |
|     if (!unionTypes) {
 | |
|       throw new Error("Unexpected node type ".concat(type));
 | |
|     }
 | |
| 
 | |
|     unionTypes.forEach(function (unionType) {
 | |
|       if (typeof visitors[unionType] === "function") {
 | |
|         before(unionType, path);
 | |
|         visitors[unionType](path);
 | |
|         after(unionType, path);
 | |
|       }
 | |
|     });
 | |
|   });
 | |
| } |