Skip to content

Commit 16c88a5

Browse files
committed
Support vscode TypeHierarchy API (references-view)
This change introduces support for vscode Typehierarchy API and integrates the solution with the facilities provided by the references-view extension. E.g. via the implementation of the commands `vscode.prepareTypeHierarchy`, `vscode.provideSupertypes`, `vscode.provideSupertypes` The `Show Type Hierarchy` context menu shall be enabled from an editor as long as a TypeHIerarchyProvider is registered for the specific language. Similarly the following commands shall now be functional from the command palette. `Types: Show Type Hierarchy` `Types: Show Subtypes` `Types: Show Supertypes` Signed-off-by: Alvaro Sanchez-Leon <[email protected]>
1 parent 7f51450 commit 16c88a5

24 files changed

+916
-237
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
generating the main code bundle (as before), the second serves to generate a *.css file for inclusion into `secondaryWindow.html` [#11707](https://github.com/eclipse-theia/theia/pull/11707)
1616
- [plugin-ext] `when` clauses removed from `codeToTheiaMappings` [#11741](https://github.com/eclipse-theia/theia/pull/#11741)
1717
- [terminal] The `AbstractCmdClickTerminalContribution` API has been removed in favor of the `TerminalLinkProvider` interface [#11552](https://github.com/eclipse-theia/theia/pull/11552) - Contributed on behalf of STMicroelectronics
18+
- [typehierarchy] - Adding Support of vscode TypeHierarchy API with the following breaking changes: [#11694](https://github.com/eclipse-theia/theia/pull/11694)
19+
- [plugin-ext/main] The file `callhierarchy-type-converters.ts` was renamed to `hierarchy-types-converters.ts`
20+
- The method `toDefinition` was renamed to `toItemHierarchyDefinition` and the overloaded signatures were removed.
21+
- The method `fromDefinition` was replaced for `fromItemHierarchyDefinition` to convert both `TypeHierarchyItem` and `CallHierarchyItem` to a common `HierarchyItem`.
22+
- [plugin-ext/plugin] - `thype-converters.ts #fromCallHierarchyItem` was replaced by `fromHierarchyItem` to convert from `CallHierarchyItem` or `TypeHierarchyItem` to `HierarchyItem`.
1823

1924
## v1.30.0 - 9/29/2022
2025

packages/plugin-ext-vscode/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"@theia/plugin": "1.30.0",
1414
"@theia/plugin-ext": "1.30.0",
1515
"@theia/terminal": "1.30.0",
16+
"@theia/typehierarchy": "1.30.0",
1617
"@theia/userstorage": "1.30.0",
1718
"@theia/workspace": "1.30.0",
1819
"@types/request": "^2.0.3",

packages/plugin-ext-vscode/src/browser/plugin-vscode-commands-contribution.ts

+78-9
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
CallHierarchyItem,
3838
CallHierarchyIncomingCall,
3939
CallHierarchyOutgoingCall,
40+
TypeHierarchyItem,
4041
Hover,
4142
TextEdit,
4243
FormattingOptions,
@@ -64,13 +65,14 @@ import { SelectableTreeNode } from '@theia/core/lib/browser/tree/tree-selection'
6465
import { UriComponents } from '@theia/plugin-ext/lib/common/uri-components';
6566
import { FileService } from '@theia/filesystem/lib/browser/file-service';
6667
import { CallHierarchyServiceProvider, CallHierarchyService } from '@theia/callhierarchy/lib/browser';
68+
import { TypeHierarchyServiceProvider, TypeHierarchyService } from '@theia/typehierarchy/lib/browser';
6769
import { MonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
6870
import {
6971
fromCallHierarchyCalleeToModelCallHierarchyOutgoingCall,
7072
fromCallHierarchyCallerToModelCallHierarchyIncomingCall,
71-
fromDefinition,
72-
toDefinition
73-
} from '@theia/plugin-ext/lib/main/browser/callhierarchy/callhierarchy-type-converters';
73+
fromItemHierarchyDefinition,
74+
toItemHierarchyDefinition
75+
} from '@theia/plugin-ext/lib/main/browser/hierarchy/hierarchy-types-converters';
7476
import { CustomEditorOpener } from '@theia/plugin-ext/lib/main/browser/custom-editors/custom-editor-opener';
7577
import { nls } from '@theia/core/lib/common/nls';
7678
import { WindowService } from '@theia/core/lib/browser/window/window-service';
@@ -170,6 +172,8 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
170172
protected readonly fileService: FileService;
171173
@inject(CallHierarchyServiceProvider)
172174
protected readonly callHierarchyProvider: CallHierarchyServiceProvider;
175+
@inject(TypeHierarchyServiceProvider)
176+
protected readonly typeHierarchyProvider: TypeHierarchyServiceProvider;
173177
@inject(MonacoTextModelService)
174178
protected readonly textModelService: MonacoTextModelService;
175179
@inject(WindowService)
@@ -642,7 +646,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
642646
new CancellationTokenSource().token
643647
);
644648
if (definition) {
645-
return definition.items.map(item => fromDefinition(item));
649+
return definition.items.map(item => fromItemHierarchyDefinition(item));
646650
};
647651
return [];
648652
}
@@ -657,7 +661,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
657661
const resource = URI.from(item.uri);
658662
const provider = await this.getCallHierarchyServiceForUri(resource);
659663
const incomingCalls = await provider?.getCallers(
660-
toDefinition(item),
664+
toItemHierarchyDefinition(item),
661665
new CancellationTokenSource().token,
662666
);
663667
if (incomingCalls) {
@@ -676,7 +680,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
676680
const resource = URI.from(item.uri);
677681
const provider = await this.getCallHierarchyServiceForUri(resource);
678682
const outgoingCalls = await provider?.getCallees?.(
679-
toDefinition(item),
683+
toItemHierarchyDefinition(item),
680684
new CancellationTokenSource().token,
681685
);
682686
if (outgoingCalls) {
@@ -686,6 +690,62 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
686690
}
687691
}
688692
);
693+
commands.registerCommand(
694+
{
695+
id: 'vscode.prepareTypeHierarchy'
696+
},
697+
{
698+
execute: async (resource: URI, position: Position): Promise<TypeHierarchyItem[]> => {
699+
const provider = await this.getTypeHierarchyServiceForUri(resource);
700+
const session = await provider?.prepareSession(
701+
resource.path,
702+
toPosition(position),
703+
new CancellationTokenSource().token
704+
);
705+
return session ? session.items.map(item => fromItemHierarchyDefinition(item)) : [];
706+
}
707+
}
708+
);
709+
commands.registerCommand(
710+
{
711+
id: 'vscode.provideSupertypes'
712+
},
713+
{
714+
execute: async (item: TypeHierarchyItem): Promise<TypeHierarchyItem[]> => {
715+
if (!item._sessionId || !item._itemId) {
716+
return [];
717+
}
718+
const resource = URI.from(item.uri);
719+
const provider = await this.getTypeHierarchyServiceForUri(resource);
720+
const items = await provider?.provideSuperTypes(
721+
item._sessionId,
722+
item._itemId,
723+
new CancellationTokenSource().token
724+
);
725+
return (items ? items : []).map(typeItem => fromItemHierarchyDefinition(typeItem));
726+
}
727+
}
728+
);
729+
commands.registerCommand(
730+
{
731+
id: 'vscode.provideSubtypes'
732+
},
733+
{
734+
execute: async (item: TypeHierarchyItem): Promise<TypeHierarchyItem[]> => {
735+
if (!item._sessionId || !item._itemId) {
736+
return [];
737+
}
738+
const resource = URI.from(item.uri);
739+
const provider = await this.getTypeHierarchyServiceForUri(resource);
740+
const items = await provider?.provideSubTypes(
741+
item._sessionId, item._itemId,
742+
new CancellationTokenSource().token
743+
);
744+
return (items ? items : []).map(typeItem => fromItemHierarchyDefinition(typeItem));
745+
746+
}
747+
}
748+
);
689749

690750
commands.registerCommand({
691751
id: 'workbench.action.openRecent'
@@ -845,11 +905,20 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
845905
});
846906
}
847907

