Revamping to matrix style

This commit is contained in:
2026-02-16 16:37:35 -05:00
parent 71852ec99a
commit 9d0e3938e4
14958 changed files with 2089572 additions and 114 deletions

View File

@@ -0,0 +1,8 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, selection: vscode.Position, change: {
rangeOffset: number;
rangeLength: number;
text: string;
}, token?: vscode.CancellationToken) => Promise<string | undefined>;

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, selection, change, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => ({ selection, change }), function* (docs) {
for (const mappedPosition of (0, featureWorkers_1.getGeneratedPositions)(docs, selection, language_core_1.isAutoInsertEnabled)) {
for (const mapped of docs[2].toGeneratedLocation(change.rangeOffset)) {
yield {
selection: mappedPosition,
change: {
text: change.text,
rangeOffset: mapped[0],
rangeLength: change.rangeLength,
},
};
break;
}
}
}, (plugin, document, args) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideAutoInsertSnippet?.(document, args.selection, args.change, token);
}, snippet => snippet);
};
}
//# sourceMappingURL=provideAutoInsertSnippet.js.map

View File

@@ -0,0 +1,17 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export interface PluginCallHierarchyData {
uri: string;
original: Pick<vscode.CallHierarchyItem, 'data'>;
pluginIndex: number;
embeddedDocumentUri: string | undefined;
}
export declare function register(context: LanguageServiceContext): {
getCallHierarchyItems(uri: URI, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.CallHierarchyItem[] | undefined>;
getTypeHierarchyItems(uri: URI, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
getCallHierarchyIncomingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyIncomingCall[]>;
getCallHierarchyOutgoingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyOutgoingCall[]>;
getTypeHierarchySupertypes(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
getTypeHierarchySubtypes(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
};

View File

@@ -0,0 +1,240 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const dedupe = require("../utils/dedupe");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return {
getCallHierarchyItems(uri, position, token = cancellation_1.NoneCancellationToken) {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isCallHierarchyEnabled), async (plugin, document, position, map) => {
if (token.isCancellationRequested) {
return;
}
const items = await plugin[1].provideCallHierarchyItems?.(document, position, token);
items?.forEach(item => {
item.data = {
uri: uri.toString(),
original: {
data: item.data,
},
pluginIndex: context.plugins.indexOf(plugin),
embeddedDocumentUri: map?.[1].uri,
};
});
return items;
}, (data, map) => {
if (!map) {
return data;
}
return data
.map(item => transformHierarchyItem(item, [])?.[0])
.filter(item => !!item);
}, arr => dedupe.withLocations(arr.flat()));
},
getTypeHierarchyItems(uri, position, token = cancellation_1.NoneCancellationToken) {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isTypeHierarchyEnabled), async (plugin, document, position, map) => {
if (token.isCancellationRequested) {
return;
}
const items = await plugin[1].provideTypeHierarchyItems?.(document, position, token);
items?.forEach(item => {
item.data = {
uri: uri.toString(),
original: {
data: item.data,
},
pluginIndex: context.plugins.indexOf(plugin),
embeddedDocumentUri: map?.[1].uri,
};
});
return items;
}, (data, map) => {
if (!map) {
return data;
}
return data
.map(item => transformHierarchyItem(item, [])?.[0])
.filter(item => !!item);
}, arr => dedupe.withLocations(arr.flat()));
},
async getCallHierarchyIncomingCalls(item, token) {
const data = item.data;
let incomingItems = [];
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].provideCallHierarchyIncomingCalls) {
return incomingItems;
}
Object.assign(item, data.original);
if (data.embeddedDocumentUri) {
const isEmbeddedContent = !!context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(data.embeddedDocumentUri));
if (isEmbeddedContent) {
const _calls = await plugin[1].provideCallHierarchyIncomingCalls(item, token);
for (const _call of _calls) {
const calls = transformHierarchyItem(_call.from, _call.fromRanges);
if (!calls) {
continue;
}
incomingItems.push({
from: calls[0],
fromRanges: calls[1],
});
}
}
}
else {
const _calls = await plugin[1].provideCallHierarchyIncomingCalls(item, token);
for (const _call of _calls) {
const calls = transformHierarchyItem(_call.from, _call.fromRanges);
if (!calls) {
continue;
}
incomingItems.push({
from: calls[0],
fromRanges: calls[1],
});
}
}
}
return dedupe.withCallHierarchyIncomingCalls(incomingItems);
},
async getCallHierarchyOutgoingCalls(item, token) {
const data = item.data;
let items = [];
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].provideCallHierarchyOutgoingCalls) {
return items;
}
Object.assign(item, data.original);
if (data.embeddedDocumentUri) {
const isEmbeddedContent = !!context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(data.embeddedDocumentUri));
if (isEmbeddedContent) {
const _calls = await plugin[1].provideCallHierarchyOutgoingCalls(item, token);
for (const call of _calls) {
const calls = transformHierarchyItem(call.to, call.fromRanges);
if (!calls) {
continue;
}
items.push({
to: calls[0],
fromRanges: calls[1],
});
}
}
}
else {
const _calls = await plugin[1].provideCallHierarchyOutgoingCalls(item, token);
for (const call of _calls) {
const calls = transformHierarchyItem(call.to, call.fromRanges);
if (!calls) {
continue;
}
items.push({
to: calls[0],
fromRanges: calls[1],
});
}
}
}
return dedupe.withCallHierarchyOutgoingCalls(items);
},
async getTypeHierarchySupertypes(item, token) {
const data = item.data;
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].provideTypeHierarchySupertypes) {
return [];
}
Object.assign(item, data.original);
if (data.embeddedDocumentUri) {
const isEmbeddedContent = !!context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(data.embeddedDocumentUri));
if (isEmbeddedContent) {
const items = await plugin[1].provideTypeHierarchySupertypes(item, token);
return items
.map(item => transformHierarchyItem(item, [])?.[0])
.filter(item => !!item);
}
}
else {
const items = await plugin[1].provideTypeHierarchySupertypes(item, token);
return items
.map(item => transformHierarchyItem(item, [])?.[0])
.filter(item => !!item);
}
}
},
async getTypeHierarchySubtypes(item, token) {
const data = item.data;
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].provideTypeHierarchySubtypes) {
return [];
}
Object.assign(item, data.original);
if (data.embeddedDocumentUri) {
const isEmbeddedContent = !!context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(data.embeddedDocumentUri));
if (isEmbeddedContent) {
const items = await plugin[1].provideTypeHierarchySubtypes(item, token);
return items
.map(item => transformHierarchyItem(item, [])?.[0])
.filter(item => !!item);
}
}
else {
const items = await plugin[1].provideTypeHierarchySubtypes(item, token);
return items
.map(item => transformHierarchyItem(item, [])?.[0])
.filter(item => !!item);
}
}
},
};
function transformHierarchyItem(tsItem, tsRanges) {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(tsItem.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (!sourceScript || !virtualCode) {
return [tsItem, tsRanges];
}
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
let range = (0, featureWorkers_1.getSourceRange)(docs, tsItem.range);
if (!range) {
// TODO: <script> range
range = {
start: sourceDocument.positionAt(0),
end: sourceDocument.positionAt(sourceDocument.getText().length),
};
}
const selectionRange = (0, featureWorkers_1.getSourceRange)(docs, tsItem.selectionRange);
if (!selectionRange) {
continue;
}
const vueRanges = tsRanges.map(tsRange => (0, featureWorkers_1.getSourceRange)(docs, tsRange)).filter(range => !!range);
const vueItem = {
...tsItem,
name: tsItem.name === embeddedDocument.uri.substring(embeddedDocument.uri.lastIndexOf('/') + 1)
? sourceDocument.uri.substring(sourceDocument.uri.lastIndexOf('/') + 1)
: tsItem.name,
uri: sourceDocument.uri,
// TS Bug: `range: range` not works
range: {
start: range.start,
end: range.end,
},
selectionRange: {
start: selectionRange.start,
end: selectionRange.end,
},
};
return [vueItem, vueRanges];
}
}
}
//# sourceMappingURL=provideCallHierarchyItems.js.map

View File

@@ -0,0 +1,10 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export interface ServiceCodeActionData {
uri: string;
version: number;
original: Pick<vscode.CodeAction, 'data' | 'edit'>;
pluginIndex: number;
}
export declare function register(context: LanguageServiceContext): (uri: URI, range: vscode.Range, codeActionContext: vscode.CodeActionContext, token?: vscode.CancellationToken) => Promise<vscode.CodeAction[] | undefined>;

View File

@@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const common_1 = require("../utils/common");
const dedupe = require("../utils/dedupe");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return async (uri, range, codeActionContext, token = cancellation_1.NoneCancellationToken) => {
const sourceScript = context.language.scripts.get(uri);
if (!sourceScript) {
return;
}
const transformedCodeActions = new WeakSet();
return await (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => ({ range, codeActionContext }), function* (docs) {
const _codeActionContext = {
diagnostics: (0, transform_1.transformLocations)(codeActionContext.diagnostics, range => (0, featureWorkers_1.getGeneratedRange)(docs, range)),
only: codeActionContext.only,
};
const mapped = (0, common_1.findOverlapCodeRange)(docs[0].offsetAt(range.start), docs[0].offsetAt(range.end), docs[2], language_core_1.isCodeActionsEnabled);
if (mapped) {
yield {
range: {
start: docs[1].positionAt(mapped.start),
end: docs[1].positionAt(mapped.end),
},
codeActionContext: _codeActionContext,
};
}
}, async (plugin, document, { range, codeActionContext }) => {
if (token.isCancellationRequested) {
return;
}
const pluginIndex = context.plugins.indexOf(plugin);
const diagnostics = codeActionContext.diagnostics.filter(diagnostic => {
const data = diagnostic.data;
if (data && data.version !== document.version) {
return false;
}
return data?.pluginIndex === pluginIndex;
}).map(diagnostic => {
const data = diagnostic.data;
return {
...diagnostic,
...data.original,
};
});
const codeActions = await plugin[1].provideCodeActions?.(document, range, {
...codeActionContext,
diagnostics,
}, token);
codeActions?.forEach(codeAction => {
if (plugin[1].resolveCodeAction) {
codeAction.data = {
uri: uri.toString(),
version: document.version,
original: {
data: codeAction.data,
edit: codeAction.edit,
},
pluginIndex: context.plugins.indexOf(plugin),
};
}
else {
delete codeAction.data;
}
});
if (codeActions && plugin[1].transformCodeAction) {
for (let i = 0; i < codeActions.length; i++) {
const transformed = plugin[1].transformCodeAction(codeActions[i]);
if (transformed) {
codeActions[i] = transformed;
transformedCodeActions.add(transformed);
}
}
}
return codeActions;
}, actions => actions
.map(action => {
if (transformedCodeActions.has(action)) {
return action;
}
if (action.edit) {
const edit = (0, transform_1.transformWorkspaceEdit)(action.edit, context, 'codeAction');
if (!edit) {
return;
}
action.edit = edit;
}
return action;
})
.filter(action => !!action), arr => dedupe.withCodeAction(arr.flat()));
};
}
//# sourceMappingURL=provideCodeActions.js.map

View File

@@ -0,0 +1,17 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export interface ServiceCodeLensData {
kind: 'normal';
uri: string;
original: Pick<vscode.CodeLens, 'data'>;
pluginIndex: number;
}
export interface ServiceReferencesCodeLensData {
kind: 'references';
sourceFileUri: string;
workerFileUri: string;
workerFileRange: vscode.Range;
pluginIndex: number;
}
export declare function register(context: LanguageServiceContext): (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.CodeLens[]>;

View File

@@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return async (uri, token = cancellation_1.NoneCancellationToken) => {
return await (0, featureWorkers_1.documentFeatureWorker)(context, uri, docs => docs[2].mappings.some(mapping => (0, language_core_1.isCodeLensEnabled)(mapping.data)), async (plugin, document) => {
if (token.isCancellationRequested) {
return;
}
let codeLens = await plugin[1].provideCodeLenses?.(document, token);
const pluginIndex = context.plugins.indexOf(plugin);
codeLens?.forEach(codeLens => {
if (plugin[1].resolveCodeLens) {
codeLens.data = {
kind: 'normal',
uri: uri.toString(),
original: {
data: codeLens.data,
},
pluginIndex,
};
}
else {
delete codeLens.data;
}
});
const ranges = await plugin[1].provideReferencesCodeLensRanges?.(document, token);
const referencesCodeLens = ranges?.map(range => ({
range,
data: {
kind: 'references',
sourceFileUri: uri.toString(),
workerFileUri: document.uri,
workerFileRange: range,
pluginIndex: pluginIndex,
},
}));
codeLens = [
...codeLens ?? [],
...referencesCodeLens ?? [],
];
return codeLens;
}, (data, docs) => {
if (!docs) {
return data;
}
return data
.map(codeLens => {
const range = (0, featureWorkers_1.getSourceRange)(docs, codeLens.range, language_core_1.isCodeLensEnabled);
if (range) {
return {
...codeLens,
range,
};
}
})
.filter(codeLens => !!codeLens);
}, arr => arr.flat()) ?? [];
};
}
//# sourceMappingURL=provideCodeLenses.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, color: vscode.Color, range: vscode.Range, token?: vscode.CancellationToken) => Promise<vscode.ColorPresentation[] | undefined>;

View File

@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, color, range, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => range, function* (docs) {
for (const mappedRange of (0, featureWorkers_1.getGeneratedRanges)(docs, range, language_core_1.isColorEnabled)) {
yield mappedRange;
}
}, (plugin, document, range) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideColorPresentations?.(document, color, range, token);
}, (data, docs) => {
if (!docs) {
return data;
}
return data
.map(colorPresentation => {
if (colorPresentation.textEdit) {
const range = (0, featureWorkers_1.getSourceRange)(docs, colorPresentation.textEdit.range);
if (!range) {
return undefined;
}
colorPresentation.textEdit.range = range;
}
if (colorPresentation.additionalTextEdits) {
for (const textEdit of colorPresentation.additionalTextEdits) {
const range = (0, featureWorkers_1.getSourceRange)(docs, textEdit.range);
if (!range) {
return undefined;
}
textEdit.range = range;
}
}
return colorPresentation;
})
.filter(colorPresentation => !!colorPresentation);
});
};
}
//# sourceMappingURL=provideColorPresentations.js.map

View File

@@ -0,0 +1,10 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export interface ServiceCompletionData {
uri: string;
original: Pick<vscode.CompletionItem, 'additionalTextEdits' | 'textEdit' | 'data'>;
pluginIndex: number;
embeddedDocumentUri: string | undefined;
}
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, completionContext?: vscode.CompletionContext, token?: vscode.CancellationToken) => Promise<vscode.CompletionList>;

View File

@@ -0,0 +1,205 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
let lastResult;
return async (uri, position, completionContext = { triggerKind: 1, }, token = cancellation_1.NoneCancellationToken) => {
let langaugeIdAndSnapshot;
let sourceScript;
const decoded = context.decodeEmbeddedDocumentUri(uri);
if (decoded) {
langaugeIdAndSnapshot = context.language.scripts.get(decoded[0])?.generated?.embeddedCodes.get(decoded[1]);
}
else {
sourceScript = context.language.scripts.get(uri);
langaugeIdAndSnapshot = sourceScript;
}
if (!langaugeIdAndSnapshot) {
return {
isIncomplete: false,
items: [],
};
}
if (completionContext?.triggerKind === 3
&& lastResult?.uri.toString() === uri.toString()) {
for (const cacheData of lastResult.results) {
if (!cacheData.list?.isIncomplete) {
continue;
}
const pluginIndex = context.plugins.findIndex(plugin => plugin[1] === cacheData.plugin);
if (cacheData.embeddedDocumentUri) {
const decoded = context.decodeEmbeddedDocumentUri(cacheData.embeddedDocumentUri);
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (!sourceScript || !virtualCode) {
continue;
}
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
for (const mapped of (0, featureWorkers_1.getGeneratedPositions)(docs, position, data => (0, language_core_1.isCompletionEnabled)(data))) {
if (!cacheData.plugin.provideCompletionItems) {
continue;
}
cacheData.list = await cacheData.plugin.provideCompletionItems(embeddedDocument, mapped, completionContext, token);
if (!cacheData.list) {
continue;
}
for (const item of cacheData.list.items) {
if (cacheData.plugin.resolveCompletionItem) {
item.data = {
uri: uri.toString(),
original: {
additionalTextEdits: item.additionalTextEdits,
textEdit: item.textEdit,
data: item.data,
},
pluginIndex: pluginIndex,
embeddedDocumentUri: embeddedDocument.uri,
};
}
else {
delete item.data;
}
}
cacheData.list = (0, transform_1.transformCompletionList)(cacheData.list, range => (0, featureWorkers_1.getSourceRange)(docs, range), embeddedDocument, context);
}
}
}
else {
if (!cacheData.plugin.provideCompletionItems) {
continue;
}
const document = context.documents.get(uri, langaugeIdAndSnapshot.languageId, langaugeIdAndSnapshot.snapshot);
cacheData.list = await cacheData.plugin.provideCompletionItems(document, position, completionContext, token);
if (!cacheData.list) {
continue;
}
for (const item of cacheData.list.items) {
if (cacheData.plugin.resolveCompletionItem) {
item.data = {
uri: uri.toString(),
original: {
additionalTextEdits: item.additionalTextEdits,
textEdit: item.textEdit,
data: item.data,
},
pluginIndex: pluginIndex,
embeddedDocumentUri: undefined,
};
}
else {
delete item.data;
}
}
}
}
}
else {
lastResult = {
uri,
results: [],
};
// monky fix https://github.com/johnsoncodehk/volar/issues/1358
let isFirstMapping = true;
let mainCompletionUri;
const sortedPlugins = [...context.plugins]
.filter(plugin => !context.disabledServicePlugins.has(plugin[1]))
.sort((a, b) => sortServices(a[1], b[1]));
const worker = async (document, position, docs, codeInfo) => {
for (const plugin of sortedPlugins) {
if (token.isCancellationRequested) {
break;
}
if (!plugin[1].provideCompletionItems) {
continue;
}
if (plugin[1].isAdditionalCompletion && !isFirstMapping) {
continue;
}
if (completionContext?.triggerCharacter && !plugin[0].capabilities.completionProvider?.triggerCharacters?.includes(completionContext.triggerCharacter)) {
continue;
}
const isAdditional = (codeInfo && typeof codeInfo.completion === 'object' && codeInfo.completion.isAdditional) || plugin[1].isAdditionalCompletion;
if (mainCompletionUri && (!isAdditional || mainCompletionUri !== document.uri)) {
continue;
}
// avoid duplicate items with .vue and .vue.html
if (plugin[1].isAdditionalCompletion && lastResult?.results.some(data => data.plugin === plugin[1])) {
continue;
}
let completionList = await plugin[1].provideCompletionItems(document, position, completionContext, token);
if (!completionList || !completionList.items.length) {
continue;
}
if (typeof codeInfo?.completion === 'object' && codeInfo.completion.onlyImport) {
completionList.items = completionList.items.filter(item => !!item.labelDetails);
}
if (!isAdditional) {
mainCompletionUri = document.uri;
}
const pluginIndex = context.plugins.indexOf(plugin);
for (const item of completionList.items) {
if (plugin[1].resolveCompletionItem) {
item.data = {
uri: uri.toString(),
original: {
additionalTextEdits: item.additionalTextEdits,
textEdit: item.textEdit,
data: item.data,
},
pluginIndex,
embeddedDocumentUri: docs ? document.uri : undefined,
};
}
else {
delete item.data;
}
}
if (docs) {
completionList = (0, transform_1.transformCompletionList)(completionList, range => (0, featureWorkers_1.getSourceRange)(docs, range, language_core_1.isCompletionEnabled), document, context);
}
lastResult?.results.push({
embeddedDocumentUri: docs ? vscode_uri_1.URI.parse(document.uri) : undefined,
plugin: plugin[1],
list: completionList,
});
}
isFirstMapping = false;
};
if (sourceScript?.generated) {
for (const docs of (0, featureWorkers_1.forEachEmbeddedDocument)(context, sourceScript, sourceScript.generated.root)) {
let _data;
for (const mappedPosition of (0, featureWorkers_1.getGeneratedPositions)(docs, position, data => {
_data = data;
return (0, language_core_1.isCompletionEnabled)(data);
})) {
await worker(docs[1], mappedPosition, docs, _data);
}
}
}
else {
const document = context.documents.get(uri, langaugeIdAndSnapshot.languageId, langaugeIdAndSnapshot.snapshot);
await worker(document, position);
}
}
return combineCompletionList(lastResult.results.map(cacheData => cacheData.list));
function sortServices(a, b) {
return (b.isAdditionalCompletion ? -1 : 1) - (a.isAdditionalCompletion ? -1 : 1);
}
function combineCompletionList(lists) {
return {
isIncomplete: lists.some(list => list?.isIncomplete),
itemDefaults: lists.find(list => list?.itemDefaults)?.itemDefaults,
items: lists.map(list => list?.items ?? []).flat(),
};
}
};
}
//# sourceMappingURL=provideCompletionItems.js.map

