From 393fbf1b663e67dab030a38be458a0a3da6a1b53 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Mon, 10 May 2010 22:41:18 -0400 Subject: [PATCH] merging in gfxmonk's cleanup to how children of nodes are determined. Removing some (so far) unused portions. --- lib/nodes.js | 77 ++++++++++++++++++++---------------------------- src/nodes.coffee | 46 +++++++++++------------------ 2 files changed, 49 insertions(+), 74 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index f57c8dc9..b6eb6ef1 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1,15 +1,15 @@ (function(){ var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, CurryNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, IndexNode, LiteralNode, ObjectNode, OpNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, Scope, SliceNode, SplatNode, TAB, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, _a, children, compact, del, flatten, helpers, literal, merge, statement, utility; - var __slice = Array.prototype.slice, __bind = function(func, obj, args) { - return function() { - return func.apply(obj || {}, args ? args.concat(__slice.call(arguments, 0)) : arguments); - }; - }, __extends = function(child, parent) { + var __slice = Array.prototype.slice, __extends = function(child, parent) { var ctor = function(){ }; ctor.prototype = parent.prototype; child.__superClass__ = parent.prototype; child.prototype = new ctor(); child.prototype.constructor = child; + }, __bind = function(func, obj, args) { + return function() { + return func.apply(obj || {}, args ? args.concat(__slice.call(arguments, 0)) : arguments); + }; }; // `nodes.coffee` contains all of the node classes for the syntax tree. Most // nodes are created as the result of actions in the [grammar](grammar.html), @@ -50,8 +50,8 @@ var child_attrs; var _b = arguments.length, _c = _b >= 2; child_attrs = __slice.call(arguments, 1, _b - 0); - klass.prototype._children_attributes = child_attrs; - return klass.prototype._children_attributes; + klass.prototype.children_attributes = child_attrs; + return klass.prototype.children_attributes; }; //### BaseNode // The **BaseNode** is the abstract base class for all nodes in the syntax tree. @@ -131,12 +131,12 @@ BaseNode.prototype.contains = function contains(block) { var contains; contains = false; - this._traverse_children(false, __bind(function(node, attr, index) { - if (block(node)) { - contains = true; - return false; - } - }, this)); + this.traverse_children(false, function(node) { + if (block(node)) { + contains = true; + return false; + } + }); return contains; }; // Is this node of a certain type, or does it contain the type? @@ -154,7 +154,7 @@ }; // Perform an in-order traversal of the AST. Crosses scope boundaries. BaseNode.prototype.traverse = function traverse(block) { - return this._traverse_children(true, block); + return this.traverse_children(true, block); }; // `toString` representation of the node, for inspecting the parse tree. // This is what `coffee --nodes` prints out. @@ -171,46 +171,37 @@ }).call(this).join(''); }; BaseNode.prototype.children = function children() { - var _children; - _children = []; - this._each_child(function(child) { - return _children.push(child); + var nodes; + nodes = []; + this.each_child(function(node) { + return nodes.push(node); }); - return _children; + return nodes; }; - BaseNode.prototype._each_child = function _each_child(func) { - var _b, _c, _d, _e, _f, _g, attr, child, child_collection, i, result; - _c = this._children_attributes; + BaseNode.prototype.each_child = function each_child(func) { + var _b, _c, _d, _e, _f, _g, attr, child; + _c = this.children_attributes; for (_b = 0, _d = _c.length; _b < _d; _b++) { attr = _c[_b]; - child_collection = this[attr]; - if (!((typeof child_collection !== "undefined" && child_collection !== null))) { - continue; - } - if (child_collection instanceof Array) { - i = 0; - _f = child_collection; + if (this[attr]) { + _f = flatten([this[attr]]); for (_e = 0, _g = _f.length; _e < _g; _e++) { child = _f[_e]; - result = func(child, attr, i); - if (result === false) { + if (func(child) === false) { return null; } - i += 1; } - } else { - func(child_collection, attr); } } }; - BaseNode.prototype._traverse_children = function _traverse_children(cross_scope, func) { - if (!(this._children_attributes)) { + BaseNode.prototype.traverse_children = function traverse_children(cross_scope, func) { + if (!(this.children_attributes)) { return null; } - return this._each_child(function(child, attr, i) { + return this.each_child(function(child) { func.apply(this, arguments); if (child instanceof BaseNode) { - return child._traverse_children(cross_scope, func); + return child.traverse_children(cross_scope, func); } }); }; @@ -263,10 +254,6 @@ Expressions.prototype.empty = function empty() { return this.expressions.length === 0; }; - // Make a copy of this node. - Expressions.prototype.copy = function copy() { - return new Expressions(this.Expressions.slice()); - }; // An Expressions node does not return its entire body, rather it // ensures that the final expression is returned. Expressions.prototype.make_return = function make_return() { @@ -1157,11 +1144,11 @@ CodeNode.prototype.top_sensitive = function top_sensitive() { return true; }; - // Short-circuit _traverse_children method to prevent it from crossing scope boundaries + // Short-circuit traverse_children method to prevent it from crossing scope boundaries // unless cross_scope is true - CodeNode.prototype._traverse_children = function _traverse_children(cross_scope, func) { + CodeNode.prototype.traverse_children = function traverse_children(cross_scope, func) { if (cross_scope) { - return CodeNode.__superClass__._traverse_children.call(this, cross_scope, func); + return CodeNode.__superClass__.traverse_children.call(this, cross_scope, func); } }; CodeNode.prototype.toString = function toString(idt) { diff --git a/src/nodes.coffee b/src/nodes.coffee index 6f08a9df..c74cb257 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -25,7 +25,7 @@ statement: (klass, only) -> (klass::is_pure_statement: -> true) if only children: (klass, child_attrs...) -> - klass::_children_attributes: child_attrs + klass::children_attributes: child_attrs #### BaseNode @@ -96,11 +96,11 @@ exports.BaseNode: class BaseNode # scope boundaries. contains: (block) -> contains: false - @_traverse_children false, (node, attr, index) => + @traverse_children false, (node) -> if block(node) contains: true return false - return contains + contains # Is this node of a certain type, or does it contain the type? contains_type: (type) -> @@ -112,7 +112,7 @@ exports.BaseNode: class BaseNode @is_pure_statement() or @contains (n) -> n.is_pure_statement() # Perform an in-order traversal of the AST. Crosses scope boundaries. - traverse: (block) -> @_traverse_children true, block + traverse: (block) -> @traverse_children true, block # `toString` representation of the node, for inspecting the parse tree. # This is what `coffee --nodes` prints out. @@ -121,28 +121,20 @@ exports.BaseNode: class BaseNode '\n' + idt + @constructor.name + (child.toString(idt + TAB) for child in @children()).join('') children: -> - _children: [] - @_each_child (child) -> _children.push(child) - _children + nodes: [] + @each_child (node) -> nodes.push node + nodes - _each_child: (func) -> - for attr in @_children_attributes - child_collection: this[attr] - continue unless child_collection? - if child_collection instanceof Array - i: 0 - for child in child_collection - result: func(child, attr, i) - return if result is false - i += 1 - else - func(child_collection, attr) + each_child: (func) -> + for attr in @children_attributes when this[attr] + for child in flatten [this[attr]] + return if func(child) is false - _traverse_children: (cross_scope, func) -> - return unless @_children_attributes - @_each_child (child, attr, i) -> + traverse_children: (cross_scope, func) -> + return unless @children_attributes + @each_child (child) -> func.apply(this, arguments) - child._traverse_children(cross_scope, func) if child instanceof BaseNode + child.traverse_children(cross_scope, func) if child instanceof BaseNode # Default implementations of the common node identification methods. Nodes # will override these with custom logic, if needed. @@ -180,10 +172,6 @@ exports.Expressions: class Expressions extends BaseNode empty: -> @expressions.length is 0 - # Make a copy of this node. - copy: -> - new Expressions @Expressions.slice() - # An Expressions node does not return its entire body, rather it # ensures that the final expression is returned. make_return: -> @@ -853,9 +841,9 @@ exports.CodeNode: class CodeNode extends BaseNode top_sensitive: -> true - # Short-circuit _traverse_children method to prevent it from crossing scope boundaries + # Short-circuit traverse_children method to prevent it from crossing scope boundaries # unless cross_scope is true - _traverse_children: (cross_scope, func) -> super(cross_scope, func) if cross_scope + traverse_children: (cross_scope, func) -> super(cross_scope, func) if cross_scope toString: (idt) -> idt: or ''