848-
protected async getCallHierarchyServiceForUri(resource: URI): Promise<CallHierarchyService | undefined> {
908+
private async resolveLanguageId(resource: URI): Promise<string> {
849909
const reference = await this.textModelService.createModelReference(resource);
850-
const uri = new TheiaURI(resource);
851910
const languageId = reference.object.languageId;
852911
reference.dispose();
853-
return this.callHierarchyProvider.get(languageId, uri);
912+
return languageId;
913+
}
914+
915+
protected async getCallHierarchyServiceForUri(resource: URI): Promise<CallHierarchyService | undefined> {
916+
const languageId = await this.resolveLanguageId(resource);
917+
return this.callHierarchyProvider.get(languageId, new TheiaURI(resource));
918+
}
919+
920+
protected async getTypeHierarchyServiceForUri(resource: URI): Promise<TypeHierarchyService | undefined> {
921+
const languageId = await this.resolveLanguageId(resource);
922+
return this.typeHierarchyProvider.get(languageId, new TheiaURI(resource));
854923
}
855924
}

packages/plugin-ext-vscode/tsconfig.json

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
{
4242
"path": "../terminal"
4343
},
44+
{
45+
"path": "../typehierarchy"
46+
},
4447
{
4548
"path": "../userstorage"
4649
},

