Skip to content

Commit 2ca0792

Browse files
Merge pull request microsoft#24074 from RyanCavanaugh/splitTransparentGoToDef
Return mapped locations in alternate fields
2 parents ba4bf21 + f01338f commit 2ca0792

File tree

5 files changed

+64
-24
lines changed

5 files changed

+64
-24
lines changed

src/server/session.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -665,9 +665,8 @@ namespace ts.server {
665665
if (simplifiedResult) {
666666
return this.mapDefinitionInfo(definitions, project);
667667
}
668-
else {
669-
return definitions;
670-
}
668+
669+
return definitions.map(Session.mapToOriginalLocation);
671670
}
672671

673672
private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan {
@@ -691,13 +690,37 @@ namespace ts.server {
691690
};
692691
}
693692

694-
return definitionAndBoundSpan;
693+
return {
694+
...definitionAndBoundSpan,
695+
definitions: definitionAndBoundSpan.definitions.map(Session.mapToOriginalLocation)
696+
};
695697
}
696698

697699
private mapDefinitionInfo(definitions: ReadonlyArray<DefinitionInfo>, project: Project): ReadonlyArray<protocol.FileSpan> {
698700
return definitions.map(def => this.toFileSpan(def.fileName, def.textSpan, project));
699701
}
700702

