1 import Exception from '../exception';
11 // Visits a given value. If mutating, will replace the value if necessary.
12 acceptKey: function(node, name) {
13 let value = this.accept(node[name]);
15 // Hacky sanity check: This may have a few false positives for type for the helper
16 // methods but will generally do the right thing without a lot of overhead.
17 if (value && !Visitor.prototype[value.type]) {
18 throw new Exception('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
24 // Performs an accept operation with added sanity check to ensure
25 // required keys are not removed.
26 acceptRequired: function(node, name) {
27 this.acceptKey(node, name);
30 throw new Exception(node.type + ' requires ' + name);
34 // Traverses a given array. If mutating, empty respnses will be removed
35 // for child elements.
36 acceptArray: function(array) {
37 for (let i = 0, l = array.length; i < l; i++) {
38 this.acceptKey(array, i);
48 accept: function(object) {
53 /* istanbul ignore next: Sanity code */
54 if (!this[object.type]) {
55 throw new Exception('Unknown type: ' + object.type, object);
59 this.parents.unshift(this.current);
61 this.current = object;
63 let ret = this[object.type](object);
65 this.current = this.parents.shift();
67 if (!this.mutating || ret) {
69 } else if (ret !== false) {
74 Program: function(program) {
75 this.acceptArray(program.body);
78 MustacheStatement: visitSubExpression,
79 Decorator: visitSubExpression,
81 BlockStatement: visitBlock,
82 DecoratorBlock: visitBlock,
84 PartialStatement: visitPartial,
85 PartialBlockStatement: function(partial) {
86 visitPartial.call(this, partial);
88 this.acceptKey(partial, 'program');
91 ContentStatement: function(/* content */) {},
92 CommentStatement: function(/* comment */) {},
94 SubExpression: visitSubExpression,
96 PathExpression: function(/* path */) {},
98 StringLiteral: function(/* string */) {},
99 NumberLiteral: function(/* number */) {},
100 BooleanLiteral: function(/* bool */) {},
101 UndefinedLiteral: function(/* literal */) {},
102 NullLiteral: function(/* literal */) {},
104 Hash: function(hash) {
105 this.acceptArray(hash.pairs);
107 HashPair: function(pair) {
108 this.acceptRequired(pair, 'value');
112 function visitSubExpression(mustache) {
113 this.acceptRequired(mustache, 'path');
114 this.acceptArray(mustache.params);
115 this.acceptKey(mustache, 'hash');
117 function visitBlock(block) {
118 visitSubExpression.call(this, block);
120 this.acceptKey(block, 'program');
121 this.acceptKey(block, 'inverse');
123 function visitPartial(partial) {
124 this.acceptRequired(partial, 'name');
125 this.acceptArray(partial.params);
126 this.acceptKey(partial, 'hash');
129 export default Visitor;