Skip to content

Commit

Permalink
Merge pull request #1772 from filipw/feature/better-metadata-navigation
Browse files Browse the repository at this point in the history
Fix "go to definition" from metadata within the same metadata file
  • Loading branch information
DustinCampbell authored Oct 2, 2017
2 parents 92e6442 + 95e4d45 commit 25e8854
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 9 deletions.
14 changes: 8 additions & 6 deletions src/features/definitionMetadataDocumentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
}
}
14 changes: 13 additions & 1 deletion src/features/definitionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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, <MetadataRequest> {
Timeout: 5000,
AssemblyName: metadataSource.AssemblyName,
Expand Down
8 changes: 6 additions & 2 deletions src/omnisharp/typeConvertion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@ 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 = (<protocol.QuickFix>location).EndLine;
const endColumn = (<protocol.QuickFix>location).EndColumn;

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 {
Expand Down

0 comments on commit 25e8854

Please sign in to comment.