View File

@@ -0,0 +1,5 @@
import type { CodeInformation } from '@volar/language-core';
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext, apiName: 'provideDeclaration' | 'provideDefinition' | 'provideTypeDefinition' | 'provideImplementation', isValidPosition: (data: CodeInformation) => boolean): (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;

View File

@@ -0,0 +1,125 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const dedupe = require("../utils/dedupe");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context, apiName, isValidPosition) {
return (uri, position, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, isValidPosition), async (plugin, document, position) => {
if (token.isCancellationRequested) {
return;
}
const recursiveChecker = dedupe.createLocationSet();
const result = [];
await withLinkedCode(document, position, undefined);
return result;
async function withLinkedCode(document, position, originDefinition) {
const api = plugin[1][apiName];
if (!api) {
return;
}
if (recursiveChecker.has({ uri: document.uri, range: { start: position, end: position } })) {
return;
}
recursiveChecker.add({ uri: document.uri, range: { start: position, end: position } });
const definitions = await api?.(document, position, token) ?? [];
for (const definition of definitions) {
let foundMirrorPosition = false;
recursiveChecker.add({ uri: definition.targetUri, range: { start: definition.targetRange.start, end: definition.targetRange.start } });
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(definition.targetUri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
const linkedCodeMap = virtualCode && sourceScript
? context.language.linkedCodeMaps.get(virtualCode)
: undefined;
if (sourceScript && virtualCode && linkedCodeMap) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const linkedPos of (0, featureWorkers_1.getLinkedCodePositions)(embeddedDocument, linkedCodeMap, definition.targetSelectionRange.start)) {
if (recursiveChecker.has({ uri: embeddedDocument.uri, range: { start: linkedPos, end: linkedPos } })) {
continue;
}
foundMirrorPosition = true;
await withLinkedCode(embeddedDocument, linkedPos, originDefinition ?? definition);
}
}
if (!foundMirrorPosition) {
if (originDefinition) {
result.push({
...definition,
originSelectionRange: originDefinition.originSelectionRange,
});
}
else {
result.push(definition);
}
}
}
}
}, (data, map) => data.map(link => {
if (link.originSelectionRange && map) {
const originSelectionRange = toSourcePositionPreferSurroundedPosition(map, link.originSelectionRange, position);
if (!originSelectionRange) {
return;
}
link.originSelectionRange = originSelectionRange;
}
let foundTargetSelectionRange = false;
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(link.targetUri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const targetVirtualFile = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (sourceScript && targetVirtualFile) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, targetVirtualFile.id), targetVirtualFile.languageId, targetVirtualFile.snapshot);
for (const [targetScript, targetSourceMap] of context.language.maps.forEach(targetVirtualFile)) {
const sourceDocument = context.documents.get(targetScript.id, targetScript.languageId, targetScript.snapshot);
const docs = [sourceDocument, embeddedDocument, targetSourceMap];
const targetSelectionRange = (0, featureWorkers_1.getSourceRange)(docs, link.targetSelectionRange);
if (!targetSelectionRange) {
continue;
}
foundTargetSelectionRange = true;
let targetRange = (0, featureWorkers_1.getSourceRange)(docs, link.targetRange);
link.targetUri = sourceDocument.uri;
// loose range mapping to for template slots, slot properties
link.targetRange = targetRange ?? targetSelectionRange;
link.targetSelectionRange = targetSelectionRange;
}
if (apiName === 'provideDefinition' && !foundTargetSelectionRange) {
for (const [targetScript] of context.language.maps.forEach(targetVirtualFile)) {
if (targetScript.id.toString() !== uri.toString()) {
return {
...link,
targetUri: targetScript.id.toString(),
targetRange: {
start: { line: 0, character: 0 },
end: { line: 0, character: 0 },
},
targetSelectionRange: {
start: { line: 0, character: 0 },
end: { line: 0, character: 0 },
},
};
}
}
return;
}
}
return link;
}).filter(link => !!link), arr => dedupe.withLocationLinks(arr.flat()));
};
}
function toSourcePositionPreferSurroundedPosition(docs, mappedRange, position) {
let result;
for (const range of (0, featureWorkers_1.getSourceRanges)(docs, mappedRange)) {
if (!result) {
result = range;
}
if ((range.start.line < position.line || (range.start.line === position.line && range.start.character <= position.character))
&& (range.end.line > position.line || (range.end.line === position.line && range.end.character >= position.character))) {
return range;
}
}
return result;
}
//# sourceMappingURL=provideDefinition.js.map

View File

@@ -0,0 +1,22 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
import { DocumentsAndMap } from '../utils/featureWorkers';
export interface ServiceDiagnosticData {
uri: string;
version: number;
original: Pick<vscode.Diagnostic, 'data'>;
isFormat: boolean;
pluginIndex: number;
documentUri: string;
}
export declare const errorMarkups: Map<URI, {
error: vscode.Diagnostic;
markup: vscode.MarkupContent;
}[]>;
export declare function register(context: LanguageServiceContext): (uri: URI, response?: (result: vscode.Diagnostic[]) => void, token?: vscode.CancellationToken) => Promise<vscode.Diagnostic[]>;
export declare function transformDiagnostic(context: LanguageServiceContext, error: vscode.Diagnostic, docs: DocumentsAndMap | undefined): vscode.Diagnostic | undefined;
export declare function updateRange(range: vscode.Range, change: {
range: vscode.Range;
newEnd: vscode.Position;
}): vscode.Range | undefined;

View File

@@ -0,0 +1,243 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorMarkups = void 0;
exports.register = register;
exports.transformDiagnostic = transformDiagnostic;
exports.updateRange = updateRange;
const language_core_1 = require("@volar/language-core");
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const common_1 = require("../utils/common");
const dedupe = require("../utils/dedupe");
const featureWorkers_1 = require("../utils/featureWorkers");
const uriMap_1 = require("../utils/uriMap");
exports.errorMarkups = (0, uriMap_1.createUriMap)();
function register(context) {
const lastResponses = (0, uriMap_1.createUriMap)();
const cacheMaps = {
semantic: new Map(),
syntactic: new Map(),
};
context.env.onDidChangeConfiguration?.(() => {
lastResponses.clear();
cacheMaps.semantic.clear();
cacheMaps.syntactic.clear();
});
return async (uri, response, token = cancellation_1.NoneCancellationToken) => {
let langaugeIdAndSnapshot;
const decoded = context.decodeEmbeddedDocumentUri(uri);
if (decoded) {
langaugeIdAndSnapshot = context.language.scripts.get(decoded[0])?.generated?.embeddedCodes.get(decoded[1]);
}
else {
langaugeIdAndSnapshot = context.language.scripts.get(uri);
}
if (!langaugeIdAndSnapshot) {
return [];
}
const document = context.documents.get(uri, langaugeIdAndSnapshot.languageId, langaugeIdAndSnapshot.snapshot);
const lastResponse = lastResponses.get(uri) ?? lastResponses.set(uri, {
semantic: { errors: [] },
syntactic: { errors: [] },
}).get(uri);
let updateCacheRangeFailed = false;
let errorsUpdated = false;
let lastCheckCancelAt = 0;
for (const cache of Object.values(lastResponse)) {
const oldSnapshot = cache.snapshot;
const oldDocument = cache.document;
const change = oldSnapshot ? langaugeIdAndSnapshot.snapshot.getChangeRange(oldSnapshot) : undefined;
cache.snapshot = langaugeIdAndSnapshot.snapshot;
cache.document = document;
if (!updateCacheRangeFailed && oldDocument && change) {
const changeRange = {
range: {
start: oldDocument.positionAt(change.span.start),
end: oldDocument.positionAt(change.span.start + change.span.length),
},
newEnd: document.positionAt(change.span.start + change.newLength),
};
for (const error of cache.errors) {
if (!updateRange(error.range, changeRange)) {
updateCacheRangeFailed = true;
break;
}
}
}
}
await worker('syntactic', cacheMaps.syntactic, lastResponse.syntactic);
processResponse();
await worker('semantic', cacheMaps.semantic, lastResponse.semantic);
return collectErrors();
function processResponse() {
if (errorsUpdated && !updateCacheRangeFailed) {
response?.(collectErrors());
errorsUpdated = false;
}
}
function collectErrors() {
return Object.values(lastResponse).flatMap(({ errors }) => errors);
}
async function worker(kind, cacheMap, cache) {
const result = await (0, featureWorkers_1.documentFeatureWorker)(context, uri, docs => docs[2].mappings.some(mapping => (0, language_core_1.isDiagnosticsEnabled)(mapping.data)), async (plugin, document) => {
const interFileDependencies = plugin[0].capabilities.diagnosticProvider?.interFileDependencies;
if (kind === 'semantic' !== interFileDependencies) {
return;
}
if (Date.now() - lastCheckCancelAt >= 10) {
await (0, common_1.sleep)(10); // waiting LSP event polling
lastCheckCancelAt = Date.now();
}
if (token.isCancellationRequested) {
return;
}
const pluginIndex = context.plugins.indexOf(plugin);
const pluginCache = cacheMap.get(pluginIndex) ?? cacheMap.set(pluginIndex, new Map()).get(pluginIndex);
const cache = pluginCache.get(document.uri);
if (!interFileDependencies && cache && cache.documentVersion === document.version) {
return cache.errors;
}
const errors = await plugin[1].provideDiagnostics?.(document, token) || [];
errors.forEach(error => {
error.data = {
uri: uri.toString(),
version: document.version,
pluginIndex: pluginIndex,
isFormat: false,
original: {
data: error.data,
},
documentUri: document.uri,
};
});
errorsUpdated = true;
pluginCache.set(document.uri, {
documentVersion: document.version,
errors,
});
return errors;
}, (errors, map) => {
return errors
.map(error => transformDiagnostic(context, error, map))
.filter(error => !!error);
}, arr => dedupe.withDiagnostics(arr.flat()));
if (result) {
cache.errors = result;
cache.snapshot = langaugeIdAndSnapshot?.snapshot;
}
}
};
}
function transformDiagnostic(context, error, docs) {
// clone it to avoid modify cache
let _error = { ...error };
if (docs) {
const range = (0, featureWorkers_1.getSourceRange)(docs, error.range, data => (0, language_core_1.shouldReportDiagnostics)(data, error.source, error.code));
if (!range) {
return;
}
_error.range = range;
}
if (_error.relatedInformation) {
const relatedInfos = [];
for (const info of _error.relatedInformation) {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(info.location.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (sourceScript && virtualCode) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
const range = (0, featureWorkers_1.getSourceRange)(docs, info.location.range, data => (0, language_core_1.shouldReportDiagnostics)(data, undefined, undefined));
if (range) {
relatedInfos.push({
location: {
uri: sourceDocument.uri,
range,
},
message: info.message,
});
}
}
}
else {
relatedInfos.push(info);
}
}
_error.relatedInformation = relatedInfos;
}
return _error;
}
function updateRange(range, change) {
if (!updatePosition(range.start, change, false)) {
return;
}
if (!updatePosition(range.end, change, true)) {
return;
}
if (range.end.line === range.start.line && range.end.character <= range.start.character) {
range.end.character++;
}
return range;
}
function updatePosition(position, change, isEnd) {
if (change.range.end.line > position.line) {
if (change.newEnd.line > position.line) {
// No change
return true;
}
else if (change.newEnd.line === position.line) {
position.character = Math.min(position.character, change.newEnd.character);
return true;
}
else if (change.newEnd.line < position.line) {
position.line = change.newEnd.line;
position.character = change.newEnd.character;
return true;
}
}
else if (change.range.end.line === position.line) {
const characterDiff = change.newEnd.character - change.range.end.character;
if (position.character >= change.range.end.character) {
if (change.newEnd.line !== change.range.end.line) {
position.line = change.newEnd.line;
position.character = change.newEnd.character + position.character - change.range.end.character;
}
else {
if (isEnd ? change.range.end.character < position.character : change.range.end.character <= position.character) {
position.character += characterDiff;
}
else {
const offset = change.range.end.character - position.character;
if (-characterDiff > offset) {
position.character += characterDiff + offset;
}
}
}
return true;
}
else {
if (change.newEnd.line === change.range.end.line) {
const offset = change.range.end.character - position.character;
if (-characterDiff > offset) {
position.character += characterDiff + offset;
}
}
else if (change.newEnd.line < change.range.end.line) {
position.line = change.newEnd.line;
position.character = change.newEnd.character;
}
else {
// No change
}
return true;
}
}
else if (change.range.end.line < position.line) {
position.line += change.newEnd.line - change.range.end.line;
return true;
}
return false;
}
//# sourceMappingURL=provideDiagnostics.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.ColorInformation[] | undefined>;

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.documentFeatureWorker)(context, uri, docs => docs[2].mappings.some(mapping => (0, language_core_1.isColorEnabled)(mapping.data)), (plugin, document) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideDocumentColors?.(document, token);
}, (data, docs) => {
if (!docs) {
return data;
}
return data
.map(color => {
const range = (0, featureWorkers_1.getSourceRange)(docs, color.range, language_core_1.isColorEnabled);
if (range) {
return {
range,
color: color.color,
};
}
})
.filter(color => !!color);
}, arr => arr.flat());
};
}
//# sourceMappingURL=provideDocumentColors.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { DataTransferItem, LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, dataTransfer: Map<string, DataTransferItem>, token?: vscode.CancellationToken) => Promise<import("../types").DocumentDropEdit | undefined>;

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return (uri, position, dataTransfer, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, function* (docs) {
for (const mappedPosition of (0, featureWorkers_1.getGeneratedPositions)(docs, position)) {
yield mappedPosition;
}
}, (plugin, document, arg) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideDocumentDropEdits?.(document, arg, dataTransfer, token);
}, edit => {
if (edit.additionalEdit) {
edit.additionalEdit = (0, transform_1.transformWorkspaceEdit)(edit.additionalEdit, context, undefined);
}
return edit;
});
};
}
//# sourceMappingURL=provideDocumentDropEdits.js.map

View File

@@ -0,0 +1,7 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, options: vscode.FormattingOptions, range: vscode.Range | undefined, onTypeParams: {
ch: string;
position: vscode.Position;
} | undefined, token?: vscode.CancellationToken) => Promise<vscode.TextEdit[] | undefined>;

View File

