var assert = require(“assert”); var Class = require(“cls”); var Node = require(“./types”).namedTypes.Node; var slice = Array.prototype.slice; var removeRequests = [];

var Visitor = exports.Visitor = Class.extend({

visit: function(node) {
    var self = this;

    if (!node) {
        // pass

    } else if (node instanceof Array) {
        node = self.visitArray(node);

    } else if (Node.check(node)) {
        var methodName = "visit" + node.type,
            method = self[methodName] || self.genericVisit;
        node = method.call(this, node);

    } else if (typeof node === "object") {
        // Some AST node types contain ad-hoc (non-AST) objects that
        // may contain nested AST nodes.
        self.genericVisit(node);
    }

    return node;
},

visitArray: function(arr, noUpdate) {
    for (var elem, result, undef,
             i = 0, len = arr.length;
         i < len;
         i += 1)
    {
        if (i in arr)
            elem = arr[i];
        else
            continue;

        var requesters = [];
        removeRequests.push(requesters);

        // Make sure we don't accidentally reuse a previous result
        // when this.visit throws an exception.
        result = undef;

        try {
            result = this.visit(elem);

        } finally {
            assert.strictEqual(
                removeRequests.pop(),
                requesters);
        }

        if (requesters.length > 0 || (result === null && elem !== null)) {
            // This hole will be elided by the compaction loop below.
            delete arr[i];
        } else if (result !== undef) {
            arr[i] = result;
        }
    }

    // Compact the array to eliminate holes.
    for (var dst = 0,
             src = dst,
             // The length of the array might have changed during the
             // iteration performed above.
             len = arr.length;
         src < len;
         src += 1)
        if (src in arr)
            arr[dst++] = arr[src];
    arr.length = dst;

    return arr;
},

remove: function() {
    var len = removeRequests.length,
        requesters = removeRequests[len - 1];
    if (requesters)
        requesters.push(this);
},

genericVisit: function(node) {
    var field,
        oldValue,
        newValue;

    for (field in node) {
        if (!node.hasOwnProperty(field))
            continue;

        oldValue = node[field];

        if (oldValue instanceof Array) {
            this.visitArray(oldValue);

        } else if (Node.check(oldValue)) {
            newValue = this.visit(oldValue);

            if (typeof newValue === "undefined") {
                // Keep oldValue.
            } else {
                node[field] = newValue;
            }

        } else if (typeof oldValue === "object") {
            this.genericVisit(oldValue);
        }
    }

    return node;
}

});

require(“depd”)('require(“recast”).Visitor').property(

Visitor, "extend",
'Please use require("recast").visit instead of require("recast").Visitor'

);