Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80738 views
1
define(
2
["../exception","./ast","exports"],
3
function(__dependency1__, __dependency2__, __exports__) {
4
"use strict";
5
var Exception = __dependency1__["default"];
6
var AST = __dependency2__["default"];
7
8
function Visitor() {
9
this.parents = [];
10
}
11
12
Visitor.prototype = {
13
constructor: Visitor,
14
mutating: false,
15
16
// Visits a given value. If mutating, will replace the value if necessary.
17
acceptKey: function(node, name) {
18
var value = this.accept(node[name]);
19
if (this.mutating) {
20
// Hacky sanity check:
21
if (value && (!value.type || !AST[value.type])) {
22
throw new Exception('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
23
}
24
node[name] = value;
25
}
26
},
27
28
// Performs an accept operation with added sanity check to ensure
29
// required keys are not removed.
30
acceptRequired: function(node, name) {
31
this.acceptKey(node, name);
32
33
if (!node[name]) {
34
throw new Exception(node.type + ' requires ' + name);
35
}
36
},
37
38
// Traverses a given array. If mutating, empty respnses will be removed
39
// for child elements.
40
acceptArray: function(array) {
41
for (var i = 0, l = array.length; i < l; i++) {
42
this.acceptKey(array, i);
43
44
if (!array[i]) {
45
array.splice(i, 1);
46
i--;
47
l--;
48
}
49
}
50
},
51
52
accept: function(object) {
53
if (!object) {
54
return;
55
}
56
57
if (this.current) {
58
this.parents.unshift(this.current);
59
}
60
this.current = object;
61
62
var ret = this[object.type](object);
63
64
this.current = this.parents.shift();
65
66
if (!this.mutating || ret) {
67
return ret;
68
} else if (ret !== false) {
69
return object;
70
}
71
},
72
73
Program: function(program) {
74
this.acceptArray(program.body);
75
},
76
77
MustacheStatement: function(mustache) {
78
this.acceptRequired(mustache, 'path');
79
this.acceptArray(mustache.params);
80
this.acceptKey(mustache, 'hash');
81
},
82
83
BlockStatement: function(block) {
84
this.acceptRequired(block, 'path');
85
this.acceptArray(block.params);
86
this.acceptKey(block, 'hash');
87
88
this.acceptKey(block, 'program');
89
this.acceptKey(block, 'inverse');
90
},
91
92
PartialStatement: function(partial) {
93
this.acceptRequired(partial, 'name');
94
this.acceptArray(partial.params);
95
this.acceptKey(partial, 'hash');
96
},
97
98
ContentStatement: function(/* content */) {},
99
CommentStatement: function(/* comment */) {},
100
101
SubExpression: function(sexpr) {
102
this.acceptRequired(sexpr, 'path');
103
this.acceptArray(sexpr.params);
104
this.acceptKey(sexpr, 'hash');
105
},
106
PartialExpression: function(partial) {
107
this.acceptRequired(partial, 'name');
108
this.acceptArray(partial.params);
109
this.acceptKey(partial, 'hash');
110
},
111
112
PathExpression: function(/* path */) {},
113
114
StringLiteral: function(/* string */) {},
115
NumberLiteral: function(/* number */) {},
116
BooleanLiteral: function(/* bool */) {},
117
118
Hash: function(hash) {
119
this.acceptArray(hash.pairs);
120
},
121
HashPair: function(pair) {
122
this.acceptRequired(pair, 'value');
123
}
124
};
125
126
__exports__["default"] = Visitor;
127
});
128