diff --git a/extensions/typescript-language-features/src/languageFeatures/copilotRelated.ts b/extensions/typescript-language-features/src/languageFeatures/copilotRelated.ts new file mode 100644 index 00000000000..2a02713d5be --- /dev/null +++ b/extensions/typescript-language-features/src/languageFeatures/copilotRelated.ts @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { nulToken } from '../utils/cancellation'; +import { jsTsLanguageModes, isSupportedLanguageMode } from '../configuration/languageIds'; +import { DocumentSelector } from '../configuration/documentSelector'; +import { API } from '../tsServer/api'; +import type * as Proto from '../tsServer/protocol/protocol'; +import { ITypeScriptServiceClient } from '../typescriptService'; +import { conditionalRegistration, requireMinVersion } from './util/dependentRegistration'; + +const minVersion = API.v560; +const dummyDisposable = new vscode.Disposable(() => { }); + +export function register( + _selector: DocumentSelector, + client: ITypeScriptServiceClient, +) { + return conditionalRegistration([ + requireMinVersion(client, minVersion), + ], () => { + const ext = vscode.extensions.getExtension('github.copilot'); + if (!ext) { + return dummyDisposable; + } + ext.activate().then(() => { + const relatedAPI = ext.exports as { + registerRelatedFilesProvider( + providerId: { extensionId: string; languageId: string }, + callback: (uri: vscode.Uri) => Promise<{ entries: vscode.Uri[]; traits?: { name: string; value: string }[] }> + ): void; + } | undefined; + if (relatedAPI?.registerRelatedFilesProvider) { + for (const languageId of jsTsLanguageModes) { + const id = { + extensionId: 'vscode.typescript-language-features', + languageId + }; + relatedAPI.registerRelatedFilesProvider(id, async uri => { + let document; + try { + document = await vscode.workspace.openTextDocument(uri); + } catch { + if (!vscode.window.activeTextEditor) { + vscode.window.showErrorMessage(vscode.l10n.t("Related files provider failed. No active text editor.")); + return { entries: [] }; + } + // something is REALLY wrong if you can't open the active text editor's document, so don't catch that + document = await vscode.workspace.openTextDocument(vscode.window.activeTextEditor.document.uri); + } + + if (!isSupportedLanguageMode(document)) { + vscode.window.showErrorMessage(vscode.l10n.t("Related files provider failed. Copilot requested file with unsupported language mode.")); + return { entries: [] }; + } + + const file = client.toOpenTsFilePath(document); + if (!file) { + return { entries: [] }; + } + // TODO ts-expect-error until ts5.7 + const response = await client.execute('copilotRelated', { file, }, nulToken) as Proto.CopilotRelatedResponse; + if (response.type !== 'response' || !response.body) { + return { entries: [] }; + } + return { entries: response.body.relatedFiles.map(f => client.toResource(f)), traits: [] }; + }); + } + } + }); + return dummyDisposable; + }); +} diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index f46d300c613..1fc9d51ff4e 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -35,7 +35,6 @@ import TypingsStatus, { AtaProgressReporter } from './ui/typingsStatus'; import { VersionStatus } from './ui/versionStatus'; import { coalesce } from './utils/arrays'; import { Disposable } from './utils/dispose'; -import { jsTsLanguageModes, isSupportedLanguageMode } from './configuration/languageIds'; // Style check diagnostics that can be reported as warnings const styleCheckDiagnostics = new Set([ @@ -151,60 +150,6 @@ export default class TypeScriptServiceClientHost extends Disposable { standardFileExtensions: [], }, onCompletionAccepted); } - // TODO: Still probably isn't the right place for this - const ext = vscode.extensions.getExtension('github.copilot'); - if (!ext) { - vscode.window.showErrorMessage(vscode.l10n.t('Could not find related-files extension')); - return; - } - await ext.activate(); - const relatedAPI = ext.exports as { - registerRelatedFilesProvider( - providerId: { extensionId: string; languageId: string }, - callback: (uri: vscode.Uri) => Promise<{ entries: vscode.Uri[]; traits?: { name: string; value: string }[] }> - ): void; - } | undefined; - if (relatedAPI) { - for (const languageId of jsTsLanguageModes) { - const id = { - extensionId: 'vscode.typescript-language-features', - languageId - }; - relatedAPI.registerRelatedFilesProvider(id, async uri => { - let document; - try { - document = await vscode.workspace.openTextDocument(uri); - } catch { - if (!vscode.window.activeTextEditor) { - vscode.window.showErrorMessage(vscode.l10n.t("Go to Source Definition failed. No resource provided.")); - return []; - } - // something is REALLY wrong if you can't open the active text editor's document, so don't catch that - document = await vscode.workspace.openTextDocument(vscode.window.activeTextEditor.document.uri); - } - - if (!isSupportedLanguageMode(document)) { - vscode.window.showErrorMessage(vscode.l10n.t("Go to Source Definition failed. Unsupported file type.")); - return []; - } - - const file = this.client.toOpenTsFilePath(document); - if (!file) { - return []; - } - // TODO: This compiles but will never cancel; this needs a token that somebody might actually cancel. - const cancel = new vscode.CancellationTokenSource(); - const response = await this.client.execute('copilotRelated', { file, }, cancel.token); - if (response.type !== 'response' || !response.body) { - return []; - } - return response.body.map(vscode.Uri.file); - }); - } - } - else { - vscode.window.showErrorMessage(vscode.l10n.t('Could not find github.copilot extension')); - } }); this.client.onTsServerStarted(() => {