"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.decorateLanguageService = void 0; const language_core_1 = require("@volar/language-core"); const dedupe_1 = require("./dedupe"); const utils_1 = require("./utils"); const transform_1 = require("./transform"); const windowsPathReg = /\\/g; function decorateLanguageService(language, languageService) { // ignored methods const { getNavigationTree, getOutliningSpans, } = languageService; languageService.getNavigationTree = filePath => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const tree = getNavigationTree(fileName); tree.childItems = undefined; return tree; } else { return getNavigationTree(fileName); } }; languageService.getOutliningSpans = filePath => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { return []; } else { return getOutliningSpans(fileName); } }; // methods const { findReferences, findRenameLocations, getCompletionEntryDetails, getCompletionsAtPosition, getDefinitionAndBoundSpan, getDefinitionAtPosition, getFileReferences, getFormattingEditsForDocument, getFormattingEditsForRange, getFormattingEditsAfterKeystroke, getImplementationAtPosition, getLinkedEditingRangeAtPosition, getQuickInfoAtPosition, getSignatureHelpItems, getReferencesAtPosition, getSemanticDiagnostics, getSyntacticDiagnostics, getSuggestionDiagnostics, getTypeDefinitionAtPosition, getEncodedSemanticClassifications, getDocumentHighlights, getApplicableRefactors, getEditsForFileRename, getEditsForRefactor, getRenameInfo, getCodeFixesAtPosition, prepareCallHierarchy, provideCallHierarchyIncomingCalls, provideCallHierarchyOutgoingCalls, provideInlayHints, organizeImports, } = languageService; languageService.getFormattingEditsForDocument = (filePath, options) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { if (!map.mappings.some(mapping => (0, language_core_1.isFormattingEnabled)(mapping.data))) { return []; } const edits = getFormattingEditsForDocument(fileName, options); return edits .map(edit => (0, transform_1.transformTextChange)(sourceScript, map, edit, language_core_1.isFormattingEnabled)) .filter(utils_1.notEmpty); } else { return getFormattingEditsForDocument(fileName, options); } }; languageService.getFormattingEditsForRange = (filePath, start, end, options) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generateStart = (0, transform_1.toGeneratedOffset)(sourceScript, map, start, language_core_1.isFormattingEnabled); const generateEnd = (0, transform_1.toGeneratedOffset)(sourceScript, map, end, language_core_1.isFormattingEnabled); if (generateStart !== undefined && generateEnd !== undefined) { const edits = getFormattingEditsForRange(fileName, generateStart, generateEnd, options); return edits .map(edit => (0, transform_1.transformTextChange)(sourceScript, map, edit, language_core_1.isFormattingEnabled)) .filter(utils_1.notEmpty); } return []; } else { return getFormattingEditsForRange(fileName, start, end, options); } }; languageService.getFormattingEditsAfterKeystroke = (filePath, position, key, options) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isFormattingEnabled); if (generatePosition !== undefined) { const edits = getFormattingEditsAfterKeystroke(fileName, generatePosition, key, options); return edits .map(edit => (0, transform_1.transformTextChange)(sourceScript, map, edit, language_core_1.isFormattingEnabled)) .filter(utils_1.notEmpty); } return []; } else { return getFormattingEditsAfterKeystroke(fileName, position, key, options); } }; languageService.getEditsForFileRename = (oldFilePath, newFilePath, formatOptions, preferences) => { const edits = getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences); return edits .map(edit => (0, transform_1.transformFileTextChanges)(language, edit, language_core_1.isRenameEnabled)) .filter(utils_1.notEmpty); }; languageService.getLinkedEditingRangeAtPosition = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isLinkedEditingEnabled); if (generatePosition !== undefined) { const info = getLinkedEditingRangeAtPosition(fileName, generatePosition); if (info) { return { ranges: info.ranges .map(span => (0, transform_1.transformTextSpan)(sourceScript, map, span, language_core_1.isLinkedEditingEnabled)) .filter(utils_1.notEmpty), wordPattern: info.wordPattern, }; } } } else { return getLinkedEditingRangeAtPosition(fileName, position); } }; languageService.prepareCallHierarchy = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled); if (generatePosition !== undefined) { const item = prepareCallHierarchy(fileName, generatePosition); if (Array.isArray(item)) { return item.map(item => (0, transform_1.transformCallHierarchyItem)(language, item, language_core_1.isCallHierarchyEnabled)); } else if (item) { return (0, transform_1.transformCallHierarchyItem)(language, item, language_core_1.isCallHierarchyEnabled); } } } else { return prepareCallHierarchy(fileName, position); } }; languageService.provideCallHierarchyIncomingCalls = (filePath, position) => { let calls = []; const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled); if (generatePosition !== undefined) { calls = provideCallHierarchyIncomingCalls(fileName, generatePosition); } } else { calls = provideCallHierarchyIncomingCalls(fileName, position); } return calls .map(call => { const from = (0, transform_1.transformCallHierarchyItem)(language, call.from, language_core_1.isCallHierarchyEnabled); const fromSpans = call.fromSpans .map(span => (0, transform_1.transformSpan)(language, call.from.file, span, language_core_1.isCallHierarchyEnabled)?.textSpan) .filter(utils_1.notEmpty); return { from, fromSpans, }; }); }; languageService.provideCallHierarchyOutgoingCalls = (filePath, position) => { let calls = []; const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCallHierarchyEnabled); if (generatePosition !== undefined) { calls = provideCallHierarchyOutgoingCalls(fileName, generatePosition); } } else { calls = provideCallHierarchyOutgoingCalls(fileName, position); } return calls .map(call => { const to = (0, transform_1.transformCallHierarchyItem)(language, call.to, language_core_1.isCallHierarchyEnabled); const fromSpans = call.fromSpans .map(span => sourceScript ? (0, transform_1.transformTextSpan)(sourceScript, map, span, language_core_1.isCallHierarchyEnabled) : span) .filter(utils_1.notEmpty); return { to, fromSpans, }; }); }; languageService.organizeImports = (args, formatOptions, preferences) => { const unresolved = organizeImports(args, formatOptions, preferences); const resolved = unresolved .map(changes => (0, transform_1.transformFileTextChanges)(language, changes, language_core_1.isCodeActionsEnabled)) .filter(utils_1.notEmpty); return resolved; }; languageService.getQuickInfoAtPosition = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isHoverEnabled); if (generatePosition !== undefined) { const result = getQuickInfoAtPosition(fileName, generatePosition); if (result) { const textSpan = (0, transform_1.transformTextSpan)(sourceScript, map, result.textSpan, language_core_1.isHoverEnabled); if (textSpan) { return { ...result, textSpan, }; } } } } else { return getQuickInfoAtPosition(fileName, position); } }; languageService.getSignatureHelpItems = (filePath, position, options) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isSignatureHelpEnabled); if (generatePosition !== undefined) { const result = getSignatureHelpItems(fileName, generatePosition, options); if (result) { const applicableSpan = (0, transform_1.transformTextSpan)(sourceScript, map, result.applicableSpan, language_core_1.isSignatureHelpEnabled); if (applicableSpan) { return { ...result, applicableSpan, }; } } } } else { return getSignatureHelpItems(fileName, position, options); } }; languageService.getDocumentHighlights = (filePath, position, filesToSearch) => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isHighlightEnabled, position => getDocumentHighlights(fileName, position, filesToSearch), function* (result) { for (const ref of result) { for (const reference of ref.highlightSpans) { yield [reference.fileName ?? ref.fileName, reference.textSpan.start]; } } }); const resolved = unresolved .flat() .map(highlights => { return { ...highlights, highlightSpans: highlights.highlightSpans .map(span => { const textSpan = (0, transform_1.transformSpan)(language, span.fileName ?? highlights.fileName, span.textSpan, language_core_1.isHighlightEnabled)?.textSpan; if (textSpan) { return { ...span, contextSpan: (0, transform_1.transformSpan)(language, span.fileName ?? highlights.fileName, span.contextSpan, language_core_1.isHighlightEnabled)?.textSpan, textSpan, }; } }) .filter(utils_1.notEmpty), }; }); return resolved; }; languageService.getApplicableRefactors = (filePath, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos, language_core_1.isCodeActionsEnabled); if (generatePosition !== undefined) { const por = typeof positionOrRange === 'number' ? generatePosition : { pos: generatePosition, end: generatePosition + positionOrRange.end - positionOrRange.pos, }; return getApplicableRefactors(fileName, por, preferences, triggerReason, kind, includeInteractiveActions); } return []; } else { return getApplicableRefactors(fileName, positionOrRange, preferences, triggerReason, kind, includeInteractiveActions); } }; languageService.getEditsForRefactor = (filePath, formatOptions, positionOrRange, refactorName, actionName, preferences) => { let edits; const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, typeof positionOrRange === 'number' ? positionOrRange : positionOrRange.pos, language_core_1.isCodeActionsEnabled); if (generatePosition !== undefined) { const por = typeof positionOrRange === 'number' ? generatePosition : { pos: generatePosition, end: generatePosition + positionOrRange.end - positionOrRange.pos, }; edits = getEditsForRefactor(fileName, formatOptions, por, refactorName, actionName, preferences); } } else { edits = getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName, preferences); } if (edits) { edits.edits = edits.edits .map(edit => (0, transform_1.transformFileTextChanges)(language, edit, language_core_1.isCodeActionsEnabled)) .filter(utils_1.notEmpty); return edits; } }; languageService.getRenameInfo = (filePath, position, options) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { let failed; for (const generateOffset of (0, transform_1.forEachGeneratedOffset)(sourceScript, map, position, language_core_1.isRenameEnabled)) { const info = getRenameInfo(fileName, generateOffset, options); if (info.canRename) { const span = (0, transform_1.transformTextSpan)(sourceScript, map, info.triggerSpan, language_core_1.isRenameEnabled); if (span) { info.triggerSpan = span; return info; } } else { failed = info; } } if (failed) { return failed; } return { canRename: false, localizedErrorMessage: 'Failed to get rename locations', }; } else { return getRenameInfo(fileName, position, options); } }; languageService.getCodeFixesAtPosition = (filePath, start, end, errorCodes, formatOptions, preferences) => { let fixes = []; const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generateStart = (0, transform_1.toGeneratedOffset)(sourceScript, map, start, language_core_1.isCodeActionsEnabled); const generateEnd = (0, transform_1.toGeneratedOffset)(sourceScript, map, end, language_core_1.isCodeActionsEnabled); if (generateStart !== undefined && generateEnd !== undefined) { fixes = getCodeFixesAtPosition(fileName, generateStart, generateEnd, errorCodes, formatOptions, preferences); } } else { fixes = getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences); } fixes = fixes.map(fix => { fix.changes = fix.changes.map(edit => (0, transform_1.transformFileTextChanges)(language, edit, language_core_1.isCodeActionsEnabled)).filter(utils_1.notEmpty); return fix; }); return fixes; }; languageService.getEncodedSemanticClassifications = (filePath, span, format) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { let start; let end; for (const mapping of map.mappings) { // TODO reuse the logic from language service if ((0, language_core_1.isSemanticTokensEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) { start ??= mapping.generatedOffsets[0]; end ??= mapping.generatedOffsets[mapping.generatedOffsets.length - 1] + mapping.lengths[mapping.lengths.length - 1]; start = Math.min(start, mapping.generatedOffsets[0]); end = Math.max(end, mapping.generatedOffsets[mapping.generatedOffsets.length - 1] + mapping.lengths[mapping.lengths.length - 1]); } } start ??= 0; end ??= sourceScript.snapshot.getLength(); start += sourceScript.snapshot.getLength(); end += sourceScript.snapshot.getLength(); const result = getEncodedSemanticClassifications(fileName, { start, length: end - start }, format); const spans = []; for (let i = 0; i < result.spans.length; i += 3) { const sourceStart = (0, transform_1.toSourceOffset)(sourceScript, map, result.spans[i], language_core_1.isSemanticTokensEnabled); const sourceEnd = (0, transform_1.toSourceOffset)(sourceScript, map, result.spans[i] + result.spans[i + 1], language_core_1.isSemanticTokensEnabled); if (sourceStart !== undefined && sourceEnd !== undefined) { spans.push(sourceStart, sourceEnd - sourceStart, result.spans[i + 2]); } } result.spans = spans; return result; } else { return getEncodedSemanticClassifications(fileName, span, format); } }; languageService.getSyntacticDiagnostics = filePath => { const fileName = filePath.replace(windowsPathReg, '/'); return getSyntacticDiagnostics(fileName) .map(d => (0, transform_1.transformDiagnostic)(language, d, false)) .filter(utils_1.notEmpty); }; languageService.getSemanticDiagnostics = filePath => { const fileName = filePath.replace(windowsPathReg, '/'); return getSemanticDiagnostics(fileName) .map(d => (0, transform_1.transformDiagnostic)(language, d, false)) .filter(utils_1.notEmpty); }; languageService.getSuggestionDiagnostics = filePath => { const fileName = filePath.replace(windowsPathReg, '/'); return getSuggestionDiagnostics(fileName) .map(d => (0, transform_1.transformDiagnostic)(language, d, false)) .filter(utils_1.notEmpty); }; languageService.getDefinitionAndBoundSpan = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAndBoundSpan(fileName, position), function* (result) { for (const ref of result.definitions ?? []) { yield [ref.fileName, ref.textSpan.start]; } }); const textSpan = unresolved .map(s => (0, transform_1.transformSpan)(language, fileName, s.textSpan, language_core_1.isDefinitionEnabled)?.textSpan) .filter(utils_1.notEmpty)[0]; if (!textSpan) { return; } const definitions = unresolved .map(s => s.definitions ?.map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName)) .filter(utils_1.notEmpty)) .filter(utils_1.notEmpty) .flat(); return { textSpan, definitions: (0, dedupe_1.dedupeDocumentSpans)(definitions), }; }; languageService.findReferences = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => findReferences(fileName, position), function* (result) { for (const ref of result) { for (const reference of ref.references) { yield [reference.fileName, reference.textSpan.start]; } } }); const resolved = unresolved .flat() .map(symbol => { const definition = (0, transform_1.transformDocumentSpan)(language, symbol.definition, language_core_1.isDefinitionEnabled, true); return { definition, references: symbol.references .map(r => (0, transform_1.transformDocumentSpan)(language, r, language_core_1.isReferencesEnabled)) .filter(utils_1.notEmpty), }; }); return resolved; }; languageService.getDefinitionAtPosition = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isDefinitionEnabled, position => getDefinitionAtPosition(fileName, position), function* (result) { for (const ref of result) { yield [ref.fileName, ref.textSpan.start]; } }); const resolved = unresolved .flat() .map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isDefinitionEnabled, s.fileName !== fileName)) .filter(utils_1.notEmpty); return (0, dedupe_1.dedupeDocumentSpans)(resolved); }; languageService.getTypeDefinitionAtPosition = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isTypeDefinitionEnabled, position => getTypeDefinitionAtPosition(fileName, position), function* (result) { for (const ref of result) { yield [ref.fileName, ref.textSpan.start]; } }); const resolved = unresolved .flat() .map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isTypeDefinitionEnabled)) .filter(utils_1.notEmpty); return (0, dedupe_1.dedupeDocumentSpans)(resolved); }; languageService.getImplementationAtPosition = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isImplementationEnabled, position => getImplementationAtPosition(fileName, position), function* (result) { for (const ref of result) { yield [ref.fileName, ref.textSpan.start]; } }); const resolved = unresolved .flat() .map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isImplementationEnabled)) .filter(utils_1.notEmpty); return (0, dedupe_1.dedupeDocumentSpans)(resolved); }; languageService.findRenameLocations = (filePath, position, findInStrings, findInComments, preferences) => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isRenameEnabled, position => findRenameLocations(fileName, position, findInStrings, findInComments, preferences), function* (result) { for (const ref of result) { yield [ref.fileName, ref.textSpan.start]; } }); const resolved = unresolved .flat() .map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isRenameEnabled)) .filter(utils_1.notEmpty); return (0, dedupe_1.dedupeDocumentSpans)(resolved); }; languageService.getReferencesAtPosition = (filePath, position) => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = linkedCodeFeatureWorker(fileName, position, language_core_1.isReferencesEnabled, position => getReferencesAtPosition(fileName, position), function* (result) { for (const ref of result) { yield [ref.fileName, ref.textSpan.start]; } }); const resolved = unresolved .flat() .map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled)) .filter(utils_1.notEmpty); return (0, dedupe_1.dedupeDocumentSpans)(resolved); }; languageService.getCompletionsAtPosition = (filePath, position, options, formattingSettings) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { let mainResult; let additionalResults = []; let isAdditional; const generatedOffset = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, data => { if (!(0, language_core_1.isCompletionEnabled)(data)) { return false; } isAdditional = typeof data.completion === 'object' && data.completion.isAdditional; if (!isAdditional && mainResult) { return false; } return true; }); if (generatedOffset !== undefined) { const result = getCompletionsAtPosition(fileName, generatedOffset, options, formattingSettings); if (result) { for (const entry of result.entries) { entry.replacementSpan = entry.replacementSpan && (0, transform_1.transformTextSpan)(sourceScript, map, entry.replacementSpan, language_core_1.isCompletionEnabled); } result.optionalReplacementSpan = result.optionalReplacementSpan && (0, transform_1.transformTextSpan)(sourceScript, map, result.optionalReplacementSpan, language_core_1.isCompletionEnabled); if (isAdditional) { additionalResults.push(result); } else { mainResult = result; } } } if (!mainResult && additionalResults.length) { mainResult = additionalResults.shift(); } if (mainResult) { return { ...mainResult, entries: [ ...mainResult.entries, ...additionalResults.map(additionalResult => additionalResult.entries).flat(), ], }; } } else { return getCompletionsAtPosition(fileName, position, options, formattingSettings); } }; languageService.getCompletionEntryDetails = (filePath, position, entryName, formatOptions, source, preferences, data) => { let details; const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { const generatePosition = (0, transform_1.toGeneratedOffset)(sourceScript, map, position, language_core_1.isCompletionEnabled); if (generatePosition !== undefined) { details = getCompletionEntryDetails(fileName, generatePosition, entryName, formatOptions, source, preferences, data); } } else { return getCompletionEntryDetails(fileName, position, entryName, formatOptions, source, preferences, data); } if (details?.codeActions) { for (const codeAction of details.codeActions) { codeAction.changes = codeAction.changes.map(edit => (0, transform_1.transformFileTextChanges)(language, edit, language_core_1.isCompletionEnabled)).filter(utils_1.notEmpty); } } return details; }; languageService.provideInlayHints = (filePath, span, preferences) => { const fileName = filePath.replace(windowsPathReg, '/'); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { let start; let end; for (const mapping of map.mappings) { if ((0, language_core_1.isInlayHintsEnabled)(mapping.data) && mapping.sourceOffsets[0] >= span.start && mapping.sourceOffsets[0] <= span.start + span.length) { start ??= mapping.generatedOffsets[0]; end ??= mapping.generatedOffsets[mapping.generatedOffsets.length - 1]; start = Math.min(start, mapping.generatedOffsets[0]); end = Math.max(end, mapping.generatedOffsets[mapping.generatedOffsets.length - 1]); } } if (start === undefined || end === undefined) { start = 0; end = 0; } start += sourceScript.snapshot.getLength(); end += sourceScript.snapshot.getLength(); const result = provideInlayHints(fileName, { start, length: end - start }, preferences); const hints = []; for (const hint of result) { const sourcePosition = (0, transform_1.toSourceOffset)(sourceScript, map, hint.position, language_core_1.isInlayHintsEnabled); if (sourcePosition !== undefined) { hints.push({ ...hint, position: sourcePosition, }); } } return hints; } else { return provideInlayHints(fileName, span, preferences); } }; languageService.getFileReferences = filePath => { const fileName = filePath.replace(windowsPathReg, '/'); const unresolved = getFileReferences(fileName); const resolved = unresolved .map(s => (0, transform_1.transformDocumentSpan)(language, s, language_core_1.isReferencesEnabled)) .filter(utils_1.notEmpty); return (0, dedupe_1.dedupeDocumentSpans)(resolved); }; function linkedCodeFeatureWorker(fileName, position, filter, worker, getLinkedCodes) { const results = []; const processedFilePositions = new Set(); const [serviceScript, sourceScript, map] = (0, utils_1.getServiceScript)(language, fileName); if (serviceScript) { for (const [generatedOffset, mapping] of map.getGeneratedOffsets(position)) { if (filter(mapping.data)) { process(fileName, generatedOffset + sourceScript.snapshot.getLength()); } } } else { process(fileName, position); } return results; function process(fileName, position) { if (processedFilePositions.has(fileName + ':' + position)) { return; } processedFilePositions.add(fileName + ':' + position); const result = worker(position); if (!result) { return; } results.push(result); for (const ref of getLinkedCodes(result)) { processedFilePositions.add(ref[0] + ':' + ref[1]); const [virtualFile, sourceScript] = (0, utils_1.getServiceScript)(language, ref[0]); if (!virtualFile) { continue; } const linkedCodeMap = language.linkedCodeMaps.get(virtualFile.code); if (!linkedCodeMap) { continue; } for (const linkedCodeOffset of linkedCodeMap.getLinkedOffsets(ref[1] - sourceScript.snapshot.getLength())) { process(ref[0], linkedCodeOffset + sourceScript.snapshot.getLength()); } } } } } exports.decorateLanguageService = decorateLanguageService; //# sourceMappingURL=decorateLanguageService.js.map