From cf67129cdccd31fb62d53c72165f5c4895876b09 Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Fri, 20 May 2022 13:50:06 -0400 Subject: [PATCH 01/16] initial draft --- packages/language-server/src/ls-config.ts | 4 ++++ .../language-server/src/plugins/PluginHost.ts | 9 +++++++++ .../language-server/src/plugins/interfaces.ts | 5 +++++ .../plugins/typescript/TypeScriptPlugin.ts | 16 +++++++++++++++ .../features/FindFileReferencesProvider.ts | 12 +++++++++++ packages/language-server/src/server.ts | 17 +++++++--------- packages/svelte-vscode/src/extension.ts | 20 +++++++++++++++++++ 7 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts diff --git a/packages/language-server/src/ls-config.ts b/packages/language-server/src/ls-config.ts index 75278af7f..4ad2842dc 100644 --- a/packages/language-server/src/ls-config.ts +++ b/packages/language-server/src/ls-config.ts @@ -14,6 +14,7 @@ const defaultLSConfig: LSConfig = { completions: { enable: true }, definitions: { enable: true }, findReferences: { enable: true }, + fileReferences: { enable: true }, documentSymbols: { enable: true }, codeActions: { enable: true }, rename: { enable: true }, @@ -97,6 +98,9 @@ export interface LSTypescriptConfig { findReferences: { enable: boolean; }; + fileReferences: { + enable: boolean; + }; definitions: { enable: boolean; }; diff --git a/packages/language-server/src/plugins/PluginHost.ts b/packages/language-server/src/plugins/PluginHost.ts index 8a31aff66..ccd6520a3 100644 --- a/packages/language-server/src/plugins/PluginHost.ts +++ b/packages/language-server/src/plugins/PluginHost.ts @@ -389,6 +389,15 @@ export class PluginHost implements LSProvider, OnWatchFileChanges { ); } + async fileReferences(fileName: string): Promise { + return await this.execute( + 'fileReferences', + [fileName], + ExecuteMode.FirstNonNull, + 'high' + ); + } + async getSignatureHelp( textDocument: TextDocumentIdentifier, position: Position, diff --git a/packages/language-server/src/plugins/interfaces.ts b/packages/language-server/src/plugins/interfaces.ts index 10872b124..dd173fec4 100644 --- a/packages/language-server/src/plugins/interfaces.ts +++ b/packages/language-server/src/plugins/interfaces.ts @@ -143,6 +143,10 @@ export interface FindReferencesProvider { ): Promise; } +export interface FileReferencesProvider { + fileReferences(fileName: string): Promise; +} + export interface SignatureHelpProvider { getSignatureHelp( document: Document, @@ -199,6 +203,7 @@ type ProviderBase = DiagnosticsProvider & UpdateImportsProvider & CodeActionsProvider & FindReferencesProvider & + FileReferencesProvider & RenameProvider & SignatureHelpProvider & SemanticTokensProvider & diff --git a/packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts b/packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts index f228a060b..b5d5c681f 100644 --- a/packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts +++ b/packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts @@ -36,6 +36,7 @@ import { DocumentSymbolsProvider, FileRename, FindReferencesProvider, + FileReferencesProvider, HoverProvider, ImplementationProvider, OnWatchFileChanges, @@ -54,6 +55,7 @@ import { CompletionsProviderImpl } from './features/CompletionProvider'; import { DiagnosticsProviderImpl } from './features/DiagnosticsProvider'; +import { FindFileReferencesProviderImpl } from './features/FindFileReferencesProvider'; import { FindReferencesProviderImpl } from './features/FindReferencesProvider'; import { getDirectiveCommentCompletions } from './features/getDirectiveCommentCompletions'; import { HoverProviderImpl } from './features/HoverProvider'; @@ -85,6 +87,7 @@ export class TypeScriptPlugin UpdateImportsProvider, RenameProvider, FindReferencesProvider, + FileReferencesProvider, SelectionRangeProvider, SignatureHelpProvider, SemanticTokensProvider, @@ -104,6 +107,8 @@ export class TypeScriptPlugin private readonly renameProvider: RenameProviderImpl; private readonly hoverProvider: HoverProviderImpl; private readonly findReferencesProvider: FindReferencesProviderImpl; + private readonly findFileReferencesProvider: FindFileReferencesProviderImpl; + private readonly selectionRangeProvider: SelectionRangeProviderImpl; private readonly signatureHelpProvider: SignatureHelpProviderImpl; private readonly semanticTokensProvider: SemanticTokensProviderImpl; @@ -130,6 +135,9 @@ export class TypeScriptPlugin this.renameProvider = new RenameProviderImpl(this.lsAndTsDocResolver, configManager); this.hoverProvider = new HoverProviderImpl(this.lsAndTsDocResolver); this.findReferencesProvider = new FindReferencesProviderImpl(this.lsAndTsDocResolver); + this.findFileReferencesProvider = new FindFileReferencesProviderImpl( + this.lsAndTsDocResolver + ); this.selectionRangeProvider = new SelectionRangeProviderImpl(this.lsAndTsDocResolver); this.signatureHelpProvider = new SignatureHelpProviderImpl(this.lsAndTsDocResolver); this.semanticTokensProvider = new SemanticTokensProviderImpl(this.lsAndTsDocResolver); @@ -423,6 +431,14 @@ export class TypeScriptPlugin return this.findReferencesProvider.findReferences(document, position, context); } + async fileReferences(fileName: string): Promise { + if (!this.featureEnabled('fileReferences')) { + return null; + } + + return this.findFileReferencesProvider.fileReferences(fileName); + } + async onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesPara[]): Promise { let doneUpdateProjectFiles = false; diff --git a/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts b/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts new file mode 100644 index 000000000..3776e124b --- /dev/null +++ b/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts @@ -0,0 +1,12 @@ +import { Location } from 'vscode-languageserver'; +import { Document } from '../../../lib/documents'; +import { FileReferencesProvider } from '../../interfaces'; +import { LSAndTSDocResolver } from '../LSAndTSDocResolver'; + +export class FindFileReferencesProviderImpl implements FileReferencesProvider { + constructor(private readonly lsAndTsDocResolver: LSAndTSDocResolver) {} + + async fileReferences(fileName: string): Promise { + //?? + } +} diff --git a/packages/language-server/src/server.ts b/packages/language-server/src/server.ts index 57fb3e246..5803fabc6 100644 --- a/packages/language-server/src/server.ts +++ b/packages/language-server/src/server.ts @@ -161,9 +161,6 @@ export function startServer(options?: LSOptions) { ); const clientSupportApplyEditCommand = !!evt.capabilities.workspace?.applyEdit; - const clientCodeActionCapabilities = evt.capabilities.textDocument?.codeAction; - const clientSupportedCodeActionKinds = - clientCodeActionCapabilities?.codeActionLiteralSupport?.codeActionKind.valueSet; return { capabilities: { @@ -210,19 +207,15 @@ export function startServer(options?: LSOptions) { colorProvider: true, documentSymbolProvider: true, definitionProvider: true, - codeActionProvider: clientCodeActionCapabilities?.codeActionLiteralSupport + codeActionProvider: evt.capabilities.textDocument?.codeAction + ?.codeActionLiteralSupport ? { codeActionKinds: [ CodeActionKind.QuickFix, CodeActionKind.SourceOrganizeImports, SORT_IMPORT_CODE_ACTION_KIND, ...(clientSupportApplyEditCommand ? [CodeActionKind.Refactor] : []) - ].filter( - clientSupportedCodeActionKinds && - evt.initializationOptions.shouldFilterCodeActionKind - ? (kind) => clientSupportedCodeActionKinds.includes(kind) - : () => true - ) + ] } : true, executeCommandProvider: clientSupportApplyEditCommand @@ -426,6 +419,10 @@ export function startServer(options?: LSOptions) { pluginHost.updateImports(fileRename) ); + connection.onRequest('$/getFileReferences', async (fileName: string) => { + return pluginHost.fileReferences(fileName); + }); + connection.onRequest('$/getCompiledCode', async (uri: DocumentUri) => { const doc = docManager.get(uri); if (!doc) { diff --git a/packages/svelte-vscode/src/extension.ts b/packages/svelte-vscode/src/extension.ts index 9c7e9700b..17a612b51 100644 --- a/packages/svelte-vscode/src/extension.ts +++ b/packages/svelte-vscode/src/extension.ts @@ -223,6 +223,7 @@ export function activateSvelteLanguageServer(context: ExtensionContext) { addDidChangeTextDocumentListener(getLS); + addWhereImportsUsedListener(getLS); addRenameFileListener(getLS); addCompilePreviewCommand(getLS, context); @@ -323,6 +324,25 @@ function addDidChangeTextDocumentListener(getLS: () => LanguageClient) { }); } +async function addWhereImportsUsedListener(getLS: () => LanguageClient) { + //?? + setTimeout(() => { + window.withProgress( + { location: ProgressLocation.Window, title: 'Updating Imports..' }, + async () => { + const filename = + 'file:///d%3A/gittest/svelte/svelte-webpack-starter1/src/Button3.svelte'; + const editsForFileRename = await getLS().sendRequest( + '$/getFileReferences', + { + filename + } + ); + } + ); + }, 4000); +} + function addRenameFileListener(getLS: () => LanguageClient) { workspace.onDidRenameFiles(async (evt) => { const oldUri = evt.files[0].oldUri.toString(true); From 6059620118339435212ea4a5e44cd8cf9eb80a1a Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Mon, 23 May 2022 23:24:50 -0400 Subject: [PATCH 02/16] Fill in more of FindFileReferencesProviderImpl --- .../features/FindFileReferencesProvider.ts | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts b/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts index 3776e124b..05f67e9dc 100644 --- a/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts @@ -1,5 +1,4 @@ import { Location } from 'vscode-languageserver'; -import { Document } from '../../../lib/documents'; import { FileReferencesProvider } from '../../interfaces'; import { LSAndTSDocResolver } from '../LSAndTSDocResolver'; @@ -7,6 +6,35 @@ export class FindFileReferencesProviderImpl implements FileReferencesProvider { constructor(private readonly lsAndTsDocResolver: LSAndTSDocResolver) {} async fileReferences(fileName: string): Promise { - //?? + const lang = await this.getLSForPath(fileName); + + const references = lang.getFileReferences(fileName); + + if (!references) { + return null; + } + + return []; + + // const docs = new SnapshotFragmentMap(this.lsAndTsDocResolver); + // docs.set(tsDoc.filePath, { fragment, snapshot: tsDoc }); + + // const locations = await Promise.all( + // references.map(async (ref) => { + // const defDoc = await docs.retrieveFragment(ref.fileName); + + // return Location.create( + // pathToUrl(ref.fileName), + // convertToLocationRange(defDoc, ref.textSpan) + // ); + // }) + // ); + // // Some references are in generated code but not wrapped with explicit ignore comments. + // // These show up as zero-length ranges, so filter them out. + // return locations.filter(hasNonZeroRange); + } + + private async getLSForPath(path: string) { + return this.lsAndTsDocResolver.getLSForPath(path); } } From 0e3a8d362507cd113e43cb2d34fd5983f9a82d48 Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Mon, 23 May 2022 23:49:01 -0400 Subject: [PATCH 03/16] test handler --- packages/svelte-vscode/src/extension.ts | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/packages/svelte-vscode/src/extension.ts b/packages/svelte-vscode/src/extension.ts index 17a612b51..29538b93b 100644 --- a/packages/svelte-vscode/src/extension.ts +++ b/packages/svelte-vscode/src/extension.ts @@ -325,22 +325,12 @@ function addDidChangeTextDocumentListener(getLS: () => LanguageClient) { } async function addWhereImportsUsedListener(getLS: () => LanguageClient) { - //?? - setTimeout(() => { - window.withProgress( - { location: ProgressLocation.Window, title: 'Updating Imports..' }, - async () => { - const filename = - 'file:///d%3A/gittest/svelte/svelte-webpack-starter1/src/Button3.svelte'; - const editsForFileRename = await getLS().sendRequest( - '$/getFileReferences', - { - filename - } - ); - } - ); - }, 4000); + //dummy test handler + workspace.onWillSaveTextDocument(async (evt) => { + const fileName = evt.document.fileName; + + await getLS().sendRequest('$/getFileReferences', fileName); + }); } function addRenameFileListener(getLS: () => LanguageClient) { From 220a210a36a009776cd92f7c52016a1134777635 Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Tue, 24 May 2022 13:52:51 +0800 Subject: [PATCH 04/16] add command definition --- packages/svelte-vscode/package.json | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/svelte-vscode/package.json b/packages/svelte-vscode/package.json index 72913c504..1ef951867 100644 --- a/packages/svelte-vscode/package.json +++ b/packages/svelte-vscode/package.json @@ -534,6 +534,10 @@ { "command": "svelte.extractComponent", "title": "Svelte: Extract Component" + }, + { + "command": "svelte.typescript.findAllFileReferences", + "title": "Svelte: Find File References" } ], "menus": { @@ -541,6 +545,10 @@ { "command": "svelte.showCompiledCodeToSide", "when": "editorLangId == svelte" + }, + { + "command": "svelte.typescript.findAllFileReferences", + "when": "editorLangId == svelte && resourceScheme == file" } ], "editor/title": [ @@ -550,12 +558,25 @@ "group": "navigation" } ], + "editor/title/context": [ + { + "command": "svelte.typescript.findAllFileReferences", + "when": "resourceLangId == svelte && resourceScheme == file" + } + ], "editor/context": [ { "command": "svelte.extractComponent", "when": "editorLangId == svelte", "group": "1_modification" } + ], + "explorer/context": [ + { + "command": "svelte.typescript.findAllFileReferences", + "when": "resourceLangId == svelte", + "group": "4_search" + } ] }, "breakpoints": [ From 680b1f4ad0afb3dab58ac3186990a7c69d431e83 Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Tue, 24 May 2022 13:55:05 +0800 Subject: [PATCH 05/16] adopt client code from ts extension --- packages/svelte-vscode/src/extension.ts | 13 +--- .../src/typescript/findFileReferences.ts | 67 +++++++++++++++++++ 2 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 packages/svelte-vscode/src/typescript/findFileReferences.ts diff --git a/packages/svelte-vscode/src/extension.ts b/packages/svelte-vscode/src/extension.ts index 29538b93b..1b7eddbcd 100644 --- a/packages/svelte-vscode/src/extension.ts +++ b/packages/svelte-vscode/src/extension.ts @@ -29,6 +29,7 @@ import CompiledCodeContentProvider from './CompiledCodeContentProvider'; import { activateTagClosing } from './html/autoClose'; import { EMPTY_ELEMENTS } from './html/htmlEmptyTagsShared'; import { TsPlugin } from './tsplugin'; +import { addFindFileReferencesListener } from './typescript/findFileReferences'; namespace TagCloseRequest { export const type: RequestType = new RequestType( @@ -223,7 +224,8 @@ export function activateSvelteLanguageServer(context: ExtensionContext) { addDidChangeTextDocumentListener(getLS); - addWhereImportsUsedListener(getLS); + addFindFileReferencesListener(getLS, context); + addRenameFileListener(getLS); addCompilePreviewCommand(getLS, context); @@ -324,15 +326,6 @@ function addDidChangeTextDocumentListener(getLS: () => LanguageClient) { }); } -async function addWhereImportsUsedListener(getLS: () => LanguageClient) { - //dummy test handler - workspace.onWillSaveTextDocument(async (evt) => { - const fileName = evt.document.fileName; - - await getLS().sendRequest('$/getFileReferences', fileName); - }); -} - function addRenameFileListener(getLS: () => LanguageClient) { workspace.onDidRenameFiles(async (evt) => { const oldUri = evt.files[0].oldUri.toString(true); diff --git a/packages/svelte-vscode/src/typescript/findFileReferences.ts b/packages/svelte-vscode/src/typescript/findFileReferences.ts new file mode 100644 index 000000000..08df2b120 --- /dev/null +++ b/packages/svelte-vscode/src/typescript/findFileReferences.ts @@ -0,0 +1,67 @@ +import { + commands, + ExtensionContext, + ProgressLocation, + Uri, + window, + workspace, + Position +} from 'vscode'; +import { LanguageClient } from 'vscode-languageclient/node'; +import { Location as LSLocation } from 'vscode-languageclient'; + +/** + * adopted from https://github.com/microsoft/vscode/blob/5f3e9c120a4407de3e55465588ce788618526eb0/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts + */ +export async function addFindFileReferencesListener( + getLS: () => LanguageClient, + context: ExtensionContext +) { + const disposable = commands.registerCommand('svelte.typescript.findAllFileReferences', handler); + + context.subscriptions.push(disposable); + + async function handler(resource?: Uri) { + if (!resource) { + resource = window.activeTextEditor?.document.uri; + } + + if (!resource || resource.scheme !== 'file') { + return; + } + + const document = await workspace.openTextDocument(resource); + + await window.withProgress( + { + location: ProgressLocation.Window, + title: 'Finding file references' + }, + async (_, token) => { + const locations = await getLS().sendRequest( + '$/getFileReferences', + { uri: document.uri.toString() }, + token + ); + + const config = workspace.getConfiguration('references'); + const existingSetting = config.inspect('preferredLocation'); + + await config.update('preferredLocation', 'view'); + try { + await commands.executeCommand( + 'editor.action.showReferences', + resource, + new Position(0, 0), + locations + ); + } finally { + await config.update( + 'preferredLocation', + existingSetting?.workspaceFolderValue ?? existingSetting?.workspaceValue + ); + } + } + ); + } +} From 9f24111093f8a33566a17698c9c33e012f0504c6 Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Fri, 27 May 2022 16:09:31 -0400 Subject: [PATCH 06/16] Complete round-trip call --- .../language-server/src/plugins/PluginHost.ts | 9 +--- .../language-server/src/plugins/interfaces.ts | 2 +- .../plugins/typescript/TypeScriptPlugin.ts | 4 +- .../features/FindFileReferencesProvider.ts | 49 ++++++++++++------- packages/language-server/src/server.ts | 4 +- .../src/typescript/findFileReferences.ts | 2 +- 6 files changed, 38 insertions(+), 32 deletions(-) diff --git a/packages/language-server/src/plugins/PluginHost.ts b/packages/language-server/src/plugins/PluginHost.ts index ccd6520a3..c763b4441 100644 --- a/packages/language-server/src/plugins/PluginHost.ts +++ b/packages/language-server/src/plugins/PluginHost.ts @@ -389,13 +389,8 @@ export class PluginHost implements LSProvider, OnWatchFileChanges { ); } - async fileReferences(fileName: string): Promise { - return await this.execute( - 'fileReferences', - [fileName], - ExecuteMode.FirstNonNull, - 'high' - ); + async fileReferences(uri: string): Promise { + return await this.execute('fileReferences', [uri], ExecuteMode.FirstNonNull, 'high'); } async getSignatureHelp( diff --git a/packages/language-server/src/plugins/interfaces.ts b/packages/language-server/src/plugins/interfaces.ts index dd173fec4..870acac2c 100644 --- a/packages/language-server/src/plugins/interfaces.ts +++ b/packages/language-server/src/plugins/interfaces.ts @@ -144,7 +144,7 @@ export interface FindReferencesProvider { } export interface FileReferencesProvider { - fileReferences(fileName: string): Promise; + fileReferences(uri: string): Promise; } export interface SignatureHelpProvider { diff --git a/packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts b/packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts index b5d5c681f..62ca1c5c7 100644 --- a/packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts +++ b/packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts @@ -431,12 +431,12 @@ export class TypeScriptPlugin return this.findReferencesProvider.findReferences(document, position, context); } - async fileReferences(fileName: string): Promise { + async fileReferences(uri: string): Promise { if (!this.featureEnabled('fileReferences')) { return null; } - return this.findFileReferencesProvider.fileReferences(fileName); + return this.findFileReferencesProvider.fileReferences(uri); } async onWatchFileChanges(onWatchFileChangesParas: OnWatchFileChangesPara[]): Promise { diff --git a/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts b/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts index 05f67e9dc..64b7ce21d 100644 --- a/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts +++ b/packages/language-server/src/plugins/typescript/features/FindFileReferencesProvider.ts @@ -1,12 +1,21 @@ import { Location } from 'vscode-languageserver'; +import { URI } from 'vscode-uri'; +import { pathToUrl } from '../../../utils'; import { FileReferencesProvider } from '../../interfaces'; import { LSAndTSDocResolver } from '../LSAndTSDocResolver'; +import { convertToLocationRange, hasNonZeroRange } from '../utils'; +import { SnapshotFragmentMap } from './utils'; export class FindFileReferencesProviderImpl implements FileReferencesProvider { constructor(private readonly lsAndTsDocResolver: LSAndTSDocResolver) {} - async fileReferences(fileName: string): Promise { + async fileReferences(uri: string): Promise { + const u = URI.parse(uri); + const fileName = u.fsPath; + const lang = await this.getLSForPath(fileName); + const tsDoc = await this.getSnapshotForPath(fileName); + const fragment = tsDoc.getFragment(); const references = lang.getFileReferences(fileName); @@ -14,27 +23,29 @@ export class FindFileReferencesProviderImpl implements FileReferencesProvider { return null; } - return []; - - // const docs = new SnapshotFragmentMap(this.lsAndTsDocResolver); - // docs.set(tsDoc.filePath, { fragment, snapshot: tsDoc }); - - // const locations = await Promise.all( - // references.map(async (ref) => { - // const defDoc = await docs.retrieveFragment(ref.fileName); - - // return Location.create( - // pathToUrl(ref.fileName), - // convertToLocationRange(defDoc, ref.textSpan) - // ); - // }) - // ); - // // Some references are in generated code but not wrapped with explicit ignore comments. - // // These show up as zero-length ranges, so filter them out. - // return locations.filter(hasNonZeroRange); + const docs = new SnapshotFragmentMap(this.lsAndTsDocResolver); + docs.set(tsDoc.filePath, { fragment, snapshot: tsDoc }); + + const locations = await Promise.all( + references.map(async (ref) => { + const defDoc = await docs.retrieveFragment(ref.fileName); + + return Location.create( + pathToUrl(ref.fileName), + convertToLocationRange(defDoc, ref.textSpan) + ); + }) + ); + // Some references are in generated code but not wrapped with explicit ignore comments. + // These show up as zero-length ranges, so filter them out. + return locations.filter(hasNonZeroRange); } private async getLSForPath(path: string) { return this.lsAndTsDocResolver.getLSForPath(path); } + + private async getSnapshotForPath(path: string) { + return this.lsAndTsDocResolver.getSnapshot(path); + } } diff --git a/packages/language-server/src/server.ts b/packages/language-server/src/server.ts index 5803fabc6..5b62bf611 100644 --- a/packages/language-server/src/server.ts +++ b/packages/language-server/src/server.ts @@ -419,8 +419,8 @@ export function startServer(options?: LSOptions) { pluginHost.updateImports(fileRename) ); - connection.onRequest('$/getFileReferences', async (fileName: string) => { - return pluginHost.fileReferences(fileName); + connection.onRequest('$/getFileReferences', async (uri: string) => { + return pluginHost.fileReferences(uri); }); connection.onRequest('$/getCompiledCode', async (uri: DocumentUri) => { diff --git a/packages/svelte-vscode/src/typescript/findFileReferences.ts b/packages/svelte-vscode/src/typescript/findFileReferences.ts index 08df2b120..dc6a01bf4 100644 --- a/packages/svelte-vscode/src/typescript/findFileReferences.ts +++ b/packages/svelte-vscode/src/typescript/findFileReferences.ts @@ -40,7 +40,7 @@ export async function addFindFileReferencesListener( async (_, token) => { const locations = await getLS().sendRequest( '$/getFileReferences', - { uri: document.uri.toString() }, + document.uri.toString(), token ); From 7f7083d5e08b1682c2655bb47f86bba361e8460b Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sat, 28 May 2022 09:51:38 -0400 Subject: [PATCH 07/16] fix revert --- packages/language-server/src/server.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/language-server/src/server.ts b/packages/language-server/src/server.ts index 5b62bf611..acdd04d67 100644 --- a/packages/language-server/src/server.ts +++ b/packages/language-server/src/server.ts @@ -161,6 +161,9 @@ export function startServer(options?: LSOptions) { ); const clientSupportApplyEditCommand = !!evt.capabilities.workspace?.applyEdit; + const clientCodeActionCapabilities = evt.capabilities.textDocument?.codeAction; + const clientSupportedCodeActionKinds = + clientCodeActionCapabilities?.codeActionLiteralSupport?.codeActionKind.valueSet; return { capabilities: { @@ -207,15 +210,19 @@ export function startServer(options?: LSOptions) { colorProvider: true, documentSymbolProvider: true, definitionProvider: true, - codeActionProvider: evt.capabilities.textDocument?.codeAction - ?.codeActionLiteralSupport + codeActionProvider: clientCodeActionCapabilities?.codeActionLiteralSupport ? { codeActionKinds: [ CodeActionKind.QuickFix, CodeActionKind.SourceOrganizeImports, SORT_IMPORT_CODE_ACTION_KIND, ...(clientSupportApplyEditCommand ? [CodeActionKind.Refactor] : []) - ] + ].filter( + clientSupportedCodeActionKinds && + evt.initializationOptions.shouldFilterCodeActionKind + ? (kind) => clientSupportedCodeActionKinds.includes(kind) + : () => true + ) } : true, executeCommandProvider: clientSupportApplyEditCommand From 43fcd7d5fa21ba8d88fc4dc016dd2c8bee1b352f Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sat, 28 May 2022 10:04:20 -0400 Subject: [PATCH 08/16] fix parsing error --- packages/language-server/src/svelte-check.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/language-server/src/svelte-check.ts b/packages/language-server/src/svelte-check.ts index 70a04220b..82e3b91ce 100644 --- a/packages/language-server/src/svelte-check.ts +++ b/packages/language-server/src/svelte-check.ts @@ -171,7 +171,7 @@ export class SvelteCheck { // doesn't apply to all code paths. That's why we do it here, too. const skipDiagnosticsForFile = (options.skipLibCheck && file.isDeclarationFile) || - (options.skipDefaultLibCheck && file.hasNoDefaultLib || + (options.skipDefaultLibCheck && file.hasNoDefaultLib) || // ignore JS files in node_modules /\/node_modules\/.+\.(c|m)?js$/.test(file.fileName); From 19e6edb0d9ef1d275e420eae523a3d39369d0583 Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sun, 29 May 2022 09:10:03 -0400 Subject: [PATCH 09/16] Convert to vscode locations --- .../src/typescript/findFileReferences.ts | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/svelte-vscode/src/typescript/findFileReferences.ts b/packages/svelte-vscode/src/typescript/findFileReferences.ts index dc6a01bf4..69da5ad6d 100644 --- a/packages/svelte-vscode/src/typescript/findFileReferences.ts +++ b/packages/svelte-vscode/src/typescript/findFileReferences.ts @@ -5,7 +5,9 @@ import { Uri, window, workspace, - Position + Position, + Location, + Range } from 'vscode'; import { LanguageClient } from 'vscode-languageclient/node'; import { Location as LSLocation } from 'vscode-languageclient'; @@ -38,12 +40,16 @@ export async function addFindFileReferencesListener( title: 'Finding file references' }, async (_, token) => { - const locations = await getLS().sendRequest( + const lsLocations = await getLS().sendRequest( '$/getFileReferences', document.uri.toString(), token ); + if (!lsLocations) { + return; + } + const config = workspace.getConfiguration('references'); const existingSetting = config.inspect('preferredLocation'); @@ -53,7 +59,18 @@ export async function addFindFileReferencesListener( 'editor.action.showReferences', resource, new Position(0, 0), - locations + lsLocations.map( + (ref) => + new Location( + Uri.parse(ref.uri), + new Range( + ref.range.start.line, + ref.range.start.character, + ref.range.end.line, + ref.range.end.character + ) + ) + ) ); } finally { await config.update( From 8e040e4dc39d03bf58d959add5ac42f8fc4bc91b Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sun, 29 May 2022 09:29:23 -0400 Subject: [PATCH 10/16] Add Find File References to menu inside editor --- packages/svelte-vscode/package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/svelte-vscode/package.json b/packages/svelte-vscode/package.json index 1ef951867..6ddcbcdb4 100644 --- a/packages/svelte-vscode/package.json +++ b/packages/svelte-vscode/package.json @@ -569,6 +569,11 @@ "command": "svelte.extractComponent", "when": "editorLangId == svelte", "group": "1_modification" + }, + { + "command": "svelte.typescript.findAllFileReferences", + "when": "editorLangId == svelte", + "group": "1_modification" } ], "explorer/context": [ From ee210770183ee58f65a96f795a9931e4734acc74 Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sun, 29 May 2022 13:55:29 -0400 Subject: [PATCH 11/16] move to 4_search group --- packages/svelte-vscode/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte-vscode/package.json b/packages/svelte-vscode/package.json index 6ddcbcdb4..d57b54ec1 100644 --- a/packages/svelte-vscode/package.json +++ b/packages/svelte-vscode/package.json @@ -573,7 +573,7 @@ { "command": "svelte.typescript.findAllFileReferences", "when": "editorLangId == svelte", - "group": "1_modification" + "group": "4_search" } ], "explorer/context": [ From a01898d6b56859174c89cf2b3bba7c6eab2753fa Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sun, 29 May 2022 16:07:39 -0400 Subject: [PATCH 12/16] whitespace formatting --- packages/svelte-vscode/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/svelte-vscode/package.json b/packages/svelte-vscode/package.json index d57b54ec1..e3fb79c4d 100644 --- a/packages/svelte-vscode/package.json +++ b/packages/svelte-vscode/package.json @@ -578,9 +578,9 @@ ], "explorer/context": [ { - "command": "svelte.typescript.findAllFileReferences", - "when": "resourceLangId == svelte", - "group": "4_search" + "command": "svelte.typescript.findAllFileReferences", + "when": "resourceLangId == svelte", + "group": "4_search" } ] }, From 0aded87a1f566c61490c71dd7e3d01b44581a08a Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sun, 29 May 2022 21:55:20 -0400 Subject: [PATCH 13/16] initial test --- packages/language-server/package.json | 1 + .../FindFileReferencesProvider.test.ts | 68 +++++++++++++++++++ .../find-file-references-child.svelte | 6 ++ .../find-file-references-parent.svelte | 10 +++ 4 files changed, 85 insertions(+) create mode 100644 packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts create mode 100644 packages/language-server/test/plugins/typescript/testfiles/find-file-references-child.svelte create mode 100644 packages/language-server/test/plugins/typescript/testfiles/find-file-references-parent.svelte diff --git a/packages/language-server/package.json b/packages/language-server/package.json index 0ec222701..0bebab364 100644 --- a/packages/language-server/package.json +++ b/packages/language-server/package.json @@ -6,6 +6,7 @@ "typings": "dist/src/index", "scripts": { "test": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register \"test/**/*.ts\" --exclude \"test/**/*.d.ts\"", + "test2": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register \"test/**/FindFileReferencesProvider.test.ts\" --exclude \"test/**/*.d.ts\"", "build": "tsc", "prepublishOnly": "npm run build", "watch": "tsc -w" diff --git a/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts b/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts new file mode 100644 index 000000000..a79835c51 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts @@ -0,0 +1,68 @@ +import * as assert from 'assert'; +import * as path from 'path'; +import ts from 'typescript'; +import { Location, Position, Range } from 'vscode-languageserver'; +import { Document, DocumentManager } from '../../../../src/lib/documents'; +import { LSConfigManager } from '../../../../src/ls-config'; +import { FindFileReferencesProviderImpl } from '../../../../src/plugins/typescript/features/FindFileReferencesProvider'; +import { LSAndTSDocResolver } from '../../../../src/plugins/typescript/LSAndTSDocResolver'; +import { pathToUrl } from '../../../../src/utils'; + +const testDir = path.join(__dirname, '..'); + +function test(useNewTransformation: boolean) { + return () => { + function getFullPath(filename: string) { + return path.join(testDir, 'testfiles', filename); + } + function getUri(filename: string) { + const filePath = path.join(testDir, 'testfiles', filename); + return pathToUrl(filePath); + } + + function setup(filename: string) { + const docManager = new DocumentManager( + (textDocument) => new Document(textDocument.uri, textDocument.text) + ); + const lsConfigManager = new LSConfigManager(); + lsConfigManager.update({ svelte: { useNewTransformation } }); + const lsAndTsDocResolver = new LSAndTSDocResolver( + docManager, + [testDir], + lsConfigManager + ); + const provider = new FindFileReferencesProviderImpl(lsAndTsDocResolver); + const document = openDoc(filename); + return { provider, document }; + + function openDoc(filename: string) { + const filePath = getFullPath(filename); + const doc = docManager.openDocument({ + uri: pathToUrl(filePath), + text: ts.sys.readFile(filePath) || '' + }); + return doc; + } + } + + async function test() { + const { provider, document } = setup('find-file-references-child.svelte'); + + const results = await provider.fileReferences(document.uri.toString()); + const expectedResults = [ + Location.create( + getUri('find-file-references-parent.svelte'), + Range.create(Position.create(1, 37), Position.create(1, 72)) + ) + ]; + + assert.deepStrictEqual(results, expectedResults); + } + + it('finds file references', async () => { + await test(); + }); + }; +} + +describe('FindFileReferencesProvider', test(true)); diff --git a/packages/language-server/test/plugins/typescript/testfiles/find-file-references-child.svelte b/packages/language-server/test/plugins/typescript/testfiles/find-file-references-child.svelte new file mode 100644 index 000000000..d4379fc66 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/testfiles/find-file-references-child.svelte @@ -0,0 +1,6 @@ + diff --git a/packages/language-server/test/plugins/typescript/testfiles/find-file-references-parent.svelte b/packages/language-server/test/plugins/typescript/testfiles/find-file-references-parent.svelte new file mode 100644 index 000000000..0be8aab96 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/testfiles/find-file-references-parent.svelte @@ -0,0 +1,10 @@ + + + From bdeb6bad207f74784120bf50baf821ba4d3edb9a Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sun, 29 May 2022 23:00:56 -0400 Subject: [PATCH 14/16] Make known all test files --- .../typescript/features/FindFileReferencesProvider.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts b/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts index a79835c51..6129f275f 100644 --- a/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts @@ -47,6 +47,7 @@ function test(useNewTransformation: boolean) { async function test() { const { provider, document } = setup('find-file-references-child.svelte'); + loadAssociatedFiles(); const results = await provider.fileReferences(document.uri.toString()); const expectedResults = [ @@ -59,6 +60,11 @@ function test(useNewTransformation: boolean) { assert.deepStrictEqual(results, expectedResults); } + //Make known all the associated files + function loadAssociatedFiles() { + setup('find-file-references-parent.svelte'); + } + it('finds file references', async () => { await test(); }); From 277f1e072843d269b917b2004bc20dac0c64fc90 Mon Sep 17 00:00:00 2001 From: Jojoshua Date: Sun, 29 May 2022 23:31:06 -0400 Subject: [PATCH 15/16] remove test script --- packages/language-server/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/language-server/package.json b/packages/language-server/package.json index 0bebab364..0ec222701 100644 --- a/packages/language-server/package.json +++ b/packages/language-server/package.json @@ -6,7 +6,6 @@ "typings": "dist/src/index", "scripts": { "test": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register \"test/**/*.ts\" --exclude \"test/**/*.d.ts\"", - "test2": "cross-env TS_NODE_TRANSPILE_ONLY=true mocha --require ts-node/register \"test/**/FindFileReferencesProvider.test.ts\" --exclude \"test/**/*.d.ts\"", "build": "tsc", "prepublishOnly": "npm run build", "watch": "tsc -w" From b7c9cd7f57de949d103cbca194db3d6bf56b35ab Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 30 May 2022 08:31:15 +0200 Subject: [PATCH 16/16] simplify test --- .../FindFileReferencesProvider.test.ts | 101 ++++++++---------- 1 file changed, 42 insertions(+), 59 deletions(-) diff --git a/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts b/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts index 6129f275f..fe7dde00f 100644 --- a/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/FindFileReferencesProvider.test.ts @@ -10,65 +10,48 @@ import { pathToUrl } from '../../../../src/utils'; const testDir = path.join(__dirname, '..'); -function test(useNewTransformation: boolean) { - return () => { - function getFullPath(filename: string) { - return path.join(testDir, 'testfiles', filename); - } - function getUri(filename: string) { - const filePath = path.join(testDir, 'testfiles', filename); - return pathToUrl(filePath); - } - - function setup(filename: string) { - const docManager = new DocumentManager( - (textDocument) => new Document(textDocument.uri, textDocument.text) - ); - const lsConfigManager = new LSConfigManager(); - lsConfigManager.update({ svelte: { useNewTransformation } }); - const lsAndTsDocResolver = new LSAndTSDocResolver( - docManager, - [testDir], - lsConfigManager - ); - const provider = new FindFileReferencesProviderImpl(lsAndTsDocResolver); - const document = openDoc(filename); - return { provider, document }; - - function openDoc(filename: string) { - const filePath = getFullPath(filename); - const doc = docManager.openDocument({ - uri: pathToUrl(filePath), - text: ts.sys.readFile(filePath) || '' - }); - return doc; - } - } - - async function test() { - const { provider, document } = setup('find-file-references-child.svelte'); - loadAssociatedFiles(); - - const results = await provider.fileReferences(document.uri.toString()); - const expectedResults = [ - Location.create( - getUri('find-file-references-parent.svelte'), - Range.create(Position.create(1, 37), Position.create(1, 72)) - ) - ]; - - assert.deepStrictEqual(results, expectedResults); +describe('FindFileReferencesProvider', () => { + function getFullPath(filename: string) { + return path.join(testDir, 'testfiles', filename); + } + function getUri(filename: string) { + const filePath = path.join(testDir, 'testfiles', filename); + return pathToUrl(filePath); + } + + function setup(filename: string) { + const docManager = new DocumentManager( + (textDocument) => new Document(textDocument.uri, textDocument.text) + ); + const lsConfigManager = new LSConfigManager(); + const lsAndTsDocResolver = new LSAndTSDocResolver(docManager, [testDir], lsConfigManager); + const provider = new FindFileReferencesProviderImpl(lsAndTsDocResolver); + const document = openDoc(filename); + return { provider, document, openDoc }; + + function openDoc(filename: string) { + const filePath = getFullPath(filename); + const doc = docManager.openDocument({ + uri: pathToUrl(filePath), + text: ts.sys.readFile(filePath) || '' + }); + return doc; } + } + it('finds file references', async () => { + const { provider, document, openDoc } = setup('find-file-references-child.svelte'); //Make known all the associated files - function loadAssociatedFiles() { - setup('find-file-references-parent.svelte'); - } - - it('finds file references', async () => { - await test(); - }); - }; -} - -describe('FindFileReferencesProvider', test(true)); + openDoc('find-file-references-parent.svelte'); + + const results = await provider.fileReferences(document.uri.toString()); + const expectedResults = [ + Location.create( + getUri('find-file-references-parent.svelte'), + Range.create(Position.create(1, 37), Position.create(1, 72)) + ) + ]; + + assert.deepStrictEqual(results, expectedResults); + }); +});