Reset hasChangedAutomaticTypeDirectiveNames once new program is created (#37266)

* Allow passing watch to the change as parameter

* Reset hasChangedAutomaticTypeDirectiveNames once new program is created
Also dont invoke afterProgramCreate if the program is not new
This commit is contained in:
Sheetal Nandi 2020-03-06 18:21:16 -08:00 committed by GitHub
parent c0c5760d15
commit 8dede43365
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 33 deletions

View File

@ -380,7 +380,7 @@ namespace ts {
createNewProgram(hasInvalidatedResolution);
}
if (host.afterProgramCreate) {
if (host.afterProgramCreate && program !== builderProgram) {
host.afterProgramCreate(builderProgram);
}
@ -399,6 +399,7 @@ namespace ts {
resolutionCache.startCachingPerDirectoryResolution();
compilerHost.hasInvalidatedResolution = hasInvalidatedResolution;
compilerHost.hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames;
hasChangedAutomaticTypeDirectiveNames = false;
builderProgram = createProgram(rootFileNames, compilerOptions, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
resolutionCache.finishCachingPerDirectoryResolution();

View File

@ -598,7 +598,7 @@ let x: string = 10;`);
}
function verifyDependencies(watch: Watch, filePath: string, expected: readonly string[]) {
checkArray(`${filePath} dependencies`, watch.getBuilderProgram().getAllDependencies(watch().getSourceFile(filePath)!), expected);
checkArray(`${filePath} dependencies`, watch.getCurrentProgram().getAllDependencies(watch.getCurrentProgram().getSourceFile(filePath)!), expected);
}
describe("on sample project", () => {
@ -639,7 +639,7 @@ let x: string = 10;`);
host.checkTimeoutQueueLengthAndRun(1);
checkOutputErrorsIncremental(host, emptyArray);
checkProgramActualFiles(watch(), expectedProgramFilesAfterEdit());
checkProgramActualFiles(watch.getCurrentProgram().getProgram(), expectedProgramFilesAfterEdit());
});
@ -739,7 +739,7 @@ export function gfoo() {
expectedWatchedDirectoriesRecursive: readonly string[],
dependencies: readonly [string, readonly string[]][],
expectedWatchedDirectories?: readonly string[]) {
checkProgramActualFiles(watch(), expectedProgramFiles);
checkProgramActualFiles(watch.getCurrentProgram().getProgram(), expectedProgramFiles);
verifyWatchesOfProject(host, expectedWatchedFiles, expectedWatchedDirectoriesRecursive, expectedWatchedDirectories);
for (const [file, deps] of dependencies) {
verifyDependencies(watch, file, deps);

View File

@ -49,10 +49,11 @@ namespace ts.tscWatch {
subScenario: "when preserveWatchOutput is true in config file/createWatchOfConfigFile",
commandLineArgs: ["--w", "-p", configFile.path],
sys,
getPrograms: () => [[watch(), watch.getBuilderProgram()]],
getPrograms: () => [[watch.getCurrentProgram().getProgram(), watch.getCurrentProgram()]],
changes: [
makeChangeToFile
]
],
watchOrSolution: watch
});
});
verifyTscWatch({

View File

@ -31,27 +31,18 @@ namespace ts.tscWatch {
checkArray(`Program rootFileNames`, program.getRootFileNames(), expectedFiles);
}
export interface Watch {
(): Program;
getBuilderProgram(): EmitAndSemanticDiagnosticsBuilderProgram;
close(): void;
}
export type Watch = WatchOfConfigFile<EmitAndSemanticDiagnosticsBuilderProgram> | WatchOfFilesAndCompilerOptions<EmitAndSemanticDiagnosticsBuilderProgram>;
export function createWatchOfConfigFile(configFileName: string, host: WatchedSystem, optionsToExtend?: CompilerOptions, watchOptionsToExtend?: WatchOptions, maxNumberOfFilesToIterateForInvalidation?: number) {
const compilerHost = createWatchCompilerHostOfConfigFile(configFileName, optionsToExtend || {}, watchOptionsToExtend, host);
compilerHost.maxNumberOfFilesToIterateForInvalidation = maxNumberOfFilesToIterateForInvalidation;
const watch = createWatchProgram(compilerHost);
const result = (() => watch.getCurrentProgram().getProgram()) as Watch;
result.getBuilderProgram = () => watch.getCurrentProgram();
result.close = () => watch.close();
return result;
return createWatchProgram(compilerHost);
}
export function createWatchOfFilesAndCompilerOptions(rootFiles: string[], host: WatchedSystem, options: CompilerOptions = {}, watchOptions?: WatchOptions, maxNumberOfFilesToIterateForInvalidation?: number) {
const compilerHost = createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles, options, watchOptions, host);
compilerHost.maxNumberOfFilesToIterateForInvalidation = maxNumberOfFilesToIterateForInvalidation;
const watch = createWatchProgram(compilerHost);
return () => watch.getCurrentProgram().getProgram();
return createWatchProgram(compilerHost);
}
const elapsedRegex = /^Elapsed:: [0-9]+ms/;
@ -281,7 +272,11 @@ namespace ts.tscWatch {
return getDiagnosticOfFileFromProgram(program, file.path, file.content.indexOf(quotedModuleName), quotedModuleName.length, Diagnostics.Cannot_find_module_0, moduleName);
}
export type TscWatchCompileChange = (sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles, programs: readonly CommandLineProgram[]) => string;
export type TscWatchCompileChange = (
sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles,
programs: readonly CommandLineProgram[],
watchOrSolution: ReturnType<typeof executeCommandLine>
) => string;
export interface TscWatchCheckOptions {
baselineSourceMap?: boolean;
}
@ -309,7 +304,7 @@ namespace ts.tscWatch {
} = input;
const { cb, getPrograms } = commandLineCallbacks(sys);
executeCommandLine(
const watchOrSolution = executeCommandLine(
sys,
cb,
commandLineArgs,
@ -322,7 +317,8 @@ namespace ts.tscWatch {
sys,
getPrograms,
baselineSourceMap,
changes
changes,
watchOrSolution
});
});
}
@ -330,12 +326,13 @@ namespace ts.tscWatch {
export interface RunWatchBaseline extends TscWatchCompileBase {
sys: TestFSWithWatch.TestServerHostTrackingWrittenFiles;
getPrograms: () => readonly CommandLineProgram[];
watchOrSolution: ReturnType<typeof executeCommandLine>;
}
export function runWatchBaseline({
scenario, subScenario, commandLineArgs,
getPrograms, sys,
baselineSourceMap,
changes
changes, watchOrSolution
}: RunWatchBaseline) {
const baseline: string[] = [];
baseline.push(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}`);
@ -349,7 +346,7 @@ namespace ts.tscWatch {
for (const change of changes) {
const oldSnap = sys.snap();
const caption = change(sys, programs);
const caption = change(sys, programs, watchOrSolution);
baseline.push(`Change:: ${caption}`, "");
programs = watchBaseline({
baseline,

View File

@ -497,13 +497,13 @@ export class A {
};
const host = createWatchedSystem([file1, file2, file3]);
const watch = createWatchOfFilesAndCompilerOptions([file2.path, file3.path], host);
checkProgramActualFiles(watch(), [file2.path, file3.path]);
checkProgramActualFiles(watch.getCurrentProgram().getProgram(), [file2.path, file3.path]);
const watch2 = createWatchOfFilesAndCompilerOptions([file1.path], host);
checkProgramActualFiles(watch2(), [file1.path, file2.path, file3.path]);
checkProgramActualFiles(watch2.getCurrentProgram().getProgram(), [file1.path, file2.path, file3.path]);
// Previous program shouldnt be updated
checkProgramActualFiles(watch(), [file2.path, file3.path]);
checkProgramActualFiles(watch.getCurrentProgram().getProgram(), [file2.path, file3.path]);
host.checkTimeoutQueueLength(0);
});
@ -937,7 +937,7 @@ declare const eval: any`
};
const host = createWatchedSystem([f, libFile]);
const watch = createWatchOfFilesAndCompilerOptions([f.path], host, { allowNonTsExtensions: true });
checkProgramActualFiles(watch(), [f.path, libFile.path]);
checkProgramActualFiles(watch.getCurrentProgram().getProgram(), [f.path, libFile.path]);
});
verifyTscWatch({

View File

@ -15,8 +15,8 @@ namespace ts.tscWatch {
const host = createWatchedSystem(files);
const watch = createWatchOfFilesAndCompilerOptions([root.path], host, { module: ModuleKind.AMD });
const f1IsNotModule = getDiagnosticOfFileFromProgram(watch(), root.path, root.content.indexOf('"f1"'), '"f1"'.length, Diagnostics.File_0_is_not_a_module, imported.path);
const cannotFindFoo = getDiagnosticOfFileFromProgram(watch(), imported.path, imported.content.indexOf("foo"), "foo".length, Diagnostics.Cannot_find_name_0, "foo");
const f1IsNotModule = getDiagnosticOfFileFromProgram(watch.getCurrentProgram().getProgram(), root.path, root.content.indexOf('"f1"'), '"f1"'.length, Diagnostics.File_0_is_not_a_module, imported.path);
const cannotFindFoo = getDiagnosticOfFileFromProgram(watch.getCurrentProgram().getProgram(), imported.path, imported.content.indexOf("foo"), "foo".length, Diagnostics.Cannot_find_name_0, "foo");
// ensure that imported file was found
checkOutputErrorsInitial(host, [f1IsNotModule, cannotFindFoo]);
@ -37,7 +37,7 @@ namespace ts.tscWatch {
// ensure file has correct number of errors after edit
checkOutputErrorsIncremental(host, [
f1IsNotModule,
getDiagnosticOfFileFromProgram(watch(), root.path, newContent.indexOf("var x") + "var ".length, "x".length, Diagnostics.Type_0_is_not_assignable_to_type_1, 1, "string"),
getDiagnosticOfFileFromProgram(watch.getCurrentProgram().getProgram(), root.path, newContent.indexOf("var x") + "var ".length, "x".length, Diagnostics.Type_0_is_not_assignable_to_type_1, 1, "string"),
cannotFindFoo
]);
}
@ -60,7 +60,7 @@ namespace ts.tscWatch {
// ensure file has correct number of errors after edit
checkOutputErrorsIncremental(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "f2")
getDiagnosticModuleNotFoundOfFile(watch.getCurrentProgram().getProgram(), root, "f2")
]);
assert.isTrue(fileExistsIsCalled);
@ -118,7 +118,7 @@ namespace ts.tscWatch {
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
checkOutputErrorsInitial(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "bar")
getDiagnosticModuleNotFoundOfFile(watch.getCurrentProgram().getProgram(), root, "bar")
]);
fileExistsCalledForBar = false;
@ -166,7 +166,7 @@ namespace ts.tscWatch {
host.runQueuedTimeoutCallbacks();
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called.");
checkOutputErrorsIncremental(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "bar")
getDiagnosticModuleNotFoundOfFile(watch.getCurrentProgram().getProgram(), root, "bar")
]);
fileExistsCalledForBar = false;
@ -391,6 +391,13 @@ declare namespace myapp {
});
sys.checkTimeoutQueueLengthAndRun(1);
return "npm install ts-types";
},
(sys, [[oldProgram, oldBuilderProgram]], watchorSolution) => {
sys.checkTimeoutQueueLength(0);
const newProgram = (watchorSolution as Watch).getProgram();
assert.strictEqual(newProgram, oldBuilderProgram, "No change so builder program should be same");
assert.strictEqual(newProgram.getProgram(), oldProgram, "No change so program should be same");
return "No change, just check program";
}
]
});

View File

@ -113,3 +113,28 @@ FsWatchesRecursive::
{"directoryName":"/user/username/projects/myproject","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
exitCode:: ExitStatus.undefined
Change:: No change, just check program
Output::
WatchedFiles::
/user/username/projects/myproject/tsconfig.json:
{"fileName":"/user/username/projects/myproject/tsconfig.json","pollingInterval":250}
/user/username/projects/myproject/lib/app.ts:
{"fileName":"/user/username/projects/myproject/lib/app.ts","pollingInterval":250}
/a/lib/lib.d.ts:
{"fileName":"/a/lib/lib.d.ts","pollingInterval":250}
/user/username/projects/myproject/node_modules/@myapp/ts-types/types/somefile.define.d.ts:
{"fileName":"/user/username/projects/myproject/node_modules/@myapp/ts-types/types/somefile.define.d.ts","pollingInterval":250}
FsWatches::
FsWatchesRecursive::
/user/username/projects/myproject/node_modules:
{"directoryName":"/user/username/projects/myproject/node_modules","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
/user/username/projects/myproject:
{"directoryName":"/user/username/projects/myproject","fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
exitCode:: ExitStatus.undefined