Merge pull request #24074 from RyanCavanaugh/splitTransparentGoToDef

Return mapped locations in alternate fields
This commit is contained in:
Ryan Cavanaugh 2018-05-16 05:39:51 +12:00 committed by GitHub
commit 2ca0792976
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 24 deletions

View File

@ -665,9 +665,8 @@ namespace ts.server {
if (simplifiedResult) {
return this.mapDefinitionInfo(definitions, project);
}
else {
return definitions;
}
return definitions.map(Session.mapToOriginalLocation);
}
private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan {
@ -691,13 +690,37 @@ namespace ts.server {
};
}
return definitionAndBoundSpan;
return {
...definitionAndBoundSpan,
definitions: definitionAndBoundSpan.definitions.map(Session.mapToOriginalLocation)
};
}
private mapDefinitionInfo(definitions: ReadonlyArray<DefinitionInfo>, project: Project): ReadonlyArray<protocol.FileSpan> {
return definitions.map(def => this.toFileSpan(def.fileName, def.textSpan, project));
}
/*
* When we map a .d.ts location to .ts, Visual Studio gets confused because there's no associated Roslyn Document in
* the same project which corresponds to the file. VS Code has no problem with this, and luckily we have two protocols.
* This retains the existing behavior for the "simplified" (VS Code) protocol but stores the .d.ts location in a
* set of additional fields, and does the reverse for VS (store the .d.ts location where
* it used to be and stores the .ts location in the additional fields).
*/
private static mapToOriginalLocation<T extends DocumentSpan>(def: T): T {
if (def.originalFileName) {
Debug.assert(def.originalTextSpan !== undefined, "originalTextSpan should be present if originalFileName is");
return {
...<any>def,
fileName: def.originalFileName,
textSpan: def.originalTextSpan,
targetFileName: def.fileName,
targetTextSpan: def.textSpan
};
}
return def;
}
private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan {
const ls = project.getLanguageService();
const start = ls.toLineColumnOffset(fileName, textSpan.start);
@ -732,9 +755,8 @@ namespace ts.server {
if (simplifiedResult) {
return implementations.map(({ fileName, textSpan }) => this.toFileSpan(fileName, textSpan, project));
}
else {
return implementations;
}
return implementations.map(Session.mapToOriginalLocation);
}
private getOccurrences(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.OccurrencesResponseItem> {

View File

@ -1600,10 +1600,10 @@ namespace ts {
function makeGetTargetOfMappedPosition<TIn>(
extract: (original: TIn) => sourcemaps.SourceMappableLocation,
create: (result: sourcemaps.SourceMappableLocation, original: TIn) => TIn
create: (result: sourcemaps.SourceMappableLocation, unmapped: TIn, original: TIn) => TIn
) {
return getTargetOfMappedPosition;
function getTargetOfMappedPosition(input: TIn): TIn {
function getTargetOfMappedPosition(input: TIn, original = input): TIn {
const info = extract(input);
if (endsWith(info.fileName, Extension.Dts)) {
let file: SourceFileLike = program.getSourceFile(info.fileName);
@ -1617,7 +1617,7 @@ namespace ts {
const mapper = getSourceMapper(info.fileName, file);
const newLoc = mapper.getOriginalPosition(info);
if (newLoc === info) return input;
return getTargetOfMappedPosition(create(newLoc, input));
return getTargetOfMappedPosition(create(newLoc, input, original), original);
}
return input;
}
@ -1625,7 +1625,7 @@ namespace ts {
const getTargetOfMappedDeclarationInfo = makeGetTargetOfMappedPosition(
(info: DefinitionInfo) => ({ fileName: info.fileName, position: info.textSpan.start }),
(newLoc, info) => ({
(newLoc, info, original) => ({
containerKind: info.containerKind,
containerName: info.containerName,
fileName: newLoc.fileName,
@ -1634,12 +1634,14 @@ namespace ts {
textSpan: {
start: newLoc.position,
length: info.textSpan.length
}
},
originalFileName: original.fileName,
originalTextSpan: original.textSpan
})
);
function getTargetOfMappedDeclarationFiles(infos: ReadonlyArray<DefinitionInfo>): DefinitionInfo[] {
return map(infos, getTargetOfMappedDeclarationInfo);
return map(infos, d => getTargetOfMappedDeclarationInfo(d));
}
/// Goto definition
@ -1678,12 +1680,14 @@ namespace ts {
textSpan: {
start: newLoc.position,
length: info.textSpan.length
}
},
originalFileName: info.fileName,
originalTextSpan: info.textSpan
})
);
function getTargetOfMappedImplementationLocations(infos: ReadonlyArray<ImplementationLocation>): ImplementationLocation[] {
return map(infos, getTargetOfMappedImplementationLocation);
return map(infos, d => getTargetOfMappedImplementationLocation(d));
}
function getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[] {

View File

@ -542,6 +542,13 @@ namespace ts {
export interface DocumentSpan {
textSpan: TextSpan;
fileName: string;
/**
* If the span represents a location that was remapped (e.g. via a .d.ts.map file),
* then the original filename and span will be specified here
*/
originalTextSpan?: TextSpan;
originalFileName?: string;
}
export interface RenameLocation extends DocumentSpan {
@ -654,9 +661,7 @@ namespace ts {
indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
}
export interface DefinitionInfo {
fileName: string;
textSpan: TextSpan;
export interface DefinitionInfo extends DocumentSpan {
kind: ScriptElementKind;
name: string;
containerKind: ScriptElementKind;

View File

@ -4703,6 +4703,12 @@ declare namespace ts {
interface DocumentSpan {
textSpan: TextSpan;
fileName: string;
/**
* If the span represents a location that was remapped (e.g. via a .d.ts.map file),
* then the original filename and span will be specified here
*/
originalTextSpan?: TextSpan;
originalFileName?: string;
}
interface RenameLocation extends DocumentSpan {
}
@ -4800,9 +4806,7 @@ declare namespace ts {
insertSpaceBeforeTypeAnnotation?: boolean;
indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
}
interface DefinitionInfo {
fileName: string;
textSpan: TextSpan;
interface DefinitionInfo extends DocumentSpan {
kind: ScriptElementKind;
name: string;
containerKind: ScriptElementKind;
@ -8412,6 +8416,7 @@ declare namespace ts.server {
private getDefinition;
private getDefinitionAndBoundSpan;
private mapDefinitionInfo;
private static mapToOriginalLocation;
private toFileSpan;
private getTypeDefinition;
private getImplementation;

View File

@ -4703,6 +4703,12 @@ declare namespace ts {
interface DocumentSpan {
textSpan: TextSpan;
fileName: string;
/**
* If the span represents a location that was remapped (e.g. via a .d.ts.map file),
* then the original filename and span will be specified here
*/
originalTextSpan?: TextSpan;
originalFileName?: string;
}
interface RenameLocation extends DocumentSpan {
}
@ -4800,9 +4806,7 @@ declare namespace ts {
insertSpaceBeforeTypeAnnotation?: boolean;
indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
}
interface DefinitionInfo {
fileName: string;
textSpan: TextSpan;
interface DefinitionInfo extends DocumentSpan {
kind: ScriptElementKind;
name: string;
containerKind: ScriptElementKind;