703+
/*
704+
* When we map a .d.ts location to .ts, Visual Studio gets confused because there's no associated Roslyn Document in
705+
* the same project which corresponds to the file. VS Code has no problem with this, and luckily we have two protocols.
706+
* This retains the existing behavior for the "simplified" (VS Code) protocol but stores the .d.ts location in a
707+
* set of additional fields, and does the reverse for VS (store the .d.ts location where
708+
* it used to be and stores the .ts location in the additional fields).
709+
*/
710+
private static mapToOriginalLocation<T extends DocumentSpan>(def: T): T {
711+
if (def.originalFileName) {
712+
Debug.assert(def.originalTextSpan !== undefined, "originalTextSpan should be present if originalFileName is");
713+
return {
714+
...<any>def,
715+
fileName: def.originalFileName,
716+
textSpan: def.originalTextSpan,
717+
targetFileName: def.fileName,
718+
targetTextSpan: def.textSpan
719+
};
720+
}
721+
return def;
722+
}
723+
701724
private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan {
702725
const ls = project.getLanguageService();
703726
const start = ls.toLineColumnOffset(fileName, textSpan.start);
@@ -732,9 +755,8 @@ namespace ts.server {
732755
if (simplifiedResult) {
733756
return implementations.map(({ fileName, textSpan }) => this.toFileSpan(fileName, textSpan, project));
734757
}
735-
else {
736-
return implementations;
737-
}
758+
759+
return implementations.map(Session.mapToOriginalLocation);
738760
}
739761

740762
private getOccurrences(args: protocol.FileLocationRequestArgs): ReadonlyArray<protocol.OccurrencesResponseItem> {

src/services/services.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,10 +1600,10 @@ namespace ts {
16001600

16011601
function makeGetTargetOfMappedPosition<TIn>(
16021602
extract: (original: TIn) => sourcemaps.SourceMappableLocation,
1603-
create: (result: sourcemaps.SourceMappableLocation, original: TIn) => TIn
1603+
create: (result: sourcemaps.SourceMappableLocation, unmapped: TIn, original: TIn) => TIn
16041604
) {
16051605
return getTargetOfMappedPosition;
1606-
function getTargetOfMappedPosition(input: TIn): TIn {
1606+
function getTargetOfMappedPosition(input: TIn, original = input): TIn {
16071607
const info = extract(input);
16081608
if (endsWith(info.fileName, Extension.Dts)) {
16091609
let file: SourceFileLike = program.getSourceFile(info.fileName);
@@ -1617,15 +1617,15 @@ namespace ts {
16171617
const mapper = getSourceMapper(info.fileName, file);
16181618
const newLoc = mapper.getOriginalPosition(info);
16191619
if (newLoc === info) return input;
1620-
return getTargetOfMappedPosition(create(newLoc, input));
1620+
return getTargetOfMappedPosition(create(newLoc, input, original), original);
16211621
}
16221622
return input;
16231623
}
16241624
}
16251625

16261626
const getTargetOfMappedDeclarationInfo = makeGetTargetOfMappedPosition(
16271627
(info: DefinitionInfo) => ({ fileName: info.fileName, position: info.textSpan.start }),
1628-
(newLoc, info) => ({
1628+
(newLoc, info, original) => ({
16291629
containerKind: info.containerKind,
16301630
containerName: info.containerName,
16311631
fileName: newLoc.fileName,
@@ -1634,12 +1634,14 @@ namespace ts {
16341634
textSpan: {
16351635
start: newLoc.position,
16361636
length: info.textSpan.length
1637-
}
1637+
},
1638+
originalFileName: original.fileName,
1639+
originalTextSpan: original.textSpan
16381640
})
16391641
);
16401642

16411643
function getTargetOfMappedDeclarationFiles(infos: ReadonlyArray<DefinitionInfo>): DefinitionInfo[] {
1642-
return map(infos, getTargetOfMappedDeclarationInfo);
1644+
return map(infos, d => getTargetOfMappedDeclarationInfo(d));
16431645
}
16441646

16451647
/// Goto definition
@@ -1678,12 +1680,14 @@ namespace ts {
16781680
textSpan: {
16791681
start: newLoc.position,
16801682
length: info.textSpan.length
1681-
}
1683+
},
1684+
originalFileName: info.fileName,
1685+
originalTextSpan: info.textSpan
16821686
})
16831687
);
16841688

16851689
function getTargetOfMappedImplementationLocations(infos: ReadonlyArray<ImplementationLocation>): ImplementationLocation[] {
1686-
return map(infos, getTargetOfMappedImplementationLocation);
1690+
return map(infos, d => getTargetOfMappedImplementationLocation(d));
16871691
}
16881692

16891693
function getImplementationAtPosition(fileName: string, position: number): ImplementationLocation[] {

src/services/types.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,13 @@ namespace ts {
542542
export interface DocumentSpan {
543543
textSpan: TextSpan;
544544
fileName: string;
545+
546+
/**
547+
* If the span represents a location that was remapped (e.g. via a .d.ts.map file),
548+
* then the original filename and span will be specified here
549+
*/
550+
originalTextSpan?: TextSpan;
551+
originalFileName?: string;
545552
}
546553

547554
export interface RenameLocation extends DocumentSpan {
@@ -654,9 +661,7 @@ namespace ts {
654661
indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
655662
}
656663

657-
export interface DefinitionInfo {
658-
fileName: string;
659-
textSpan: TextSpan;
664+
export interface DefinitionInfo extends DocumentSpan {
660665
kind: ScriptElementKind;
661666
name: string;
662667
containerKind: ScriptElementKind;

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4703,6 +4703,12 @@ declare namespace ts {
47034703
interface DocumentSpan {
47044704
textSpan: TextSpan;
47054705
fileName: string;
4706+
/**
4707+
* If the span represents a location that was remapped (e.g. via a .d.ts.map file),
4708+
* then the original filename and span will be specified here
4709+
*/
4710+
originalTextSpan?: TextSpan;
4711+
originalFileName?: string;
47064712
}
47074713
interface RenameLocation extends DocumentSpan {
47084714
}
@@ -4800,9 +4806,7 @@ declare namespace ts {
48004806
insertSpaceBeforeTypeAnnotation?: boolean;
48014807
indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
48024808
}
4803-
interface DefinitionInfo {
4804-
fileName: string;
4805-
textSpan: TextSpan;
4809+
interface DefinitionInfo extends DocumentSpan {
48064810
kind: ScriptElementKind;
48074811
name: string;
48084812
containerKind: ScriptElementKind;
@@ -8412,6 +8416,7 @@ declare namespace ts.server {
84128416
private getDefinition;
84138417
private getDefinitionAndBoundSpan;
84148418
private mapDefinitionInfo;
8419+
private static mapToOriginalLocation;
84158420
private toFileSpan;
84168421
private getTypeDefinition;
84178422
private getImplementation;

tests/baselines/reference/api/typescript.d.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4703,6 +4703,12 @@ declare namespace ts {
47034703
interface DocumentSpan {
47044704
textSpan: TextSpan;
47054705
fileName: string;
4706+
/**
4707+
* If the span represents a location that was remapped (e.g. via a .d.ts.map file),
4708+
* then the original filename and span will be specified here
4709+
*/
4710+
originalTextSpan?: TextSpan;
4711+
originalFileName?: string;
47064712
}
47074713
interface RenameLocation extends DocumentSpan {
47084714
}
@@ -4800,9 +4806,7 @@ declare namespace ts {
48004806
insertSpaceBeforeTypeAnnotation?: boolean;
48014807
indentMultiLineObjectLiteralBeginningOnBlankLine?: boolean;
48024808
}
4803-
interface DefinitionInfo {
4804-
fileName: string;
4805-
textSpan: TextSpan;
4809+
interface DefinitionInfo extends DocumentSpan {
48064810
kind: ScriptElementKind;
48074811
name: string;
48084812
containerKind: ScriptElementKind;

0 commit comments

Comments
 (0)