<commit_before>var assert = require("assert");
var types = require("./types");
var NodePath = require("./node-path");
var Node = types.namedTypes.Node;
var isArray = types.builtInTypes.array;
var isObject = types.builtInTypes.object;
var isFunction = types.builtInTypes.function;
var hasOwn = Object.prototype.hasOwnProperty;
var undefined;

function PathVisitor() {
    assert.ok(this instanceof PathVisitor);

    // Permanent state.
    this._reusableContextStack = [];
    this._methodNameTable = computeMethodNameTable(this);
    this.Context = makeContextConstructor(this);

    // State reset every time PathVisitor.prototype.visit is called.
    this._visiting = false;
    this._changeReported = false;
}

function computeMethodNameTable(visitor) {
    var typeNames = Object.create(null);

    for (var methodName in visitor) {
        if (/^visit[A-Z]/.test(methodName)) {
            typeNames[methodName.slice("visit".length)] = true;
        }
    }

    var supertypeTable = types.computeSupertypeLookupTable(typeNames);
    var methodNameTable = Object.create(null);

    var typeNames = Object.keys(supertypeTable);
    var typeNameCount = typeNames.length;
    for (var i = 0; i < typeNameCount; ++i) {
        var typeName = typeNames[i];
        methodName = "visit" + supertypeTable[typeName];
        if (isFunction.check(visitor[methodName])) {
            methodNameTable[typeName] = methodName;
        }
    }

    return methodNameTable;
}

PathVisitor.fromMethodsObject = function fromMethodsObject(methods) {
    if (methods instanceof PathVisitor) {
        return methods;
    }

    if (!isObject.check(methods)) {
        // An empty visitor?
        return new PathVisitor;
    }

    function Visitor() {
        assert.ok(this instanceof Visitor);
        PathVisitor.call(this);
    }

    var Vp = Visitor.prototype = Object.create(PVp);
    Vp.constructor = Visitor;

    extend(Vp, methods);
    extend(Visitor, PathVisitor);

    isFunction.assert(Visitor.fromMethodsObject);
    isFunction.assert(Visitor.visit);

    return new Visitor;
};

function extend(target, source) {
    for (var property in source) {
        if (hasOwn.call(source, property)) {
            target[property] = source[property];
        }
    }

    return target;
}

PathVisitor.visit = function visit(node, methods) {
    var visitor = PathVisitor.fromMethodsObject(methods);

    if (node instanceof NodePath) {
        visitor.visit(node);
        return node.value;
    }

    var rootPath = new NodePath({ root: node });
    visitor.visit(rootPath.get("root"));
    return rootPath.value.root;
};

var PVp = PathVisitor.prototype;

var recursiveVisitWarning = [
    "Recursively calling visitor.visit(path) resets visitor state.",
    "Try this.visit(path) or this.traverse(path) instead."
].join(" ");

PVp.visit = function(path) {
    assert.ok(!this._visiting, recursiveVisitWarning);

    // Private state that needs to be reset before every traversal.
    this._visiting = true;
    this._changeReported = false;

    // Called with the same arguments as .visit.
    this.reset.apply(this, arguments);

    try {
        return this.visitWithoutReset(path);
    } finally {
        this._visiting = false;
    }
};

PVp.reset = function(path/*, additional arguments */) {
    // Empty stub; may be reassigned or overridden by subclasses.
};

PVp.visitWithoutReset = function(path) {
    if (this instanceof this.Context) {
        // Since this.Context.prototype === this, there's a chance we
        // might accidentally call context.visitWithoutReset. If that
        // happens, re-invoke the method against context.visitor.
        return this.visitor.visitWithoutReset(path);
    }<commit_msg>Coerce first PathVisitor.prototype.visit argument to NodePath.<commit_after>var assert = require("assert");
var types = require("./types");
var NodePath = require("./node-path");
var Node = types.namedTypes.Node;
var isArray = types.builtInTypes.array;
var isObject = types.builtInTypes.object;
var isFunction = types.builtInTypes.function;
var hasOwn = Object.prototype.hasOwnProperty;
var undefined;

function PathVisitor() {
    assert.ok(this instanceof PathVisitor);

    // Permanent state.
    this._reusableContextStack = [];
    this._methodNameTable = computeMethodNameTable(this);
    this.Context = makeContextConstructor(this);

    // State reset every time PathVisitor.prototype.visit is called.
    this._visiting = false;
    this._changeReported = false;
}

function computeMethodNameTable(visitor) {
    var typeNames = Object.create(null);

    for (var methodName in visitor) {
        if (/^visit[A-Z]/.test(methodName)) {
            typeNames[methodName.slice("visit".length)] = true;
        }
    }

    var supertypeTable = types.computeSupertypeLookupTable(typeNames);
    var methodNameTable = Object.create(null);

    var typeNames = Object.keys(supertypeTable);
    var typeNameCount = typeNames.length;
    for (var i = 0; i < typeNameCount; ++i) {
        var typeName = typeNames[i];
        methodName = "visit" + supertypeTable[typeName];
        if (isFunction.check(visitor[methodName])) {
            methodNameTable[typeName] = methodName;
        }
    }

    return methodNameTable;
}

PathVisitor.fromMethodsObject = function fromMethodsObject(methods) {
    if (methods instanceof PathVisitor) {
        return methods;
    }

    if (!isObject.check(methods)) {
        // An empty visitor?
        return new PathVisitor;
    }

    function Visitor() {
        assert.ok(this instanceof Visitor);
        PathVisitor.call(this);
    }

    var Vp = Visitor.prototype = Object.create(PVp);
    Vp.constructor = Visitor;

    extend(Vp, methods);
    extend(Visitor, PathVisitor);

    isFunction.assert(Visitor.fromMethodsObject);
    isFunction.assert(Visitor.visit);

    return new Visitor;
};

function extend(target, source) {
    for (var property in source) {
        if (hasOwn.call(source, property)) {
            target[property] = source[property];
        }
    }

    return target;
}

PathVisitor.visit = function visit(node, methods) {
    return PathVisitor.fromMethodsObject(methods).visit(node);
};

var PVp = PathVisitor.prototype;

var recursiveVisitWarning = [
    "Recursively calling visitor.visit(path) resets visitor state.",
    "Try this.visit(path) or this.traverse(path) instead."
].join(" ");

PVp.visit = function() {
    assert.ok(!this._visiting, recursiveVisitWarning);

    // Private state that needs to be reset before every traversal.
    this._visiting = true;
    this._changeReported = false;

    var argc = arguments.length;
    var args = new Array(argc)
    for (var i = 0; i < argc; ++i) {
        args[i] = arguments[i];
    }

    if (!(args[0] instanceof NodePath)) {
        args[0] = new NodePath({ root: args[0] }).get("root");
    }

    // Called with the same arguments as .visit.
    this.reset.apply(this, args);

    try {
        return this.visitWithoutReset(args[0]);
    } finally {
        this._visiting = false;
    }
};

PVp.reset = function(path/*, additional arguments */) {
    // Empty stub; may be reassigned or overridden by subclasses.
};

PVp.visitWithoutReset = function(path) {
    if (this instanceof this.Context) {
        // Since this.Context.prototype === this, there's a chance we
        // might accidentally call context.visitWithoutReset. If that
        // happens, re-invoke the method against context.visitor.
        return this.visitor.visitWithoutReset(path);
    }
{'fraction_non_alphanumeric': 0.11640562782054685, 'fraction_numerical': 0.0009291213166976374, 'mean_word_length': 3.072972972972973, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '614859', 'n_tokens_mistral': 2224, 'n_tokens_neox': 2155, 'n_words': 534}