start: "[AST_Token] The first token of this node",
end: "[AST_Token] The last token of this node"
},
- _walk: function(visitor) {
- return visitor._visit(this);
- },
walk: function(visitor) {
- return this._walk(visitor); // not sure the indirection will be any help
+ return visitor.visit(this);
}
}, null);
$propdoc: {
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.body._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.body.walk(visitor);
});
}
}, AST_Statement);
function walk_body(node, visitor) {
node.body.forEach(function(node) {
- node._walk(visitor);
+ node.walk(visitor);
});
}
$propdoc: {
body: "[AST_Statement*] an array of statements"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- walk_body(this, visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ walk_body(node, visitor);
});
}
}, AST_Statement);
$propdoc: {
label: "[AST_Label] a label definition"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.label._walk(visitor);
- this.body._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.label.walk(visitor);
+ node.body.walk(visitor);
});
},
clone: function(deep) {
var AST_Do = DEFNODE("Do", null, {
$documentation: "A `do` statement",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.body._walk(visitor);
- this.condition._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.body.walk(visitor);
+ node.condition.walk(visitor);
});
}
}, AST_DWLoop);
var AST_While = DEFNODE("While", null, {
$documentation: "A `while` statement",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.condition._walk(visitor);
- this.body._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.condition.walk(visitor);
+ node.body.walk(visitor);
});
}
}, AST_DWLoop);
condition: "[AST_Node?] the `for` termination clause, or null if empty",
step: "[AST_Node?] the `for` update clause, or null if empty"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.init) this.init._walk(visitor);
- if (this.condition) this.condition._walk(visitor);
- if (this.step) this.step._walk(visitor);
- this.body._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ if (node.init) node.init.walk(visitor);
+ if (node.condition) node.condition.walk(visitor);
+ if (node.step) node.step.walk(visitor);
+ node.body.walk(visitor);
});
}
}, AST_IterationStatement);
init: "[AST_Node] the `for/in` initialization code",
object: "[AST_Node] the object that we're looping through"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.init._walk(visitor);
- this.object._walk(visitor);
- this.body._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.init.walk(visitor);
+ node.object.walk(visitor);
+ node.body.walk(visitor);
});
}
}, AST_IterationStatement);
$propdoc: {
expression: "[AST_Node] the `with` expression"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- this.body._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.expression.walk(visitor);
+ node.body.walk(visitor);
});
}
}, AST_StatementWithBody);
argnames: "[AST_SymbolFunarg*] array of function arguments",
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- if (this.name) this.name._walk(visitor);
- this.argnames.forEach(function(argname) {
- argname._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ if (node.name) node.name.walk(visitor);
+ node.argnames.forEach(function(argname) {
+ argname.walk(visitor);
});
- walk_body(this, visitor);
+ walk_body(node, visitor);
});
}
}, AST_Scope);
$propdoc: {
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
},
- _walk: function(visitor) {
- return visitor._visit(this, this.value && function() {
- this.value._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ if (node.value) node.value.walk(visitor);
});
}
}, AST_Jump);
$propdoc: {
label: "[AST_LabelRef?] the label, or null if none",
},
- _walk: function(visitor) {
- return visitor._visit(this, this.label && function() {
- this.label._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ if (node.label) node.label.walk(visitor);
});
}
}, AST_Jump);
condition: "[AST_Node] the `if` condition",
alternative: "[AST_Statement?] the `else` part, or null if not present"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.condition._walk(visitor);
- this.body._walk(visitor);
- if (this.alternative) this.alternative._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.condition.walk(visitor);
+ node.body.walk(visitor);
+ if (node.alternative) node.alternative.walk(visitor);
});
}
}, AST_StatementWithBody);
$propdoc: {
expression: "[AST_Node] the `switch` “discriminant”"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- walk_body(this, visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.expression.walk(visitor);
+ walk_body(node, visitor);
});
}
}, AST_Block);
$propdoc: {
expression: "[AST_Node] the `case` expression"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- walk_body(this, visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.expression.walk(visitor);
+ walk_body(node, visitor);
});
}
}, AST_SwitchBranch);
bcatch: "[AST_Catch?] the catch block, or null if not present",
bfinally: "[AST_Finally?] the finally block, or null if not present"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- walk_body(this, visitor);
- if (this.bcatch) this.bcatch._walk(visitor);
- if (this.bfinally) this.bfinally._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ walk_body(node, visitor);
+ if (node.bcatch) node.bcatch.walk(visitor);
+ if (node.bfinally) node.bfinally.walk(visitor);
});
}
}, AST_Block);
$propdoc: {
argname: "[AST_SymbolCatch] symbol for the exception"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.argname._walk(visitor);
- walk_body(this, visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.argname.walk(visitor);
+ walk_body(node, visitor);
});
}
}, AST_Block);
$propdoc: {
definitions: "[AST_VarDef*] array of variable definitions"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.definitions.forEach(function(defn) {
- defn._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.definitions.forEach(function(defn) {
+ defn.walk(visitor);
});
});
}
name: "[AST_SymbolVar] name of the variable",
value: "[AST_Node?] initializer, or null of there's no initializer"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.name._walk(visitor);
- if (this.value) this.value._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.name.walk(visitor);
+ if (node.value) node.value.walk(visitor);
});
}
});
expression: "[AST_Node] expression to invoke as function",
args: "[AST_Node*] array of arguments"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- this.args.forEach(function(node) {
- node._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.expression.walk(visitor);
+ node.args.forEach(function(arg) {
+ arg.walk(visitor);
});
});
}
$propdoc: {
expressions: "[AST_Node*] array of expressions (at least two)"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expressions.forEach(function(node) {
- node._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.expressions.forEach(function(expr) {
+ expr.walk(visitor);
});
});
}
var AST_Dot = DEFNODE("Dot", null, {
$documentation: "A dotted property access expression",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.expression.walk(visitor);
});
}
}, AST_PropAccess);
var AST_Sub = DEFNODE("Sub", null, {
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
- this.property._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.expression.walk(visitor);
+ node.property.walk(visitor);
});
}
}, AST_PropAccess);
operator: "[string] the operator",
expression: "[AST_Node] expression that this unary operator applies to"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.expression._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.expression.walk(visitor);
});
}
});
operator: "[string] the operator",
right: "[AST_Node] right-hand side expression"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.left._walk(visitor);
- this.right._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.left.walk(visitor);
+ node.right.walk(visitor);
});
}
});
consequent: "[AST_Node]",
alternative: "[AST_Node]"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.condition._walk(visitor);
- this.consequent._walk(visitor);
- this.alternative._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.condition.walk(visitor);
+ node.consequent.walk(visitor);
+ node.alternative.walk(visitor);
});
}
});
$propdoc: {
elements: "[AST_Node*] array of elements"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.elements.forEach(function(element) {
- element._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.elements.forEach(function(element) {
+ element.walk(visitor);
});
});
}
$propdoc: {
properties: "[AST_ObjectProperty*] array of properties"
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.properties.forEach(function(prop) {
- prop._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.properties.forEach(function(prop) {
+ prop.walk(visitor);
});
});
}
key: "[string|AST_SymbolAccessor] property name. For ObjectKeyVal this is a string. For getters and setters this is an AST_SymbolAccessor.",
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
},
- _walk: function(visitor) {
- return visitor._visit(this, function() {
- this.value._walk(visitor);
+ walk: function(visitor) {
+ var node = this;
+ return visitor.visit(node, function() {
+ node.value.walk(visitor);
});
}
});
/* -----[ TreeWalker ]----- */
function TreeWalker(callback) {
- this.visit = callback;
- this.stack = [];
+ this.callback = callback;
this.directives = Object.create(null);
+ this.stack = [];
}
TreeWalker.prototype = {
- _visit: function(node, descend) {
+ visit: function(node, descend) {
this.push(node);
- var ret = this.visit(node, descend ? function() {
- descend.call(node);
- } : noop);
- if (!ret && descend) {
- descend.call(node);
- }
+ var done = this.callback(node, descend || noop);
+ if (!done && descend) descend();
this.pop();
- return ret;
+ return done;
},
parent: function(n) {
return this.stack[this.stack.length - 2 - (n || 0)];