Skip to content

Commit 12aa8ed

Browse files
committed
[type-hierarchy] Implement LSP proposal
See: microsoft/vscode-languageserver-node#426 Signed-off-by: Alex Tugarev <alex.tugarev@typefox.io>
1 parent f4d585b commit 12aa8ed

File tree

6 files changed

+694
-0
lines changed

6 files changed

+694
-0
lines changed

server/src/lsp-connection.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { Logger, LspClientLogger } from './logger';
1212
import { LspServer } from './lsp-server';
1313
import { LspClient, LspClientImpl } from './lsp-client';
1414

15+
import * as lspTypeHierarchy from './type-hierarchy.lsp.proposal'
16+
1517
export interface IServerOptions {
1618
tsserverPath: string;
1719
tsserverLogFile?: string;
@@ -59,5 +61,9 @@ export function createLspConnection(options: IServerOptions): lsp.IConnection {
5961
connection.onRequest(lspCallHierarchy.CallHierarchyRequest.type, server.callHierarchy.bind(server));
6062
connection.onRequest(lspCallHierarchy.CallHierarchyResolveRequest.type, server.callHierarchyResolve.bind(server));
6163

64+
// proposed `textDocument/typeHierarchy` request
65+
connection.onRequest(lspTypeHierarchy.TypeHierarchyRequest.type, server.typeHierarchy.bind(server));
66+
connection.onRequest(lspTypeHierarchy.ResolveTypeHierarchyRequest.type, server.typeHierarchyResolve.bind(server));
67+
6268
return connection;
6369
}

server/src/lsp-server.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ import { provideOrganizeImports } from './organize-imports';
4040
import { TypeScriptInitializeParams, TypeScriptInitializationOptions, TypeScriptInitializeResult } from './ts-protocol';
4141
import { collectDocumentSymbols, collectSymbolInformations } from './document-symbol';
4242

43+
import * as lspTypeHierarchy from './type-hierarchy.lsp.proposal';
44+
import { computeTypeHierarchy, resolveTypeHierarchy } from './type-hierarchy';
45+
4346
export interface IServerOptions {
4447
logger: Logger
4548
tsserverPath?: string;
@@ -165,6 +168,7 @@ export class LspServer {
165168
logFileUri
166169
};
167170
(this.initializeResult.capabilities as lspCallHierarchy.CallHierarchyServerCapabilities).callHierarchyProvider = true;
171+
(this.initializeResult.capabilities as lspTypeHierarchy.TypeHierarchyServerCapabilities).typeHierarchyProvider = true;
168172
this.logger.log('onInitialize result', this.initializeResult);
169173
return this.initializeResult;
170174
}
@@ -886,4 +890,18 @@ export class LspServer {
886890
const result = await resolveCallHierarchy(this.tspClient, documentProvider, params);
887891
return result;
888892
}
893+
894+
async typeHierarchy(params: lspTypeHierarchy.TypeHierarchyParams): Promise<lspTypeHierarchy.TypeHierarchyItem | null> {
895+
this.logger.log('typeHierarchy', params);
896+
const documentProvider = (file: string) => this.documents.get(file);
897+
const result = await computeTypeHierarchy(this.tspClient, documentProvider, params);
898+
return result;
899+
}
900+
901+
async typeHierarchyResolve(params: lspTypeHierarchy.ResolveTypeHierarchyItemParams): Promise<lspTypeHierarchy.TypeHierarchyItem> {
902+
this.logger.log('typeHierarchyResolve', params);
903+
const documentProvider = (file: string) => this.documents.get(file);
904+
const result = await resolveTypeHierarchy(this.tspClient, documentProvider, params);
905+
return result;
906+
}
889907
}
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/********************************************************************************
2+
* Copyright (C) 2018 TypeFox and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the Eclipse
10+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
11+
* with the GNU Classpath Exception which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
********************************************************************************/
16+
17+
import { RequestType } from 'vscode-jsonrpc';
18+
import { SymbolKind, Range } from 'vscode-languageserver-types';
19+
import * as lsp from 'vscode-languageserver';
20+
21+
// NOTE: This module can be removed, once the type hierarchy will become the part of the LSP.
22+
// https://github.com/Microsoft/language-server-protocol/issues/582
23+
// https://github.com/Microsoft/vscode-languageserver-node/pull/346#discussion_r221659062
24+
25+
/**
26+
* Client capabilities specific to the type hierarchy feature.
27+
*/
28+
export interface TypeHierarchyCapabilities {
29+
30+
/**
31+
* The text document client capabilities.
32+
*/
33+
textDocument?: {
34+
35+
/**
36+
* Capabilities specific to the `textDocument/typeHierarchy`.
37+
*/
38+
typeHierarchy?: {
39+
40+
/**
41+
* Whether implementation supports dynamic registration. If this is set to `true`
42+
* the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
43+
* return value for the corresponding server capability as well.
44+
*/
45+
dynamicRegistration?: boolean;
46+
47+
}
48+
49+
}
50+
51+
}
52+
53+
/**
54+
* Type hierarchy language server capability.
55+
*/
56+
export interface TypeHierarchyServerCapabilities {
57+
58+
/**
59+
* Server capability for calculating super- and subtype hierarchies.
60+
*/
61+
typeHierarchyProvider?: boolean | (lsp.TextDocumentRegistrationOptions & lsp.StaticRegistrationOptions);
62+
63+
}
64+
65+
/**
66+
* The type hierarchy params is an extension of the `TextDocumentPositionParams` with optional properties
67+
* which can be used to eagerly resolve the item when requesting from the server.
68+
*/
69+
export interface TypeHierarchyParams extends lsp.TextDocumentPositionParams {
70+
71+
/**
72+
* The hierarchy levels to resolve. `0` indicates no level. When not defined, it is treated as `0`.
73+
*/
74+
resolve?: number;
75+
76+
/**
77+
* The direction of the hierarchy levels to resolve.
78+
*/
79+
direction?: TypeHierarchyDirection
80+
81+
}
82+
83+
export namespace TypeHierarchyDirection {
84+
85+
/**
86+
* Flag for retrieving/resolving the subtypes.
87+
*/
88+
export const Children = 0;
89+
90+
/**
91+
* Flag to use when retrieving/resolving the supertypes.
92+
*/
93+
export const Parents = 1;
94+
95+
/**
96+
* Flag for resolving both the super- and subtypes.
97+
*/
98+
export const Both = 2;
99+
100+
}
101+
export type TypeHierarchyDirection = 0 | 1 | 2;
102+
103+
/**
104+
* The `textDocument/typeHierarchy` request is sent from the client to the server to retrieve the type hierarchy
105+
* items from a given position of a text document. Can resolve the parentage information on demand.
106+
* If no item can be retrieved for a given text document position, returns with `null`.
107+
*/
108+
export namespace TypeHierarchyRequest {
109+
export const type = new RequestType<TypeHierarchyParams, TypeHierarchyItem | null, void, void>('textDocument/typeHierarchy');
110+
}
111+
112+
/**
113+
* Parameters for the `typeHierarchy/resolve` request.
114+
*/
115+
export interface ResolveTypeHierarchyItemParams {
116+
117+
/**
118+
* The item to resolve.
119+
*/
120+
item: TypeHierarchyItem;
121+
122+
/**
123+
* The hierarchy levels to resolve. `0` indicates no level.
124+
*/
125+
resolve: number;
126+
127+
/**
128+
* The direction of the hierarchy levels to resolve.
129+
*/
130+
direction: TypeHierarchyDirection;
131+
}
132+
133+
/**
134+
* The `typeHierarchy/resolve` request is sent from the client to the server to resolve a type hierarchy
135+
* item by resolving sub- and supertype information.
136+
*/
137+
export namespace ResolveTypeHierarchyRequest {
138+
export const type = new RequestType<ResolveTypeHierarchyItemParams, TypeHierarchyItem | null, void, void>('typeHierarchy/resolve');
139+
}
140+
141+
export interface TypeHierarchyItem {
142+
143+
/**
144+
* The human readable name of the hierarchy item.
145+
*/
146+
name: string;
147+
148+
/**
149+
* Optional detail for the hierarchy item. It can be, for instance, the signature of a function or method.
150+
*/
151+
detail?: string;
152+
153+
/**
154+
* The kind of the hierarchy item. For instance, class or interface.
155+
*/
156+
kind: SymbolKind;
157+
158+
/**
159+
* `true` if the hierarchy item is deprecated. Otherwise, `false`. It is `false` by default.
160+
*/
161+
deprecated?: boolean;
162+
163+
/**
164+
* The URI of the text document where this type hierarchy item belongs to.
165+
*/
166+
uri: string;
167+
168+
/**
169+
* The range enclosing this type hierarchy item not including leading/trailing whitespace but everything else
170+
* like comments. This information is typically used to determine if the clients cursor is inside the type
171+
* hierarchy item to reveal in the symbol in the UI.
172+
*/
173+
range: Range;
174+
175+
/**
176+
* The range that should be selected and revealed when this type hierarchy item is being picked, e.g the name
177+
* of a function. Must be contained by the `range`.
178+
*/
179+
selectionRange: Range;
180+
181+
/**
182+
* If this type hierarchy item is resolved, it contains the direct parents. Could be empty if the item does
183+
* not have any direct parents. If not defined, the parents have not been resolved yet.
184+
*/
185+
parents?: TypeHierarchyItem[];
186+
187+
/**
188+
* If this type hierarchy item is resolved, it contains the direct children of the current item. Could be
189+
* empty if the item does not have any descendants. If not defined, the children have not been resolved.
190+
*/
191+
children?: TypeHierarchyItem[];
192+
193+
/**
194+
* An optional data field can be used to identify a type hierarchy item in a resolve request.
195+
*/
196+
// tslint:disable-next-line:no-any
197+
data?: any;
198+
}

0 commit comments

Comments
 (0)