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) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy