提交 b565c422 编写于 作者: M Matt Bierner

Add find all references command for JS/TS

Fixes #66150
上级 0f9ee988
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
"onCommand:workbench.action.tasks.runTask", "onCommand:workbench.action.tasks.runTask",
"onCommand:_typescript.configurePlugin", "onCommand:_typescript.configurePlugin",
"onCommand:_typescript.learnMoreAboutRefactorings", "onCommand:_typescript.learnMoreAboutRefactorings",
"onCommand:typescript.fileReferences",
"onLanguage:jsonc" "onLanguage:jsonc"
], ],
"main": "./out/extension", "main": "./out/extension",
...@@ -961,6 +962,11 @@ ...@@ -961,6 +962,11 @@
"command": "typescript.restartTsServer", "command": "typescript.restartTsServer",
"title": "%typescript.restartTsServer%", "title": "%typescript.restartTsServer%",
"category": "TypeScript" "category": "TypeScript"
},
{
"command": "typescript.findAllFileReferences",
"title": "%typescript.findAllFileReferences%",
"category": "TypeScript"
} }
], ],
"menus": { "menus": {
...@@ -1008,6 +1014,46 @@ ...@@ -1008,6 +1014,46 @@
{ {
"command": "typescript.restartTsServer", "command": "typescript.restartTsServer",
"when": "typescript.isManagedFile" "when": "typescript.isManagedFile"
},
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && typescript.isManagedFile"
}
],
"explorer/context": [
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && resourceLangId == javascript"
},
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && resourceLangId == javascriptreact"
},
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && resourceLangId == typescript"
},
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && resourceLangId == typescriptreact"
}
],
"editor/title/context": [
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && resourceLangId == javascript"
},
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && resourceLangId == javascriptreact"
},
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && resourceLangId == typescript"
},
{
"command": "typescript.findAllFileReferences",
"when": "tsSupportsFileReferences && resourceLangId == typescriptreact"
} }
] ]
}, },
......
...@@ -135,5 +135,6 @@ ...@@ -135,5 +135,6 @@
"codeActions.refactor.rewrite.parameters.toDestructured.title": "Convert parameters to destructured object", "codeActions.refactor.rewrite.parameters.toDestructured.title": "Convert parameters to destructured object",
"codeActions.refactor.rewrite.property.generateAccessors.title": "Generate accessors", "codeActions.refactor.rewrite.property.generateAccessors.title": "Generate accessors",
"codeActions.refactor.rewrite.property.generateAccessors.description": "Generate 'get' and 'set' accessors", "codeActions.refactor.rewrite.property.generateAccessors.description": "Generate 'get' and 'set' accessors",
"codeActions.source.organizeImports.title": "Organize imports" "codeActions.source.organizeImports.title": "Organize imports",
"typescript.findAllFileReferences": "Find File References"
} }
/*---------------------------------------------------------------------------------------------
* 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 * as nls from 'vscode-nls';
import { Command, CommandManager } from '../commands/commandManager';
import { ITypeScriptServiceClient } from '../typescriptService';
import API from '../utils/api';
import { isSupportedLanguageMode } from '../utils/languageModeIds';
import * as typeConverters from '../utils/typeConverters';
const localize = nls.loadMessageBundle();
class FileReferencesCommand implements Command {
public static readonly context = 'tsSupportsFileReferences';
public static readonly minVersion = API.v420;
public readonly id = 'typescript.findAllFileReferences';
public constructor(
private readonly client: ITypeScriptServiceClient
) { }
public async execute(resource?: vscode.Uri) {
if (this.client.apiVersion.lt(FileReferencesCommand.minVersion)) {
vscode.window.showErrorMessage(localize('error.unsupportedVersion', "Find file references failed. Requires TypeScript 4.2+."));
return;
}
if (!resource) {
resource = vscode.window.activeTextEditor?.document.uri;
}
if (!resource) {
vscode.window.showErrorMessage(localize('error.noResource', "Find file references failed. No resource provided."));
return;
}
const document = await vscode.workspace.openTextDocument(resource);
if (!isSupportedLanguageMode(document)) {
vscode.window.showErrorMessage(localize('error.unsupportedLanguage', "Find file references failed. Unsupported file type."));
return;
}
const openedFiledPath = this.client.toOpenedFilePath(document);
if (!openedFiledPath) {
vscode.window.showErrorMessage(localize('error.unknownFile', "Find file references failed. Unknown file type."));
return;
}
await vscode.window.withProgress({
location: vscode.ProgressLocation.Window,
title: localize('progress.title', "Finding file references")
}, async (_progress, token) => {
const response = await this.client.execute('fileReferences', {
file: openedFiledPath
}, token);
if (response.type !== 'response' || !response.body) {
return;
}
const locations: vscode.Location[] = response.body.refs.map(reference =>
typeConverters.Location.fromTextSpan(this.client.toResource(reference.file), reference));
const config = vscode.workspace.getConfiguration('references');
const existingSetting = config.get('preferredLocation', undefined);
await config.update('preferredLocation', 'view');
try {
await vscode.commands.executeCommand('editor.action.showReferences', resource, new vscode.Position(0, 0), locations);
} finally {
await config.update('preferredLocation', existingSetting);
}
});
}
}
export function register(
client: ITypeScriptServiceClient,
commandManager: CommandManager
) {
function updateContext() {
vscode.commands.executeCommand('setContext', FileReferencesCommand.context, client.apiVersion.gte(FileReferencesCommand.minVersion));
}
updateContext();
commandManager.register(new FileReferencesCommand(client));
return client.onTsServerStarted(() => updateContext());
}
...@@ -63,6 +63,7 @@ export default class LanguageProvider extends Disposable { ...@@ -63,6 +63,7 @@ export default class LanguageProvider extends Disposable {
import('./languageFeatures/directiveCommentCompletions').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/directiveCommentCompletions').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/documentHighlight').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/documentHighlight').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/documentSymbol').then(provider => this._register(provider.register(selector, this.client, cachedResponse))), import('./languageFeatures/documentSymbol').then(provider => this._register(provider.register(selector, this.client, cachedResponse))),
import('./languageFeatures/fileReferences').then(provider => this._register(provider.register(this.client, this.commandManager))),
import('./languageFeatures/folding').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/folding').then(provider => this._register(provider.register(selector, this.client))),
import('./languageFeatures/formatting').then(provider => this._register(provider.register(selector, this.description.id, this.client, this.fileConfigurationManager))), import('./languageFeatures/formatting').then(provider => this._register(provider.register(selector, this.description.id, this.client, this.fileConfigurationManager))),
import('./languageFeatures/hover').then(provider => this._register(provider.register(selector, this.client))), import('./languageFeatures/hover').then(provider => this._register(provider.register(selector, this.client))),
......
...@@ -9,4 +9,22 @@ declare module 'typescript/lib/protocol' { ...@@ -9,4 +9,22 @@ declare module 'typescript/lib/protocol' {
interface Response { interface Response {
readonly _serverType?: ServerType; readonly _serverType?: ServerType;
} }
interface FileReferencesRequest extends FileRequest {
command: CommandTypes.FileReferences;
}
interface FileReferencesResponseBody {
/**
* The file locations referencing the symbol.
*/
refs: readonly ReferencesResponseItem[];
/**
* The name of the symbol.
*/
symbolName: string;
}
interface FileReferencesResponse extends Response {
body?: FileReferencesResponseBody;
}
} }
...@@ -68,6 +68,7 @@ interface StandardTsServerRequests { ...@@ -68,6 +68,7 @@ interface StandardTsServerRequests {
'prepareCallHierarchy': [Proto.FileLocationRequestArgs, Proto.PrepareCallHierarchyResponse]; 'prepareCallHierarchy': [Proto.FileLocationRequestArgs, Proto.PrepareCallHierarchyResponse];
'provideCallHierarchyIncomingCalls': [Proto.FileLocationRequestArgs, Proto.ProvideCallHierarchyIncomingCallsResponse]; 'provideCallHierarchyIncomingCalls': [Proto.FileLocationRequestArgs, Proto.ProvideCallHierarchyIncomingCallsResponse];
'provideCallHierarchyOutgoingCalls': [Proto.FileLocationRequestArgs, Proto.ProvideCallHierarchyOutgoingCallsResponse]; 'provideCallHierarchyOutgoingCalls': [Proto.FileLocationRequestArgs, Proto.ProvideCallHierarchyOutgoingCallsResponse];
'fileReferences': [Proto.FileRequestArgs, Proto.FileReferencesResponse];
} }
interface NoResponseTsServerRequests { interface NoResponseTsServerRequests {
......
...@@ -34,6 +34,7 @@ export default class API { ...@@ -34,6 +34,7 @@ export default class API {
public static readonly v390 = API.fromSimpleString('3.9.0'); public static readonly v390 = API.fromSimpleString('3.9.0');
public static readonly v400 = API.fromSimpleString('4.0.0'); public static readonly v400 = API.fromSimpleString('4.0.0');
public static readonly v401 = API.fromSimpleString('4.0.1'); public static readonly v401 = API.fromSimpleString('4.0.1');
public static readonly v420 = API.fromSimpleString('4.2.0');
public static fromVersionString(versionString: string): API { public static fromVersionString(versionString: string): API {
let version = semver.valid(versionString); let version = semver.valid(versionString);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册