mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-07 23:08:20 -06:00
Merge pull request #28273 from Microsoft/buildSourceMapNavigation
Fix source map decoding to handle case sensitivity and --out option
This commit is contained in:
commit
0544b7745d
@ -57,6 +57,7 @@ namespace ts.sourcemaps {
|
||||
fileExists(path: string): boolean;
|
||||
getCanonicalFileName(path: string): string;
|
||||
log(text: string): void;
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
}
|
||||
|
||||
export function decode(host: SourceMapDecodeHost, mapPath: string, map: SourceMapData, program?: Program, fallbackCache = createSourceFileLikeCache(host)): SourceMapper {
|
||||
@ -79,7 +80,7 @@ namespace ts.sourcemaps {
|
||||
// if no exact match, closest is 2's compliment of result
|
||||
targetIndex = ~targetIndex;
|
||||
}
|
||||
if (!maps[targetIndex] || comparePaths(loc.fileName, maps[targetIndex].sourcePath, sourceRoot) !== 0) {
|
||||
if (!maps[targetIndex] || comparePaths(loc.fileName, maps[targetIndex].sourcePath, sourceRoot, !host.useCaseSensitiveFileNames) !== 0) {
|
||||
return loc;
|
||||
}
|
||||
return { fileName: toPath(map.file!, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].emittedPosition }; // Closest pos
|
||||
@ -129,7 +130,7 @@ namespace ts.sourcemaps {
|
||||
}
|
||||
|
||||
function compareProcessedPositionSourcePositions(a: ProcessedSourceMapPosition, b: ProcessedSourceMapPosition) {
|
||||
return comparePaths(a.sourcePath, b.sourcePath, sourceRoot) ||
|
||||
return comparePaths(a.sourcePath, b.sourcePath, sourceRoot, !host.useCaseSensitiveFileNames) ||
|
||||
compareValues(a.sourcePosition, b.sourcePosition);
|
||||
}
|
||||
|
||||
|
||||
@ -1139,7 +1139,7 @@ namespace ts {
|
||||
const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host);
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
|
||||
const sourceMapper = getSourceMapper(getCanonicalFileName, currentDirectory, log, host, () => program);
|
||||
const sourceMapper = getSourceMapper(useCaseSensitiveFileNames, currentDirectory, log, host, () => program);
|
||||
|
||||
function getValidSourceFile(fileName: string): SourceFile {
|
||||
const sourceFile = program.getSourceFile(fileName);
|
||||
|
||||
@ -13,12 +13,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getSourceMapper(
|
||||
getCanonicalFileName: GetCanonicalFileName,
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
currentDirectory: string,
|
||||
log: (message: string) => void,
|
||||
host: LanguageServiceHost,
|
||||
getProgram: () => Program,
|
||||
): SourceMapper {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
let sourcemappedFileCache: SourceFileLikeCache;
|
||||
return { tryGetOriginalLocation, tryGetGeneratedLocation, toLineColumnOffset, clearCache };
|
||||
|
||||
@ -56,6 +57,7 @@ namespace ts {
|
||||
return file.sourceMapper = sourcemaps.decode({
|
||||
readFile: s => host.readFile!(s), // TODO: GH#18217
|
||||
fileExists: s => host.fileExists!(s), // TODO: GH#18217
|
||||
useCaseSensitiveFileNames,
|
||||
getCanonicalFileName,
|
||||
log,
|
||||
}, mapFileName, maps, getProgram(), sourcemappedFileCache);
|
||||
@ -105,7 +107,11 @@ namespace ts {
|
||||
|
||||
function tryGetGeneratedLocation(info: sourcemaps.SourceMappableLocation): sourcemaps.SourceMappableLocation | undefined {
|
||||
const program = getProgram();
|
||||
const declarationPath = getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
|
||||
const options = program.getCompilerOptions();
|
||||
const outPath = options.outFile || options.out;
|
||||
const declarationPath = outPath ?
|
||||
removeFileExtension(outPath) + Extension.Dts :
|
||||
getDeclarationEmitOutputFilePathWorker(info.fileName, program.getCompilerOptions(), currentDirectory, program.getCommonSourceDirectory(), getCanonicalFileName);
|
||||
if (declarationPath === undefined) return undefined;
|
||||
const declarationFile = getFile(declarationPath);
|
||||
if (!declarationFile) return undefined;
|
||||
|
||||
@ -10481,13 +10481,15 @@ declare class TestLib {
|
||||
TestFSWithWatch.getTsBuildProjectFile(project, "index.ts"),
|
||||
];
|
||||
}
|
||||
it("does not error on container only project", () => {
|
||||
const project = "container";
|
||||
const containerLib = getProjectFiles("container/lib");
|
||||
const containerExec = getProjectFiles("container/exec");
|
||||
const containerCompositeExec = getProjectFiles("container/compositeExec");
|
||||
const containerConfig = TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json");
|
||||
const files = [libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig];
|
||||
|
||||
const project = "container";
|
||||
const containerLib = getProjectFiles("container/lib");
|
||||
const containerExec = getProjectFiles("container/exec");
|
||||
const containerCompositeExec = getProjectFiles("container/compositeExec");
|
||||
const containerConfig = TestFSWithWatch.getTsBuildProjectFile(project, "tsconfig.json");
|
||||
const files = [libFile, ...containerLib, ...containerExec, ...containerCompositeExec, containerConfig];
|
||||
|
||||
function createHost() {
|
||||
const host = createServerHost(files);
|
||||
|
||||
// ts build should succeed
|
||||
@ -10495,6 +10497,12 @@ declare class TestLib {
|
||||
solutionBuilder.buildAllProjects();
|
||||
assert.equal(host.getOutput().length, 0);
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
it("does not error on container only project", () => {
|
||||
const host = createHost();
|
||||
|
||||
// Open external project for the folder
|
||||
const session = createSession(host);
|
||||
const service = session.getProjectService();
|
||||
@ -10521,6 +10529,30 @@ declare class TestLib {
|
||||
assert.deepEqual(semanticDiagnostics, []);
|
||||
});
|
||||
});
|
||||
|
||||
it("can successfully find references with --out options", () => {
|
||||
const host = createHost();
|
||||
const session = createSession(host);
|
||||
openFilesForSession([containerCompositeExec[1]], session);
|
||||
const service = session.getProjectService();
|
||||
checkNumberOfProjects(service, { configuredProjects: 1 });
|
||||
const locationOfMyConst = protocolLocationFromSubstring(containerCompositeExec[1].content, "myConst");
|
||||
const response = session.executeCommandSeq<protocol.RenameRequest>({
|
||||
command: protocol.CommandTypes.Rename,
|
||||
arguments: {
|
||||
file: containerCompositeExec[1].path,
|
||||
...locationOfMyConst
|
||||
}
|
||||
}).response as protocol.RenameResponseBody;
|
||||
|
||||
|
||||
const myConstLen = "myConst".length;
|
||||
const locationOfMyConstInLib = protocolLocationFromSubstring(containerLib[1].content, "myConst");
|
||||
assert.deepEqual(response.locs, [
|
||||
{ file: containerCompositeExec[1].path, locs: [{ start: locationOfMyConst, end: { line: locationOfMyConst.line, offset: locationOfMyConst.offset + myConstLen } }] },
|
||||
{ file: containerLib[1].path, locs: [{ start: locationOfMyConstInLib, end: { line: locationOfMyConstInLib.line, offset: locationOfMyConstInLib.offset + myConstLen } }] }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem duplicate packages", () => {
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outFile": "../built/local/compositeExec.js",
|
||||
"composite": true
|
||||
"composite": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"files": [
|
||||
"index.ts"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user