improve TreeWalker performance (#3848)
This commit is contained in:
279
lib/ast.js
279
lib/ast.js
@@ -110,11 +110,8 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
start: "[AST_Token] The first token of this node",
|
start: "[AST_Token] The first token of this node",
|
||||||
end: "[AST_Token] The last token of this node"
|
end: "[AST_Token] The last token of this node"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
|
||||||
return visitor._visit(this);
|
|
||||||
},
|
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return this._walk(visitor); // not sure the indirection will be any help
|
return visitor.visit(this);
|
||||||
}
|
}
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
@@ -161,16 +158,17 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
|
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.body._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
|
node.body.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
function walk_body(node, visitor) {
|
function walk_body(node, visitor) {
|
||||||
node.body.forEach(function(node) {
|
node.body.forEach(function(node) {
|
||||||
node._walk(visitor);
|
node.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,9 +177,10 @@ var AST_Block = DEFNODE("Block", "body", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Statement*] an array of statements"
|
body: "[AST_Statement*] an array of statements"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
walk_body(this, visitor);
|
return visitor.visit(node, function() {
|
||||||
|
walk_body(node, visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -206,10 +205,11 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
label: "[AST_Label] a label definition"
|
label: "[AST_Label] a label definition"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.label._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.body._walk(visitor);
|
node.label.walk(visitor);
|
||||||
|
node.body.walk(visitor);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
clone: function(deep) {
|
clone: function(deep) {
|
||||||
@@ -241,20 +241,22 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
|||||||
|
|
||||||
var AST_Do = DEFNODE("Do", null, {
|
var AST_Do = DEFNODE("Do", null, {
|
||||||
$documentation: "A `do` statement",
|
$documentation: "A `do` statement",
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.body._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.condition._walk(visitor);
|
node.body.walk(visitor);
|
||||||
|
node.condition.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_DWLoop);
|
}, AST_DWLoop);
|
||||||
|
|
||||||
var AST_While = DEFNODE("While", null, {
|
var AST_While = DEFNODE("While", null, {
|
||||||
$documentation: "A `while` statement",
|
$documentation: "A `while` statement",
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.condition._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.body._walk(visitor);
|
node.condition.walk(visitor);
|
||||||
|
node.body.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_DWLoop);
|
}, AST_DWLoop);
|
||||||
@@ -266,12 +268,13 @@ var AST_For = DEFNODE("For", "init condition step", {
|
|||||||
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
||||||
step: "[AST_Node?] the `for` update clause, or null if empty"
|
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
if (this.init) this.init._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
if (this.condition) this.condition._walk(visitor);
|
if (node.init) node.init.walk(visitor);
|
||||||
if (this.step) this.step._walk(visitor);
|
if (node.condition) node.condition.walk(visitor);
|
||||||
this.body._walk(visitor);
|
if (node.step) node.step.walk(visitor);
|
||||||
|
node.body.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_IterationStatement);
|
}, AST_IterationStatement);
|
||||||
@@ -282,11 +285,12 @@ var AST_ForIn = DEFNODE("ForIn", "init object", {
|
|||||||
init: "[AST_Node] the `for/in` initialization code",
|
init: "[AST_Node] the `for/in` initialization code",
|
||||||
object: "[AST_Node] the object that we're looping through"
|
object: "[AST_Node] the object that we're looping through"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.init._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.object._walk(visitor);
|
node.init.walk(visitor);
|
||||||
this.body._walk(visitor);
|
node.object.walk(visitor);
|
||||||
|
node.body.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_IterationStatement);
|
}, AST_IterationStatement);
|
||||||
@@ -296,10 +300,11 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `with` expression"
|
expression: "[AST_Node] the `with` expression"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.expression._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.body._walk(visitor);
|
node.expression.walk(visitor);
|
||||||
|
node.body.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_StatementWithBody);
|
}, AST_StatementWithBody);
|
||||||
@@ -380,13 +385,14 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments length_read", {
|
|||||||
argnames: "[AST_SymbolFunarg*] array of function arguments",
|
argnames: "[AST_SymbolFunarg*] array of function arguments",
|
||||||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
|
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
if (this.name) this.name._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.argnames.forEach(function(argname) {
|
if (node.name) node.name.walk(visitor);
|
||||||
argname._walk(visitor);
|
node.argnames.forEach(function(argname) {
|
||||||
|
argname.walk(visitor);
|
||||||
});
|
});
|
||||||
walk_body(this, visitor);
|
walk_body(node, visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Scope);
|
}, AST_Scope);
|
||||||
@@ -414,9 +420,10 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, this.value && function() {
|
var node = this;
|
||||||
this.value._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
|
if (node.value) node.value.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Jump);
|
}, AST_Jump);
|
||||||
@@ -434,9 +441,10 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
label: "[AST_LabelRef?] the label, or null if none",
|
label: "[AST_LabelRef?] the label, or null if none",
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, this.label && function() {
|
var node = this;
|
||||||
this.label._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
|
if (node.label) node.label.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Jump);
|
}, AST_Jump);
|
||||||
@@ -457,11 +465,12 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
|||||||
condition: "[AST_Node] the `if` condition",
|
condition: "[AST_Node] the `if` condition",
|
||||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.condition._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.body._walk(visitor);
|
node.condition.walk(visitor);
|
||||||
if (this.alternative) this.alternative._walk(visitor);
|
node.body.walk(visitor);
|
||||||
|
if (node.alternative) node.alternative.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_StatementWithBody);
|
}, AST_StatementWithBody);
|
||||||
@@ -473,10 +482,11 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `switch` “discriminant”"
|
expression: "[AST_Node] the `switch` “discriminant”"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.expression._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
walk_body(this, visitor);
|
node.expression.walk(visitor);
|
||||||
|
walk_body(node, visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
@@ -494,10 +504,11 @@ var AST_Case = DEFNODE("Case", "expression", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the `case` expression"
|
expression: "[AST_Node] the `case` expression"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.expression._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
walk_body(this, visitor);
|
node.expression.walk(visitor);
|
||||||
|
walk_body(node, visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_SwitchBranch);
|
}, AST_SwitchBranch);
|
||||||
@@ -510,11 +521,12 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
|||||||
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||||
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
walk_body(this, visitor);
|
return visitor.visit(node, function() {
|
||||||
if (this.bcatch) this.bcatch._walk(visitor);
|
walk_body(node, visitor);
|
||||||
if (this.bfinally) this.bfinally._walk(visitor);
|
if (node.bcatch) node.bcatch.walk(visitor);
|
||||||
|
if (node.bfinally) node.bfinally.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
@@ -524,10 +536,11 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
argname: "[AST_SymbolCatch] symbol for the exception"
|
argname: "[AST_SymbolCatch] symbol for the exception"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.argname._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
walk_body(this, visitor);
|
node.argname.walk(visitor);
|
||||||
|
walk_body(node, visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
@@ -543,10 +556,11 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
definitions: "[AST_VarDef*] array of variable definitions"
|
definitions: "[AST_VarDef*] array of variable definitions"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.definitions.forEach(function(defn) {
|
return visitor.visit(node, function() {
|
||||||
defn._walk(visitor);
|
node.definitions.forEach(function(defn) {
|
||||||
|
defn.walk(visitor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -562,10 +576,11 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
|||||||
name: "[AST_SymbolVar] name of the variable",
|
name: "[AST_SymbolVar] name of the variable",
|
||||||
value: "[AST_Node?] initializer, or null of there's no initializer"
|
value: "[AST_Node?] initializer, or null of there's no initializer"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.name._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
if (this.value) this.value._walk(visitor);
|
node.name.walk(visitor);
|
||||||
|
if (node.value) node.value.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -578,11 +593,12 @@ var AST_Call = DEFNODE("Call", "expression args", {
|
|||||||
expression: "[AST_Node] expression to invoke as function",
|
expression: "[AST_Node] expression to invoke as function",
|
||||||
args: "[AST_Node*] array of arguments"
|
args: "[AST_Node*] array of arguments"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.expression._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.args.forEach(function(node) {
|
node.expression.walk(visitor);
|
||||||
node._walk(visitor);
|
node.args.forEach(function(arg) {
|
||||||
|
arg.walk(visitor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -597,10 +613,11 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.expressions.forEach(function(node) {
|
return visitor.visit(node, function() {
|
||||||
node._walk(visitor);
|
node.expressions.forEach(function(expr) {
|
||||||
|
expr.walk(visitor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -628,19 +645,21 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
|||||||
|
|
||||||
var AST_Dot = DEFNODE("Dot", null, {
|
var AST_Dot = DEFNODE("Dot", null, {
|
||||||
$documentation: "A dotted property access expression",
|
$documentation: "A dotted property access expression",
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.expression._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
|
node.expression.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_PropAccess);
|
}, AST_PropAccess);
|
||||||
|
|
||||||
var AST_Sub = DEFNODE("Sub", null, {
|
var AST_Sub = DEFNODE("Sub", null, {
|
||||||
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
|
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.expression._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.property._walk(visitor);
|
node.expression.walk(visitor);
|
||||||
|
node.property.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, AST_PropAccess);
|
}, AST_PropAccess);
|
||||||
@@ -651,9 +670,10 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
|||||||
operator: "[string] the operator",
|
operator: "[string] the operator",
|
||||||
expression: "[AST_Node] expression that this unary operator applies to"
|
expression: "[AST_Node] expression that this unary operator applies to"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.expression._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
|
node.expression.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -673,10 +693,11 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
|||||||
operator: "[string] the operator",
|
operator: "[string] the operator",
|
||||||
right: "[AST_Node] right-hand side expression"
|
right: "[AST_Node] right-hand side expression"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.left._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.right._walk(visitor);
|
node.left.walk(visitor);
|
||||||
|
node.right.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -688,11 +709,12 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
|||||||
consequent: "[AST_Node]",
|
consequent: "[AST_Node]",
|
||||||
alternative: "[AST_Node]"
|
alternative: "[AST_Node]"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.condition._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
this.consequent._walk(visitor);
|
node.condition.walk(visitor);
|
||||||
this.alternative._walk(visitor);
|
node.consequent.walk(visitor);
|
||||||
|
node.alternative.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -708,10 +730,11 @@ var AST_Array = DEFNODE("Array", "elements", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
elements: "[AST_Node*] array of elements"
|
elements: "[AST_Node*] array of elements"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.elements.forEach(function(element) {
|
return visitor.visit(node, function() {
|
||||||
element._walk(visitor);
|
node.elements.forEach(function(element) {
|
||||||
|
element.walk(visitor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -722,10 +745,11 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
properties: "[AST_ObjectProperty*] array of properties"
|
properties: "[AST_ObjectProperty*] array of properties"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.properties.forEach(function(prop) {
|
return visitor.visit(node, function() {
|
||||||
prop._walk(visitor);
|
node.properties.forEach(function(prop) {
|
||||||
|
prop.walk(visitor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -737,9 +761,10 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
|||||||
key: "[string|AST_SymbolAccessor] property name. For ObjectKeyVal this is a string. For getters and setters this is an AST_SymbolAccessor.",
|
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."
|
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
var node = this;
|
||||||
this.value._walk(visitor);
|
return visitor.visit(node, function() {
|
||||||
|
node.value.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -891,21 +916,17 @@ var AST_True = DEFNODE("True", null, {
|
|||||||
/* -----[ TreeWalker ]----- */
|
/* -----[ TreeWalker ]----- */
|
||||||
|
|
||||||
function TreeWalker(callback) {
|
function TreeWalker(callback) {
|
||||||
this.visit = callback;
|
this.callback = callback;
|
||||||
this.stack = [];
|
|
||||||
this.directives = Object.create(null);
|
this.directives = Object.create(null);
|
||||||
|
this.stack = [];
|
||||||
}
|
}
|
||||||
TreeWalker.prototype = {
|
TreeWalker.prototype = {
|
||||||
_visit: function(node, descend) {
|
visit: function(node, descend) {
|
||||||
this.push(node);
|
this.push(node);
|
||||||
var ret = this.visit(node, descend ? function() {
|
var done = this.callback(node, descend || noop);
|
||||||
descend.call(node);
|
if (!done && descend) descend();
|
||||||
} : noop);
|
|
||||||
if (!ret && descend) {
|
|
||||||
descend.call(node);
|
|
||||||
}
|
|
||||||
this.pop();
|
this.pop();
|
||||||
return ret;
|
return done;
|
||||||
},
|
},
|
||||||
parent: function(n) {
|
parent: function(n) {
|
||||||
return this.stack[this.stack.length - 2 - (n || 0)];
|
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||||
|
|||||||
Reference in New Issue
Block a user