1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var tree_1 = tslib_1.__importDefault(require("../tree"));
|
5 | var _visitArgs = { visitDeeper: true };
|
6 | var _hasIndexed = false;
|
7 | function _noop(node) {
|
8 | return node;
|
9 | }
|
10 | function indexNodeTypes(parent, ticker) {
|
11 |
|
12 | var key, child;
|
13 | for (key in parent) {
|
14 |
|
15 | child = parent[key];
|
16 | switch (typeof child) {
|
17 | case 'function':
|
18 |
|
19 |
|
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 | }
|
31 | var Visitor = (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 |
|
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 |
|
96 | if (nonReplacing || !this._implementation.isReplacing) {
|
97 | for (i = 0; i < cnt; i++) {
|
98 | this.visit(nodes[i]);
|
99 | }
|
100 | return nodes;
|
101 | }
|
102 |
|
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 | }());
|
149 | exports.default = Visitor;
|
150 |
|
\ | No newline at end of file |