"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FindComponentReferencesProviderImpl = void 0;
const vscode_languageserver_1 = require("vscode-languageserver");
const utils_1 = require("../../../utils");
const DocumentSnapshot_1 = require("../DocumentSnapshot");
const utils_2 = require("../utils");
const utils_3 = require("./utils");
class FindComponentReferencesProviderImpl {
    constructor(lsAndTsDocResolver) {
        this.lsAndTsDocResolver = lsAndTsDocResolver;
    }
    async findComponentReferences(uri) {
        // No document available, just the uri, because it could be called on an unopened file
        const fileName = (0, utils_1.urlToPath)(uri);
        if (!fileName) {
            return null;
        }
        const lang = await this.lsAndTsDocResolver.getLSForPath(fileName);
        const tsDoc = await this.lsAndTsDocResolver.getSnapshot(fileName);
        if (!(tsDoc instanceof DocumentSnapshot_1.SvelteDocumentSnapshot)) {
            return null;
        }
        const references = lang.findReferences(tsDoc.filePath, (0, utils_2.offsetOfGeneratedComponentExport)(tsDoc));
        if (!references) {
            return null;
        }
        const snapshots = new utils_3.SnapshotMap(this.lsAndTsDocResolver);
        snapshots.set(tsDoc.filePath, tsDoc);
        const locations = await Promise.all((0, utils_1.flatten)(references.map((ref) => ref.references)).map(async (ref) => {
            if (ref.isDefinition) {
                return null;
            }
            const snapshot = await snapshots.retrieve(ref.fileName);
            if ((0, utils_3.isTextSpanInGeneratedCode)(snapshot.getFullText(), ref.textSpan)) {
                return null;
            }
            const refLocation = vscode_languageserver_1.Location.create((0, utils_1.pathToUrl)(ref.fileName), (0, utils_2.convertToLocationRange)(snapshot, ref.textSpan));
            //Only report starting tags
            if (this.isEndTag(refLocation, snapshot)) {
                return null;
            }
            // Some references are in generated code but not wrapped with explicit ignore comments.
            // These show up as zero-length ranges, so filter them out.
            if (!(0, utils_2.hasNonZeroRange)(refLocation)) {
                return null;
            }
            return refLocation;
        }));
        return locations.filter(utils_1.isNotNullOrUndefined);
    }
    isEndTag(element, snapshot) {
        if (!(snapshot instanceof DocumentSnapshot_1.SvelteDocumentSnapshot)) {
            return false;
        }
        const testEndTagRange = vscode_languageserver_1.Range.create(vscode_languageserver_1.Position.create(element.range.start.line, element.range.start.character - 1), element.range.end);
        const text = snapshot.getOriginalText(testEndTagRange);
        if (text.substring(0, 1) == '/') {
            return true;
        }
        return false;
    }
}
exports.FindComponentReferencesProviderImpl = FindComponentReferencesProviderImpl;
//# sourceMappingURL=FindComponentReferencesProvider.js.map