"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const main_1 = require("vscode-languageserver/lib/main");
function forEach(node, cb) {
    cb(node);
    if (node.children.length) {
        node.children.forEach(n => forEach(n, cb));
    }
}
exports.forEach = forEach;
function range(n) {
    return main_1.Range.create(n.startPosition.row, n.startPosition.column, n.endPosition.row, n.endPosition.column);
}
exports.range = range;
function isDefinition(n) {
    switch (n.type) {
        // For now. Later we'll have a command_declaration take precedence over
        // variable_assignment
        case 'variable_assignment':
        case 'function_definition':
            return true;
        default:
            return false;
    }
}
exports.isDefinition = isDefinition;
function isReference(n) {
    switch (n.type) {
        case 'variable_name':
        case 'command_name':
            return true;
        default:
            return false;
    }
}
exports.isReference = isReference;
function findParent(start, predicate) {
    let node = start.parent;
    while (node !== null) {
        if (predicate(node)) {
            return node;
        }
        node = node.parent;
    }
    return null;
}
exports.findParent = findParent;
/**
 * Given a tree and a point, try to find the named leaf node that the point corresponds to.
 * This is a helper for wordAtPoint, useful in cases where the point occurs at the boundary of
 * a word so the normal behavior of "namedDescendantForPosition" does not find the desired leaf.
 * For example, if you do
 * > (new Parser()).setLanguage(bash).parse("echo 42").rootNode.descendantForIndex(4).text
 * then you get 'echo 42', not the leaf node for 'echo'.
 *
 * TODO: the need for this function might reveal a flaw in tree-sitter-bash.
 */
function namedLeafDescendantForPosition(point, rootNode) {
    const node = rootNode.namedDescendantForPosition(point);
    if (node.childCount === 0) {
        return node;
    }
    else {
        // The node wasn't a leaf. Try to figure out what word we should use.
        const nodeToUse = searchForLeafNode(point, node);
        if (nodeToUse) {
            return nodeToUse;
        }
        else {
            return null;
        }
    }
}
exports.namedLeafDescendantForPosition = namedLeafDescendantForPosition;
function searchForLeafNode(point, parent) {
    let child = parent.firstNamedChild;
    while (child) {
        if (pointsEqual(child.startPosition, point) ||
            pointsEqual(child.endPosition, point)) {
            if (child.childCount === 0) {
                return child;
            }
            else {
                return searchForLeafNode(point, child);
            }
        }
        child = child.nextNamedSibling;
    }
    return null;
}
function pointsEqual(point1, point2) {
    return point1.row === point2.row && point1.column === point2.column;
}
//# sourceMappingURL=tree-sitter.js.map