packages/plugin-ext/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@theia/task": "1.30.0",
2727
"@theia/terminal": "1.30.0",
2828
"@theia/timeline": "1.30.0",
29+
"@theia/typehierarchy": "1.30.0",
2930
"@theia/variable-resolver": "1.30.0",
3031
"@theia/workspace": "1.30.0",
3132
"@types/mime": "^2.0.1",

packages/plugin-ext/src/common/plugin-api-rpc-model.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -565,17 +565,22 @@ export interface RenameLocation {
565565
text: string;
566566
}
567567

568-
export interface CallHierarchyItem {
568+
export class HierarchyItem {
569569
_sessionId?: string;
570570
_itemId?: string;
571571

572572
kind: SymbolKind;
573+
tags?: readonly SymbolTag[];
573574
name: string;
574575
detail?: string;
575576
uri: UriComponents;
576577
range: Range;
577578
selectionRange: Range;
578-
tags?: readonly SymbolTag[];
579+
}
580+
581+
export class TypeHierarchyItem extends HierarchyItem { }
582+
583+
export interface CallHierarchyItem extends HierarchyItem {
579584
data?: unknown;
580585
}
581586

packages/plugin-ext/src/common/plugin-api-rpc.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ import {
8080
ProvidedTerminalLink,
8181
InlayHint,
8282
CachedSession,
83-
CachedSessionItem
83+
CachedSessionItem,
84+
TypeHierarchyItem
8485
} from './plugin-api-rpc-model';
8586
import { ExtPluginApi } from './plugin-ext-api-contribution';
8687
import { KeysToAnyValues, KeysToKeysToAnyValue } from './types';
@@ -1566,6 +1567,10 @@ export interface LanguagesExt {
15661567
$provideCallees(handle: number, definition: CallHierarchyItem, token: CancellationToken): Promise<CallHierarchyOutgoingCall[] | undefined>;
15671568
$provideLinkedEditingRanges(handle: number, resource: UriComponents, position: Position, token: CancellationToken): Promise<LinkedEditingRanges | undefined>;
15681569
$releaseCallHierarchy(handle: number, session?: string): Promise<boolean>;
1570+
$prepareTypeHierarchy(handle: number, resource: UriComponents, location: Position, token: theia.CancellationToken): Promise<TypeHierarchyItem[] | undefined>
1571+
$provideSuperTypes(handle: number, sessionId: string, itemId: string, token: theia.CancellationToken): Promise<TypeHierarchyItem[] | undefined>
1572+
$provideSubTypes(handle: number, sessionId: string, itemId: string, token: theia.CancellationToken): Promise<TypeHierarchyItem[] | undefined>;
1573+
$releaseTypeHierarchy(handle: number, session?: string): Promise<boolean>;
15691574
}
15701575

15711576
export const LanguagesMainFactory = Symbol('LanguagesMainFactory');
@@ -1620,6 +1625,7 @@ export interface LanguagesMain {
16201625
$registerDocumentRangeSemanticTokensProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], legend: theia.SemanticTokensLegend): void;
16211626
$registerCallHierarchyProvider(handle: number, selector: SerializedDocumentFilter[]): void;
16221627
$registerLinkedEditingRangeProvider(handle: number, selector: SerializedDocumentFilter[]): void;
1628+
$registerTypeHierarchyProvider(handle: number, selector: SerializedDocumentFilter[]): void;
16231629
$setLanguageStatus(handle: number, status: LanguageStatus): void;
16241630
$removeLanguageStatus(handle: number): void;
16251631
}

0 commit comments

Comments
 (0)