UNPKG

4.66 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var tree_1 = tslib_1.__importDefault(require("../tree"));
5var _visitArgs = { visitDeeper: true };
6var _hasIndexed = false;
7function _noop(node) {
8 return node;
9}
10function indexNodeTypes(parent, ticker) {
11 // add .typeIndex to tree node types for lookup table
12 var key, child;
13 for (key in parent) {
14 /* eslint guard-for-in: 0 */
15 child = parent[key];
16 switch (typeof child) {
17 case 'function':
18 // ignore bound functions directly on tree which do not have a prototype
19 // or aren't nodes
20 if (child.prototype && child.prototype.type) {
21 child.prototype.typeIndex = ticker++;
22 }
23 break;
24 case 'object':
25 ticker = indexNodeTypes(child, ticker);
26 break;
27 }
28 }
29 return ticker;
30}
31var Visitor = /** @class */ (function () {
32 function Visitor(implementation) {
33 this._implementation = implementation;
34 this._visitInCache = {};
35 this._visitOutCache = {};
36 if (!_hasIndexed) {
37 indexNodeTypes(tree_1.default, 1);
38 _hasIndexed = true;
39 }
40 }
41 Visitor.prototype.visit = function (node) {
42 if (!node) {
43 return node;
44 }
45 var nodeTypeIndex = node.typeIndex;
46 if (!nodeTypeIndex) {
47 // MixinCall args aren't a node type?
48 if (node.value && node.value.typeIndex) {
49 this.visit(node.value);
50 }
51 return node;
52 }
53 var impl = this._implementation;
54 var func = this._visitInCache[nodeTypeIndex];
55 var funcOut = this._visitOutCache[nodeTypeIndex];
56 var visitArgs = _visitArgs;
57 var fnName;
58 visitArgs.visitDeeper = true;
59 if (!func) {
60 fnName = "visit" + node.type;
61 func = impl[fnName] || _noop;
62 funcOut = impl[fnName + "Out"] || _noop;
63 this._visitInCache[nodeTypeIndex] = func;
64 this._visitOutCache[nodeTypeIndex] = funcOut;
65 }
66 if (func !== _noop) {
67 var newNode = func.call(impl, node, visitArgs);
68 if (node && impl.isReplacing) {
69 node = newNode;
70 }
71 }
72 if (visitArgs.visitDeeper && node) {
73 if (node.length) {
74 for (var i = 0, cnt = node.length; i < cnt; i++) {
75 if (node[i].accept) {
76 node[i].accept(this);
77 }
78 }
79 }
80 else if (node.accept) {
81 node.accept(this);
82 }
83 }
84 if (funcOut != _noop) {
85 funcOut.call(impl, node);
86 }
87 return node;
88 };
89 Visitor.prototype.visitArray = function (nodes, nonReplacing) {
90 if (!nodes) {
91 return nodes;
92 }
93 var cnt = nodes.length;
94 var i;
95 // Non-replacing
96 if (nonReplacing || !this._implementation.isReplacing) {
97 for (i = 0; i < cnt; i++) {
98 this.visit(nodes[i]);
99 }
100 return nodes;
101 }
102 // Replacing
103 var out = [];
104 for (i = 0; i < cnt; i++) {
105 var evald = this.visit(nodes[i]);
106 if (evald === undefined) {
107 continue;
108 }
109 if (!evald.splice) {
110 out.push(evald);
111 }
112 else if (evald.length) {
113 this.flatten(evald, out);
114 }
115 }
116 return out;
117 };
118 Visitor.prototype.flatten = function (arr, out) {
119 if (!out) {
120 out = [];
121 }
122 var cnt, i, item, nestedCnt, j, nestedItem;
123 for (i = 0, cnt = arr.length; i < cnt; i++) {
124 item = arr[i];
125 if (item === undefined) {
126 continue;
127 }
128 if (!item.splice) {
129 out.push(item);
130 continue;
131 }
132 for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) {
133 nestedItem = item[j];
134 if (nestedItem === undefined) {
135 continue;
136 }
137 if (!nestedItem.splice) {
138 out.push(nestedItem);
139 }
140 else if (nestedItem.length) {
141 this.flatten(nestedItem, out);
142 }
143 }
144 }
145 return out;
146 };
147 return Visitor;
148}());
149exports.default = Visitor;
150//# sourceMappingURL=visitor.js.map
\No newline at end of file