File: /home/frenchy/www/french-american.org/current/node_modules/uglyfly-js/lib/TreeWalker.js
/***********************************************************************
Copyright 2014 (c) Saair Quaderi <saair.quaderi@gmail.com>
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
UglyflyJS sourcecode can be found here:
https://github.com/quaderi/uglyflyjs
UglyflyJS (by Saair) is a fork of UglifyJS2 (by Mihai Bazon)
Both libraries are released under the BSD 2-Clause License.
***********************************************************************/
/*globals define, module, require */
((typeof define === "function") ? define :
function () { "use strict"; require('./nd').apply(module, arguments); })(
"TreeWalker",
[
//no dependencies
],
function () {
"use strict";
/*jslint nomen: true, plusplus: true */
/* -----[ TreeWalker ]----- */
function TreeWalker(callback) {
this.visit = callback;
this.stack = [];
}
TreeWalker.prototype = {
_visit: function (node, descend) {
var ret;
this.stack.push(node);
ret = this.visit(node, descend ? function () {
descend.call(node);
} : function () {
return;
});
if (!ret && descend) {
descend.call(node);
}
this.stack.pop();
return ret;
},
parent: function (n) {
return this.stack[this.stack.length - 2 - (n || 0)];
},
push: function (node) {
this.stack.push(node);
},
pop: function () {
return this.stack.pop();
},
self: function () {
return this.stack[this.stack.length - 1];
},
find_parent: function (type) {
var stack = this.stack,
i,
x;
for (i = stack.length - 1; i >= 0; --i) {
x = stack[i];
if (x["instanceof_" + type]) {
return x;
}
}
},
has_directive: function (type) {
return this.find_parent("Scope").has_directive(type);
},
in_boolean_context: function () {
var stack = this.stack,
i = stack.length,
self = stack[--i],
p;
while (i > 0) {
p = stack[--i];
if ((((p.instanceof_If) ||
(p.instanceof_Conditional) ||
(p.instanceof_DWLoop) ||
(p.instanceof_For)) &&
(p.condition === self)) ||
((p.instanceof_UnaryPrefix) &&
(p.operator === "!") &&
(p.expression === self))) {
return true;
}
if (!(p.instanceof_Binary) ||
((p.operator !== "&&") && (p.operator !== "||"))) {
return false;
}
self = p;
}
},
loopcontrol_target: function (label) {
var stack = this.stack,
i,
x;
if (label) {
for (i = stack.length - 1; i >= 0; --i) {
x = stack[i];
if ((x.instanceof_LabeledStatement) && (x.label.name === label.name)) {
return x.body;
}
}
} else {
for (i = stack.length - 1; i >= 0; --i) {
x = stack[i];
if ((x.instanceof_Switch) || (x.instanceof_IterationStatement)) {
return x;
}
}
}
}
};
return TreeWalker;
}
);