@@ -0,0 +1,226 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const common_1 = require("../utils/common");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return async (uri, options, range, onTypeParams, token = cancellation_1.NoneCancellationToken) => {
const sourceScript = context.language.scripts.get(uri);
if (!sourceScript) {
return;
}
let document = context.documents.get(uri, sourceScript.languageId, sourceScript.snapshot);
range ??= {
start: document.positionAt(0),
end: document.positionAt(document.getText().length),
};
if (!sourceScript.generated) {
return onTypeParams
? (await tryFormat(document, document, sourceScript, undefined, 0, onTypeParams.position, onTypeParams.ch))?.edits
: (await tryFormat(document, document, sourceScript, undefined, 0, range, undefined))?.edits;
}
const embeddedRanges = new Map(); // TODO: Formatting of upper-level virtual code may cause offset of lower-level selection range
const startOffset = document.offsetAt(range.start);
const endOffset = document.offsetAt(range.end);
for (const code of (0, language_core_1.forEachEmbeddedCode)(sourceScript.generated.root)) {
const map = context.language.maps.get(code, sourceScript);
if (map) {
const embeddedRange = (0, common_1.findOverlapCodeRange)(startOffset, endOffset, map, language_core_1.isFormattingEnabled);
if (embeddedRange) {
if (embeddedRange.start === map.mappings[0].generatedOffsets[0]) {
embeddedRange.start = 0;
}
const lastMapping = map.mappings[map.mappings.length - 1];
if (embeddedRange.end === lastMapping.generatedOffsets[lastMapping.generatedOffsets.length - 1] + (lastMapping.generatedLengths ?? lastMapping.lengths)[lastMapping.lengths.length - 1]) {
embeddedRange.end = code.snapshot.getLength();
}
embeddedRanges.set(code.id, embeddedRange);
}
}
}
try {
const originalDocument = document;
let tempSourceSnapshot = sourceScript.snapshot;
let tempVirtualFile = context.language.scripts.set(vscode_uri_1.URI.parse(sourceScript.id.toString() + '.tmp'), sourceScript.snapshot, sourceScript.languageId, [sourceScript.generated.languagePlugin])?.generated?.root;
if (!tempVirtualFile) {
return;
}
let currentCodes = [];
for (let depth = 0; (currentCodes = getNestedEmbeddedFiles(context, sourceScript.id, tempVirtualFile, depth)).length > 0; depth++) {
let edits = [];
for (const code of currentCodes) {
if (!code.mappings.some(mapping => (0, language_core_1.isFormattingEnabled)(mapping.data))) {
continue;
}
const currentRange = embeddedRanges.get(code.id);
if (!currentRange) {
continue;
}
const isChildRange = [...(0, language_core_1.forEachEmbeddedCode)(code)].some(child => {
if (child === code) {
return false;
}
const childRange = embeddedRanges.get(child.id);
return childRange && childRange.end - childRange.start >= currentRange.end - currentRange.start;
});
if (isChildRange) {
continue;
}
const docs = [
context.documents.get(uri, sourceScript.languageId, tempSourceSnapshot),
context.documents.get(context.encodeEmbeddedDocumentUri(uri, code.id), code.languageId, code.snapshot),
context.language.mapperFactory(code.mappings),
];
let embeddedResult;
if (onTypeParams) {
for (const embeddedPosition of (0, featureWorkers_1.getGeneratedPositions)(docs, onTypeParams.position)) {
embeddedResult = await tryFormat(docs[0], docs[1], sourceScript, code, depth, embeddedPosition, onTypeParams.ch);
break;
}
}
else if (currentRange) {
embeddedResult = await tryFormat(docs[0], docs[1], sourceScript, code, depth, {
start: docs[1].positionAt(currentRange.start),
end: docs[1].positionAt(currentRange.end),
});
}
if (!embeddedResult) {
continue;
}
for (const textEdit of embeddedResult.edits) {
const range = (0, featureWorkers_1.getSourceRange)(docs, textEdit.range);
if (range) {
edits.push({
newText: textEdit.newText,
range,
});
}
}
}
if (edits.length > 0) {
const newText = vscode_languageserver_textdocument_1.TextDocument.applyEdits(document, edits);
document = vscode_languageserver_textdocument_1.TextDocument.create(document.uri, document.languageId, document.version + 1, newText);
tempSourceSnapshot = (0, common_1.stringToSnapshot)(newText);
tempVirtualFile = context.language.scripts.set(vscode_uri_1.URI.parse(sourceScript.id.toString() + '.tmp'), tempSourceSnapshot, sourceScript.languageId, [sourceScript.generated.languagePlugin])?.generated?.root;
if (!tempVirtualFile) {
break;
}
}
}
if (document.getText() === originalDocument.getText()) {
return;
}
const editRange = {
start: originalDocument.positionAt(0),
end: originalDocument.positionAt(originalDocument.getText().length),
};
const textEdit = {
range: editRange,
newText: document.getText(),
};
return [textEdit];
}
finally {
context.language.scripts.delete(vscode_uri_1.URI.parse(sourceScript.id.toString() + '.tmp'));
}
async function tryFormat(sourceDocument, document, sourceScript, virtualCode, embeddedLevel, rangeOrPosition, ch) {
if (context.disabledEmbeddedDocumentUris.get(vscode_uri_1.URI.parse(document.uri))) {
return;
}
let codeOptions;
rangeOrPosition ??= {
start: document.positionAt(0),
end: document.positionAt(document.getText().length),
};
if (virtualCode) {
codeOptions = {
level: embeddedLevel,
initialIndentLevel: 0,
};
if (virtualCode.mappings.length) {
const firstMapping = virtualCode.mappings[0];
const startOffset = firstMapping.sourceOffsets[0];
const startPosition = sourceDocument.positionAt(startOffset);
codeOptions.initialIndentLevel = computeInitialIndent(sourceDocument.getText(), sourceDocument.offsetAt({ line: startPosition.line, character: 0 }), options);
}
for (const plugin of context.plugins) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
codeOptions = await plugin[1].resolveEmbeddedCodeFormattingOptions?.(sourceScript, virtualCode, codeOptions, token) ?? codeOptions;
}
}
for (const plugin of context.plugins) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
if (token.isCancellationRequested) {
break;
}
let edits;
try {
if (ch !== undefined && rangeOrPosition && 'line' in rangeOrPosition && 'character' in rangeOrPosition) {
if (plugin[0].capabilities.documentOnTypeFormattingProvider?.triggerCharacters?.includes(ch)) {
edits = await plugin[1].provideOnTypeFormattingEdits?.(document, rangeOrPosition, ch, options, codeOptions, token);
}
}
else if (ch === undefined && rangeOrPosition && 'start' in rangeOrPosition && 'end' in rangeOrPosition) {
edits = await plugin[1].provideDocumentFormattingEdits?.(document, rangeOrPosition, options, codeOptions, token);
}
}
catch (err) {
console.warn(err);
}
if (!edits) {
continue;
}
return {
plugin,
edits,
};
}
}
};
}
function getNestedEmbeddedFiles(context, uri, rootCode, depth) {
const nestedCodesByLevel = [[rootCode]];
while (true) {
if (nestedCodesByLevel.length > depth) {
return nestedCodesByLevel[depth];
}
const nestedCodes = [];
for (const code of nestedCodesByLevel[nestedCodesByLevel.length - 1]) {
if (code.embeddedCodes) {
for (const embedded of code.embeddedCodes) {
if (!context.disabledEmbeddedDocumentUris.get(context.encodeEmbeddedDocumentUri(uri, embedded.id))) {
nestedCodes.push(embedded);
}
}
}
}
nestedCodesByLevel.push(nestedCodes);
}
}
function computeInitialIndent(content, i, options) {
let nChars = 0;
const tabSize = options.tabSize || 4;
while (i < content.length) {
const ch = content.charAt(i);
if (ch === ' ') {
nChars++;
}
else if (ch === '\t') {
nChars += tabSize;
}
else {
break;
}
i++;
}
return Math.floor(nChars / tabSize);
}
//# sourceMappingURL=provideDocumentFormattingEdits.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.DocumentHighlight[] | undefined>;

View File

@@ -0,0 +1,68 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const dedupe = require("../utils/dedupe");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, position, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isHighlightEnabled), async (plugin, document, position) => {
if (token.isCancellationRequested) {
return;
}
const recursiveChecker = dedupe.createLocationSet();
const result = [];
await withLinkedCode(document, position);
return result;
async function withLinkedCode(document, position) {
if (!plugin[1].provideDocumentHighlights) {
return;
}
if (recursiveChecker.has({ uri: document.uri, range: { start: position, end: position } })) {
return;
}
recursiveChecker.add({ uri: document.uri, range: { start: position, end: position } });
const references = await plugin[1].provideDocumentHighlights(document, position, token) ?? [];
for (const reference of references) {
let foundMirrorPosition = false;
recursiveChecker.add({ uri: document.uri, range: { start: reference.range.start, end: reference.range.start } });
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(document.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
const linkedCodeMap = virtualCode && sourceScript
? context.language.linkedCodeMaps.get(virtualCode)
: undefined;
if (sourceScript && virtualCode && linkedCodeMap) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const linkedPos of (0, featureWorkers_1.getLinkedCodePositions)(embeddedDocument, linkedCodeMap, reference.range.start)) {
if (recursiveChecker.has({ uri: embeddedDocument.uri, range: { start: linkedPos, end: linkedPos } })) {
continue;
}
foundMirrorPosition = true;
await withLinkedCode(embeddedDocument, linkedPos);
}
}
if (!foundMirrorPosition) {
result.push(reference);
}
}
}
}, (data, docs) => data
.map(highlight => {
if (!docs) {
return highlight;
}
const range = (0, featureWorkers_1.getSourceRange)(docs, highlight.range, language_core_1.isHighlightEnabled);
if (range) {
return {
...highlight,
range,
};
}
})
.filter(highlight => !!highlight), arr => arr.flat());
};
}
//# sourceMappingURL=provideDocumentHighlights.js.map

View File

@@ -0,0 +1,9 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export interface DocumentLinkData {
uri: string;
original: Pick<vscode.DocumentLink, 'data'>;
pluginIndex: number;
}
export declare function register(context: LanguageServiceContext): (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.DocumentLink[]>;

View File

@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return async (uri, token = cancellation_1.NoneCancellationToken) => {
return await (0, featureWorkers_1.documentFeatureWorker)(context, uri, docs => docs[2].mappings.some(mapping => (0, language_core_1.isDocumentLinkEnabled)(mapping.data)), async (plugin, document) => {
if (token.isCancellationRequested) {
return;
}
const links = await plugin[1].provideDocumentLinks?.(document, token);
for (const link of links ?? []) {
if (plugin[1].resolveDocumentLink) {
link.data = {
uri: uri.toString(),
original: {
data: link.data,
},
pluginIndex: context.plugins.indexOf(plugin),
};
}
else {
delete link.data;
}
}
return links;
}, (links, docs) => {
if (!docs) {
return links;
}
return links
.map(link => {
const range = (0, featureWorkers_1.getSourceRange)(docs, link.range, language_core_1.isDocumentLinkEnabled);
if (!range) {
return;
}
link = {
...link,
range,
};
if (link.target) {
link.target = (0, transform_1.transformDocumentLinkTarget)(link.target, context).toString();
}
return link;
})
.filter(link => !!link);
}, arr => arr.flat()) ?? [];
};
}
//# sourceMappingURL=provideDocumentLinks.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, range: vscode.Range | undefined, legend: vscode.SemanticTokensLegend, _reportProgress?: (tokens: vscode.SemanticTokens) => void, token?: vscode.CancellationToken) => Promise<vscode.SemanticTokens | undefined>;

View File

@@ -0,0 +1,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const SemanticTokensBuilder_1 = require("../utils/SemanticTokensBuilder");
const cancellation_1 = require("../utils/cancellation");
const common_1 = require("../utils/common");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return async (uri, range, legend, _reportProgress, // TODO
token = cancellation_1.NoneCancellationToken) => {
const sourceScript = context.language.scripts.get(uri);
if (!sourceScript) {
return;
}
const document = context.documents.get(uri, sourceScript.languageId, sourceScript.snapshot);
if (!range) {
range = {
start: { line: 0, character: 0 },
end: { line: document.lineCount - 1, character: document.getText().length },
};
}
const tokens = await (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => range, function* (docs) {
const mapped = (0, common_1.findOverlapCodeRange)(docs[0].offsetAt(range.start), docs[0].offsetAt(range.end), docs[2], language_core_1.isSemanticTokensEnabled);
if (mapped) {
yield {
start: docs[1].positionAt(mapped.start),
end: docs[1].positionAt(mapped.end),
};
}
}, (plugin, document, range) => {
if (token?.isCancellationRequested) {
return;
}
return plugin[1].provideDocumentSemanticTokens?.(document, range, legend, token);
}, (tokens, docs) => {
if (!docs) {
return tokens;
}
return tokens
.map(_token => {
const range = (0, featureWorkers_1.getSourceRange)(docs, {
start: { line: _token[0], character: _token[1] },
end: { line: _token[0], character: _token[1] + _token[2] },
}, language_core_1.isSemanticTokensEnabled);
if (range) {
return [range.start.line, range.start.character, range.end.character - range.start.character, _token[3], _token[4]];
}
})
.filter(token => !!token);
}, tokens => tokens.flat()
// tokens => reportProgress?.(buildTokens(tokens)), // TODO: this has no effect with LSP
);
if (tokens) {
return buildTokens(tokens);
}
};
}
function buildTokens(tokens) {
const builder = new SemanticTokensBuilder_1.SemanticTokensBuilder();
const sortedTokens = tokens.sort((a, b) => a[0] - b[0] === 0 ? a[1] - b[1] : a[0] - b[0]);
for (const token of sortedTokens) {
builder.push(...token);
}
return builder.build();
}
//# sourceMappingURL=provideDocumentSemanticTokens.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.DocumentSymbol[] | undefined>;

View File

@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const common_1 = require("../utils/common");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return (uri, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.documentFeatureWorker)(context, uri, docs => docs[2].mappings.some(mapping => (0, language_core_1.isSymbolsEnabled)(mapping.data)), (plugin, document) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideDocumentSymbols?.(document, token);
}, (data, docs) => {
if (!docs) {
return data;
}
return data
.map(symbol => (0, transform_1.transformDocumentSymbol)(symbol, range => (0, featureWorkers_1.getSourceRange)(docs, range, language_core_1.isSymbolsEnabled)))
.filter(symbol => !!symbol);
}, results => {
for (let i = 0; i < results.length; i++) {
for (let j = 0; j < results.length; j++) {
if (i === j) {
continue;
}
results[i] = results[i].filter(child => {
for (const parent of forEachSymbol(results[j])) {
if ((0, common_1.isInsideRange)(parent.range, child.range)) {
parent.children ??= [];
parent.children.push(child);
return false;
}
}
return true;
});
}
}
return results.flat();
});
};
}
function* forEachSymbol(symbols) {
for (const symbol of symbols) {
if (symbol.children) {
yield* forEachSymbol(symbol.children);
}
yield symbol;
}
}
//# sourceMappingURL=provideDocumentSymbols.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext, NullableProviderResult } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, token?: vscode.CancellationToken) => NullableProviderResult<vscode.Location[]>;

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const dedupe = require("../utils/dedupe");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.documentFeatureWorker)(context, uri, () => true, async (plugin, document) => {
if (token.isCancellationRequested) {
return;
}
return await plugin[1].provideFileReferences?.(document, token) ?? [];
}, data => data
.map(reference => {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(reference.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (!sourceScript || !virtualCode) {
return reference;
}
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
const range = (0, featureWorkers_1.getSourceRange)(docs, reference.range, language_core_1.isReferencesEnabled);
if (range) {
reference.uri = sourceDocument.uri;
reference.range = range;
return reference;
}
}
})
.filter(reference => !!reference), arr => dedupe.withLocations(arr.flat()));
};
}
//# sourceMappingURL=provideFileReferences.js.map

View File

@@ -0,0 +1,4 @@
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
import type * as _ from 'vscode-languageserver-protocol';
export declare function register(context: LanguageServiceContext): (oldUri: URI, newUri: URI, token?: _.CancellationToken) => Promise<_.WorkspaceEdit | undefined>;

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const cancellation_1 = require("../utils/cancellation");
const dedupe = require("../utils/dedupe");
const transform_1 = require("../utils/transform");
function register(context) {
return async (oldUri, newUri, token = cancellation_1.NoneCancellationToken) => {
for (const plugin of context.plugins) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
if (token.isCancellationRequested) {
break;
}
if (!plugin[1].provideFileRenameEdits) {
continue;
}
const workspaceEdit = await plugin[1].provideFileRenameEdits(oldUri, newUri, token);
if (workspaceEdit) {
const result = (0, transform_1.transformWorkspaceEdit)(workspaceEdit, context, 'fileName');
if (result?.documentChanges) {
result.documentChanges = dedupe.withDocumentChanges(result.documentChanges);
}
return result;
}
}
};
}
//# sourceMappingURL=provideFileRenameEdits.js.map

View File

@@ -0,0 +1,4 @@
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
import type * as _ from 'vscode-languageserver-protocol';
export declare function register(context: LanguageServiceContext): (uri: URI, token?: _.CancellationToken) => Promise<_.FoldingRange[] | undefined>;

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return (uri, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.documentFeatureWorker)(context, uri, docs => docs[2].mappings.some(mapping => (0, language_core_1.isFoldingRangesEnabled)(mapping.data)), (plugin, document) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideFoldingRanges?.(document, token);
}, (data, docs) => {
if (!docs) {
return data;
}
return (0, transform_1.transformFoldingRanges)(data, range => (0, featureWorkers_1.getSourceRange)(docs, range, language_core_1.isFoldingRangesEnabled));
}, arr => arr.flat());
};
}
//# sourceMappingURL=provideFoldingRanges.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Hover | undefined>;

View File

@@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const common_1 = require("../utils/common");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
const provideDiagnostics_1 = require("./provideDiagnostics");
function register(context) {
return async (uri, position, token = cancellation_1.NoneCancellationToken) => {
let hover = await (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isHoverEnabled), (plugin, document, position) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideHover?.(document, position, token);
}, (item, docs) => {
if (!docs || !item.range) {
return item;
}
item.range = (0, featureWorkers_1.getSourceRange)(docs, item.range, language_core_1.isHoverEnabled);
return item;
}, (hovers) => ({
contents: {
kind: 'markdown',
value: hovers.map(getHoverTexts).flat().join('\n\n---\n\n'),
},
range: hovers.find(hover => hover.range && (0, common_1.isInsideRange)(hover.range, { start: position, end: position }))?.range ?? hovers[0].range,
}));
const markups = provideDiagnostics_1.errorMarkups.get(uri);
if (markups) {
for (const errorAndMarkup of markups) {
if ((0, common_1.isInsideRange)(errorAndMarkup.error.range, { start: position, end: position })) {
hover ??= {
contents: {
kind: 'markdown',
value: '',
},
};
hover.range = errorAndMarkup.error.range;
if (typeof hover.contents !== 'object' || typeof hover.contents !== 'string') {
hover.contents = {
kind: 'markdown',
value: hover.contents,
};
}
if (hover.contents.value) {
hover.contents.value += '\n\n---\n\n';
}
hover.contents.value += errorAndMarkup.markup.value;
}
}
}
return hover;
};
function getHoverTexts(hover) {
if (typeof hover.contents === 'string') {
return [(0, transform_1.transformMarkdown)(hover.contents, context)];
}
if (Array.isArray(hover.contents)) {
return hover.contents.map(content => {
if (typeof content === 'string') {
return (0, transform_1.transformMarkdown)(content, context);
}
if (content.language === 'md') {
return `\`\`\`${content.language}\n${(0, transform_1.transformMarkdown)(content.value, context)}\n\`\`\``;
}
else {
return `\`\`\`${content.language}\n${content.value}\n\`\`\``;
}
});
}
if ('kind' in hover.contents) {
if (hover.contents.kind === 'markdown') {
return [(0, transform_1.transformMarkdown)(hover.contents.value, context)];
}
else {
return [hover.contents.value];
}
}
if (hover.contents.language === 'md') {
return [`\`\`\`${hover.contents.language}\n${(0, transform_1.transformMarkdown)(hover.contents.value, context)}\n\`\`\``];
}
else {
return [`\`\`\`${hover.contents.language}\n${hover.contents.value}\n\`\`\``];
}
}
}
//# sourceMappingURL=provideHover.js.map

View File

@@ -0,0 +1,9 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export interface InlayHintData {
uri: string;
original: Pick<vscode.CodeAction, 'data' | 'edit'>;
pluginIndex: number;
}
export declare function register(context: LanguageServiceContext): (uri: URI, range: vscode.Range, token?: vscode.CancellationToken) => Promise<vscode.InlayHint[] | undefined>;

View File

