From fcc0ccbdc77f9806eb9efabf77a1a10d29f66208 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Mon, 18 Jun 2018 17:40:44 -0700 Subject: [PATCH 1/2] chore: update vscode-languageserver --- package-lock.json | 38 +++++++++++++------------- package.json | 2 +- src/test/typescript-service-helpers.ts | 6 ++++ 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index b187a7435..4403f449e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7658,32 +7658,32 @@ "integrity": "sha512-+Eb+Dxf2kC2h079msx61hkblxAKE0S2j78+8QpnigLAO2aIIjkCwTIH34etBrU8E8VItRinec7YEwULx9at5bQ==" }, "vscode-languageserver": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.5.1.tgz", - "integrity": "sha512-RYUKn0DgHTFcS8kS4VaNCjNMaQXYqiXdN9bKrFjXzu5RPKfjIYcoh47oVWwZj4L3R/DPB0Se7HPaDatvYY2XgQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-4.2.1.tgz", + "integrity": "sha512-5WAxaK1nEpe52ZaWNMqmd6rO5CIE72J/7UkGKPUTdGa0l0haWHS69tpRz+LetBlgTpP7PYacl4xhDaLZv82a+g==", "requires": { - "vscode-languageserver-protocol": "3.5.1", - "vscode-uri": "^1.0.1" + "vscode-languageserver-protocol": "^3.8.1", + "vscode-uri": "^1.0.3" } }, "vscode-languageserver-protocol": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.1.tgz", - "integrity": "sha512-1fPDIwsAv1difCV+8daOrJEGunClNJWqnUHq/ncWrjhitKWXgGmRCjlwZ3gDUTt54yRcvXz1PXJDaRNvNH6pYA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.8.1.tgz", + "integrity": "sha512-KdeetvQ2JavRiuE9afNrV5+xJZocj7NGPQwH4kpSFw5cp+0wijv87qgXfSEvmwPUaknhMBoSuSrSIG/LRrzWJQ==", "requires": { - "vscode-jsonrpc": "3.5.0", - "vscode-languageserver-types": "3.5.0" + "vscode-jsonrpc": "^3.6.2", + "vscode-languageserver-types": "^3.8.1" }, "dependencies": { "vscode-jsonrpc": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz", - "integrity": "sha1-hyOdnhZrLXNSJFuKgTWXgEwdY6o=" + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz", + "integrity": "sha512-T24Jb5V48e4VgYliUXMnZ379ItbrXgOimweKaJshD84z+8q7ZOZjJan0MeDe+Ugb+uqERDVV8SBmemaGMSMugA==" }, "vscode-languageserver-types": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz", - "integrity": "sha1-5I15li8LjgLelV4/UkkI4rGcA3Q=" + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.8.2.tgz", + "integrity": "sha512-2RMkyt1O1czGPCnkjKZWSio2D8oh3XlQ4zi4W2xL8q2Dvi4hB3/DEt+wYyzo4hmE2ZFP0RB8PXyzHyed7p1hbw==" } } }, @@ -7693,9 +7693,9 @@ "integrity": "sha512-ftGfU79AnnI3OHCG7kzCCN47jNI7BjECPAH2yhddtYTiQk0bnFbuFeQKvpXQcyNI3GsKEx5b6kSiBYshTiep6w==" }, "vscode-uri": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.3.tgz", - "integrity": "sha1-Yxvb9xbcyrDmUpGo3CXCMjIIWlI=" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.5.tgz", + "integrity": "sha1-O4majvccN/MFTXm9vdoxx7828g0=" }, "which": { "version": "1.3.0", diff --git a/package.json b/package.json index c92d2f998..ea8435273 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "string-similarity": "^1.1.0", "typescript": "2.8.3", "vscode-jsonrpc": "^3.3.1", - "vscode-languageserver": "^3.1.0", + "vscode-languageserver": "^4.2.1", "vscode-languageserver-types": "^3.0.3" }, "devDependencies": { diff --git a/src/test/typescript-service-helpers.ts b/src/test/typescript-service-helpers.ts index 3b0a7dc62..0099c6525 100644 --- a/src/test/typescript-service-helpers.ts +++ b/src/test/typescript-service-helpers.ts @@ -93,6 +93,12 @@ export const initializeTypeScriptService = ( processId: process.pid, rootUri, capabilities: clientCapabilities || DEFAULT_CAPABILITIES, + workspaceFolders: [ + { + uri: rootUri, + name: 'test', + }, + ], }) .toPromise() } From d107424f1f964c4cb3b6061570890639fd69b9e6 Mon Sep 17 00:00:00 2001 From: Troy Patrick Date: Tue, 19 Jun 2018 10:55:05 +1000 Subject: [PATCH 2/2] feat: Add goto type definition. (#475) Adds support to go directly to the type definition for the symbol under the cursor. --- README.md | 1 + src/test/typescript-service-helpers.ts | 64 ++++++++++++++++++++++++++ src/typescript-service.ts | 27 +++++++++-- 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7ab0fff58..f2488f36a 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ This is a language server for JavaScript and TypeScript that adheres to the [Lan - Hovers - Goto definition + - Goto type definition - Find all references - Document symbols - Workspace symbol search diff --git a/src/test/typescript-service-helpers.ts b/src/test/typescript-service-helpers.ts index 0099c6525..36458c42d 100644 --- a/src/test/typescript-service-helpers.ts +++ b/src/test/typescript-service-helpers.ts @@ -143,6 +143,8 @@ export function describeTypeScriptService( 'let target = i.target;', ].join('\n'), ], + [rootUri + 'foo/f.ts', ['import {Foo} from "./b";', '', 'let foo: Foo = Object({});'].join('\n')], + [rootUri + 'foo/g.ts', ['class Foo = {}', '', 'let foo: Foo = Object({});'].join('\n')], ]) ) ) @@ -224,6 +226,68 @@ export function describeTypeScriptService( ]) }) }) + + describe('textDocumentTypeDefinition()', function(this: TestContext & ISuiteCallbackContext): void { + specify('in other file', async function(this: TestContext & ITestCallbackContext): Promise { + const result: Location[] = await this.service + .textDocumentTypeDefinition({ + textDocument: { + uri: rootUri + 'foo/f.ts', + }, + position: { + line: 2, + character: 5, + }, + }) + .reduce(applyReducer, null as any) + .toPromise() + assert.deepEqual(result, [ + { + uri: rootUri + 'foo/b.ts', + range: { + start: { + line: 1, + character: 13, + }, + end: { + line: 1, + character: 16, + }, + }, + }, + ]) + }) + specify('in same file', async function(this: TestContext & ITestCallbackContext): Promise { + const result: Location[] = await this.service + .textDocumentTypeDefinition({ + textDocument: { + uri: rootUri + 'foo/g.ts', + }, + position: { + line: 2, + character: 5, + }, + }) + .reduce(applyReducer, null as any) + .toPromise() + assert.deepEqual(result, [ + { + uri: rootUri + 'foo/g.ts', + range: { + start: { + line: 0, + character: 6, + }, + end: { + line: 0, + character: 9, + }, + }, + }, + ]) + }) + }) + describe('textDocumentXdefinition()', function(this: TestContext & ISuiteCallbackContext): void { specify('on interface field reference', async function( this: TestContext & ITestCallbackContext diff --git a/src/typescript-service.ts b/src/typescript-service.ts index a09b00315..fbb00aa98 100644 --- a/src/typescript-service.ts +++ b/src/typescript-service.ts @@ -297,6 +297,7 @@ export class TypeScriptService { triggerCharacters: ['(', ','], }, definitionProvider: true, + typeDefinitionProvider: true, referencesProvider: true, documentSymbolProvider: true, workspaceSymbolProvider: true, @@ -362,7 +363,19 @@ export class TypeScriptService { */ public textDocumentDefinition(params: TextDocumentPositionParams, span = new Span()): Observable { - return this._getDefinitionLocations(params, span) + return this._getDefinitionLocations(params, span, false) + .map((location: Location): Operation => ({ op: 'add', path: '/-', value: location })) + .startWith({ op: 'add', path: '', value: [] }) + } + + /** + * The goto type definition request is sent from the client to the server to resolve the type + * location of a symbol at a given text document position. + * + * @return Observable of JSON Patches that build a `Location[]` result + */ + public textDocumentTypeDefinition(params: TextDocumentPositionParams, span = new Span()): Observable { + return this._getDefinitionLocations(params, span, true) .map((location: Location): Operation => ({ op: 'add', path: '/-', value: location })) .startWith({ op: 'add', path: '', value: [] }) } @@ -370,7 +383,11 @@ export class TypeScriptService { /** * Returns an Observable of all definition locations found for a symbol. */ - protected _getDefinitionLocations(params: TextDocumentPositionParams, span = new Span()): Observable { + protected _getDefinitionLocations( + params: TextDocumentPositionParams, + span = new Span(), + goToType = false + ): Observable { const uri = normalizeUri(params.textDocument.uri) // Fetch files needed to resolve definition @@ -392,9 +409,9 @@ export class TypeScriptService { params.position.line, params.position.character ) - const definitions: ts.DefinitionInfo[] | undefined = configuration - .getService() - .getDefinitionAtPosition(fileName, offset) + const definitions: ts.DefinitionInfo[] | undefined = goToType + ? configuration.getService().getTypeDefinitionAtPosition(fileName, offset) + : configuration.getService().getDefinitionAtPosition(fileName, offset) return Observable.from(definitions || []).map((definition): Location => { const sourceFile = this._getSourceFile(configuration, definition.fileName, span)