"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasNodeModule = exports.findIdentifier = exports.gatherDescendants = exports.offsetOfGeneratedComponentExport = exports.isGeneratedSvelteComponentName = exports.isTopLevelExport = exports.findNodeAtPosition = exports.findNodeAtSpan = exports.get$storeOffsetOf$storeDeclaration = exports.isStoreVariableIn$storeDeclaration = exports.getConfigPathForProject = exports.replaceDeep = exports.isNoTextSpanInGeneratedCode = exports.isInGeneratedCode = exports.isNotNullOrUndefined = exports.ensureRealSvelteFilePath = exports.toRealSvelteFilePath = exports.isVirtualSvelteFilePath = exports.isSvelteFilePath = void 0;
function isSvelteFilePath(filePath) {
    return filePath.endsWith('.svelte');
}
exports.isSvelteFilePath = isSvelteFilePath;
function isVirtualSvelteFilePath(filePath) {
    return filePath.endsWith('.svelte.ts');
}
exports.isVirtualSvelteFilePath = isVirtualSvelteFilePath;
function toRealSvelteFilePath(filePath) {
    return filePath.slice(0, -'.ts'.length);
}
exports.toRealSvelteFilePath = toRealSvelteFilePath;
function ensureRealSvelteFilePath(filePath) {
    return isVirtualSvelteFilePath(filePath) ? toRealSvelteFilePath(filePath) : filePath;
}
exports.ensureRealSvelteFilePath = ensureRealSvelteFilePath;
function isNotNullOrUndefined(val) {
    return val !== undefined && val !== null;
}
exports.isNotNullOrUndefined = isNotNullOrUndefined;
/**
 * Checks if this a section that should be completely ignored
 * because it's purely generated.
 */
function isInGeneratedCode(text, start, end) {
    const lineStart = text.lastIndexOf('\n', start);
    const lineEnd = text.indexOf('\n', end);
    const lastStart = text.substring(lineStart, start).lastIndexOf('/*Ωignore_startΩ*/');
    const lastEnd = text.substring(lineStart, start).lastIndexOf('/*Ωignore_endΩ*/');
    return lastStart > lastEnd && text.substring(end, lineEnd).includes('/*Ωignore_endΩ*/');
}
exports.isInGeneratedCode = isInGeneratedCode;
/**
 * Checks that this isn't a text span that should be completely ignored
 * because it's purely generated.
 */
function isNoTextSpanInGeneratedCode(text, span) {
    return !isInGeneratedCode(text, span.start, span.start + span.length);
}
exports.isNoTextSpanInGeneratedCode = isNoTextSpanInGeneratedCode;
/**
 * Replace all occurrences of a string within an object with another string,
 */
function replaceDeep(obj, searchStr, replacementStr) {
    return _replaceDeep(obj);
    function _replaceDeep(_obj) {
        if (typeof _obj === 'string') {
            return _obj.replace(searchStr, replacementStr);
        }
        if (Array.isArray(_obj)) {
            return _obj.map((entry) => _replaceDeep(entry));
        }
        if (typeof _obj === 'object') {
            return Object.keys(_obj).reduce((_o, key) => {
                _o[key] = _replaceDeep(_obj[key]);
                return _o;
            }, {});
        }
        return _obj;
    }
}
exports.replaceDeep = replaceDeep;
function getConfigPathForProject(project) {
    return (project.canonicalConfigFilePath ??
        project.getCompilerOptions().configFilePath);
}
exports.getConfigPathForProject = getConfigPathForProject;
function isStoreVariableIn$storeDeclaration(text, varStart) {
    return (text.lastIndexOf('__sveltets_2_store_get(', varStart) ===
        varStart - '__sveltets_2_store_get('.length);
}
exports.isStoreVariableIn$storeDeclaration = isStoreVariableIn$storeDeclaration;
function get$storeOffsetOf$storeDeclaration(text, storePosition) {
    return text.lastIndexOf(' =', storePosition) - 1;
}
exports.get$storeOffsetOf$storeDeclaration = get$storeOffsetOf$storeDeclaration;
/**
 * Finds node exactly matching span {start, length}.
 */
