Skip to content

Commit 49d341d

Browse files
authored
Feature proposal: Navigate to class declaration (#2132)
Signed-off-by: Frederik Claus <[email protected]>
1 parent 083f580 commit 49d341d

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/commands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,6 @@ export namespace Commands {
244244
export const MEATDATA_FILES_GENERATION = '_java.metadataFilesGeneration';
245245

246246
export const RUNTIME_VALIDATION_OPEN = 'java.runtimeValidation.open';
247+
248+
export const RESOLVE_WORKSPACE_SYMBOL = 'java.project.resolveWorkspaceSymbol';
247249
}

src/providerDispatcher.ts

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
'use strict';
22

3-
import { DocumentSymbolRequest, SymbolInformation as clientSymbolInformation, DocumentSymbol as clientDocumentSymbol, HoverRequest } from "vscode-languageclient";
3+
import { DocumentSymbolRequest, SymbolInformation as clientSymbolInformation, DocumentSymbol as clientDocumentSymbol, HoverRequest, WorkspaceSymbolRequest } from "vscode-languageclient";
44
import { LanguageClient } from "vscode-languageclient/node";
5-
import { ExtensionContext, languages, DocumentSymbolProvider, TextDocument, CancellationToken, SymbolInformation, DocumentSymbol, TextDocumentContentProvider, workspace, Uri, Event, HoverProvider, Position, Hover } from "vscode";
6-
import { ClassFileContentsRequest } from "./protocol";
5+
import { ExtensionContext, languages, DocumentSymbolProvider, TextDocument, CancellationToken, SymbolInformation, DocumentSymbol, TextDocumentContentProvider, workspace, Uri, Event, HoverProvider, Position, Hover, WorkspaceSymbolProvider, Range, commands, SymbolKind } from "vscode";
6+
import { ClassFileContentsRequest, StatusNotification } from "./protocol";
77
import { createClientHoverProvider } from "./hoverAction";
88
import { getActiveLanguageClient } from "./extension";
99
import { apiManager } from "./apiManager";
1010
import { ServerMode } from "./settings";
11+
import { serverStatus, ServerStatusKind } from "./serverStatus";
12+
import { Commands } from "./commands";
1113

1214
export interface ProviderOptions {
1315
contentProviderEvent: Event<Uri>;
@@ -26,6 +28,9 @@ export function registerClientProviders(context: ExtensionContext, options: Prov
2628

2729
const jdtProvider = createJDTContentProvider(options);
2830
context.subscriptions.push(workspace.registerTextDocumentContentProvider('jdt', jdtProvider));
31+
32+
overwriteWorkspaceSymbolProvider(context);
33+
2934
return {
3035
handles: [hoverProvider, symbolProvider, jdtProvider]
3136
};
@@ -100,3 +105,50 @@ function createDocumentSymbolProvider(): DocumentSymbolProvider {
100105
}
101106
};
102107
}
108+
109+
const START_OF_DOCUMENT = new Range(new Position(0, 0), new Position(0, 0));
110+
111+
function createWorkspaceSymbolProvider(existingWorkspaceSymbolProvider: WorkspaceSymbolProvider): WorkspaceSymbolProvider {
112+
return {
113+
provideWorkspaceSymbols: existingWorkspaceSymbolProvider.provideWorkspaceSymbols,
114+
resolveWorkspaceSymbol: async (symbol: SymbolInformation, token: CancellationToken): Promise<SymbolInformation> => {
115+
const range = symbol.location.range;
116+
if (range && !range.isEqual(START_OF_DOCUMENT)) {
117+
return symbol;
118+
}
119+
120+
const languageClient = await getActiveLanguageClient();
121+
const serializableSymbol = {
122+
name: symbol.name,
123+
// Cannot serialize SymbolKind as number, because GSON + lsp4j.SymbolKind expect a name.
124+
kind: SymbolKind[symbol.kind],
125+
location: {
126+
uri: languageClient.code2ProtocolConverter.asUri(symbol.location.uri),
127+
range: languageClient.code2ProtocolConverter.asRange(symbol.location.range)
128+
},
129+
containerName: symbol.containerName
130+
};
131+
132+
const response = await commands.executeCommand(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.RESOLVE_WORKSPACE_SYMBOL, JSON.stringify(serializableSymbol));
133+
if (token.isCancellationRequested) {
134+
return undefined;
135+
}
136+
return languageClient.protocol2CodeConverter.asSymbolInformation(response as clientSymbolInformation);
137+
}
138+
};
139+
}
140+
141+
function overwriteWorkspaceSymbolProvider(context: ExtensionContext): void {
142+
const disposable = apiManager.getApiInstance().onDidServerModeChange( async (mode) => {
143+
if (mode === ServerMode.STANDARD) {
144+
const feature = (await getActiveLanguageClient()).getFeature(WorkspaceSymbolRequest.method);
145+
const providers = feature.getProviders();
146+
if (providers && providers.length > 0) {
147+
feature.dispose();
148+
const workspaceSymbolProvider = createWorkspaceSymbolProvider(providers[0]);
149+
context.subscriptions.push(languages.registerWorkspaceSymbolProvider(workspaceSymbolProvider));
150+
disposable.dispose();
151+
}
152+
}
153+
});
154+
}

0 commit comments

Comments
 (0)