@@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const common_1 = require("../utils/common");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return async (uri, range, token = cancellation_1.NoneCancellationToken) => {
const sourceScript = context.language.scripts.get(uri);
if (!sourceScript) {
return;
}
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => range, function* (docs) {
const mapped = (0, common_1.findOverlapCodeRange)(docs[0].offsetAt(range.start), docs[0].offsetAt(range.end), docs[2], language_core_1.isInlayHintsEnabled);
if (mapped) {
yield {
start: docs[1].positionAt(mapped.start),
end: docs[1].positionAt(mapped.end),
};
}
}, async (plugin, document, arg) => {
if (token.isCancellationRequested) {
return;
}
const hints = await plugin[1].provideInlayHints?.(document, arg, token);
hints?.forEach(link => {
if (plugin[1].resolveInlayHint) {
link.data = {
uri: uri.toString(),
original: {
data: link.data,
},
pluginIndex: context.plugins.indexOf(plugin),
};
}
else {
delete link.data;
}
});
return hints;
}, (inlayHints, docs) => {
if (!docs) {
return inlayHints;
}
return inlayHints
.map((_inlayHint) => {
const edits = _inlayHint.textEdits
?.map(textEdit => (0, transform_1.transformTextEdit)(textEdit, range => (0, featureWorkers_1.getSourceRange)(docs, range), docs[1]))
.filter(textEdit => !!textEdit);
for (const position of (0, featureWorkers_1.getSourcePositions)(docs, _inlayHint.position, language_core_1.isInlayHintsEnabled)) {
return {
..._inlayHint,
position,
textEdits: edits,
};
}
})
.filter(hint => !!hint);
}, arr => arr.flat());
};
}
//# sourceMappingURL=provideInlayHints.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, range: vscode.Range, ivContext: vscode.InlineValueContext, token?: vscode.CancellationToken) => Promise<vscode.InlineValue[] | undefined>;

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, range, ivContext, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => range, docs => (0, featureWorkers_1.getGeneratedRanges)(docs, range, language_core_1.isInlineValueEnabled), (plugin, document, range) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideInlineValues?.(document, range, ivContext, token);
}, (items, docs) => {
if (!docs) {
return items;
}
return items
.map(item => {
const mappedRange = (0, featureWorkers_1.getSourceRange)(docs, item.range, language_core_1.isInlineValueEnabled);
if (mappedRange) {
item.range = mappedRange;
return item;
}
})
.filter(item => !!item);
}, results => results.flat());
};
}
//# sourceMappingURL=provideInlineValue.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LinkedEditingRanges | undefined>;

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, position, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, function* (docs) {
for (const pos of (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isLinkedEditingEnabled)) {
yield pos;
}
}, (plugin, document, position) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideLinkedEditingRanges?.(document, position, token);
}, (ranges, docs) => {
if (!docs) {
return ranges;
}
return {
wordPattern: ranges.wordPattern,
ranges: ranges.ranges
.map(range => (0, featureWorkers_1.getSourceRange)(docs, range, language_core_1.isLinkedEditingEnabled))
.filter(range => !!range),
};
});
};
}
//# sourceMappingURL=provideLinkedEditingRanges.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Moniker[] | undefined>;

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, position, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isMonikerEnabled), (plugin, document, position) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideMoniker?.(document, position, token);
}, result => result, results => results.flat());
};
}
//# sourceMappingURL=provideMoniker.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, referenceContext: vscode.ReferenceContext, token?: vscode.CancellationToken) => Promise<vscode.Location[] | undefined>;

View File

@@ -0,0 +1,80 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const dedupe = require("../utils/dedupe");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, position, referenceContext, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isReferencesEnabled), async (plugin, document, position) => {
if (token.isCancellationRequested) {
return;
}
const recursiveChecker = dedupe.createLocationSet();
const result = [];
await withLinkedCode(document, position);
return result;
async function withLinkedCode(document, position) {
if (!plugin[1].provideReferences) {
return;
}
if (recursiveChecker.has({ uri: document.uri, range: { start: position, end: position } })) {
return;
}
recursiveChecker.add({ uri: document.uri, range: { start: position, end: position } });
const references = await plugin[1].provideReferences(document, position, referenceContext, token) ?? [];
for (const reference of references) {
let foundMirrorPosition = false;
recursiveChecker.add({ uri: reference.uri, range: { start: reference.range.start, end: reference.range.start } });
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(reference.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
const linkedCodeMap = virtualCode && sourceScript
? context.language.linkedCodeMaps.get(virtualCode)
: undefined;
if (sourceScript && virtualCode && linkedCodeMap) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const linkedPos of (0, featureWorkers_1.getLinkedCodePositions)(embeddedDocument, linkedCodeMap, reference.range.start)) {
if (recursiveChecker.has({ uri: embeddedDocument.uri, range: { start: linkedPos, end: linkedPos } })) {
continue;
}
foundMirrorPosition = true;
await withLinkedCode(embeddedDocument, linkedPos);
}
}
if (!foundMirrorPosition) {
result.push(reference);
}
}
}
}, data => {
const results = [];
for (const reference of data) {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(reference.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (sourceScript && virtualCode) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
const range = (0, featureWorkers_1.getSourceRange)(docs, reference.range, language_core_1.isReferencesEnabled);
if (range) {
results.push({
uri: sourceDocument.uri,
range,
});
}
}
}
else {
results.push(reference);
}
}
return results;
}, arr => dedupe.withLocations(arr.flat()));
};
}
//# sourceMappingURL=provideReferences.js.map

View File

@@ -0,0 +1,5 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, newName: string, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceEdit | undefined>;
export declare function mergeWorkspaceEdits(original: vscode.WorkspaceEdit, ...others: vscode.WorkspaceEdit[]): void;

View File

@@ -0,0 +1,140 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
exports.mergeWorkspaceEdits = mergeWorkspaceEdits;
const language_core_1 = require("@volar/language-core");
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const dedupe = require("../utils/dedupe");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return (uri, position, newName, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => ({ position, newName }), function* (docs) {
let _data;
for (const mappedPosition of (0, featureWorkers_1.getGeneratedPositions)(docs, position, data => {
_data = data;
return (0, language_core_1.isRenameEnabled)(data);
})) {
yield {
position: mappedPosition,
newName: (0, language_core_1.resolveRenameNewName)(newName, _data),
};
}
;
}, async (plugin, document, params) => {
if (token.isCancellationRequested) {
return;
}
const recursiveChecker = dedupe.createLocationSet();
let result;
await withLinkedCode(document, params.position, params.newName);
return result;
async function withLinkedCode(document, position, newName) {
if (!plugin[1].provideRenameEdits) {
return;
}
if (recursiveChecker.has({ uri: document.uri, range: { start: position, end: position } })) {
return;
}
recursiveChecker.add({ uri: document.uri, range: { start: position, end: position } });
const workspaceEdit = await plugin[1].provideRenameEdits(document, position, newName, token);
if (!workspaceEdit) {
return;
}
if (!result) {
result = {};
}
if (workspaceEdit.changes) {
for (const editUri in workspaceEdit.changes) {
const textEdits = workspaceEdit.changes[editUri];
for (const textEdit of textEdits) {
let foundMirrorPosition = false;
recursiveChecker.add({ uri: editUri, range: { start: textEdit.range.start, end: textEdit.range.start } });
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(editUri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
const linkedCodeMap = virtualCode && sourceScript
? context.language.linkedCodeMaps.get(virtualCode)
: undefined;
if (sourceScript && virtualCode && linkedCodeMap) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const linkedPos of (0, featureWorkers_1.getLinkedCodePositions)(embeddedDocument, linkedCodeMap, textEdit.range.start)) {
if (recursiveChecker.has({ uri: embeddedDocument.uri, range: { start: linkedPos, end: linkedPos } })) {
continue;
}
foundMirrorPosition = true;
await withLinkedCode(embeddedDocument, linkedPos, newName);
}
}
if (!foundMirrorPosition) {
if (!result.changes) {
result.changes = {};
}
if (!result.changes[editUri]) {
result.changes[editUri] = [];
}
result.changes[editUri].push(textEdit);
}
}
}
}
if (workspaceEdit.changeAnnotations) {
for (const uri in workspaceEdit.changeAnnotations) {
if (!result.changeAnnotations) {
result.changeAnnotations = {};
}
result.changeAnnotations[uri] = workspaceEdit.changeAnnotations[uri];
}
}
if (workspaceEdit.documentChanges) {
if (!result.documentChanges) {
result.documentChanges = [];
}
result.documentChanges = result.documentChanges.concat(workspaceEdit.documentChanges);
}
}
}, data => {
return (0, transform_1.transformWorkspaceEdit)(data, context, 'rename');
}, workspaceEdits => {
const mainEdit = workspaceEdits[0];
const otherEdits = workspaceEdits.slice(1);
mergeWorkspaceEdits(mainEdit, ...otherEdits);
if (mainEdit.changes) {
for (const uri in mainEdit.changes) {
mainEdit.changes[uri] = dedupe.withTextEdits(mainEdit.changes[uri]);
}
}
return workspaceEdits[0];
});
};
}
function mergeWorkspaceEdits(original, ...others) {
for (const other of others) {
for (const uri in other.changeAnnotations) {
if (!original.changeAnnotations) {
original.changeAnnotations = {};
}
original.changeAnnotations[uri] = other.changeAnnotations[uri];
}
for (const uri in other.changes) {
if (!original.changes) {
original.changes = {};
}
if (!original.changes[uri]) {
original.changes[uri] = [];
}
const edits = other.changes[uri];
original.changes[uri] = original.changes[uri].concat(edits);
}
if (other.documentChanges) {
if (!original.documentChanges) {
original.documentChanges = [];
}
for (const docChange of other.documentChanges) {
(0, transform_1.pushEditToDocumentChanges)(original.documentChanges, docChange);
}
}
}
}
//# sourceMappingURL=provideRenameEdits.js.map

View File

@@ -0,0 +1,9 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Range | {
range: vscode.Range;
placeholder: string;
} | {
message: string;
} | undefined>;

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, position, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isRenameEnabled), (plugin, document, position) => {
if (token.isCancellationRequested) {
return;
}
return plugin[1].provideRenameRange?.(document, position, token);
}, (item, docs) => {
if (!docs) {
return item;
}
if ('start' in item && 'end' in item) {
return (0, featureWorkers_1.getSourceRange)(docs, item);
}
return item;
}, prepares => {
for (const prepare of prepares) {
if ('start' in prepare && 'end' in prepare) {
return prepare; // if has any valid range, ignore other errors
}
}
return prepares[0];
});
};
}
//# sourceMappingURL=provideRenameRange.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, positions: vscode.Position[], token?: vscode.CancellationToken) => Promise<vscode.SelectionRange[] | undefined>;

View File

@@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const common_1 = require("../utils/common");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return (uri, positions, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => positions, function* (docs) {
const result = positions
.map(position => {
for (const mappedPosition of (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isSelectionRangesEnabled)) {
return mappedPosition;
}
})
.filter(position => !!position);
if (result.length) {
yield result;
}
}, async (plugin, document, positions) => {
if (token.isCancellationRequested) {
return;
}
const selectionRanges = await plugin[1].provideSelectionRanges?.(document, positions, token);
if (selectionRanges && selectionRanges.length !== positions.length) {
console.error('Selection ranges count should be equal to positions count:', plugin[0].name, selectionRanges.length, positions.length);
return;
}
return selectionRanges;
}, (data, docs) => {
if (!docs) {
return data;
}
return (0, transform_1.transformSelectionRanges)(data, range => (0, featureWorkers_1.getSourceRange)(docs, range, language_core_1.isSelectionRangesEnabled));
}, results => {
const result = [];
for (let i = 0; i < positions.length; i++) {
let pluginResults = [];
for (const ranges of results) {
pluginResults.push(ranges[i]);
}
pluginResults = pluginResults.sort((a, b) => {
if ((0, common_1.isInsideRange)(a.range, b.range)) {
return 1;
}
if ((0, common_1.isInsideRange)(b.range, a.range)) {
return -1;
}
return 0;
});
for (let j = 1; j < pluginResults.length; j++) {
let top = pluginResults[j - 1];
const parent = pluginResults[j];
while (top.parent && (0, common_1.isInsideRange)(parent.range, top.parent.range) && !(0, common_1.isEqualRange)(parent.range, top.parent.range)) {
top = top.parent;
}
if (top) {
top.parent = parent;
}
}
result.push(pluginResults[0]);
}
return result;
});
};
}
//# sourceMappingURL=provideSelectionRanges.js.map

View File

@@ -0,0 +1,4 @@
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (uri: URI, position: vscode.Position, signatureHelpContext?: vscode.SignatureHelpContext, token?: vscode.CancellationToken) => Promise<vscode.SignatureHelp | undefined>;

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const language_core_1 = require("@volar/language-core");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
function register(context) {
return (uri, position, signatureHelpContext = {
triggerKind: 1,
isRetrigger: false,
}, token = cancellation_1.NoneCancellationToken) => {
return (0, featureWorkers_1.languageFeatureWorker)(context, uri, () => position, docs => (0, featureWorkers_1.getGeneratedPositions)(docs, position, language_core_1.isSignatureHelpEnabled), (plugin, document, position) => {
if (token.isCancellationRequested) {
return;
}
if (signatureHelpContext?.triggerKind === 2
&& signatureHelpContext.triggerCharacter
&& !(signatureHelpContext.isRetrigger
? plugin[0].capabilities.signatureHelpProvider?.retriggerCharacters
: plugin[0].capabilities.signatureHelpProvider?.triggerCharacters)?.includes(signatureHelpContext.triggerCharacter)) {
return;
}
return plugin[1].provideSignatureHelp?.(document, position, signatureHelpContext, token);
}, data => data);
};
}
//# sourceMappingURL=provideSignatureHelp.js.map

View File

@@ -0,0 +1,3 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (token?: vscode.CancellationToken) => Promise<vscode.WorkspaceDocumentDiagnosticReport[]>;

View File

@@ -0,0 +1,68 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const provideDiagnostics_1 = require("./provideDiagnostics");
function register(context) {
return async (token = cancellation_1.NoneCancellationToken) => {
const allItems = [];
for (const plugin of context.plugins) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
if (token.isCancellationRequested) {
break;
}
if (!plugin[1].provideWorkspaceDiagnostics) {
continue;
}
const report = await plugin[1].provideWorkspaceDiagnostics(token);
if (!report) {
continue;
}
const items = report
.map(item => {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(item.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (virtualCode && sourceScript) {
if (item.kind === 'unchanged') {
return {
...item,
uri: sourceScript.id.toString(),
};
}
else {
const map = context.language.maps.get(virtualCode, sourceScript);
const docs = [
context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot),
context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot),
map,
];
return {
...item,
items: item.items
.map(error => (0, provideDiagnostics_1.transformDiagnostic)(context, error, docs))
.filter(error => !!error)
};
}
}
else {
if (item.kind === 'unchanged') {
return item;
}
return {
...item,
items: item.items
.map(error => (0, provideDiagnostics_1.transformDiagnostic)(context, error, undefined))
.filter(error => !!error)
};
}
});
allItems.push(...items);
}
return allItems;
};
}
//# sourceMappingURL=provideWorkspaceDiagnostics.js.map

View File

@@ -0,0 +1,7 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceContext } from '../types';
export interface WorkspaceSymbolData {
original: Pick<vscode.WorkspaceSymbol, 'data'>;
pluginIndex: number;
}
export declare function register(context: LanguageServiceContext): (query: string, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceSymbol[]>;

View File

@@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return async (query, token = cancellation_1.NoneCancellationToken) => {
const symbolsList = [];
for (const plugin of context.plugins) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
if (token.isCancellationRequested) {
break;
}
if (!plugin[1].provideWorkspaceSymbols) {
continue;
}
const embeddedSymbols = await plugin[1].provideWorkspaceSymbols(query, token);
if (!embeddedSymbols) {
continue;
}
const symbols = embeddedSymbols
.map(symbol => (0, transform_1.transformWorkspaceSymbol)(symbol, loc => {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(loc.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (sourceScript && virtualCode) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
const range = (0, featureWorkers_1.getSourceRange)(docs, loc.range);
if (range) {
return { uri: sourceDocument.uri, range };
}
}
}
else {
return loc;
}
}))
.filter(symbol => !!symbol);
symbols?.forEach(symbol => {
if (plugin[1].resolveWorkspaceSymbol) {
symbol.data = {
original: {
data: symbol.data,
},
pluginIndex: context.plugins.indexOf(plugin),
};
}
else {
delete symbol.data;
}
});
symbolsList.push(symbols);
}
return symbolsList.flat();
};
}
//# sourceMappingURL=provideWorkspaceSymbols.js.map

View File

@@ -0,0 +1,3 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (item: vscode.CodeAction, token?: vscode.CancellationToken) => Promise<vscode.CodeAction>;

View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const cancellation_1 = require("../utils/cancellation");
const transform_1 = require("../utils/transform");
function register(context) {
return async (item, token = cancellation_1.NoneCancellationToken) => {
const data = item.data;
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].resolveCodeAction) {
delete item.data;
return item;
}
Object.assign(item, data.original);
item = await plugin[1].resolveCodeAction(item, token);
item = plugin[1].transformCodeAction?.(item)
?? (item.edit
? {
...item,
edit: (0, transform_1.transformWorkspaceEdit)(item.edit, context, 'codeAction', { [data.uri]: data.version }),
}
: item);
}
delete item.data;
return item;
};
}
//# sourceMappingURL=resolveCodeAction.js.map

View File

@@ -0,0 +1,3 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (item: vscode.CodeLens, token?: vscode.CancellationToken) => Promise<vscode.CodeLens>;

View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const references = require("./provideReferences");
function register(context) {
const findReferences = references.register(context);
return async (item, token = cancellation_1.NoneCancellationToken) => {
const data = item.data;
if (data?.kind === 'normal') {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].resolveCodeLens) {
delete item.data;
return item;
}
Object.assign(item, data.original);
item = await plugin[1].resolveCodeLens(item, token);
// item.range already transformed in codeLens request
}
else if (data?.kind === 'references') {
const references = await findReferences(vscode_uri_1.URI.parse(data.sourceFileUri), item.range.start, { includeDeclaration: false }, token) ?? [];
item.command = context.commands.showReferences.create(data.sourceFileUri, item.range.start, references);
}
delete item.data;
return item;
};
}
//# sourceMappingURL=resolveCodeLens.js.map

View File

@@ -0,0 +1,3 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (item: vscode.CompletionItem, token?: vscode.CancellationToken) => Promise<vscode.CompletionItem>;