function findNodeAtSpan(node, span, predicate) {
    const { start, length } = span;
    const end = start + length;
    for (const child of node.getChildren()) {
        const childStart = child.getStart();
        if (end <= childStart) {
            return;
        }
        const childEnd = child.getEnd();
        if (start >= childEnd) {
            continue;
        }
        if (start === childStart && end === childEnd) {
            if (!predicate) {
                return child;
            }
            if (predicate(child)) {
                return child;
            }
        }
        const foundInChildren = findNodeAtSpan(child, span, predicate);
        if (foundInChildren) {
            return foundInChildren;
        }
    }
}
exports.findNodeAtSpan = findNodeAtSpan;
/**
 * Finds node somewhere at position.
 */
function findNodeAtPosition(node, pos, predicate) {
    for (const child of node.getChildren()) {
        const childStart = child.getStart();
        if (pos < childStart) {
            return;
        }
        const childEnd = child.getEnd();
        if (pos > childEnd) {
            continue;
        }
        const foundInChildren = findNodeAtPosition(child, pos, predicate);
        if (foundInChildren) {
            return foundInChildren;
        }
        if (!predicate) {
            return child;
        }
        if (predicate(child)) {
            return child;
        }
    }
}
exports.findNodeAtPosition = findNodeAtPosition;
/**
 * True if is `export const/let/function`
 */
function isTopLevelExport(ts, node, source) {
    return ((ts.isVariableStatement(node) && source.statements.includes(node)) ||
        (ts.isIdentifier(node) &&
            node.parent &&
            ts.isVariableDeclaration(node.parent) &&
            source.statements.includes(node.parent?.parent?.parent)) ||
        (ts.isIdentifier(node) &&
            node.parent &&
            ts.isFunctionDeclaration(node.parent) &&
            source.statements.includes(node.parent)));
}
exports.isTopLevelExport = isTopLevelExport;
const COMPONENT_SUFFIX = '__SvelteComponent_';
function isGeneratedSvelteComponentName(className) {
    return className.endsWith(COMPONENT_SUFFIX);
}
exports.isGeneratedSvelteComponentName = isGeneratedSvelteComponentName;
function offsetOfGeneratedComponentExport(snapshot) {
    return snapshot.getText().lastIndexOf(COMPONENT_SUFFIX);
}
exports.offsetOfGeneratedComponentExport = offsetOfGeneratedComponentExport;
function gatherDescendants(node, predicate, dest = []) {
    if (predicate(node)) {
        dest.push(node);
    }
    else {
        for (const child of node.getChildren()) {
            gatherDescendants(child, predicate, dest);
        }
    }
    return dest;
}
exports.gatherDescendants = gatherDescendants;
function findIdentifier(ts, node) {
    if (ts.isIdentifier(node)) {
        return node;
    }
    if (ts.isFunctionDeclaration(node)) {
        return node.name;
    }
    while (node) {
        if (ts.isIdentifier(node)) {
            return node;
        }
        if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name)) {
            return node.name;
        }
        node = node.parent;
    }
}
exports.findIdentifier = findIdentifier;
function hasNodeModule(compilerOptions, module) {
    try {
        const hasModule = typeof compilerOptions.configFilePath !== 'string' ||
            require.resolve(module, { paths: [compilerOptions.configFilePath] });
        return hasModule;
    }
    catch (e) {
        // If require.resolve fails, we end up here, which can be either because the package is not found,
        // or (in case of things like SvelteKit) the package is found but the package.json is not exported.
        return e?.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED';
    }
}
exports.hasNodeModule = hasNodeModule;
//# sourceMappingURL=utils.js.map