Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/lang-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,17 @@ export class RemoteLanguageClient {
}

/**
* The content request is sent from a server to a client to request the
* current content of a text document identified by the URI
* The content request is sent from the server to the client to request the current content of
* any text document. This allows language servers to operate without accessing the file system
* directly.
*/
textDocumentXcontent(params: TextDocumentContentParams): Promise<TextDocumentItem> {
return this.request('textDocument/xcontent', params).toPromise();
}

/**
* Returns a list of all files in a directory
* The files request is sent from the server to the client to request a list of all files in the
* workspace or inside the directory of the `base` parameter, if given.
*/
workspaceXfiles(params: WorkspaceFilesParams): Promise<TextDocumentIdentifier[]> {
return this.request('workspace/xfiles', params).toPromise();
Expand Down
65 changes: 58 additions & 7 deletions src/request-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ export interface InitializeParams extends vscode.InitializeParams {
capabilities: ClientCapabilities;
}

export interface ClientCapabilities {
export interface ClientCapabilities extends vscode.ClientCapabilities {

/**
* The client provides support for workspace/xfiles.
*/
xfilesProvider?: boolean;

/**
* The client provides support for textDocument/xcontent.
*/
xcontentProvider?: boolean;
}

Expand All @@ -17,13 +25,31 @@ export interface ServerCapabilities extends vscode.ServerCapabilities {
}

export interface TextDocumentContentParams {

/**
* The text document to receive the content for.
*/
textDocument: vscode.TextDocumentIdentifier;
}

export interface WorkspaceFilesParams {

/**
* The URI of a directory to search.
* Can be relative to the rootPath.
* If not given, defaults to rootPath.
*/
base?: string;
}

/**
* Represents information about a programming construct that can be used to identify and locate the
* construct's symbol. The identification does not have to be unique, but it should be as unique as
* possible. It is up to the language server to define the schema of this object.
*
* In contrast to `SymbolInformation`, `SymbolDescriptor` includes more concrete, language-specific,
* metadata about the symbol.
*/
export interface SymbolDescriptor {
kind: string;
name: string;
Expand All @@ -44,9 +70,9 @@ export namespace SymbolDescriptor {
* If both properties are set, the requirements are AND'd.
*/
export interface WorkspaceSymbolParams {
/**
* A non-empty query string.
*/
/**
* A non-empty query string.
*/
query?: string;

/**
Expand All @@ -66,21 +92,46 @@ export interface WorkspaceSymbolParams {
* spec).
*/
export interface WorkspaceReferenceParams {

/**
* Metadata about the symbol that is being searched for.
*/
query: Partial<SymbolDescriptor>;

/**
* Hints provides optional hints about where the language server should look in order to find
* the symbol (this is an optimization). It is up to the language server to define the schema of
* this object.
*/
hints?: DependencyHints;
}

export interface SymbolLocationInformation {

/**
* The location where the symbol is defined, if any
*/
location?: vscode.Location;

/**
* Metadata about the symbol that can be used to identify or locate its definition.
*/
symbol: SymbolDescriptor;
}

/*
* ReferenceInformation enapsulates the metadata for a symbol
* reference in code.
/**
* Represents information about a reference to programming constructs like variables, classes,
* interfaces, etc.
*/
export interface ReferenceInformation {
/**
* The location in the workspace where the `symbol` is referenced.
*/
reference: vscode.Location;

/**
* Metadata about the symbol that can be used to identify or locate its definition.
*/
symbol: SymbolDescriptor;
}

Expand Down
83 changes: 83 additions & 0 deletions src/typescript-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,23 @@ export class TypeScriptService {
this.logger = new LSPLogger(client);
}

/**
* The initialize request is sent as the first request from the client to the server. If the
* server receives request or notification before the `initialize` request it should act as
* follows:
*
* - for a request the respond should be errored with `code: -32002`. The message can be picked by
* the server.
* - notifications should be dropped, except for the exit notification. This will allow the exit a
* server without an initialize request.
*
* Until the server has responded to the `initialize` request with an `InitializeResult` the
* client must not sent any additional requests or notifications to the server.
*
* During the `initialize` request the server is allowed to sent the notifications
* `window/showMessage`, `window/logMessage` and `telemetry/event` as well as the
* `window/showMessageRequest` request to the client.
*/
async initialize(params: InitializeParams, span = new Span()): Promise<InitializeResult> {
if (params.rootUri || params.rootPath) {
this.root = params.rootPath || util.uri2path(params.rootUri!);
Expand Down Expand Up @@ -150,11 +167,20 @@ export class TypeScriptService {
this.inMemoryFileSystem = new InMemoryFileSystem(this.root);
}

/**
* The shutdown request is sent from the client to the server. It asks the server to shut down,
* but to not exit (otherwise the response might not be delivered correctly to the client).
* There is a separate exit notification that asks the server to exit.
*/
async shutdown(params = {}, span = new Span()): Promise<null> {
this.projectManager.dispose();
return null;
}

/**
* The goto definition request is sent from the client to the server to resolve the definition
* location of a symbol at a given text document position.
*/
async textDocumentDefinition(params: TextDocumentPositionParams, span = new Span()): Promise<Location[]> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
const line = params.position.line;
Expand Down Expand Up @@ -229,6 +255,10 @@ export class TypeScriptService {
return ret;
}

/**
* The hover request is sent from the client to the server to request hover information at a
* given text document position.
*/
async textDocumentHover(params: TextDocumentPositionParams, span = new Span()): Promise<Hover> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
const line = params.position.line;
Expand Down Expand Up @@ -262,6 +292,10 @@ export class TypeScriptService {
return { contents, range: Range.create(start.line, start.character, end.line, end.character) };
}

/**
* The references request is sent from the client to the server to resolve project-wide
* references for the symbol denoted by the given text document position.
*/
async textDocumentReferences(params: ReferenceParams, span = new Span()): Promise<Location[]> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
const line = params.position.line;
Expand Down Expand Up @@ -298,6 +332,11 @@ export class TypeScriptService {
});
}

/**
* The workspace symbol request is sent from the client to the server to list project-wide
* symbols matching the query string. The text document parameter specifies the active document
* at time of the query. This can be used to rank or limit results.
*/
async workspaceSymbol(params: WorkspaceSymbolParams, span = new Span()): Promise<SymbolInformation[]> {
const query = params.query;
const symQuery = params.symbol ? Object.assign({}, params.symbol) : undefined;
Expand Down Expand Up @@ -383,6 +422,10 @@ export class TypeScriptService {
return (await itemsPromise).slice(0, params.limit);
}

/**
* The document symbol request is sent from the client to the server to list all symbols found
* in a given text document.
*/
async textDocumentDocumentSymbol(params: DocumentSymbolParams, span = new Span()): Promise<SymbolInformation[]> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
await this.projectManager.ensureFilesForHoverAndDefinition(uri, span);
Expand All @@ -400,6 +443,10 @@ export class TypeScriptService {
return Promise.resolve(result);
}

/**
* The workspace references request is sent from the client to the server to locate project-wide
* references to a symbol given its description / metadata.
*/
async workspaceXreferences(params: WorkspaceReferenceParams, span = new Span()): Promise<ReferenceInformation[]> {
const refInfo: ReferenceInformation[] = [];

Expand Down Expand Up @@ -536,6 +583,19 @@ export class TypeScriptService {
return deps;
}

/**
* The Completion request is sent from the client to the server to compute completion items at a
* given cursor position. Completion items are presented in the
* [IntelliSense](https://code.visualstudio.com/docs/editor/editingevolved#_intellisense) user
* interface. If computing full completion items is expensive, servers can additionally provide
* a handler for the completion item resolve request ('completionItem/resolve'). This request is
* sent when a completion item is selected in the user interface. A typically use case is for
* example: the 'textDocument/completion' request doesn't fill in the `documentation` property
* for returned completion items since it is expensive to compute. When the item is selected in
* the user interface then a 'completionItem/resolve' request is sent with the selected
* completion item as a param. The returned completion item should have the documentation
* property filled in.
*/
async textDocumentCompletion(params: TextDocumentPositionParams, span = new Span()): Promise<CompletionList> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
const line = params.position.line;
Expand Down Expand Up @@ -577,6 +637,10 @@ export class TypeScriptService {
}));
}

/**
* The signature help request is sent from the client to the server to request signature
* information at a given cursor position.
*/
async textDocumentSignatureHelp(params: TextDocumentPositionParams, span = new Span()): Promise<SignatureHelp> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
const line = params.position.line;
Expand Down Expand Up @@ -1407,13 +1471,23 @@ export class TypeScriptService {
}
}

/**
* The document open notification is sent from the client to the server to signal newly opened
* text documents. The document's truth is now managed by the client and the server must not try
* to read the document's truth using the document's uri.
*/
textDocumentDidOpen(params: DidOpenTextDocumentParams): Promise<void> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
return this.projectManager.ensureFilesForHoverAndDefinition(uri).then(() => {
this.projectManager.didOpen(util.uri2path(uri), params.textDocument.text);
});
}

/**
* The document change notification is sent from the client to the server to signal changes to a
* text document. In 2.0 the shape of the params has changed to include proper version numbers
* and language ids.
*/
async textDocumentDidChange(params: DidChangeTextDocumentParams): Promise<void> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
let text = null;
Expand All @@ -1429,13 +1503,22 @@ export class TypeScriptService {
this.projectManager.didChange(util.uri2path(uri), text);
}

/**
* The document save notification is sent from the client to the server when the document was
* saved in the client.
*/
textDocumentDidSave(params: DidSaveTextDocumentParams): Promise<void> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
return this.projectManager.ensureFilesForHoverAndDefinition(uri).then(() => {
this.projectManager.didSave(util.uri2path(uri));
});
}

/**
* The document close notification is sent from the client to the server when the document got
* closed in the client. The document's truth now exists where the document's uri points to
* (e.g. if the document's uri is a file uri the truth now exists on disk).
*/
textDocumentDidClose(params: DidCloseTextDocumentParams): Promise<void> {
const uri = util.uri2reluri(params.textDocument.uri, this.root);
return this.projectManager.ensureFilesForHoverAndDefinition(uri).then(() => {
Expand Down