View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const vscode_uri_1 = require("vscode-uri");
const cancellation_1 = require("../utils/cancellation");
const featureWorkers_1 = require("../utils/featureWorkers");
const transform_1 = require("../utils/transform");
function register(context) {
return async (item, token = cancellation_1.NoneCancellationToken) => {
const data = item.data;
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].resolveCompletionItem) {
delete item.data;
return item;
}
item = Object.assign(item, data.original);
if (data.embeddedDocumentUri) {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(data.embeddedDocumentUri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (sourceScript && virtualCode) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
item = await plugin[1].resolveCompletionItem(item, token);
item = plugin[1].transformCompletionItem?.(item) ?? (0, transform_1.transformCompletionItem)(item, embeddedRange => (0, featureWorkers_1.getSourceRange)(docs, embeddedRange), embeddedDocument, context);
}
}
}
else {
item = await plugin[1].resolveCompletionItem(item, token);
}
}
// TODO: monkey fix import ts file icon
if (item.detail !== item.detail + '.ts') {
item.detail = item.detail;
}
delete item.data;
return item;
};
}
//# sourceMappingURL=resolveCompletionItem.js.map

View File

@@ -0,0 +1,3 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (item: vscode.DocumentLink, token?: vscode.CancellationToken) => Promise<vscode.DocumentLink>;

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const cancellation_1 = require("../utils/cancellation");
const transform_1 = require("../utils/transform");
function register(context) {
return async (item, token = cancellation_1.NoneCancellationToken) => {
const data = item.data;
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].resolveDocumentLink) {
delete item.data;
return item;
}
Object.assign(item, data.original);
item = await plugin[1].resolveDocumentLink(item, token);
if (item.target) {
item.target = (0, transform_1.transformDocumentLinkTarget)(item.target, context).toString();
}
}
delete item.data;
return item;
};
}
//# sourceMappingURL=resolveDocumentLink.js.map

View File

@@ -0,0 +1,3 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (item: vscode.InlayHint, token?: vscode.CancellationToken) => Promise<vscode.InlayHint>;

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const cancellation_1 = require("../utils/cancellation");
function register(context) {
return async (item, token = cancellation_1.NoneCancellationToken) => {
const data = item.data;
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].resolveInlayHint) {
delete item.data;
return item;
}
Object.assign(item, data.original);
item = await plugin[1].resolveInlayHint(item, token);
}
delete item.data;
return item;
};
}
//# sourceMappingURL=resolveInlayHint.js.map

View File

