diff --git a/src/features/definitionMetadataDocumentProvider.ts b/src/features/definitionMetadataDocumentProvider.ts index 66b6e3a8d..f9a337da1 100644 --- a/src/features/definitionMetadataDocumentProvider.ts +++ b/src/features/definitionMetadataDocumentProvider.ts @@ -23,24 +23,26 @@ export default class DefinitionMetadataDocumentProvider implements TextDocumentC } public addMetadataResponse(metadataResponse: MetadataResponse) : Uri { - const uri = this.createUri(metadataResponse); - + const uri = this.createUri(metadataResponse.SourceName); this._documents.set(uri.toString(), metadataResponse); return uri; } + public getExistingMetadataResponseUri(sourceName: string) : Uri { + return this.createUri(sourceName); + } + public register() : void { this._registration = workspace.registerTextDocumentContentProvider(this.scheme, this); } - public provideTextDocumentContent(uri : Uri) : string { + public provideTextDocumentContent(uri: Uri) : string { return this._documents.get(uri.toString()).Source; } - private createUri(metadataResponse: MetadataResponse) : Uri { + private createUri(sourceName: string) : Uri { return Uri.parse(this.scheme + "://" + - metadataResponse.SourceName.replace(/\\/g, "/") - .replace(/(.*)\/(.*)/g, "$1/[metadata] $2")); + sourceName.replace(/\\/g, "/").replace(/(.*)\/(.*)/g, "$1/[metadata] $2")); } } \ No newline at end of file diff --git a/src/features/definitionProvider.ts b/src/features/definitionProvider.ts index 408842026..61514c391 100644 --- a/src/features/definitionProvider.ts +++ b/src/features/definitionProvider.ts @@ -8,7 +8,7 @@ import AbstractSupport from './abstractProvider'; import {MetadataRequest, GoToDefinitionRequest, MetadataSource} from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; -import {createRequest, toLocation} from '../omnisharp/typeConvertion'; +import {createRequest, toLocation, toLocationFromUri} from '../omnisharp/typeConvertion'; import {Uri, TextDocument, Position, Location, CancellationToken, DefinitionProvider} from 'vscode'; import DefinitionMetadataDocumentProvider from './definitionMetadataDocumentProvider'; import TelemetryReporter from 'vscode-extension-telemetry'; @@ -29,11 +29,23 @@ export default class CSharpDefinitionProvider extends AbstractSupport implements return serverUtils.goToDefinition(this._server, req, token).then(gotoDefinitionResponse => { + // the defintion is in source if (gotoDefinitionResponse && gotoDefinitionResponse.FileName) { + + // if it is part of an already used metadata file, retrieve its uri instead of going to the physical file + if (gotoDefinitionResponse.FileName.startsWith("$metadata$")) { + const uri = this._definitionMetadataDocumentProvider.getExistingMetadataResponseUri(gotoDefinitionResponse.FileName); + return toLocationFromUri(uri, gotoDefinitionResponse); + } + + // if it is a normal source definition, convert the response to a location return toLocation(gotoDefinitionResponse); + + // the definition is in metadata } else if (gotoDefinitionResponse.MetadataSource) { const metadataSource: MetadataSource = gotoDefinitionResponse.MetadataSource; + // go to metadata endpoint for more information return serverUtils.getMetadata(this._server, { Timeout: 5000, AssemblyName: metadataSource.AssemblyName, diff --git a/src/omnisharp/typeConvertion.ts b/src/omnisharp/typeConvertion.ts index 161df401d..532d026a0 100644 --- a/src/omnisharp/typeConvertion.ts +++ b/src/omnisharp/typeConvertion.ts @@ -9,6 +9,10 @@ import * as vscode from 'vscode'; export function toLocation(location: protocol.ResourceLocation | protocol.QuickFix): vscode.Location { const fileName = vscode.Uri.file(location.FileName); + return toLocationFromUri(fileName, location); +} + +export function toLocationFromUri(uri: vscode.Uri, location: protocol.ResourceLocation | protocol.QuickFix): vscode.Location { const position = new vscode.Position(location.Line - 1, location.Column - 1); const endLine = (location).EndLine; @@ -16,10 +20,10 @@ export function toLocation(location: protocol.ResourceLocation | protocol.QuickF if (endLine !== undefined && endColumn !== undefined) { const endPosition = new vscode.Position(endLine - 1, endColumn - 1); - return new vscode.Location(fileName, new vscode.Range(position, endPosition)); + return new vscode.Location(uri, new vscode.Range(position, endPosition)); } - return new vscode.Location(fileName, position); + return new vscode.Location(uri, position); } export function toRange(rangeLike: { Line: number; Column: number; EndLine: number; EndColumn: number; }): vscode.Range {