"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.decorateDiagnostics = void 0;
const path_1 = __importDefault(require("path"));
const svelte2tsx_1 = require("svelte2tsx");
const utils_1 = require("../utils");
const sveltekit_1 = require("./sveltekit");
function decorateDiagnostics(ls, info, typescript, logger) {
    decorateSyntacticDiagnostics(ls, info, typescript, logger);
    decorateSemanticDiagnostics(ls, info, typescript, logger);
    decorateSuggestionDiagnostics(ls, info, typescript, logger);
}
exports.decorateDiagnostics = decorateDiagnostics;
function decorateSyntacticDiagnostics(ls, info, typescript, logger) {
    const getSyntacticDiagnostics = ls.getSyntacticDiagnostics;
    ls.getSyntacticDiagnostics = (fileName) => {
        // Diagnostics inside Svelte files are done
        // by the svelte-language-server / Svelte for VS Code extension
        if ((0, utils_1.isSvelteFilePath)(fileName)) {
            return [];
        }
        const kitDiagnostics = getKitDiagnostics('getSyntacticDiagnostics', fileName, info, typescript, logger);
        return kitDiagnostics ?? getSyntacticDiagnostics(fileName);
    };
}
function decorateSemanticDiagnostics(ls, info, typescript, logger) {
    const getSemanticDiagnostics = ls.getSemanticDiagnostics;
    ls.getSemanticDiagnostics = (fileName) => {
        // Diagnostics inside Svelte files are done
        // by the svelte-language-server / Svelte for VS Code extension
        if ((0, utils_1.isSvelteFilePath)(fileName)) {
            return [];
        }
        const kitDiagnostics = getKitDiagnostics('getSemanticDiagnostics', fileName, info, typescript, logger);
        return kitDiagnostics ?? getSemanticDiagnostics(fileName);
    };
}
function decorateSuggestionDiagnostics(ls, info, typescript, logger) {
    const getSuggestionDiagnostics = ls.getSuggestionDiagnostics;
    ls.getSuggestionDiagnostics = (fileName) => {
        // Diagnostics inside Svelte files are done
        // by the svelte-language-server / Svelte for VS Code extension
        if ((0, utils_1.isSvelteFilePath)(fileName)) {
            return [];
        }
        const kitDiagnostics = getKitDiagnostics('getSuggestionDiagnostics', fileName, info, typescript, logger);
        return kitDiagnostics ?? getSuggestionDiagnostics(fileName);
    };
}
function getKitDiagnostics(methodName, fileName, info, ts, logger) {
    const result = (0, sveltekit_1.getVirtualLS)(fileName, info, ts, logger);
    if (!result)
        return;
    const { languageService, toOriginalPos } = result;
    const diagnostics = [];
    for (let diagnostic of languageService[methodName](fileName)) {
        if (!diagnostic.start || !diagnostic.length) {
            diagnostics.push(diagnostic);
            continue;
        }
        const mapped = toOriginalPos(diagnostic.start);
        if (mapped.inGenerated) {
            // If not "Cannot find module './$types' .." then filter out
            if (diagnostic.code === 2307) {
                diagnostic = {
                    ...diagnostic,
                    // adjust length so it doesn't spill over to the next line
                    length: 1,
                    messageText: typeof diagnostic.messageText === 'string' &&
                        diagnostic.messageText.includes('./$types')
                        ? diagnostic.messageText +
                            ` (this likely means that SvelteKit's type generation didn't run yet - try running it by executing 'npm run dev' or 'npm run build')`
                        : diagnostic.messageText
                };
            }
            else if (diagnostic.code === 2694) {
                diagnostic = {
                    ...diagnostic,
                    // adjust length so it doesn't spill over to the next line
                    length: 1,
                    messageText: typeof diagnostic.messageText === 'string' &&
                        diagnostic.messageText.includes('/$types')
                        ? diagnostic.messageText +
                            ` (this likely means that SvelteKit's generated types are out of date - try rerunning it by executing 'npm run dev' or 'npm run build')`
                        : diagnostic.messageText
                };
            }
            else if (diagnostic.code === 2355) {
                // A function whose declared type is neither 'void' nor 'any' must return a value
                diagnostic = {
                    ...diagnostic,
                    // adjust length so it doesn't spill over to the next line
                    length: 1
                };
            }
            else {
                continue;
            }
        }
        diagnostic = {
            ...diagnostic,
            start: mapped.pos
        };
        diagnostics.push(diagnostic);
    }
    if (methodName === 'getSemanticDiagnostics') {
        // We're in a Svelte file - check top level exports
        // We're using the original file to have the correct position without mapping
        const source = info.languageService.getProgram()?.getSourceFile(fileName);
        const basename = path_1.default.basename(fileName);
        const validExports = Object.keys(sveltekit_1.kitExports).filter((key) => (0, sveltekit_1.isKitRouteExportAllowedIn)(basename, sveltekit_1.kitExports[key]));
        if (source && basename.startsWith('+')) {
            const exports = svelte2tsx_1.internalHelpers.findExports(ts, source, /* irrelevant */ false);
            for (const exportName of exports.keys()) {
                if (!validExports.includes(exportName) && !exportName.startsWith('_')) {
                    const node = exports.get(exportName).node;
                    const identifier = (0, utils_1.findIdentifier)(ts, node) ?? node;
                    diagnostics.push({
                        file: source,
                        start: identifier.getStart(),
                        length: identifier.getEnd() - identifier.getStart(),
                        messageText: `Invalid export '${exportName}' (valid exports are ${validExports.join(', ')}, or anything with a '_' prefix)`,
                        category: ts.DiagnosticCategory.Error,
                        code: 71001 // arbitrary
                    });
                }
            }
        }
    }
    // @ts-ignore TS doesn't get the return type right
    return diagnostics;
}
//# sourceMappingURL=diagnostics.js.map