Skip to content

Commit 0544b77

Browse files
authored
Merge pull request #28273 from Microsoft/buildSourceMapNavigation
Fix source map decoding to handle case sensitivity and --out option
2 parents a4a1bed + 9f844c4 commit 0544b77

File tree

5 files changed

+53
-13
lines changed

5 files changed

+53
-13
lines changed

src/compiler/sourcemapDecoder.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ namespace ts.sourcemaps {
5757
fileExists(path: string): boolean;
5858
getCanonicalFileName(path: string): string;
5959
log(text: string): void;
60+
useCaseSensitiveFileNames: boolean;
6061
}
6162

6263
export function decode(host: SourceMapDecodeHost, mapPath: string, map: SourceMapData, program?: Program, fallbackCache = createSourceFileLikeCache(host)): SourceMapper {
@@ -79,7 +80,7 @@ namespace ts.sourcemaps {
7980
// if no exact match, closest is 2's compliment of result
8081
targetIndex = ~targetIndex;
8182
}
82-
if (!maps[targetIndex] || comparePaths(loc.fileName, maps[targetIndex].sourcePath, sourceRoot) !== 0) {
83+
if (!maps[targetIndex] || comparePaths(loc.fileName, maps[targetIndex].sourcePath, sourceRoot, !host.useCaseSensitiveFileNames) !== 0) {
8384
return loc;
8485
}
8586
return { fileName: toPath(map.file!, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].emittedPosition }; // Closest pos
@@ -129,7 +130,7 @@ namespace ts.sourcemaps {
129130
}
130131

131132
function compareProcessedPositionSourcePositions(a: ProcessedSourceMapPosition, b: ProcessedSourceMapPosition) {
132-
return comparePaths(a.sourcePath, b.sourcePath, sourceRoot) ||
133+
return comparePaths(a.sourcePath, b.sourcePath, sourceRoot, !host.useCaseSensitiveFileNames) ||
133134
compareValues(a.sourcePosition, b.sourcePosition);
134135
}
135136

src/services/services.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ namespace ts {
11391139
const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host);
11401140
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
11411141

1142-
const sourceMapper = getSourceMapper(getCanonicalFileName, currentDirectory, log, host, () => program);
1142+
const sourceMapper = getSourceMapper(useCaseSensitiveFileNames, currentDirectory, log, host, () => program);
11431143

11441144
function getValidSourceFile(fileName: string): SourceFile {
11451145
const sourceFile = program.getSourceFile(fileName);

src/services/sourcemaps.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ namespace ts {
1313
}
1414

1515
export function getSourceMapper(
16-
getCanonicalFileName: GetCanonicalFileName,
16+
useCaseSensitiveFileNames: boolean,
1717
currentDirectory: string,
1818
log: (message: string) => void,
1919
host: LanguageServiceHost,
2020
getProgram: () => Program,
2121
): SourceMapper {
22+
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
2223
let sourcemappedFileCache: SourceFileLikeCache;
2324
return { tryGetOriginalLocation, tryGetGeneratedLocation, toLineColumnOffset, clearCache };
2425

@@ -56,6 +57,7 @@ namespace ts {
5657
return file.sourceMapper = sourcemaps.decode({
5758
readFile: s => host.readFile!(s), // TODO: GH#18217
5859
fileExists: s => host.fileExists!(s), // TODO: GH#18217
60+
useCaseSensitiveFileNames,
5961
getCanonicalFileName,
6062
log,
6163
}, mapFileName, maps, getProgram(), sourcemappedFileCache);
@@ -105,7 +107,11 @@ namespace ts {
105107

106108
function tryGetGeneratedLocation(info: sourcemaps.SourceMappableLocation): sourcemaps.SourceMappableLocation | undefined {
107109
const program = getProgram();
108-
const declarationPath = getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
110+
const options = program.getCompilerOptions();
111+
const outPath = options.outFile || options.out;
112+
const declarationPath = outPath ?
113+
removeFileExtension(outPath) + Extension.Dts :
114+
getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
109115
if (declarationPath === undefined) return undefined;
110116
const declarationFile = getFile(declarationPath);
111117
if (!declarationFile) return undefined;

src/testRunner/unittests/tsserverProjectSystem.ts

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10481,20 +10481,28 @@ declare class TestLib {
1048110481
TestFSWithWatch.getTsBuildProjectFile(project, "index.ts"),
1048210482
];
1048310483
}
10484-
it("does not error on container only project", () => {
10485-
const project = "container";
10486-
const containerLib = getProjectFiles("container/lib");
10487-
const containerExec = getProjectFiles("container/exec");
10488-
const containerCompositeExec = getProjectFiles("container/compositeExec");
10489-
const containerConfig = TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json");
10490-
const files = [libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig];
10484+
10485+
const project = "container";
10486+
const containerLib = getProjectFiles("container/lib");
10487+
const containerExec = getProjectFiles("container/exec");
10488+
const containerCompositeExec = getProjectFiles("container/compositeExec");
10489+
const containerConfig = TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json");
10490+
const files = [libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig];
10491+
10492+
function createHost() {
1049110493
const host = createServerHost(files);
1049210494

1049310495
// ts build should succeed
1049410496
const solutionBuilder = tscWatch.createSolutionBuilder(host, [containerConfig.path], {});
1049510497
solutionBuilder.buildAllProjects();
1049610498
assert.equal(host.getOutput().length, 0);
1049710499

10500+
return host;
10501+
}
10502+
10503+
it("does not error on container only project", () => {
10504+
const host = createHost();
10505+
1049810506
// Open external project for the folder
1049910507
const session = createSession(host);
1050010508
const service = session.getProjectService();
@@ -10521,6 +10529,30 @@ declare class TestLib {
1052110529
assert.deepEqual(semanticDiagnostics, []);
1052210530
});
1052310531
});
10532+
10533+
it("can successfully find references with --out options", () => {
10534+
const host = createHost();
10535+
const session = createSession(host);
10536+
openFilesForSession([containerCompositeExec[1]], session);
10537+
const service = session.getProjectService();
10538+
checkNumberOfProjects(service, { configuredProjects: 1 });
10539+
const locationOfMyConst = protocolLocationFromSubstring(containerCompositeExec[1].content, "myConst");
10540+
const response = session.executeCommandSeq<protocol.RenameRequest>({
10541+
command: protocol.CommandTypes.Rename,
10542+
arguments: {
10543+
file: containerCompositeExec[1].path,
10544+
...locationOfMyConst
10545+
}
10546+
}).response as protocol.RenameResponseBody;
10547+
10548+
10549+
const myConstLen = "myConst".length;
10550+
const locationOfMyConstInLib = protocolLocationFromSubstring(containerLib[1].content, "myConst");
10551+
assert.deepEqual(response.locs, [
10552+
{ file: containerCompositeExec[1].path, locs: [{ start: locationOfMyConst, end: { line: locationOfMyConst.line, offset: locationOfMyConst.offset + myConstLen } }] },
10553+
{ file: containerLib[1].path, locs: [{ start: locationOfMyConstInLib, end: { line: locationOfMyConstInLib.line, offset: locationOfMyConstInLib.offset + myConstLen } }] }
10554+
]);
10555+
});
1052410556
});
1052510557

1052610558
describe("tsserverProjectSystem duplicate packages", () => {

tests/projects/container/compositeExec/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"compilerOptions": {
33
"outFile": "../built/local/compositeExec.js",
4-
"composite": true
4+
"composite": true,
5+
"declarationMap": true
56
},
67
"files": [
78
"index.ts"

0 commit comments

Comments
 (0)