Merge pull request #32360 from microsoft/incrementalPaths

Ensure that the filePaths in compiler options are absolute before getting relative path to buildInfo directory
This commit is contained in:
Sheetal Nandi 2019-07-11 13:45:39 -07:00 committed by GitHub
commit ea730939d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 63 deletions

View file

@ -612,7 +612,8 @@ namespace ts {
*/
function getProgramBuildInfo(state: Readonly<ReusableBuilderProgramState>, getCanonicalFileName: GetCanonicalFileName): ProgramBuildInfo | undefined {
if (state.compilerOptions.outFile || state.compilerOptions.out) return undefined;
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getOutputPathForBuildInfo(state.compilerOptions)!, Debug.assertDefined(state.program).getCurrentDirectory()));
const currentDirectory = Debug.assertDefined(state.program).getCurrentDirectory();
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getOutputPathForBuildInfo(state.compilerOptions)!, currentDirectory));
const fileInfos: MapLike<BuilderState.FileInfo> = {};
state.fileInfos.forEach((value, key) => {
const signature = state.currentAffectedFilesSignatures && state.currentAffectedFilesSignatures.get(key);
@ -621,7 +622,7 @@ namespace ts {
const result: ProgramBuildInfo = {
fileInfos,
options: convertToReusableCompilerOptions(state.compilerOptions, relativeToBuildInfo)
options: convertToReusableCompilerOptions(state.compilerOptions, relativeToBuildInfoEnsuringAbsolutePath)
};
if (state.referencedMap) {
const referencedMap: MapLike<string[]> = {};
@ -661,6 +662,10 @@ namespace ts {
return result;
function relativeToBuildInfoEnsuringAbsolutePath(path: string) {
return relativeToBuildInfo(getNormalizedAbsolutePath(path, currentDirectory));
}
function relativeToBuildInfo(path: string) {
return ensurePathIsNonModuleName(getRelativePathFromDirectory(buildInfoDirectory, path, getCanonicalFileName));
}

View file

@ -35,8 +35,8 @@ namespace ts.tscWatch {
close(): void;
}
export function createWatchOfConfigFile(configFileName: string, host: WatchedSystem, maxNumberOfFilesToIterateForInvalidation?: number) {
const compilerHost = createWatchCompilerHostOfConfigFile(configFileName, {}, host);
export function createWatchOfConfigFile(configFileName: string, host: WatchedSystem, optionsToExtend?: CompilerOptions, maxNumberOfFilesToIterateForInvalidation?: number) {
const compilerHost = createWatchCompilerHostOfConfigFile(configFileName, optionsToExtend || {}, host);
compilerHost.maxNumberOfFilesToIterateForInvalidation = maxNumberOfFilesToIterateForInvalidation;
const watch = createWatchProgram(compilerHost);
const result = (() => watch.getCurrentProgram().getProgram()) as Watch;

View file

@ -9,6 +9,7 @@ namespace ts.tscWatch {
interface VerifyIncrementalWatchEmitInput {
files: ReadonlyArray<File>;
optionsToExtend?: CompilerOptions;
expectedInitialEmit: ReadonlyArray<File>;
expectedInitialErrors: ReadonlyArray<string>;
modifyFs?: (host: WatchedSystem) => void;
@ -32,9 +33,9 @@ namespace ts.tscWatch {
});
}
function incrementalBuild(configFile: string, host: WatchedSystem) {
function incrementalBuild(configFile: string, host: WatchedSystem, optionsToExtend?: CompilerOptions) {
const reportDiagnostic = createDiagnosticReporter(host);
const config = parseConfigFileWithSystem(configFile, {}, host, reportDiagnostic);
const config = parseConfigFileWithSystem(configFile, optionsToExtend || {}, host, reportDiagnostic);
if (config) {
performIncrementalCompilation({
rootNames: config.fileNames,
@ -50,12 +51,14 @@ namespace ts.tscWatch {
interface VerifyIncrementalWatchEmitWorkerInput {
input: VerifyIncrementalWatchEmitInput;
emitAndReportErrors: (configFile: string, host: WatchedSystem) => { close(): void; };
emitAndReportErrors: (configFile: string, host: WatchedSystem, optionsToExtend?: CompilerOptions) => { close(): void; };
verifyErrors: (host: WatchedSystem, errors: ReadonlyArray<string>) => void;
}
function verifyIncrementalWatchEmitWorker({
input: {
files, expectedInitialEmit, expectedInitialErrors, modifyFs, expectedIncrementalEmit, expectedIncrementalErrors
files, optionsToExtend,
expectedInitialEmit, expectedInitialErrors,
modifyFs, expectedIncrementalEmit, expectedIncrementalErrors
},
emitAndReportErrors,
verifyErrors
@ -70,6 +73,7 @@ namespace ts.tscWatch {
};
verifyBuild({
host,
optionsToExtend,
writtenFiles,
emitAndReportErrors,
verifyErrors,
@ -80,6 +84,7 @@ namespace ts.tscWatch {
modifyFs(host);
verifyBuild({
host,
optionsToExtend,
writtenFiles,
emitAndReportErrors,
verifyErrors,
@ -91,15 +96,19 @@ namespace ts.tscWatch {
interface VerifyBuildWorker {
host: WatchedSystem;
optionsToExtend?: CompilerOptions;
writtenFiles: Map<string>;
emitAndReportErrors: VerifyIncrementalWatchEmitWorkerInput["emitAndReportErrors"];
verifyErrors: VerifyIncrementalWatchEmitWorkerInput["verifyErrors"];
expectedEmit: ReadonlyArray<File>;
expectedErrors: ReadonlyArray<string>;
}
function verifyBuild({ host, writtenFiles, emitAndReportErrors, verifyErrors, expectedEmit, expectedErrors }: VerifyBuildWorker) {
function verifyBuild({
host, optionsToExtend, writtenFiles, emitAndReportErrors,
verifyErrors, expectedEmit, expectedErrors
}: VerifyBuildWorker) {
writtenFiles.clear();
const result = emitAndReportErrors("tsconfig.json", host);
const result = emitAndReportErrors("tsconfig.json", host, optionsToExtend);
checkFileEmit(writtenFiles, expectedEmit);
verifyErrors(host, expectedErrors);
result.close();
@ -159,60 +168,69 @@ namespace ts.tscWatch {
content: "var y = 20;\n"
};
describe("own file emit without errors", () => {
const modifiedFile2Content = file2.content.replace("y", "z").replace("20", "10");
verifyIncrementalWatchEmit({
files: [libFile, file1, file2, configFile],
expectedInitialEmit: [
file1Js,
file2Js,
{
path: `${project}/tsconfig.tsbuildinfo`,
content: getBuildInfoText({
program: {
fileInfos: {
[libFilePath]: libFileInfo,
[file1Path]: getFileInfo(file1.content),
[file2Path]: getFileInfo(file2.content)
function verify(optionsToExtend?: CompilerOptions, expectedBuildinfoOptions?: CompilerOptions) {
const modifiedFile2Content = file2.content.replace("y", "z").replace("20", "10");
verifyIncrementalWatchEmit({
files: [libFile, file1, file2, configFile],
optionsToExtend,
expectedInitialEmit: [
file1Js,
file2Js,
{
path: `${project}/tsconfig.tsbuildinfo`,
content: getBuildInfoText({
program: {
fileInfos: {
[libFilePath]: libFileInfo,
[file1Path]: getFileInfo(file1.content),
[file2Path]: getFileInfo(file2.content)
},
options: {
incremental: true,
...expectedBuildinfoOptions,
configFilePath: "./tsconfig.json"
},
referencedMap: {},
exportedModulesMap: {},
semanticDiagnosticsPerFile: [libFilePath, file1Path, file2Path]
},
options: {
incremental: true,
configFilePath: "./tsconfig.json"
version
})
}
],
expectedInitialErrors: emptyArray,
modifyFs: host => host.writeFile(file2.path, modifiedFile2Content),
expectedIncrementalEmit: [
file1Js,
{ path: file2Js.path, content: file2Js.content.replace("y", "z").replace("20", "10") },
{
path: `${project}/tsconfig.tsbuildinfo`,
content: getBuildInfoText({
program: {
fileInfos: {
[libFilePath]: libFileInfo,
[file1Path]: getFileInfo(file1.content),
[file2Path]: getFileInfo(modifiedFile2Content)
},
options: {
incremental: true,
...expectedBuildinfoOptions,
configFilePath: "./tsconfig.json"
},
referencedMap: {},
exportedModulesMap: {},
semanticDiagnosticsPerFile: [libFilePath, file1Path, file2Path]
},
referencedMap: {},
exportedModulesMap: {},
semanticDiagnosticsPerFile: [libFilePath, file1Path, file2Path]
},
version
})
}
],
expectedInitialErrors: emptyArray,
modifyFs: host => host.writeFile(file2.path, modifiedFile2Content),
expectedIncrementalEmit: [
file1Js,
{ path: file2Js.path, content: file2Js.content.replace("y", "z").replace("20", "10") },
{
path: `${project}/tsconfig.tsbuildinfo`,
content: getBuildInfoText({
program: {
fileInfos: {
[libFilePath]: libFileInfo,
[file1Path]: getFileInfo(file1.content),
[file2Path]: getFileInfo(modifiedFile2Content)
},
options: {
incremental: true,
configFilePath: "./tsconfig.json"
},
referencedMap: {},
exportedModulesMap: {},
semanticDiagnosticsPerFile: [libFilePath, file1Path, file2Path]
},
version
})
}
],
expectedIncrementalErrors: emptyArray,
version
})
}
],
expectedIncrementalErrors: emptyArray,
});
}
verify();
describe("with commandline parameters that are not relative", () => {
verify({ project: "tsconfig.json" }, { project: "./tsconfig.json" });
});
});
@ -337,6 +355,7 @@ namespace ts.tscWatch {
expectedInitialErrors: emptyArray
});
});
});
describe("module compilation", () => {

View file

@ -931,7 +931,7 @@ namespace ts.tscWatch {
content: generateTSConfig(options, emptyArray, "\n")
};
const host = createWatchedSystem([file1, file2, libFile, tsconfig], { currentDirectory: proj });
const watch = createWatchOfConfigFile(tsconfig.path, host, /*maxNumberOfFilesToIterateForInvalidation*/1);
const watch = createWatchOfConfigFile(tsconfig.path, host, /*optionsToExtend*/ undefined, /*maxNumberOfFilesToIterateForInvalidation*/1);
checkProgramActualFiles(watch(), [file1.path, file2.path, libFile.path]);
outputFiles.forEach(f => host.fileExists(f));