@@ -0,0 +1,3 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceContext } from '../types';
export declare function register(context: LanguageServiceContext): (item: vscode.WorkspaceSymbol, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceSymbol>;

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = register;
const cancellation_1 = require("../utils/cancellation");
function register(context) {
return async (item, token = cancellation_1.NoneCancellationToken) => {
const data = item.data;
if (data) {
const plugin = context.plugins[data.pluginIndex];
if (!plugin[1].resolveWorkspaceSymbol) {
delete item.data;
return item;
}
Object.assign(item, data.original);
item = await plugin[1].resolveWorkspaceSymbol(item, token);
}
delete item.data;
return item;
};
}
//# sourceMappingURL=resolveWorkspaceSymbol.js.map

View File

@@ -0,0 +1,152 @@
import { type Language } from '@volar/language-core';
import type * as vscode from 'vscode-languageserver-protocol';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext, LanguageServiceEnvironment, LanguageServicePlugin, ProjectContext } from './types';
export type LanguageService = ReturnType<typeof createLanguageServiceBase>;
export declare const embeddedContentScheme = "volar-embedded-content";
export declare function createLanguageService(language: Language<URI>, plugins: LanguageServicePlugin[], env: LanguageServiceEnvironment, project: ProjectContext): {
dispose: () => void;
context: LanguageServiceContext;
getCallHierarchyItems(uri: URI, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.CallHierarchyItem[] | undefined>;
getTypeHierarchyItems(uri: URI, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
getCallHierarchyIncomingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyIncomingCall[]>;
getCallHierarchyOutgoingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyOutgoingCall[]>;
getTypeHierarchySupertypes(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
getTypeHierarchySubtypes(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
semanticTokenLegend: {
tokenModifiers: string[];
tokenTypes: string[];
};
commands: string[];
triggerCharacters: string[];
autoFormatTriggerCharacters: string[];
signatureHelpTriggerCharacters: string[];
signatureHelpRetriggerCharacters: string[];
executeCommand(command: string, args: any[], token?: vscode.CancellationToken): any;
getDocumentFormattingEdits: (uri: URI, options: vscode.FormattingOptions, range: vscode.Range | undefined, onTypeParams: {
ch: string;
position: vscode.Position;
} | undefined, token?: vscode.CancellationToken) => Promise<vscode.TextEdit[] | undefined>;
getFoldingRanges: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.FoldingRange[] | undefined>;
getSelectionRanges: (uri: URI, positions: vscode.Position[], token?: vscode.CancellationToken) => Promise<vscode.SelectionRange[] | undefined>;
getLinkedEditingRanges: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LinkedEditingRanges | undefined>;
getDocumentSymbols: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.DocumentSymbol[] | undefined>;
getDocumentColors: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.ColorInformation[] | undefined>;
getColorPresentations: (uri: URI, color: vscode.Color, range: vscode.Range, token?: vscode.CancellationToken) => Promise<vscode.ColorPresentation[] | undefined>;
getDiagnostics: (uri: URI, response?: (result: vscode.Diagnostic[]) => void, token?: vscode.CancellationToken) => Promise<vscode.Diagnostic[]>;
getWorkspaceDiagnostics: (token?: vscode.CancellationToken) => Promise<vscode.WorkspaceDocumentDiagnosticReport[]>;
getReferences: (uri: URI, position: vscode.Position, referenceContext: vscode.ReferenceContext, token?: vscode.CancellationToken) => Promise<vscode.Location[] | undefined>;
getFileReferences: (uri: URI, token?: vscode.CancellationToken) => import("./types").NullableProviderResult<vscode.Location[]>;
getDeclaration: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;
getDefinition: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;
getTypeDefinition: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;
getImplementations: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;
getRenameRange: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Range | {
range: vscode.Range;
placeholder: string;
} | {
message: string;
} | undefined>;
getRenameEdits: (uri: URI, position: vscode.Position, newName: string, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceEdit | undefined>;
getFileRenameEdits: (oldUri: URI, newUri: URI, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceEdit | undefined>;
getSemanticTokens: (uri: URI, range: vscode.Range | undefined, legend: vscode.SemanticTokensLegend, _reportProgress?: (tokens: vscode.SemanticTokens) => void, token?: vscode.CancellationToken) => Promise<vscode.SemanticTokens | undefined>;
getHover: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Hover | undefined>;
getCompletionItems: (uri: URI, position: vscode.Position, completionContext?: vscode.CompletionContext, token?: vscode.CancellationToken) => Promise<vscode.CompletionList>;
getCodeActions: (uri: URI, range: vscode.Range, codeActionContext: vscode.CodeActionContext, token?: vscode.CancellationToken) => Promise<vscode.CodeAction[] | undefined>;
getSignatureHelp: (uri: URI, position: vscode.Position, signatureHelpContext?: vscode.SignatureHelpContext, token?: vscode.CancellationToken) => Promise<vscode.SignatureHelp | undefined>;
getCodeLenses: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.CodeLens[]>;
getDocumentHighlights: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.DocumentHighlight[] | undefined>;
getDocumentLinks: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.DocumentLink[]>;
getWorkspaceSymbols: (query: string, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceSymbol[]>;
getAutoInsertSnippet: (uri: URI, selection: vscode.Position, change: {
rangeOffset: number;
rangeLength: number;
text: string;
}, token?: vscode.CancellationToken) => Promise<string | undefined>;
getDocumentDropEdits: (uri: URI, position: vscode.Position, dataTransfer: Map<string, import("./types").DataTransferItem>, token?: vscode.CancellationToken) => Promise<import("./types").DocumentDropEdit | undefined>;
getInlayHints: (uri: URI, range: vscode.Range, token?: vscode.CancellationToken) => Promise<vscode.InlayHint[] | undefined>;
getMoniker: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Moniker[] | undefined>;
getInlineValue: (uri: URI, range: vscode.Range, ivContext: vscode.InlineValueContext, token?: vscode.CancellationToken) => Promise<vscode.InlineValue[] | undefined>;
resolveCodeAction: (item: vscode.CodeAction, token?: vscode.CancellationToken) => Promise<vscode.CodeAction>;
resolveCompletionItem: (item: vscode.CompletionItem, token?: vscode.CancellationToken) => Promise<vscode.CompletionItem>;
resolveCodeLens: (item: vscode.CodeLens, token?: vscode.CancellationToken) => Promise<vscode.CodeLens>;
resolveDocumentLink: (item: vscode.DocumentLink, token?: vscode.CancellationToken) => Promise<vscode.DocumentLink>;
resolveInlayHint: (item: vscode.InlayHint, token?: vscode.CancellationToken) => Promise<vscode.InlayHint>;
resolveWorkspaceSymbol: (item: vscode.WorkspaceSymbol, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceSymbol>;
};
export declare function decodeEmbeddedDocumentUri(maybeEmbeddedContentUri: URI): [
documentUri: URI,
embeddedCodeId: string
] | undefined;
export declare function encodeEmbeddedDocumentUri(documentUri: URI, embeddedContentId: string): URI;
declare function createLanguageServiceBase(plugins: LanguageServicePlugin[], context: LanguageServiceContext): {
dispose: () => void;
context: LanguageServiceContext;
getCallHierarchyItems(uri: URI, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.CallHierarchyItem[] | undefined>;
getTypeHierarchyItems(uri: URI, position: vscode.Position, token?: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
getCallHierarchyIncomingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyIncomingCall[]>;
getCallHierarchyOutgoingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyOutgoingCall[]>;
getTypeHierarchySupertypes(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
getTypeHierarchySubtypes(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.TypeHierarchyItem[] | undefined>;
semanticTokenLegend: {
tokenModifiers: string[];
tokenTypes: string[];
};
commands: string[];
triggerCharacters: string[];
autoFormatTriggerCharacters: string[];
signatureHelpTriggerCharacters: string[];
signatureHelpRetriggerCharacters: string[];
executeCommand(command: string, args: any[], token?: vscode.CancellationToken): any;
getDocumentFormattingEdits: (uri: URI, options: vscode.FormattingOptions, range: vscode.Range | undefined, onTypeParams: {
ch: string;
position: vscode.Position;
} | undefined, token?: vscode.CancellationToken) => Promise<vscode.TextEdit[] | undefined>;
getFoldingRanges: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.FoldingRange[] | undefined>;
getSelectionRanges: (uri: URI, positions: vscode.Position[], token?: vscode.CancellationToken) => Promise<vscode.SelectionRange[] | undefined>;
getLinkedEditingRanges: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LinkedEditingRanges | undefined>;
getDocumentSymbols: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.DocumentSymbol[] | undefined>;
getDocumentColors: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.ColorInformation[] | undefined>;
getColorPresentations: (uri: URI, color: vscode.Color, range: vscode.Range, token?: vscode.CancellationToken) => Promise<vscode.ColorPresentation[] | undefined>;
getDiagnostics: (uri: URI, response?: (result: vscode.Diagnostic[]) => void, token?: vscode.CancellationToken) => Promise<vscode.Diagnostic[]>;
getWorkspaceDiagnostics: (token?: vscode.CancellationToken) => Promise<vscode.WorkspaceDocumentDiagnosticReport[]>;
getReferences: (uri: URI, position: vscode.Position, referenceContext: vscode.ReferenceContext, token?: vscode.CancellationToken) => Promise<vscode.Location[] | undefined>;
getFileReferences: (uri: URI, token?: vscode.CancellationToken) => import("./types").NullableProviderResult<vscode.Location[]>;
getDeclaration: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;
getDefinition: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;
getTypeDefinition: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;
getImplementations: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.LocationLink[] | undefined>;
getRenameRange: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Range | {
range: vscode.Range;
placeholder: string;
} | {
message: string;
} | undefined>;
getRenameEdits: (uri: URI, position: vscode.Position, newName: string, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceEdit | undefined>;
getFileRenameEdits: (oldUri: URI, newUri: URI, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceEdit | undefined>;
getSemanticTokens: (uri: URI, range: vscode.Range | undefined, legend: vscode.SemanticTokensLegend, _reportProgress?: (tokens: vscode.SemanticTokens) => void, token?: vscode.CancellationToken) => Promise<vscode.SemanticTokens | undefined>;
getHover: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Hover | undefined>;
getCompletionItems: (uri: URI, position: vscode.Position, completionContext?: vscode.CompletionContext, token?: vscode.CancellationToken) => Promise<vscode.CompletionList>;
getCodeActions: (uri: URI, range: vscode.Range, codeActionContext: vscode.CodeActionContext, token?: vscode.CancellationToken) => Promise<vscode.CodeAction[] | undefined>;
getSignatureHelp: (uri: URI, position: vscode.Position, signatureHelpContext?: vscode.SignatureHelpContext, token?: vscode.CancellationToken) => Promise<vscode.SignatureHelp | undefined>;
getCodeLenses: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.CodeLens[]>;
getDocumentHighlights: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.DocumentHighlight[] | undefined>;
getDocumentLinks: (uri: URI, token?: vscode.CancellationToken) => Promise<vscode.DocumentLink[]>;
getWorkspaceSymbols: (query: string, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceSymbol[]>;
getAutoInsertSnippet: (uri: URI, selection: vscode.Position, change: {
rangeOffset: number;
rangeLength: number;
text: string;
}, token?: vscode.CancellationToken) => Promise<string | undefined>;
getDocumentDropEdits: (uri: URI, position: vscode.Position, dataTransfer: Map<string, import("./types").DataTransferItem>, token?: vscode.CancellationToken) => Promise<import("./types").DocumentDropEdit | undefined>;
getInlayHints: (uri: URI, range: vscode.Range, token?: vscode.CancellationToken) => Promise<vscode.InlayHint[] | undefined>;
getMoniker: (uri: URI, position: vscode.Position, token?: vscode.CancellationToken) => Promise<vscode.Moniker[] | undefined>;
getInlineValue: (uri: URI, range: vscode.Range, ivContext: vscode.InlineValueContext, token?: vscode.CancellationToken) => Promise<vscode.InlineValue[] | undefined>;
resolveCodeAction: (item: vscode.CodeAction, token?: vscode.CancellationToken) => Promise<vscode.CodeAction>;
resolveCompletionItem: (item: vscode.CompletionItem, token?: vscode.CancellationToken) => Promise<vscode.CompletionItem>;
resolveCodeLens: (item: vscode.CodeLens, token?: vscode.CancellationToken) => Promise<vscode.CodeLens>;
resolveDocumentLink: (item: vscode.DocumentLink, token?: vscode.CancellationToken) => Promise<vscode.DocumentLink>;
resolveInlayHint: (item: vscode.InlayHint, token?: vscode.CancellationToken) => Promise<vscode.InlayHint>;
resolveWorkspaceSymbol: (item: vscode.WorkspaceSymbol, token?: vscode.CancellationToken) => Promise<vscode.WorkspaceSymbol>;
};
export {};

View File

@@ -0,0 +1,233 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.embeddedContentScheme = void 0;
exports.createLanguageService = createLanguageService;
exports.decodeEmbeddedDocumentUri = decodeEmbeddedDocumentUri;
exports.encodeEmbeddedDocumentUri = encodeEmbeddedDocumentUri;
const language_core_1 = require("@volar/language-core");
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
const vscode_uri_1 = require("vscode-uri");
const autoInsert = require("./features/provideAutoInsertSnippet");
const hierarchy = require("./features/provideCallHierarchyItems");
const codeActions = require("./features/provideCodeActions");
const codeLens = require("./features/provideCodeLenses");
const colorPresentations = require("./features/provideColorPresentations");
const completions = require("./features/provideCompletionItems");
const definition = require("./features/provideDefinition");
const diagnostics = require("./features/provideDiagnostics");
const documentColors = require("./features/provideDocumentColors");
const documentDrop = require("./features/provideDocumentDropEdits");
const format = require("./features/provideDocumentFormattingEdits");
const documentHighlight = require("./features/provideDocumentHighlights");
const documentLink = require("./features/provideDocumentLinks");
const semanticTokens = require("./features/provideDocumentSemanticTokens");
const documentSymbols = require("./features/provideDocumentSymbols");
const fileReferences = require("./features/provideFileReferences");
const fileRename = require("./features/provideFileRenameEdits");
const foldingRanges = require("./features/provideFoldingRanges");
const hover = require("./features/provideHover");
const inlayHints = require("./features/provideInlayHints");
const moniker = require("./features/provideMoniker");
const inlineValue = require("./features/provideInlineValue");
const linkedEditing = require("./features/provideLinkedEditingRanges");
const references = require("./features/provideReferences");
const rename = require("./features/provideRenameEdits");
const renamePrepare = require("./features/provideRenameRange");
const selectionRanges = require("./features/provideSelectionRanges");
const signatureHelp = require("./features/provideSignatureHelp");
const workspaceDiagnostics = require("./features/provideWorkspaceDiagnostics");
const workspaceSymbol = require("./features/provideWorkspaceSymbols");
const codeActionResolve = require("./features/resolveCodeAction");
const codeLensResolve = require("./features/resolveCodeLens");
const completionResolve = require("./features/resolveCompletionItem");
const documentLinkResolve = require("./features/resolveDocumentLink");
const inlayHintResolve = require("./features/resolveInlayHint");
const workspaceSymbolResolve = require("./features/resolveWorkspaceSymbol");
const cancellation_1 = require("./utils/cancellation");
const uriMap_1 = require("./utils/uriMap");
exports.embeddedContentScheme = 'volar-embedded-content';
function createLanguageService(language, plugins, env, project) {
const documentVersions = (0, uriMap_1.createUriMap)();
const snapshot2Doc = new WeakMap();
const context = {
language,
project,
getLanguageService: () => langaugeService,
documents: {
get(uri, languageId, snapshot) {
if (!snapshot2Doc.has(snapshot)) {
snapshot2Doc.set(snapshot, (0, uriMap_1.createUriMap)());
}
const map = snapshot2Doc.get(snapshot);
if (!map.has(uri)) {
const version = documentVersions.get(uri) ?? 0;
documentVersions.set(uri, version + 1);
map.set(uri, vscode_languageserver_textdocument_1.TextDocument.create(uri.toString(), languageId, version, snapshot.getText(0, snapshot.getLength())));
}
return map.get(uri);
},
},
env,
inject: (key, ...args) => {
for (const plugin of context.plugins) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
const provide = plugin[1].provide?.[key];
if (provide) {
return provide(...args);
}
}
},
plugins: [],
commands: {
rename: {
create(uri, position) {
return {
title: '',
command: 'editor.action.rename',
arguments: [
uri,
position,
],
};
},
is(command) {
return command.command === 'editor.action.rename';
},
},
showReferences: {
create(uri, position, locations) {
return {
title: locations.length === 1 ? '1 reference' : `${locations.length} references`,
command: 'editor.action.showReferences',
arguments: [
uri,
position,
locations,
],
};
},
is(command) {
return command.command === 'editor.action.showReferences';
},
},
setSelection: {
create(position) {
return {
title: '',
command: 'setSelection',
arguments: [{
selection: {
selectionStartLineNumber: position.line + 1,
positionLineNumber: position.line + 1,
selectionStartColumn: position.character + 1,
positionColumn: position.character + 1,
},
}],
};
},
is(command) {
return command.command === 'setSelection';
},
},
},
disabledEmbeddedDocumentUris: (0, uriMap_1.createUriMap)(),
disabledServicePlugins: new WeakSet(),
decodeEmbeddedDocumentUri,
encodeEmbeddedDocumentUri,
};
for (const plugin of plugins) {
context.plugins.push([plugin, plugin.create(context)]);
}
const langaugeService = createLanguageServiceBase(plugins, context);
return langaugeService;
}
function decodeEmbeddedDocumentUri(maybeEmbeddedContentUri) {
if (maybeEmbeddedContentUri.scheme === exports.embeddedContentScheme) {
const embeddedCodeId = decodeURIComponent(maybeEmbeddedContentUri.authority);
const documentUri = decodeURIComponent(maybeEmbeddedContentUri.path.substring(1));
return [
vscode_uri_1.URI.parse(documentUri),
embeddedCodeId,
];
}
}
function encodeEmbeddedDocumentUri(documentUri, embeddedContentId) {
if (embeddedContentId !== embeddedContentId.toLowerCase()) {
console.error(`embeddedContentId must be lowercase: ${embeddedContentId}`);
}
return vscode_uri_1.URI.from({
scheme: exports.embeddedContentScheme,
authority: encodeURIComponent(embeddedContentId),
path: '/' + encodeURIComponent(documentUri.toString()),
});
}
function createLanguageServiceBase(plugins, context) {
const tokenModifiers = plugins.map(plugin => plugin.capabilities.semanticTokensProvider?.legend?.tokenModifiers ?? []).flat();
const tokenTypes = plugins.map(plugin => plugin.capabilities.semanticTokensProvider?.legend?.tokenTypes ?? []).flat();
return {
semanticTokenLegend: {
tokenModifiers: [...new Set(tokenModifiers)],
tokenTypes: [...new Set(tokenTypes)],
},
commands: plugins.map(plugin => plugin.capabilities.executeCommandProvider?.commands ?? []).flat(),
triggerCharacters: plugins.map(plugin => plugin.capabilities.completionProvider?.triggerCharacters ?? []).flat(),
autoFormatTriggerCharacters: plugins.map(plugin => plugin.capabilities.documentOnTypeFormattingProvider?.triggerCharacters ?? []).flat(),
signatureHelpTriggerCharacters: plugins.map(plugin => plugin.capabilities.signatureHelpProvider?.triggerCharacters ?? []).flat(),
signatureHelpRetriggerCharacters: plugins.map(plugin => plugin.capabilities.signatureHelpProvider?.retriggerCharacters ?? []).flat(),
executeCommand(command, args, token = cancellation_1.NoneCancellationToken) {
for (const plugin of context.plugins) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
if (!plugin[1].executeCommand || !plugin[0].capabilities.executeCommandProvider?.commands.includes(command)) {
continue;
}
return plugin[1].executeCommand(command, args, token);
}
},
getDocumentFormattingEdits: format.register(context),
getFoldingRanges: foldingRanges.register(context),
getSelectionRanges: selectionRanges.register(context),
getLinkedEditingRanges: linkedEditing.register(context),
getDocumentSymbols: documentSymbols.register(context),
getDocumentColors: documentColors.register(context),
getColorPresentations: colorPresentations.register(context),
getDiagnostics: diagnostics.register(context),
getWorkspaceDiagnostics: workspaceDiagnostics.register(context),
getReferences: references.register(context),
getFileReferences: fileReferences.register(context),
getDeclaration: definition.register(context, 'provideDeclaration', language_core_1.isDefinitionEnabled),
getDefinition: definition.register(context, 'provideDefinition', language_core_1.isDefinitionEnabled),
getTypeDefinition: definition.register(context, 'provideTypeDefinition', language_core_1.isTypeDefinitionEnabled),
getImplementations: definition.register(context, 'provideImplementation', language_core_1.isImplementationEnabled),
getRenameRange: renamePrepare.register(context),
getRenameEdits: rename.register(context),
getFileRenameEdits: fileRename.register(context),
getSemanticTokens: semanticTokens.register(context),
getHover: hover.register(context),
getCompletionItems: completions.register(context),
getCodeActions: codeActions.register(context),
getSignatureHelp: signatureHelp.register(context),
getCodeLenses: codeLens.register(context),
getDocumentHighlights: documentHighlight.register(context),
getDocumentLinks: documentLink.register(context),
getWorkspaceSymbols: workspaceSymbol.register(context),
getAutoInsertSnippet: autoInsert.register(context),
getDocumentDropEdits: documentDrop.register(context),
getInlayHints: inlayHints.register(context),
getMoniker: moniker.register(context),
getInlineValue: inlineValue.register(context),
resolveCodeAction: codeActionResolve.register(context),
resolveCompletionItem: completionResolve.register(context),
resolveCodeLens: codeLensResolve.register(context),
resolveDocumentLink: documentLinkResolve.register(context),
resolveInlayHint: inlayHintResolve.register(context),
resolveWorkspaceSymbol: workspaceSymbolResolve.register(context),
...hierarchy.register(context),
dispose: () => context.plugins.forEach(plugin => plugin[1].dispose?.()),
context,
};
}
//# sourceMappingURL=languageService.js.map

229
node_modules/@volar/language-service/lib/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,229 @@
import type { Language, SourceScript, VirtualCode } from '@volar/language-core';
import type * as vscode from 'vscode-languageserver-protocol';
import type { TextDocument } from 'vscode-languageserver-textdocument';
import type * as ts from 'typescript';
import type { LanguageService } from './languageService';
import type { URI } from 'vscode-uri';
import type { UriMap } from './utils/uriMap';
export type * from 'vscode-languageserver-protocol';
export interface LanguageServiceEnvironment {
workspaceFolders: URI[];
locale?: string;
clientCapabilities?: vscode.ClientCapabilities;
fs?: FileSystem;
console?: Console;
getConfiguration?<T>(section: string, scopeUri?: string): Promise<T | undefined>;
onDidChangeConfiguration?(cb: (params: vscode.DidChangeConfigurationParams) => void): vscode.Disposable;
onDidChangeWatchedFiles?(cb: (params: vscode.DidChangeWatchedFilesParams) => void): vscode.Disposable;
}
export interface FileSystem {
stat(uri: URI): ProviderResult<FileStat | undefined>;
readDirectory(uri: URI): ProviderResult<[string, FileType][]>;
readFile(uri: URI, encoding?: string): ProviderResult<string | undefined>;
}
export interface FileStat {
type: FileType;
ctime: number;
mtime: number;
size: number;
}
export declare enum FileType {
Unknown = 0,
File = 1,
Directory = 2,
SymbolicLink = 64
}
export interface LanguageServiceCommand<T extends any[]> {
create(...args: T): vscode.Command | undefined;
is(value: vscode.Command): boolean;
}
export interface ProjectContext {
}
export interface LanguageServiceContext {
language: Language<URI>;
project: ProjectContext;
getLanguageService(): LanguageService;
env: LanguageServiceEnvironment;
inject<Provide = any, K extends keyof Provide = keyof Provide>(key: K, ...args: Provide[K] extends (...args: any) => any ? Parameters<Provide[K]> : never): ReturnType<Provide[K] extends (...args: any) => any ? Provide[K] : never> | undefined;
commands: {
showReferences: LanguageServiceCommand<[uri: string, position: vscode.Position, locations: vscode.Location[]]>;
rename: LanguageServiceCommand<[uri: string, position: vscode.Position]>;
setSelection: LanguageServiceCommand<[position: vscode.Position]>;
};
documents: {
get(uri: URI, languageId: string, snapshot: ts.IScriptSnapshot): TextDocument;
};
plugins: [LanguageServicePlugin, LanguageServicePluginInstance][];
disabledEmbeddedDocumentUris: UriMap<boolean>;
disabledServicePlugins: WeakSet<LanguageServicePluginInstance>;
decodeEmbeddedDocumentUri(maybeEmbeddedUri: URI): [
documentUri: URI,
embeddedCodeId: string
] | undefined;
encodeEmbeddedDocumentUri(uri: URI, embeededCodeId: string): URI;
}
export type ProviderResult<T> = T | Thenable<T>;
export type NullableProviderResult<T> = ProviderResult<T | undefined | null>;
export type SemanticToken = [
line: number,
character: number,
length: number,
tokenTypes: number,
tokenModifiers: number
];
export interface LanguageServicePlugin<P = any> {
name?: string;
capabilities: {
executeCommandProvider?: {
commands: string[];
};
selectionRangeProvider?: boolean;
foldingRangeProvider?: boolean;
linkedEditingRangeProvider?: boolean;
colorProvider?: boolean;
documentSymbolProvider?: boolean;
documentFormattingProvider?: boolean;
referencesProvider?: boolean;
implementationProvider?: boolean;
declarationProvider?: boolean;
definitionProvider?: boolean;
typeDefinitionProvider?: boolean;
callHierarchyProvider?: boolean;
typeHierarchyProvider?: boolean;
hoverProvider?: boolean;
documentHighlightProvider?: boolean;
monikerProvider?: boolean;
inlineValueProvider?: boolean;
workspaceSymbolProvider?: {
resolveProvider?: boolean;
};
renameProvider?: {
prepareProvider?: boolean;
};
signatureHelpProvider?: {
triggerCharacters?: string[];
retriggerCharacters?: string[];
};
completionProvider?: {
resolveProvider?: boolean;
triggerCharacters?: string[];
};
autoInsertionProvider?: {
triggerCharacters: string[];
configurationSections?: string[];
};
documentOnTypeFormattingProvider?: {
triggerCharacters: string[];
};
documentLinkProvider?: {
resolveProvider?: boolean;
};
codeLensProvider?: {
resolveProvider?: boolean;
};
inlayHintProvider?: {
resolveProvider?: boolean;
};
semanticTokensProvider?: {
legend: vscode.SemanticTokensLegend;
};
codeActionProvider?: {
codeActionKinds?: string[];
resolveProvider?: boolean;
};
diagnosticProvider?: {
interFileDependencies: boolean;
workspaceDiagnostics: boolean;
};
fileReferencesProvider?: boolean;
fileRenameEditsProvider?: boolean;
documentDropEditsProvider?: boolean;
};
create(context: LanguageServiceContext): LanguageServicePluginInstance<P>;
}
export interface EmbeddedCodeFormattingOptions {
level: number;
initialIndentLevel: number;
}
export interface LanguageServicePluginInstance<P = any> {
provide?: P;
isAdditionalCompletion?: boolean;
executeCommand?(command: string, args: any[], token: vscode.CancellationToken): ProviderResult<any>;
provideHover?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.Hover>;
provideDocumentSymbols?(document: TextDocument, token: vscode.CancellationToken): NullableProviderResult<vscode.DocumentSymbol[]>;
provideDocumentHighlights?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.DocumentHighlight[]>;
provideLinkedEditingRanges?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.LinkedEditingRanges>;
provideDeclaration?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.DeclarationLink[]>;
provideDefinition?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.LocationLink[]>;
provideTypeDefinition?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.LocationLink[]>;
provideImplementation?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.LocationLink[]>;
provideCodeLenses?(document: TextDocument, token: vscode.CancellationToken): NullableProviderResult<vscode.CodeLens[]>;
provideCodeActions?(document: TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken): NullableProviderResult<vscode.CodeAction[]>;
provideDocumentFormattingEdits?(document: TextDocument, range: vscode.Range, options: vscode.FormattingOptions, embeddedCodeContext: EmbeddedCodeFormattingOptions | undefined, token: vscode.CancellationToken): NullableProviderResult<vscode.TextEdit[]>;
provideOnTypeFormattingEdits?(document: TextDocument, position: vscode.Position, key: string, options: vscode.FormattingOptions, embeddedCodeContext: EmbeddedCodeFormattingOptions | undefined, token: vscode.CancellationToken): NullableProviderResult<vscode.TextEdit[]>;
provideDocumentLinks?(document: TextDocument, token: vscode.CancellationToken): NullableProviderResult<vscode.DocumentLink[]>;
provideCompletionItems?(document: TextDocument, position: vscode.Position, context: vscode.CompletionContext, token: vscode.CancellationToken): NullableProviderResult<vscode.CompletionList>;
provideDocumentColors?(document: TextDocument, token: vscode.CancellationToken): NullableProviderResult<vscode.ColorInformation[]>;
provideColorPresentations?(document: TextDocument, color: vscode.Color, range: vscode.Range, token: vscode.CancellationToken): NullableProviderResult<vscode.ColorPresentation[]>;
provideFoldingRanges?(document: TextDocument, token: vscode.CancellationToken): NullableProviderResult<vscode.FoldingRange[]>;
provideSignatureHelp?(document: TextDocument, position: vscode.Position, context: vscode.SignatureHelpContext, token: vscode.CancellationToken): NullableProviderResult<vscode.SignatureHelp>;
provideRenameRange?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.Range | {
range: vscode.Range;
placeholder: string;
} | {
message: string;
}>;
provideRenameEdits?(document: TextDocument, position: vscode.Position, newName: string, token: vscode.CancellationToken): NullableProviderResult<vscode.WorkspaceEdit>;
provideReferences?(document: TextDocument, position: vscode.Position, context: vscode.ReferenceContext, token: vscode.CancellationToken): NullableProviderResult<vscode.Location[]>;
provideSelectionRanges?(document: TextDocument, positions: vscode.Position[], token: vscode.CancellationToken): NullableProviderResult<vscode.SelectionRange[]>;
provideInlayHints?(document: TextDocument, range: vscode.Range, token: vscode.CancellationToken): NullableProviderResult<vscode.InlayHint[]>;
provideInlineValues?(document: TextDocument, range: vscode.Range, context: vscode.InlineValueContext, token: vscode.CancellationToken): NullableProviderResult<vscode.InlineValue[]>;
provideCallHierarchyItems?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.CallHierarchyItem[]>;
provideCallHierarchyIncomingCalls?(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): ProviderResult<vscode.CallHierarchyIncomingCall[]>;
provideCallHierarchyOutgoingCalls?(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): ProviderResult<vscode.CallHierarchyOutgoingCall[]>;
provideTypeHierarchyItems?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.TypeHierarchyItem[]>;
provideTypeHierarchySupertypes?(item: vscode.TypeHierarchyItem, token: vscode.CancellationToken): ProviderResult<vscode.TypeHierarchyItem[]>;
provideTypeHierarchySubtypes?(item: vscode.TypeHierarchyItem, token: vscode.CancellationToken): ProviderResult<vscode.TypeHierarchyItem[]>;
provideDocumentSemanticTokens?(document: TextDocument, range: vscode.Range, legend: vscode.SemanticTokensLegend, token: vscode.CancellationToken): NullableProviderResult<SemanticToken[]>;
provideWorkspaceSymbols?(query: string, token: vscode.CancellationToken): NullableProviderResult<vscode.WorkspaceSymbol[]>;
provideDiagnostics?(document: TextDocument, token: vscode.CancellationToken): NullableProviderResult<vscode.Diagnostic[]>;
provideWorkspaceDiagnostics?(token: vscode.CancellationToken): NullableProviderResult<vscode.WorkspaceDocumentDiagnosticReport[]>;
provideMoniker?(document: TextDocument, position: vscode.Position, token: vscode.CancellationToken): NullableProviderResult<vscode.Moniker[]>;
provideFileReferences?(document: TextDocument, token: vscode.CancellationToken): NullableProviderResult<vscode.Location[]>;
provideReferencesCodeLensRanges?(document: TextDocument, token: vscode.CancellationToken): NullableProviderResult<vscode.Range[]>;
provideAutoInsertSnippet?(document: TextDocument, position: vscode.Position, lastChange: {
rangeOffset: number;
rangeLength: number;
text: string;
}, token: vscode.CancellationToken): NullableProviderResult<string>;
provideFileRenameEdits?(oldUri: URI, newUri: URI, token: vscode.CancellationToken): NullableProviderResult<vscode.WorkspaceEdit>;
provideDocumentDropEdits?(document: TextDocument, position: vscode.Position, dataTransfer: Map<string, DataTransferItem>, token: vscode.CancellationToken): NullableProviderResult<DocumentDropEdit>;
resolveCodeLens?(codeLens: vscode.CodeLens, token: vscode.CancellationToken): ProviderResult<vscode.CodeLens>;
resolveCodeAction?(codeAction: vscode.CodeAction, token: vscode.CancellationToken): ProviderResult<vscode.CodeAction>;
resolveCompletionItem?(item: vscode.CompletionItem, token: vscode.CancellationToken): ProviderResult<vscode.CompletionItem>;
resolveDocumentLink?(link: vscode.DocumentLink, token: vscode.CancellationToken): ProviderResult<vscode.DocumentLink>;
resolveInlayHint?(inlayHint: vscode.InlayHint, token: vscode.CancellationToken): ProviderResult<vscode.InlayHint>;
resolveWorkspaceSymbol?(symbol: vscode.WorkspaceSymbol, token: vscode.CancellationToken): ProviderResult<vscode.WorkspaceSymbol>;
resolveEmbeddedCodeFormattingOptions?(sourceScript: SourceScript<URI>, embeddedCode: VirtualCode, options: EmbeddedCodeFormattingOptions, token: vscode.CancellationToken): NullableProviderResult<EmbeddedCodeFormattingOptions>;
transformCompletionItem?(item: vscode.CompletionItem): vscode.CompletionItem | undefined;
transformCodeAction?(item: vscode.CodeAction): vscode.CodeAction | undefined;
dispose?(): void;
}
export interface DocumentDropEdit {
insertText: string;
insertTextFormat: vscode.InsertTextFormat;
additionalEdit?: vscode.WorkspaceEdit;
createDataTransferFile?: (vscode.CreateFile & {
contentsMimeType: string;
})[];
}
export interface DataTransferItem {
value: any;
asString(): Thenable<string>;
asFile(): DataTransferFile | undefined;
}
export interface DataTransferFile {
name: string;
uri?: string;
data(): Thenable<Uint8Array>;
}

11
node_modules/@volar/language-service/lib/types.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileType = void 0;
var FileType;
(function (FileType) {
FileType[FileType["Unknown"] = 0] = "Unknown";
FileType[FileType["File"] = 1] = "File";
FileType[FileType["Directory"] = 2] = "Directory";
FileType[FileType["SymbolicLink"] = 64] = "SymbolicLink";
})(FileType || (exports.FileType = FileType = {}));
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1,13 @@
import type { SemanticTokens } from 'vscode-languageserver-protocol';
export declare class SemanticTokensBuilder {
private _id;
private _prevLine;
private _prevChar;
private _data;
private _dataLen;
constructor();
private initialize;
push(line: number, char: number, length: number, tokenType: number, tokenModifiers: number): void;
get id(): string;
build(): SemanticTokens;
}

View File

@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SemanticTokensBuilder = void 0;
class SemanticTokensBuilder {
constructor() {
this.initialize();
}
initialize() {
this._id = Date.now();
this._prevLine = 0;
this._prevChar = 0;
this._data = [];
this._dataLen = 0;
}
push(line, char, length, tokenType, tokenModifiers) {
let pushLine = line;
let pushChar = char;
if (this._dataLen > 0) {
pushLine -= this._prevLine;
if (pushLine === 0) {
pushChar -= this._prevChar;
}
}
this._data[this._dataLen++] = pushLine;
this._data[this._dataLen++] = pushChar;
this._data[this._dataLen++] = length;
this._data[this._dataLen++] = tokenType;
this._data[this._dataLen++] = tokenModifiers;
this._prevLine = line;
this._prevChar = char;
}
get id() {
return this._id.toString();
}
build() {
return {
resultId: this.id,
data: this._data,
};
}
}
exports.SemanticTokensBuilder = SemanticTokensBuilder;
//# sourceMappingURL=SemanticTokensBuilder.js.map

View File

@@ -0,0 +1,2 @@
import type * as vscode from 'vscode-languageserver-protocol';
export declare const NoneCancellationToken: vscode.CancellationToken;

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NoneCancellationToken = void 0;
exports.NoneCancellationToken = {
isCancellationRequested: false,
onCancellationRequested: () => ({ dispose: () => { } }),
};
//# sourceMappingURL=cancellation.js.map

View File

@@ -0,0 +1,11 @@
import type { CodeInformation, Mapper } from '@volar/language-core';
import type * as ts from 'typescript';
import type * as vscode from 'vscode-languageserver-protocol';
export declare function findOverlapCodeRange(start: number, end: number, map: Mapper, filter: (data: CodeInformation) => boolean): {
start: number;
end: number;
} | undefined;
export declare function isInsideRange(parent: vscode.Range, child: vscode.Range): boolean;
export declare function isEqualRange(a: vscode.Range, b: vscode.Range): boolean;
export declare function stringToSnapshot(str: string): ts.IScriptSnapshot;
export declare function sleep(ms: number): Promise<unknown>;

View File

@@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findOverlapCodeRange = findOverlapCodeRange;
exports.isInsideRange = isInsideRange;
exports.isEqualRange = isEqualRange;
exports.stringToSnapshot = stringToSnapshot;
exports.sleep = sleep;
function findOverlapCodeRange(start, end, map, filter) {
let mappedStart;
let mappedEnd;
for (const [mapped, mapping] of map.toGeneratedLocation(start)) {
if (filter(mapping.data)) {
mappedStart = mapped;
break;
}
}
for (const [mapped, mapping] of map.toGeneratedLocation(end)) {
if (filter(mapping.data)) {
mappedEnd = mapped;
break;
}
}
if (mappedStart === undefined || mappedEnd === undefined) {
for (const mapping of map.mappings) {
if (filter(mapping.data)) {
const mappingStart = mapping.sourceOffsets[0];
const mappingEnd = mapping.sourceOffsets[mapping.sourceOffsets.length - 1] + mapping.lengths[mapping.lengths.length - 1];
const overlap = getOverlapRange(start, end, mappingStart, mappingEnd);
if (overlap) {
const curMappedStart = (overlap.start - mappingStart) + mapping.generatedOffsets[0];
const lastGeneratedLength = (mapping.generatedLengths ?? mapping.lengths)[mapping.generatedOffsets.length - 1];
const curMappedEndOffset = Math.min(overlap.end - mapping.sourceOffsets[mapping.sourceOffsets.length - 1], lastGeneratedLength);
const curMappedEnd = mapping.generatedOffsets[mapping.generatedOffsets.length - 1] + curMappedEndOffset;
mappedStart = mappedStart === undefined ? curMappedStart : Math.min(mappedStart, curMappedStart);
mappedEnd = mappedEnd === undefined ? curMappedEnd : Math.max(mappedEnd, curMappedEnd);
}
}
}
}
if (mappedStart !== undefined && mappedEnd !== undefined) {
return {
start: mappedStart,
end: mappedEnd,
};
}
}
function getOverlapRange(range1Start, range1End, range2Start, range2End) {
const start = Math.max(range1Start, range2Start);
const end = Math.min(range1End, range2End);
if (start > end) {
return undefined;
}
return {
start,
end,
};
}
function isInsideRange(parent, child) {
if (child.start.line < parent.start.line) {
return false;
}
if (child.end.line > parent.end.line) {
return false;
}
if (child.start.line === parent.start.line && child.start.character < parent.start.character) {
return false;
}
if (child.end.line === parent.end.line && child.end.character > parent.end.character) {
return false;
}
return true;
}
function isEqualRange(a, b) {
return a.start.line === b.start.line
&& a.start.character === b.start.character
&& a.end.line === b.end.line
&& a.end.character === b.end.character;
}
function stringToSnapshot(str) {
return {
getText: (start, end) => str.substring(start, end),
getLength: () => str.length,
getChangeRange: () => undefined,
};
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
//# sourceMappingURL=common.js.map

View File

@@ -0,0 +1,14 @@
import type * as vscode from 'vscode-languageserver-protocol';
export declare function createLocationSet(): {
add: (item: vscode.Location) => boolean;
has: (item: vscode.Location) => boolean;
};
export declare function withCodeAction<T extends vscode.CodeAction>(items: T[]): T[];
export declare function withTextEdits<T extends vscode.TextEdit>(items: T[]): T[];
export declare function withDocumentChanges(items: NonNullable<vscode.WorkspaceEdit['documentChanges']>): (vscode.CreateFile | vscode.TextDocumentEdit | vscode.RenameFile | vscode.DeleteFile)[];
export declare function withDiagnostics<T extends vscode.Diagnostic>(items: T[]): T[];
export declare function withLocations<T extends vscode.Location>(items: T[]): T[];
export declare function withLocationLinks<T extends vscode.LocationLink>(items: T[]): T[];
export declare function withCallHierarchyIncomingCalls<T extends vscode.CallHierarchyIncomingCall>(items: T[]): T[];
export declare function withCallHierarchyOutgoingCalls<T extends vscode.CallHierarchyOutgoingCall>(items: T[]): T[];
export declare function withRanges<T extends vscode.Range>(items: T[]): T[];

View File

@@ -0,0 +1,120 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLocationSet = createLocationSet;
exports.withCodeAction = withCodeAction;
exports.withTextEdits = withTextEdits;
exports.withDocumentChanges = withDocumentChanges;
exports.withDiagnostics = withDiagnostics;
exports.withLocations = withLocations;
exports.withLocationLinks = withLocationLinks;
exports.withCallHierarchyIncomingCalls = withCallHierarchyIncomingCalls;
exports.withCallHierarchyOutgoingCalls = withCallHierarchyOutgoingCalls;
exports.withRanges = withRanges;
function createLocationSet() {
const set = new Set();
return {
add,
has,
};
function add(item) {
if (has(item)) {
return false;
}
set.add(getKey(item));
return true;
}
function has(item) {
return set.has(getKey(item));
}
function getKey(item) {
return [
item.uri,
item.range.start.line,
item.range.start.character,
item.range.end.line,
item.range.end.character,
].join(':');
}
}
function withCodeAction(items) {
return dedupe(items, item => [
item.title
].join(':'));
}
function withTextEdits(items) {
return dedupe(items, item => [
item.range.start.line,
item.range.start.character,
item.range.end.line,
item.range.end.character,
item.newText,
].join(':'));
}
function withDocumentChanges(items) {
return dedupe(items, item => JSON.stringify(item)); // TODO: improve this
}
function withDiagnostics(items) {
return dedupe(items, item => [
item.range.start.line,
item.range.start.character,
item.range.end.line,
item.range.end.character,
item.source,
item.code,
item.severity,
item.message,
].join(':'));
}
function withLocations(items) {
return dedupe(items, item => [
item.uri,
item.range.start.line,
item.range.start.character,
item.range.end.line,
item.range.end.character,
].join(':'));
}
function withLocationLinks(items) {
return dedupe(items, item => [
item.targetUri,
item.targetSelectionRange.start.line,
item.targetSelectionRange.start.character,
item.targetSelectionRange.end.line,
item.targetSelectionRange.end.character,
// ignore difference targetRange
].join(':'));
}
function withCallHierarchyIncomingCalls(items) {
return dedupe(items, item => [
item.from.uri,
item.from.range.start.line,
item.from.range.start.character,
item.from.range.end.line,
item.from.range.end.character,
].join(':'));
}
function withCallHierarchyOutgoingCalls(items) {
return dedupe(items, item => [
item.to.uri,
item.to.range.start.line,
item.to.range.start.character,
item.to.range.end.line,
item.to.range.end.character,
].join(':'));
}
function withRanges(items) {
return dedupe(items, item => [
item.start.line,
item.start.character,
item.end.line,
item.end.character,
].join(':'));
}
function dedupe(items, getKey) {
const map = new Map();
for (const item of items.reverse()) {
map.set(getKey(item), item);
}
return [...map.values()];
}
//# sourceMappingURL=dedupe.js.map

View File

@@ -0,0 +1,33 @@
import type { CodeInformation, LinkedCodeMap, Mapper, SourceScript, VirtualCode } from '@volar/language-core';
import type * as vscode from 'vscode-languageserver-protocol';
import type { TextDocument } from 'vscode-languageserver-textdocument';
import type { URI } from 'vscode-uri';
import type { LanguageServiceContext, LanguageServicePlugin, LanguageServicePluginInstance } from '../types';
export type DocumentsAndMap = [
sourceDocument: TextDocument,
embeddedDocument: TextDocument,
map: Mapper
];
export declare function documentFeatureWorker<T>(context: LanguageServiceContext, uri: URI, valid: (info: DocumentsAndMap) => boolean, worker: (plugin: [LanguageServicePlugin, LanguageServicePluginInstance], document: TextDocument) => Thenable<T | null | undefined> | T | null | undefined, transformResult: (result: T, map?: DocumentsAndMap) => T | undefined, combineResult?: (results: T[]) => T): Promise<T | undefined>;
export declare function languageFeatureWorker<T, K>(context: LanguageServiceContext, uri: URI, getRealDocParams: () => K, eachVirtualDocParams: (map: DocumentsAndMap) => Generator<K>, worker: (plugin: [LanguageServicePlugin, LanguageServicePluginInstance], document: TextDocument, params: K, map?: DocumentsAndMap) => Thenable<T | null | undefined> | T | null | undefined, transformResult: (result: T, map?: DocumentsAndMap) => T | undefined, combineResult?: (results: T[]) => T): Promise<T | undefined>;
export declare function safeCall<T>(cb: () => Thenable<T> | T, errorMsg?: string): Promise<T | undefined>;
export declare function forEachEmbeddedDocument(context: LanguageServiceContext, sourceScript: SourceScript<URI>, current: VirtualCode): Generator<DocumentsAndMap>;
export declare function getSourceRange(docs: DocumentsAndMap, range: vscode.Range, filter?: (data: CodeInformation) => boolean): {
start: import("vscode-languageserver-textdocument").Position;
end: import("vscode-languageserver-textdocument").Position;
} | undefined;
export declare function getGeneratedRange(docs: DocumentsAndMap, range: vscode.Range, filter?: (data: CodeInformation) => boolean): {
start: import("vscode-languageserver-textdocument").Position;
end: import("vscode-languageserver-textdocument").Position;
} | undefined;
export declare function getSourceRanges([sourceDocument, embeddedDocument, map]: DocumentsAndMap, range: vscode.Range, filter?: (data: CodeInformation) => boolean): Generator<{
start: import("vscode-languageserver-textdocument").Position;
end: import("vscode-languageserver-textdocument").Position;
}, void, unknown>;
export declare function getGeneratedRanges([sourceDocument, embeddedDocument, map]: DocumentsAndMap, range: vscode.Range, filter?: (data: CodeInformation) => boolean): Generator<{
start: import("vscode-languageserver-textdocument").Position;
end: import("vscode-languageserver-textdocument").Position;
}, void, unknown>;
export declare function getSourcePositions([sourceDocument, embeddedDocument, map]: DocumentsAndMap, position: vscode.Position, filter?: (data: CodeInformation) => boolean): Generator<import("vscode-languageserver-textdocument").Position, void, unknown>;
export declare function getGeneratedPositions([sourceDocument, embeddedDocument, map]: DocumentsAndMap, position: vscode.Position, filter?: (data: CodeInformation) => boolean): Generator<import("vscode-languageserver-textdocument").Position, void, unknown>;
export declare function getLinkedCodePositions(document: TextDocument, linkedMap: LinkedCodeMap, posotion: vscode.Position): Generator<import("vscode-languageserver-textdocument").Position, void, unknown>;

View File

@@ -0,0 +1,168 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.documentFeatureWorker = documentFeatureWorker;
exports.languageFeatureWorker = languageFeatureWorker;
exports.safeCall = safeCall;
exports.forEachEmbeddedDocument = forEachEmbeddedDocument;
exports.getSourceRange = getSourceRange;
exports.getGeneratedRange = getGeneratedRange;
exports.getSourceRanges = getSourceRanges;
exports.getGeneratedRanges = getGeneratedRanges;
exports.getSourcePositions = getSourcePositions;
exports.getGeneratedPositions = getGeneratedPositions;
exports.getLinkedCodePositions = getLinkedCodePositions;
function documentFeatureWorker(context, uri, valid, worker, transformResult, combineResult) {
return languageFeatureWorker(context, uri, () => void 0, function* (map) {
if (valid(map)) {
yield;
}
}, worker, transformResult, combineResult);
}
async function languageFeatureWorker(context, uri, getRealDocParams, eachVirtualDocParams, worker, transformResult, combineResult) {
let sourceScript;
const decoded = context.decodeEmbeddedDocumentUri(uri);
if (decoded) {
sourceScript = context.language.scripts.get(decoded[0]);
}
else {
sourceScript = context.language.scripts.get(uri);
}
if (!sourceScript) {
return;
}
let results = [];
if (decoded) {
const virtualCode = sourceScript.generated?.embeddedCodes.get(decoded[1]);
if (virtualCode) {
const docs = [
context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot),
context.documents.get(uri, virtualCode.languageId, virtualCode.snapshot),
context.language.maps.get(virtualCode, sourceScript),
];
await docsWorker(docs, false);
}
}
else if (sourceScript.generated) {
for (const docs of forEachEmbeddedDocument(context, sourceScript, sourceScript.generated.root)) {
if (results.length && !combineResult) {
continue;
}
await docsWorker(docs, true);
}
}
else {
const document = context.documents.get(uri, sourceScript.languageId, sourceScript.snapshot);
const params = getRealDocParams();
for (const [pluginIndex, plugin] of Object.entries(context.plugins)) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
const embeddedResult = await safeCall(() => worker(plugin, document, params, undefined), `Language service plugin "${plugin[0].name}" (${pluginIndex}) failed to provide document feature for ${document.uri}.`);
if (!embeddedResult) {
continue;
}
const result = transformResult(embeddedResult, undefined);
if (!result) {
continue;
}
results.push(result);
if (!combineResult) {
break;
}
}
}
if (combineResult && results.length > 0) {
const combined = combineResult(results);
return combined;
}
else if (results.length > 0) {
return results[0];
}
async function docsWorker(docs, transform) {
for (const mappedArg of eachVirtualDocParams(docs)) {
if (results.length && !combineResult) {
continue;
}
for (const [pluginIndex, plugin] of Object.entries(context.plugins)) {
if (context.disabledServicePlugins.has(plugin[1])) {
continue;
}
if (results.length && !combineResult) {
continue;
}
const embeddedResult = await safeCall(() => worker(plugin, docs[1], mappedArg, docs), `Language service plugin "${plugin[0].name}" (${pluginIndex}) failed to provide document feature for ${docs[1].uri}.`);
if (!embeddedResult) {
continue;
}
if (transform) {
const mappedResult = transformResult(embeddedResult, docs);
if (mappedResult) {
results.push(mappedResult);
}
}
else {
results.push(embeddedResult);
}
}
}
}
}
async function safeCall(cb, errorMsg) {
try {
return await cb();
}
catch (err) {
console.warn(errorMsg, err);
}
}
function* forEachEmbeddedDocument(context, sourceScript, current) {
if (current.embeddedCodes) {
for (const embeddedCode of current.embeddedCodes) {
yield* forEachEmbeddedDocument(context, sourceScript, embeddedCode);
}
}
const embeddedDocumentUri = context.encodeEmbeddedDocumentUri(sourceScript.id, current.id);
if (!context.disabledEmbeddedDocumentUris.get(embeddedDocumentUri)) {
yield [
context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot),
context.documents.get(embeddedDocumentUri, current.languageId, current.snapshot),
context.language.maps.get(current, sourceScript),
];
}
}
function getSourceRange(docs, range, filter) {
for (const result of getSourceRanges(docs, range, filter)) {
return result;
}
}
function getGeneratedRange(docs, range, filter) {
for (const result of getGeneratedRanges(docs, range, filter)) {
return result;
}
}
function* getSourceRanges([sourceDocument, embeddedDocument, map], range, filter) {
for (const [mappedStart, mappedEnd] of map.toSourceRange(embeddedDocument.offsetAt(range.start), embeddedDocument.offsetAt(range.end), true, filter)) {
yield { start: sourceDocument.positionAt(mappedStart), end: sourceDocument.positionAt(mappedEnd) };
}
}
function* getGeneratedRanges([sourceDocument, embeddedDocument, map], range, filter) {
for (const [mappedStart, mappedEnd] of map.toGeneratedRange(sourceDocument.offsetAt(range.start), sourceDocument.offsetAt(range.end), true, filter)) {
yield { start: embeddedDocument.positionAt(mappedStart), end: embeddedDocument.positionAt(mappedEnd) };
}
}
function* getSourcePositions([sourceDocument, embeddedDocument, map], position, filter = () => true) {
for (const mapped of map.toSourceLocation(embeddedDocument.offsetAt(position), filter)) {
yield sourceDocument.positionAt(mapped[0]);
}
}
function* getGeneratedPositions([sourceDocument, embeddedDocument, map], position, filter = () => true) {
for (const mapped of map.toGeneratedLocation(sourceDocument.offsetAt(position), filter)) {
yield embeddedDocument.positionAt(mapped[0]);
}
}
function* getLinkedCodePositions(document, linkedMap, posotion) {
for (const linkedPosition of linkedMap.getLinkedOffsets(document.offsetAt(posotion))) {
yield document.positionAt(linkedPosition);
}
}
//# sourceMappingURL=featureWorkers.js.map

View File

@@ -0,0 +1,23 @@
import type * as vscode from 'vscode-languageserver-protocol';
import type { TextDocument } from 'vscode-languageserver-textdocument';
import { URI } from 'vscode-uri';
import type { LanguageServiceContext } from '../types';
export declare function transformDocumentLinkTarget(_target: string, context: LanguageServiceContext): URI;
export declare function transformMarkdown(content: string, context: LanguageServiceContext): string;
export declare function transformCompletionItem<T extends vscode.CompletionItem>(item: T, getOtherRange: (range: vscode.Range) => vscode.Range | undefined, document: vscode.TextDocument, context: LanguageServiceContext): T;
export declare function transformCompletionList<T extends vscode.CompletionList>(completionList: T, getOtherRange: (range: vscode.Range) => vscode.Range | undefined, document: TextDocument, context: LanguageServiceContext): T;
export declare function transformDocumentSymbol(symbol: vscode.DocumentSymbol, getOtherRange: (range: vscode.Range) => vscode.Range | undefined): vscode.DocumentSymbol | undefined;
export declare function transformFoldingRanges(ranges: vscode.FoldingRange[], getOtherRange: (range: vscode.Range) => vscode.Range | undefined): vscode.FoldingRange[];
export declare function transformHover<T extends vscode.Hover>(hover: T, getOtherRange: (range: vscode.Range) => vscode.Range | undefined): T | undefined;
export declare function transformLocation<T extends {
range: vscode.Range;
}>(location: T, getOtherRange: (range: vscode.Range) => vscode.Range | undefined): T | undefined;
export declare function transformLocations<T extends {
range: vscode.Range;
}>(locations: T[], getOtherRange: (range: vscode.Range) => vscode.Range | undefined): T[];
export declare function transformSelectionRange<T extends vscode.SelectionRange>(location: T, getOtherRange: (range: vscode.Range) => vscode.Range | undefined): T | undefined;
export declare function transformSelectionRanges<T extends vscode.SelectionRange>(locations: T[], getOtherRange: (range: vscode.Range) => vscode.Range | undefined): T[];
export declare function transformTextEdit<T extends vscode.TextEdit | vscode.InsertReplaceEdit>(textEdit: T, getOtherRange: (range: vscode.Range) => vscode.Range | undefined, document: vscode.TextDocument): T | undefined;
export declare function transformWorkspaceSymbol(symbol: vscode.WorkspaceSymbol, getOtherLocation: (location: vscode.Location) => vscode.Location | undefined): vscode.WorkspaceSymbol | undefined;
export declare function transformWorkspaceEdit(edit: vscode.WorkspaceEdit, context: LanguageServiceContext, mode: 'fileName' | 'rename' | 'codeAction' | undefined, versions?: Record<string, number>): vscode.WorkspaceEdit | undefined;
export declare function pushEditToDocumentChanges(arr: NonNullable<vscode.WorkspaceEdit['documentChanges']>, item: NonNullable<vscode.WorkspaceEdit['documentChanges']>[number]): void;

View File

@@ -0,0 +1,460 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformDocumentLinkTarget = transformDocumentLinkTarget;
exports.transformMarkdown = transformMarkdown;
exports.transformCompletionItem = transformCompletionItem;
exports.transformCompletionList = transformCompletionList;
exports.transformDocumentSymbol = transformDocumentSymbol;
exports.transformFoldingRanges = transformFoldingRanges;
exports.transformHover = transformHover;
exports.transformLocation = transformLocation;
exports.transformLocations = transformLocations;
exports.transformSelectionRange = transformSelectionRange;
exports.transformSelectionRanges = transformSelectionRanges;
exports.transformTextEdit = transformTextEdit;
exports.transformWorkspaceSymbol = transformWorkspaceSymbol;
exports.transformWorkspaceEdit = transformWorkspaceEdit;
exports.pushEditToDocumentChanges = pushEditToDocumentChanges;
const language_core_1 = require("@volar/language-core");
const vscode_uri_1 = require("vscode-uri");
const featureWorkers_1 = require("./featureWorkers");
function transformDocumentLinkTarget(_target, context) {
let target = vscode_uri_1.URI.parse(_target);
const decoded = context.decodeEmbeddedDocumentUri(target);
if (!decoded) {
return target;
}
const embeddedRange = target.fragment.match(/^L(\d+)(,(\d+))?(-L(\d+)(,(\d+))?)?$/);
const sourceScript = context.language.scripts.get(decoded[0]);
const virtualCode = sourceScript?.generated?.embeddedCodes.get(decoded[1]);
target = decoded[0];
if (embeddedRange && sourceScript && virtualCode) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
if (!map.mappings.some(mapping => (0, language_core_1.isDocumentLinkEnabled)(mapping.data))) {
continue;
}
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
const startLine = Number(embeddedRange[1]) - 1;
const startCharacter = Number(embeddedRange[3] ?? 1) - 1;
if (embeddedRange[5] !== undefined) {
const endLine = Number(embeddedRange[5]) - 1;
const endCharacter = Number(embeddedRange[7] ?? 1) - 1;
const sourceRange = (0, featureWorkers_1.getSourceRange)(docs, {
start: { line: startLine, character: startCharacter },
end: { line: endLine, character: endCharacter },
});
if (sourceRange) {
target = target.with({
fragment: 'L' + (sourceRange.start.line + 1) + ',' + (sourceRange.start.character + 1)
+ '-L' + (sourceRange.end.line + 1) + ',' + (sourceRange.end.character + 1),
});
break;
}
}
else {
let mapped = false;
for (const sourcePos of (0, featureWorkers_1.getSourcePositions)(docs, { line: startLine, character: startCharacter })) {
mapped = true;
target = target.with({
fragment: 'L' + (sourcePos.line + 1) + ',' + (sourcePos.character + 1),
});
break;
}
if (mapped) {
break;
}
}
}
}
return target;
}
function transformMarkdown(content, context) {
return content.replace(/(?!\()volar-embedded-content:\/\/\w+\/[^)]+/g, match => {
const segments = match.split('|');
segments[0] = transformDocumentLinkTarget(segments[0], context).toString();
return segments.join('|');
});
}
function transformCompletionItem(item, getOtherRange, document, context) {
return {
...item,
additionalTextEdits: item.additionalTextEdits
?.map(edit => transformTextEdit(edit, getOtherRange, document))
.filter(edit => !!edit),
textEdit: item.textEdit
? transformTextEdit(item.textEdit, getOtherRange, document)
: undefined,
documentation: item.documentation ?
typeof item.documentation === 'string' ? transformMarkdown(item.documentation, context) :
item.documentation.kind === 'markdown' ?
{ kind: 'markdown', value: transformMarkdown(item.documentation.value, context) }
: item.documentation
: undefined
};
}
function transformCompletionList(completionList, getOtherRange, document, context) {
return {
isIncomplete: completionList.isIncomplete,
itemDefaults: completionList.itemDefaults ? {
...completionList.itemDefaults,
editRange: completionList.itemDefaults.editRange
? 'replace' in completionList.itemDefaults.editRange
? {
insert: getOtherRange(completionList.itemDefaults.editRange.insert),
replace: getOtherRange(completionList.itemDefaults.editRange.replace),
}
: getOtherRange(completionList.itemDefaults.editRange)
: undefined,
} : undefined,
items: completionList.items.map(item => transformCompletionItem(item, getOtherRange, document, context)),
};
}
function transformDocumentSymbol(symbol, getOtherRange) {
const range = getOtherRange(symbol.range);
if (!range) {
return;
}
const selectionRange = getOtherRange(symbol.selectionRange);
if (!selectionRange) {
return;
}
return {
...symbol,
range,
selectionRange,
children: symbol.children
?.map(child => transformDocumentSymbol(child, getOtherRange))
.filter(child => !!child),
};
}
function transformFoldingRanges(ranges, getOtherRange) {
const result = [];
for (const range of ranges) {
const otherRange = getOtherRange({
start: { line: range.startLine, character: range.startCharacter ?? 0 },
end: { line: range.endLine, character: range.endCharacter ?? 0 },
});
if (otherRange) {
range.startLine = otherRange.start.line;
range.endLine = otherRange.end.line;
if (range.startCharacter !== undefined) {
range.startCharacter = otherRange.start.character;
}
if (range.endCharacter !== undefined) {
range.endCharacter = otherRange.end.character;
}
result.push(range);
}
}
return result;
}
function transformHover(hover, getOtherRange) {
if (!hover?.range) {
return hover;
}
const range = getOtherRange(hover.range);
if (!range) {
return;
}
return {
...hover,
range,
};
}
function transformLocation(location, getOtherRange) {
const range = getOtherRange(location.range);
if (!range) {
return;
}
return {
...location,
range,
};
}
function transformLocations(locations, getOtherRange) {
return locations
.map(location => transformLocation(location, getOtherRange))
.filter(location => !!location);
}
function transformSelectionRange(location, getOtherRange) {
const range = getOtherRange(location.range);
if (!range) {
return;
}
const parent = location.parent ? transformSelectionRange(location.parent, getOtherRange) : undefined;
return {
range,
parent,
};
}
function transformSelectionRanges(locations, getOtherRange) {
return locations
.map(location => transformSelectionRange(location, getOtherRange))
.filter(location => !!location);
}
function transformTextEdit(textEdit, getOtherRange, document) {
if ('range' in textEdit) {
let range = getOtherRange(textEdit.range);
if (range) {
return {
...textEdit,
range,
};
}
;
const cover = tryRecoverTextEdit(getOtherRange, textEdit.range, textEdit.newText, document);
if (cover) {
return {
...textEdit,
range: cover.range,
newText: cover.newText,
};
}
}
else if ('replace' in textEdit && 'insert' in textEdit) {
const insert = getOtherRange(textEdit.insert);
const replace = insert ? getOtherRange(textEdit.replace) : undefined;
if (insert && replace) {
return {
...textEdit,
insert,
replace,
};
}
const recoverInsert = tryRecoverTextEdit(getOtherRange, textEdit.insert, textEdit.newText, document);
const recoverReplace = recoverInsert ? tryRecoverTextEdit(getOtherRange, textEdit.replace, textEdit.newText, document) : undefined;
if (recoverInsert && recoverReplace && recoverInsert.newText === recoverReplace.newText) {
return {
...textEdit,
insert: recoverInsert.range,
replace: recoverReplace.range,
newText: recoverInsert.newText,
};
}
}
}
/**
* update edit text from ". foo" to " foo"
* fix https://github.com/johnsoncodehk/volar/issues/2155
*/
function tryRecoverTextEdit(getOtherRange, replaceRange, newText, document) {
if (replaceRange.start.line === replaceRange.end.line && replaceRange.end.character > replaceRange.start.character) {
let character = replaceRange.start.character;
while (newText.length && replaceRange.end.character > character) {
const newStart = { line: replaceRange.start.line, character: replaceRange.start.character + 1 };
if (document.getText({ start: replaceRange.start, end: newStart }) === newText[0]) {
newText = newText.slice(1);
character++;
const otherRange = getOtherRange({ start: newStart, end: replaceRange.end });
if (otherRange) {
return {
newText,
range: otherRange,
};
}
}
else {
break;
}
}
}
}
function transformWorkspaceSymbol(symbol, getOtherLocation) {
if (!('range' in symbol.location)) {
return symbol;
}
const loc = getOtherLocation(symbol.location);
if (!loc) {
return;
}
return {
...symbol,
location: loc,
};
}
function transformWorkspaceEdit(edit, context, mode, versions = {}) {
const sourceResult = {};
let hasResult = false;
for (const tsUri in edit.changeAnnotations) {
sourceResult.changeAnnotations ??= {};
const tsAnno = edit.changeAnnotations[tsUri];
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(tsUri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (sourceScript && virtualCode) {
for (const [sourceScript] of context.language.maps.forEach(virtualCode)) {
// TODO: check capability?
const uri = sourceScript.id.toString();
sourceResult.changeAnnotations[uri] = tsAnno;
break;
}
}
else {
sourceResult.changeAnnotations[tsUri] = tsAnno;
}
}
for (const tsUri in edit.changes) {
sourceResult.changes ??= {};
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(tsUri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (sourceScript && virtualCode) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
const tsEdits = edit.changes[tsUri];
for (const tsEdit of tsEdits) {
if (mode === 'rename' || mode === 'fileName' || mode === 'codeAction') {
let _data;
const range = (0, featureWorkers_1.getSourceRange)(docs, tsEdit.range, data => {
_data = data;
return (0, language_core_1.isRenameEnabled)(data);
});
if (range) {
sourceResult.changes[sourceDocument.uri] ??= [];
sourceResult.changes[sourceDocument.uri].push({
newText: (0, language_core_1.resolveRenameEditText)(tsEdit.newText, _data),
range,
});
hasResult = true;
}
}
else {
const range = (0, featureWorkers_1.getSourceRange)(docs, tsEdit.range);
if (range) {
sourceResult.changes[sourceDocument.uri] ??= [];
sourceResult.changes[sourceDocument.uri].push({ newText: tsEdit.newText, range });
hasResult = true;
}
}
}
}
}
else {
sourceResult.changes[tsUri] = edit.changes[tsUri];
hasResult = true;
}
}
if (edit.documentChanges) {
for (const tsDocEdit of edit.documentChanges) {
sourceResult.documentChanges ??= [];
let sourceEdit;
if ('textDocument' in tsDocEdit) {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(tsDocEdit.textDocument.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (sourceScript && virtualCode) {
const embeddedDocument = context.documents.get(context.encodeEmbeddedDocumentUri(sourceScript.id, virtualCode.id), virtualCode.languageId, virtualCode.snapshot);
for (const [sourceScript, map] of context.language.maps.forEach(virtualCode)) {
const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
const docs = [sourceDocument, embeddedDocument, map];
sourceEdit = {
textDocument: {
uri: sourceDocument.uri,
version: versions[sourceDocument.uri] ?? null,
},
edits: [],
};
for (const tsEdit of tsDocEdit.edits) {
if (mode === 'rename' || mode === 'fileName' || mode === 'codeAction') {
let _data;
const range = (0, featureWorkers_1.getSourceRange)(docs, tsEdit.range, data => {
_data = data;
// fix https://github.com/johnsoncodehk/volar/issues/1091
return (0, language_core_1.isRenameEnabled)(data);
});
if (range) {
sourceEdit.edits.push({
annotationId: 'annotationId' in tsEdit ? tsEdit.annotationId : undefined,
newText: (0, language_core_1.resolveRenameEditText)(tsEdit.newText, _data),
range,
});
}
}
else {
const range = (0, featureWorkers_1.getSourceRange)(docs, tsEdit.range);
if (range) {
sourceEdit.edits.push({
annotationId: 'annotationId' in tsEdit ? tsEdit.annotationId : undefined,
newText: tsEdit.newText,
range,
});
}
}
}
if (!sourceEdit.edits.length) {
sourceEdit = undefined;
}
}
}
else {
sourceEdit = tsDocEdit;
}
}
else if (tsDocEdit.kind === 'create') {
sourceEdit = tsDocEdit; // TODO: remove .ts?
}
else if (tsDocEdit.kind === 'rename') {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(tsDocEdit.oldUri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (virtualCode) {
for (const [sourceScript] of context.language.maps.forEach(virtualCode)) {
// TODO: check capability?
sourceEdit = {
kind: 'rename',
oldUri: sourceScript.id.toString(),
newUri: tsDocEdit.newUri /* TODO: remove .ts? */,
options: tsDocEdit.options,
annotationId: tsDocEdit.annotationId,
};
}
}
else {
sourceEdit = tsDocEdit;
}
}
else if (tsDocEdit.kind === 'delete') {
const decoded = context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(tsDocEdit.uri));
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
if (virtualCode) {
for (const [sourceScript] of context.language.maps.forEach(virtualCode)) {
// TODO: check capability?
sourceEdit = {
kind: 'delete',
uri: sourceScript.id.toString(),
options: tsDocEdit.options,
annotationId: tsDocEdit.annotationId,
};
}
}
else {
sourceEdit = tsDocEdit;
}
}
if (sourceEdit) {
pushEditToDocumentChanges(sourceResult.documentChanges, sourceEdit);
hasResult = true;
}
}
}
if (hasResult) {
return sourceResult;
}
}
function pushEditToDocumentChanges(arr, item) {
const current = arr.find(edit => 'textDocument' in edit
&& 'textDocument' in item
&& edit.textDocument.uri === item.textDocument.uri);
if (current) {
current.edits.push(...item.edits);
}
else {
arr.push(item);
}
}
//# sourceMappingURL=transform.js.map

View File

@@ -0,0 +1,3 @@
import type { URI } from 'vscode-uri';
export type UriMap<T> = ReturnType<typeof createUriMap<T>>;
export declare function createUriMap<T>(caseSensitive?: boolean): Map<URI, T>;

View File

@@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createUriMap = createUriMap;
function createUriMap(caseSensitive = false) {
const map = new Map();
const rawUriToNormalizedUri = new Map();
const normalizedUriToRawUri = new Map();
return {
get size() {
return map.size;
},
get [Symbol.toStringTag]() {
return 'UriMap';
},
[Symbol.iterator]() {
return this.entries();
},
clear() {
rawUriToNormalizedUri.clear();
normalizedUriToRawUri.clear();
return map.clear();
},
values() {
return map.values();
},
*keys() {
for (const normalizedUri of map.keys()) {
yield normalizedUriToRawUri.get(normalizedUri);
}
return undefined;
},
*entries() {
for (const [normalizedUri, item] of map.entries()) {
yield [normalizedUriToRawUri.get(normalizedUri), item];
}
return undefined;
},
forEach(callbackfn, thisArg) {
for (const [uri, item] of this.entries()) {
callbackfn.call(thisArg, item, uri, this);
}
},
delete(uri) {
return map.delete(toKey(uri));
},
get(uri) {
return map.get(toKey(uri));
},
has(uri) {
return map.has(toKey(uri));
},
set(uri, item) {
map.set(toKey(uri), item);
return this;
},
};
function toKey(uri) {
const rawUri = uri.toString();
if (!rawUriToNormalizedUri.has(rawUri)) {
let normalizedUri = uri.toString();
if (!caseSensitive) {
normalizedUri = normalizedUri.toLowerCase();
}
rawUriToNormalizedUri.set(rawUri, normalizedUri);
normalizedUriToRawUri.set(normalizedUri, uri);
}
return rawUriToNormalizedUri.get(rawUri);
}
}
//# sourceMappingURL=uriMap.js.map