Expose the watch and builder API in the typescript.d.ts

This commit is contained in:
Sheetal Nandi 2017-10-26 10:00:23 -07:00
parent a06f0c3d9f
commit 576fe1e995
7 changed files with 382 additions and 235 deletions

View File

@ -21,10 +21,10 @@ namespace ts {
return <string>diagnostic.messageText;
}
let reportDiagnostic = createDiagnosticReporter(sys, reportDiagnosticSimply);
let reportDiagnostic = createDiagnosticReporter();
function udpateReportDiagnostic(options: CompilerOptions) {
if (options.pretty) {
reportDiagnostic = createDiagnosticReporter(sys, reportDiagnosticWithColorAndContext);
reportDiagnostic = createDiagnosticReporter(sys, /*pretty*/ true);
}
}
@ -55,7 +55,7 @@ namespace ts {
// If there are any errors due to command line parsing and/or
// setting up localization, report them and quit.
if (commandLine.errors.length > 0) {
reportDiagnostics(commandLine.errors, reportDiagnostic);
commandLine.errors.forEach(reportDiagnostic);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
@ -110,12 +110,11 @@ namespace ts {
const commandLineOptions = commandLine.options;
if (configFileName) {
const reportWatchDiagnostic = createWatchDiagnosticReporter();
const configParseResult = parseConfigFile(configFileName, commandLineOptions, sys, reportDiagnostic, reportWatchDiagnostic);
const configParseResult = parseConfigFile(configFileName, commandLineOptions, sys, reportDiagnostic);
udpateReportDiagnostic(configParseResult.options);
if (isWatchSet(configParseResult.options)) {
reportWatchModeWithoutSysSupport();
createWatchModeWithConfigFile(configParseResult, commandLineOptions, createWatchingSystemHost(reportWatchDiagnostic));
createWatchOfConfigFile(configParseResult, commandLineOptions);
}
else {
performCompilation(configParseResult.fileNames, configParseResult.options);
@ -125,7 +124,7 @@ namespace ts {
udpateReportDiagnostic(commandLineOptions);
if (isWatchSet(commandLineOptions)) {
reportWatchModeWithoutSysSupport();
createWatchModeWithoutConfigFile(commandLine.fileNames, commandLineOptions, createWatchingSystemHost());
createWatchOfFilesAndCompilerOptions(commandLine.fileNames, commandLineOptions);
}
else {
performCompilation(commandLine.fileNames, commandLineOptions);
@ -151,15 +150,37 @@ namespace ts {
return sys.exit(exitStatus);
}
function createWatchingSystemHost(reportWatchDiagnostic?: DiagnosticReporter) {
const watchingHost = ts.createWatchingSystemHost(/*pretty*/ undefined, sys, parseConfigFile, reportDiagnostic, reportWatchDiagnostic);
watchingHost.beforeCompile = enableStatistics;
const afterCompile = watchingHost.afterCompile;
watchingHost.afterCompile = (host, program) => {
afterCompile(host, program);
function createProgramCompilerWithBuilderState() {
const compilerWithBuilderState = ts.createProgramCompilerWithBuilderState(sys, reportDiagnostic);
return (host: DirectoryStructureHost, program: Program) => {
compilerWithBuilderState(host, program);
reportStatistics(program);
};
return watchingHost;
}
function createWatchOfConfigFile(configParseResult: ParsedCommandLine, optionsToExtend: CompilerOptions) {
createWatch({
system: sys,
beforeProgramCreate: enableStatistics,
afterProgramCreate: createProgramCompilerWithBuilderState(),
onConfigFileDiagnostic: reportDiagnostic,
rootFiles: configParseResult.fileNames,
options: configParseResult.options,
configFileName: configParseResult.options.configFilePath,
optionsToExtend,
configFileSpecs: configParseResult.configFileSpecs,
configFileWildCardDirectories: configParseResult.wildcardDirectories
});
}
function createWatchOfFilesAndCompilerOptions(rootFiles: string[], options: CompilerOptions) {
createWatch({
system: sys,
beforeProgramCreate: enableStatistics,
afterProgramCreate: createProgramCompilerWithBuilderState(),
rootFiles,
options
});
}
function compileProgram(program: Program): ExitStatus {
@ -182,7 +203,18 @@ namespace ts {
const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit();
addRange(diagnostics, emitDiagnostics);
return handleEmitOutputAndReportErrors(sys, program, emittedFiles, emitSkipped, diagnostics, reportDiagnostic);
sortAndDeduplicateDiagnostics(diagnostics).forEach(reportDiagnostic);
writeFileAndEmittedFileList(sys, program, emittedFiles);
if (emitSkipped && diagnostics.length > 0) {
// If the emitter didn't emit anything, then pass that value along.
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
}
else if (diagnostics.length > 0) {
// The emitter emitted something, inform the caller if that happened in the presence
// of diagnostics or not.
return ExitStatus.DiagnosticsPresent_OutputsGenerated;
}
return ExitStatus.Success;
}
function enableStatistics(compilerOptions: CompilerOptions) {

View File

@ -4,149 +4,97 @@
namespace ts {
export type DiagnosticReporter = (diagnostic: Diagnostic) => void;
export type ParseConfigFile = (configFileName: string, optionsToExtend: CompilerOptions, system: DirectoryStructureHost, reportDiagnostic: DiagnosticReporter, reportWatchDiagnostic: DiagnosticReporter) => ParsedCommandLine;
export interface WatchingSystemHost {
// FS system to use
system: System;
// parse config file
parseConfigFile: ParseConfigFile;
// Reporting errors
reportDiagnostic: DiagnosticReporter;
reportWatchDiagnostic: DiagnosticReporter;
// Callbacks to do custom action before creating program and after creating program
beforeCompile(compilerOptions: CompilerOptions): void;
afterCompile(host: DirectoryStructureHost, program: Program): void;
}
const defaultFormatDiagnosticsHost: FormatDiagnosticsHost = sys ? {
const sysFormatDiagnosticsHost: FormatDiagnosticsHost = sys ? {
getCurrentDirectory: () => sys.getCurrentDirectory(),
getNewLine: () => sys.newLine,
getCanonicalFileName: createGetCanonicalFileName(sys.useCaseSensitiveFileNames)
} : undefined;
export function createDiagnosticReporter(system = sys, worker = reportDiagnosticSimply, formatDiagnosticsHost?: FormatDiagnosticsHost): DiagnosticReporter {
return diagnostic => worker(diagnostic, getFormatDiagnosticsHost(), system);
function getFormatDiagnosticsHost() {
return formatDiagnosticsHost || (formatDiagnosticsHost = system === sys ? defaultFormatDiagnosticsHost : {
getCurrentDirectory: () => system.getCurrentDirectory(),
getNewLine: () => system.newLine,
getCanonicalFileName: createGetCanonicalFileName(system.useCaseSensitiveFileNames),
});
/**
* Create a function that reports error by writing to the system and handles the formating of the diagnostic
*/
/*@internal*/
export function createDiagnosticReporter(system = sys, pretty?: boolean): DiagnosticReporter {
const host: FormatDiagnosticsHost = system === sys ? sysFormatDiagnosticsHost : {
getCurrentDirectory: () => system.getCurrentDirectory(),
getNewLine: () => system.newLine,
getCanonicalFileName: createGetCanonicalFileName(system.useCaseSensitiveFileNames),
};
if (!pretty) {
return diagnostic => system.write(ts.formatDiagnostic(diagnostic, host));
}
}
export function createWatchDiagnosticReporter(system = sys): DiagnosticReporter {
const diagnostics: Diagnostic[] = new Array(1);
return diagnostic => {
let output = new Date().toLocaleTimeString() + " - ";
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${system.newLine + system.newLine + system.newLine}`;
system.write(output);
diagnostics[0] = diagnostic;
system.write(formatDiagnosticsWithColorAndContext(diagnostics, host) + host.getNewLine());
diagnostics[0] = undefined;
};
}
export function reportDiagnostics(diagnostics: Diagnostic[], reportDiagnostic: DiagnosticReporter): void {
for (const diagnostic of diagnostics) {
reportDiagnostic(diagnostic);
}
}
export function reportDiagnosticSimply(diagnostic: Diagnostic, host: FormatDiagnosticsHost, system: System): void {
system.write(ts.formatDiagnostic(diagnostic, host));
}
export function reportDiagnosticWithColorAndContext(diagnostic: Diagnostic, host: FormatDiagnosticsHost, system: System): void {
system.write(ts.formatDiagnosticsWithColorAndContext([diagnostic], host) + host.getNewLine());
}
export function parseConfigFile(configFileName: string, optionsToExtend: CompilerOptions, system: DirectoryStructureHost, reportDiagnostic: DiagnosticReporter, reportWatchDiagnostic: DiagnosticReporter): ParsedCommandLine {
/**
* Reads the config file, reports errors if any and exits if the config file cannot be found
*/
/*@internal*/
export function parseConfigFile(configFileName: string, optionsToExtend: CompilerOptions, system: DirectoryStructureHost, reportDiagnostic: DiagnosticReporter): ParsedCommandLine {
let configFileText: string;
try {
configFileText = system.readFile(configFileName);
}
catch (e) {
const error = createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, configFileName, e.message);
reportWatchDiagnostic(error);
reportDiagnostic(error);
system.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
return;
}
if (!configFileText) {
const error = createCompilerDiagnostic(Diagnostics.File_0_not_found, configFileName);
reportDiagnostics([error], reportDiagnostic);
reportDiagnostic(error);
system.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
return;
}
const result = parseJsonText(configFileName, configFileText);
reportDiagnostics(result.parseDiagnostics, reportDiagnostic);
result.parseDiagnostics.forEach(reportDiagnostic);
const cwd = system.getCurrentDirectory();
const configParseResult = parseJsonSourceFileConfigFileContent(result, system, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd));
reportDiagnostics(configParseResult.errors, reportDiagnostic);
configParseResult.errors.forEach(reportDiagnostic);
return configParseResult;
}
function reportEmittedFiles(files: string[], system: DirectoryStructureHost): void {
if (!files || files.length === 0) {
return;
}
/**
* Writes emitted files, source files depending on options
*/
/*@internal*/
export function writeFileAndEmittedFileList(system: System, program: Program, emittedFiles: string[]) {
const currentDir = system.getCurrentDirectory();
for (const file of files) {
forEach(emittedFiles, file => {
const filepath = getNormalizedAbsolutePath(file, currentDir);
system.write(`TSFILE: ${filepath}${system.newLine}`);
}
}
export function handleEmitOutputAndReportErrors(system: DirectoryStructureHost, program: Program,
emittedFiles: string[], emitSkipped: boolean,
diagnostics: Diagnostic[], reportDiagnostic: DiagnosticReporter
): ExitStatus {
reportDiagnostics(sortAndDeduplicateDiagnostics(diagnostics), reportDiagnostic);
reportEmittedFiles(emittedFiles, system);
});
if (program.getCompilerOptions().listFiles) {
forEach(program.getSourceFiles(), file => {
system.write(file.fileName + system.newLine);
});
}
if (emitSkipped && diagnostics.length > 0) {
// If the emitter didn't emit anything, then pass that value along.
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
}
else if (diagnostics.length > 0) {
// The emitter emitted something, inform the caller if that happened in the presence
// of diagnostics or not.
return ExitStatus.DiagnosticsPresent_OutputsGenerated;
}
return ExitStatus.Success;
}
export function createWatchingSystemHost(pretty?: DiagnosticStyle, system = sys,
parseConfigFile?: ParseConfigFile, reportDiagnostic?: DiagnosticReporter,
reportWatchDiagnostic?: DiagnosticReporter
): WatchingSystemHost {
reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system, pretty ? reportDiagnosticWithColorAndContext : reportDiagnosticSimply);
reportWatchDiagnostic = reportWatchDiagnostic || createWatchDiagnosticReporter(system);
parseConfigFile = parseConfigFile || ts.parseConfigFile;
/**
* Creates the function that compiles the program by maintaining the builder state and also return diagnostic reporter
*/
export function createProgramCompilerWithBuilderState(system = sys, reportDiagnostic?: DiagnosticReporter) {
reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system);
let builderState: Readonly<BuilderState> | undefined;
const options: BuilderOptions = {
getCanonicalFileName: createGetCanonicalFileName(system.useCaseSensitiveFileNames),
computeHash: data => system.createHash ? system.createHash(data) : data
};
return {
system,
parseConfigFile,
reportDiagnostic,
reportWatchDiagnostic,
beforeCompile: noop,
afterCompile: compileWatchedProgram,
};
function compileWatchedProgram(host: DirectoryStructureHost, program: Program) {
return (host: DirectoryStructureHost, program: Program) => {
builderState = createBuilderState(program, options, builderState);
// First get and report any syntactic errors.
@ -179,8 +127,9 @@ namespace ts {
if (reportSemanticDiagnostics) {
addRange(diagnostics, builderState.getSemanticDiagnostics(program));
}
return handleEmitOutputAndReportErrors(host, program, emittedFiles, emitSkipped,
diagnostics, reportDiagnostic);
sortAndDeduplicateDiagnostics(diagnostics).forEach(reportDiagnostic);
writeFileAndEmittedFileList(system, program, emittedFiles);
function ensureDirectoriesExist(directoryPath: string) {
if (directoryPath.length > getRootLength(directoryPath) && !host.directoryExists(directoryPath)) {
@ -210,24 +159,120 @@ namespace ts {
}
}
}
};
}
export interface WatchHost {
/** FS system to use */
system: System;
/** Custom action before creating the program */
beforeProgramCreate(compilerOptions: CompilerOptions): void;
/** Custom action after new program creation is successful */
afterProgramCreate(host: DirectoryStructureHost, program: Program): void;
}
/**
* Host to create watch with root files and options
*/
export interface WatchOfFilesAndCompilerOptionsHost extends WatchHost {
/** root files to use to generate program */
rootFiles: string[];
/** Compiler options */
options: CompilerOptions;
}
/**
* Host to create watch with config file
*/
export interface WatchOfConfigFileHost extends WatchHost {
/** Name of the config file to compile */
configFileName: string;
/** Options to extend */
optionsToExtend?: CompilerOptions;
// Reports errors in the config file
onConfigFileDiagnostic(diagnostic: Diagnostic): void;
}
/*@internal*/
/**
* Host to create watch with config file that is already parsed (from tsc)
*/
export interface WatchOfConfigFileHost extends WatchHost {
rootFiles?: string[];
options?: CompilerOptions;
optionsToExtend?: CompilerOptions;
configFileSpecs?: ConfigFileSpecs;
configFileWildCardDirectories?: MapLike<WatchDirectoryFlags>;
}
export interface Watch {
/** Synchronize the program with the changes */
synchronizeProgram(): void;
/** Get current program */
/*@internal*/
getProgram(): Program;
}
/**
* Creates the watch what generates program using the config file
*/
export interface WatchOfConfigFile extends Watch {
}
/**
* Creates the watch that generates program using the root files and compiler options
*/
export interface WatchOfFilesAndCompilerOptions extends Watch {
/** Updates the root files in the program, only if this is not config file compilation */
updateRootFileNames(fileNames: string[]): void;
}
/**
* Create the watched program for config file
*/
export function createWatchOfConfigFile(configFileName: string, optionsToExtend?: CompilerOptions, system = sys, reportDiagnostic?: DiagnosticReporter): WatchOfConfigFile {
return createWatch({
system,
beforeProgramCreate: noop,
afterProgramCreate: createProgramCompilerWithBuilderState(system, reportDiagnostic),
onConfigFileDiagnostic: reportDiagnostic || createDiagnosticReporter(system),
configFileName,
optionsToExtend
});
}
/**
* Create the watched program for root files and compiler options
*/
export function createWatchOfFilesAndCompilerOptions(rootFiles: string[], options: CompilerOptions, system = sys, reportDiagnostic?: DiagnosticReporter): WatchOfFilesAndCompilerOptions {
return createWatch({
system,
beforeProgramCreate: noop,
afterProgramCreate: createProgramCompilerWithBuilderState(system, reportDiagnostic),
rootFiles,
options
});
}
/**
* Creates the watch from the host for root files and compiler options
*/
export function createWatch(host: WatchOfFilesAndCompilerOptionsHost): WatchOfFilesAndCompilerOptions;
/**
* Creates the watch from the host for config file
*/
export function createWatch(host: WatchOfConfigFileHost): WatchOfConfigFile;
export function createWatch(host: WatchOfFilesAndCompilerOptionsHost | WatchOfConfigFileHost): WatchOfFilesAndCompilerOptions | WatchOfConfigFile {
interface HostFileInfo {
version: number;
sourceFile: SourceFile;
fileWatcher: FileWatcher;
}
}
export function createWatchModeWithConfigFile(configParseResult: ParsedCommandLine, optionsToExtend: CompilerOptions = {}, watchingHost?: WatchingSystemHost) {
return createWatchMode(configParseResult.fileNames, configParseResult.options, watchingHost, configParseResult.options.configFilePath, configParseResult.configFileSpecs, configParseResult.wildcardDirectories, optionsToExtend);
}
export function createWatchModeWithoutConfigFile(rootFileNames: string[], compilerOptions: CompilerOptions, watchingHost?: WatchingSystemHost) {
return createWatchMode(rootFileNames, compilerOptions, watchingHost);
}
interface HostFileInfo {
version: number;
sourceFile: SourceFile;
fileWatcher: FileWatcher;
}
function createWatchMode(rootFileNames: string[], compilerOptions: CompilerOptions, watchingHost?: WatchingSystemHost, configFileName?: string, configFileSpecs?: ConfigFileSpecs, configFileWildCardDirectories?: MapLike<WatchDirectoryFlags>, optionsToExtendForConfigFile?: CompilerOptions) {
let program: Program;
let reloadLevel: ConfigFileProgramReloadLevel; // level to indicate if the program needs to be reloaded from config file/just filenames etc
let missingFilesMap: Map<FileWatcher>; // Map of file watchers for the missing files
@ -239,16 +284,21 @@ namespace ts {
let hasChangedCompilerOptions = false; // True if the compiler options have changed between compilations
let hasChangedAutomaticTypeDirectiveNames = false; // True if the automatic type directives have changed
const { system, configFileName, onConfigFileDiagnostic, afterProgramCreate, beforeProgramCreate, optionsToExtend: optionsToExtendForConfigFile = {} } = host as WatchOfConfigFileHost;
let { rootFiles: rootFileNames, options: compilerOptions, configFileSpecs, configFileWildCardDirectories } = host as WatchOfConfigFileHost;
// From tsc we want to get already parsed result and hence check for rootFileNames
const directoryStructureHost = configFileName ? createCachedDirectoryStructureHost(system) : system;
if (configFileName && !rootFileNames) {
parseConfigFile();
}
const loggingEnabled = compilerOptions.diagnostics || compilerOptions.extendedDiagnostics;
const writeLog: (s: string) => void = loggingEnabled ? s => { system.write(s); system.write(system.newLine); } : noop;
const watchFile = compilerOptions.extendedDiagnostics ? ts.addFileWatcherWithLogging : loggingEnabled ? ts.addFileWatcherWithOnlyTriggerLogging : ts.addFileWatcher;
const watchFilePath = compilerOptions.extendedDiagnostics ? ts.addFilePathWatcherWithLogging : ts.addFilePathWatcher;
const watchDirectoryWorker = compilerOptions.extendedDiagnostics ? ts.addDirectoryWatcherWithLogging : ts.addDirectoryWatcher;
watchingHost = watchingHost || createWatchingSystemHost(compilerOptions.pretty);
const { system, parseConfigFile, reportDiagnostic, reportWatchDiagnostic, beforeCompile, afterCompile } = watchingHost;
const directoryStructureHost = configFileName ? createCachedDirectoryStructureHost(system) : system;
if (configFileName) {
watchFile(system, configFileName, scheduleProgramReload, writeLog);
}
@ -304,7 +354,9 @@ namespace ts {
// Update the wild card directory watch
watchConfigFileWildCardDirectories();
return () => program;
return configFileName ?
{ getProgram: () => program, synchronizeProgram } :
{ getProgram: () => program, synchronizeProgram, updateRootFileNames };
function synchronizeProgram() {
writeLog(`Synchronizing program`);
@ -321,7 +373,7 @@ namespace ts {
return;
}
beforeCompile(compilerOptions);
beforeProgramCreate(compilerOptions);
// Compile the program
const needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !program;
@ -352,10 +404,16 @@ namespace ts {
missingFilePathsRequestedForRelease = undefined;
}
afterCompile(directoryStructureHost, program);
afterProgramCreate(directoryStructureHost, program);
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
}
function updateRootFileNames(files: string[]) {
Debug.assert(!configFileName, "Cannot update root file names with config file watch mode");
rootFileNames = files;
scheduleProgramUpdate();
}
function toPath(fileName: string) {
return ts.toPath(fileName, getCurrentDirectory(), getCanonicalFileName);
}
@ -468,6 +526,10 @@ namespace ts {
}
}
function reportWatchDiagnostic(diagnostic: Diagnostic) {
system.write(`${new Date().toLocaleTimeString()} - ${flattenDiagnosticMessageText(diagnostic.messageText, newLine)}${newLine + newLine + newLine}`);
}
// Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch
// operations (such as saving all modified files in an editor) a chance to complete before we kick
// off a new compilation.
@ -505,7 +567,7 @@ namespace ts {
function reloadFileNamesFromConfigFile() {
const result = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), compilerOptions, directoryStructureHost);
if (!configFileSpecs.filesSpecs && result.fileNames.length === 0) {
reportDiagnostic(getErrorForNoInputFiles(configFileSpecs, configFileName));
onConfigFileDiagnostic(getErrorForNoInputFiles(configFileSpecs, configFileName));
}
rootFileNames = result.fileNames;
@ -519,19 +581,22 @@ namespace ts {
const cachedHost = directoryStructureHost as CachedDirectoryStructureHost;
cachedHost.clearCache();
const configParseResult = parseConfigFile(configFileName, optionsToExtendForConfigFile, cachedHost, reportDiagnostic, reportWatchDiagnostic);
rootFileNames = configParseResult.fileNames;
compilerOptions = configParseResult.options;
parseConfigFile();
hasChangedCompilerOptions = true;
configFileSpecs = configParseResult.configFileSpecs;
configFileWildCardDirectories = configParseResult.wildcardDirectories;
synchronizeProgram();
// Update the wild card directory watch
watchConfigFileWildCardDirectories();
}
function parseConfigFile() {
const configParseResult = ts.parseConfigFile(configFileName, optionsToExtendForConfigFile, directoryStructureHost as CachedDirectoryStructureHost, onConfigFileDiagnostic);
rootFileNames = configParseResult.fileNames;
compilerOptions = configParseResult.options;
configFileSpecs = configParseResult.configFileSpecs;
configFileWildCardDirectories = configParseResult.wildcardDirectories;
}
function onSourceFileChange(fileName: string, eventKind: FileWatcherEventKind, path: Path) {
updateCachedSystemWithFile(fileName, path, eventKind);
const hostSourceFile = sourceFilesCache.get(path);
@ -590,11 +655,16 @@ namespace ts {
}
function watchConfigFileWildCardDirectories() {
updateWatchingWildcardDirectories(
watchedWildcardDirectories || (watchedWildcardDirectories = createMap()),
createMapFromTemplate(configFileWildCardDirectories),
watchWildcardDirectory
);
if (configFileWildCardDirectories) {
updateWatchingWildcardDirectories(
watchedWildcardDirectories || (watchedWildcardDirectories = createMap()),
createMapFromTemplate(configFileWildCardDirectories),
watchWildcardDirectory
);
}
else if (watchedWildcardDirectories) {
clearMap(watchedWildcardDirectories, closeFileWatcherOf);
}
}
function watchWildcardDirectory(directory: string, flags: WatchDirectoryFlags) {

View File

@ -871,7 +871,6 @@ namespace ts {
});
});
import TestSystem = ts.TestFSWithWatch.TestServerHost;
type FileOrFolder = ts.TestFSWithWatch.FileOrFolder;
import createTestSystem = ts.TestFSWithWatch.createWatchedSystem;
import libFile = ts.TestFSWithWatch.libFile;
@ -897,30 +896,21 @@ namespace ts {
return JSON.parse(JSON.stringify(filesOrOptions));
}
function createWatchingSystemHost(host: TestSystem) {
return ts.createWatchingSystemHost(/*pretty*/ undefined, host);
}
function verifyProgramWithoutConfigFile(watchingSystemHost: WatchingSystemHost, rootFiles: string[], options: CompilerOptions) {
const program = createWatchModeWithoutConfigFile(rootFiles, options, watchingSystemHost)();
function verifyProgramWithoutConfigFile(system: System, rootFiles: string[], options: CompilerOptions) {
const program = createWatchOfFilesAndCompilerOptions(rootFiles, options, system).getProgram();
verifyProgramIsUptoDate(program, duplicate(rootFiles), duplicate(options));
}
function getConfigParseResult(watchingSystemHost: WatchingSystemHost, configFileName: string) {
return parseConfigFile(configFileName, {}, watchingSystemHost.system, watchingSystemHost.reportDiagnostic, watchingSystemHost.reportWatchDiagnostic);
}
function verifyProgramWithConfigFile(watchingSystemHost: WatchingSystemHost, configFile: string) {
const result = getConfigParseResult(watchingSystemHost, configFile);
const program = createWatchModeWithConfigFile(result, {}, watchingSystemHost)();
const { fileNames, options } = getConfigParseResult(watchingSystemHost, configFile);
function verifyProgramWithConfigFile(system: System, configFileName: string) {
const program = createWatchOfConfigFile(configFileName, {}, system).getProgram();
const { fileNames, options } = parseConfigFile(configFileName, {}, system, notImplemented);
verifyProgramIsUptoDate(program, fileNames, options);
}
function verifyProgram(files: FileOrFolder[], rootFiles: string[], options: CompilerOptions, configFile: string) {
const watchingSystemHost = createWatchingSystemHost(createTestSystem(files));
verifyProgramWithoutConfigFile(watchingSystemHost, rootFiles, options);
verifyProgramWithConfigFile(watchingSystemHost, configFile);
const system = createTestSystem(files);
verifyProgramWithoutConfigFile(system, rootFiles, options);
verifyProgramWithConfigFile(system, configFile);
}
it("has empty options", () => {
@ -1031,11 +1021,9 @@ namespace ts {
};
const configFile: FileOrFolder = {
path: "/src/tsconfig.json",
content: JSON.stringify({ compilerOptions, include: ["packages/**/ *.ts"] })
content: JSON.stringify({ compilerOptions, include: ["packages/**/*.ts"] })
};
const watchingSystemHost = createWatchingSystemHost(createTestSystem([app, module1, module2, module3, libFile, configFile]));
verifyProgramWithConfigFile(watchingSystemHost, configFile.path);
verifyProgramWithConfigFile(createTestSystem([app, module1, module2, module3, libFile, configFile]), configFile.path);
});
});
}

View File

@ -22,23 +22,14 @@ namespace ts.tscWatch {
checkFileNames(`Program rootFileNames`, program.getRootFileNames(), expectedFiles);
}
function createWatchingSystemHost(system: WatchedSystem) {
return ts.createWatchingSystemHost(/*pretty*/ undefined, system);
function createWatchOfConfigFile(configFileName: string, host: WatchedSystem) {
const watch = ts.createWatchOfConfigFile(configFileName, {}, host);
return () => watch.getProgram();
}
function parseConfigFile(configFileName: string, watchingSystemHost: WatchingSystemHost) {
return ts.parseConfigFile(configFileName, {}, watchingSystemHost.system, watchingSystemHost.reportDiagnostic, watchingSystemHost.reportWatchDiagnostic);
}
function createWatchModeWithConfigFile(configFilePath: string, host: WatchedSystem) {
const watchingSystemHost = createWatchingSystemHost(host);
const configFileResult = parseConfigFile(configFilePath, watchingSystemHost);
return ts.createWatchModeWithConfigFile(configFileResult, {}, watchingSystemHost);
}
function createWatchModeWithoutConfigFile(fileNames: string[], host: WatchedSystem, options: CompilerOptions = {}) {
const watchingSystemHost = createWatchingSystemHost(host);
return ts.createWatchModeWithoutConfigFile(fileNames, options, watchingSystemHost);
function createWatchOfFilesAndCompilerOptions(rootFiles: string[], host: WatchedSystem, options: CompilerOptions = {}) {
const watch = ts.createWatchOfFilesAndCompilerOptions(rootFiles, options, host);
return () => watch.getProgram();
}
function getEmittedLineForMultiFileOutput(file: FileOrFolder, host: WatchedSystem) {
@ -190,7 +181,7 @@ namespace ts.tscWatch {
content: `export let x: number`
};
const host = createWatchedSystem([appFile, moduleFile, libFile]);
const watch = createWatchModeWithoutConfigFile([appFile.path], host);
const watch = createWatchOfFilesAndCompilerOptions([appFile.path], host);
checkProgramActualFiles(watch(), [appFile.path, libFile.path, moduleFile.path]);
@ -215,7 +206,7 @@ namespace ts.tscWatch {
const host = createWatchedSystem([f1, config], { useCaseSensitiveFileNames: false });
const upperCaseConfigFilePath = combinePaths(getDirectoryPath(config.path).toUpperCase(), getBaseFileName(config.path));
const watch = createWatchModeWithConfigFile(upperCaseConfigFilePath, host);
const watch = createWatchOfConfigFile(upperCaseConfigFilePath, host);
checkProgramActualFiles(watch(), [combinePaths(getDirectoryPath(upperCaseConfigFilePath), getBaseFileName(f1.path))]);
});
@ -244,14 +235,10 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([configFile, libFile, file1, file2, file3]);
const watchingSystemHost = createWatchingSystemHost(host);
const configFileResult = parseConfigFile(configFile.path, watchingSystemHost);
assert.equal(configFileResult.errors.length, 0, `expect no errors in config file, got ${JSON.stringify(configFileResult.errors)}`);
const watch = ts.createWatchOfConfigFile(configFile.path, {}, host, notImplemented);
const watch = ts.createWatchModeWithConfigFile(configFileResult, {}, watchingSystemHost);
checkProgramActualFiles(watch(), [file1.path, libFile.path, file2.path]);
checkProgramRootFiles(watch(), [file1.path, file2.path]);
checkProgramActualFiles(watch.getProgram(), [file1.path, libFile.path, file2.path]);
checkProgramRootFiles(watch.getProgram(), [file1.path, file2.path]);
checkWatchedFiles(host, [configFile.path, file1.path, file2.path, libFile.path]);
const configDir = getDirectoryPath(configFile.path);
checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true);
@ -267,7 +254,7 @@ namespace ts.tscWatch {
content: `{}`
};
const host = createWatchedSystem([commonFile1, libFile, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
const configDir = getDirectoryPath(configFile.path);
checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true);
@ -291,7 +278,7 @@ namespace ts.tscWatch {
}`
};
const host = createWatchedSystem([commonFile1, commonFile2, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
const commonFile3 = "/a/b/commonFile3.ts";
checkProgramRootFiles(watch(), [commonFile1.path, commonFile3]);
@ -304,7 +291,7 @@ namespace ts.tscWatch {
content: `{}`
};
const host = createWatchedSystem([commonFile1, commonFile2, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramRootFiles(watch(), [commonFile1.path, commonFile2.path]);
// delete commonFile2
@ -326,7 +313,7 @@ namespace ts.tscWatch {
let x = y`
};
const host = createWatchedSystem([file1, libFile]);
const watch = createWatchModeWithoutConfigFile([file1.path], host);
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
checkProgramRootFiles(watch(), [file1.path]);
checkProgramActualFiles(watch(), [file1.path, libFile.path]);
@ -352,7 +339,7 @@ namespace ts.tscWatch {
};
const files = [commonFile1, commonFile2, configFile];
const host = createWatchedSystem(files);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramRootFiles(watch(), [commonFile1.path, commonFile2.path]);
configFile.content = `{
@ -379,7 +366,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([commonFile1, commonFile2, excludedFile1, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramRootFiles(watch(), [commonFile1.path, commonFile2.path]);
});
@ -407,7 +394,7 @@ namespace ts.tscWatch {
};
const files = [file1, nodeModuleFile, classicModuleFile, configFile];
const host = createWatchedSystem(files);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramRootFiles(watch(), [file1.path]);
checkProgramActualFiles(watch(), [file1.path, nodeModuleFile.path]);
@ -435,7 +422,7 @@ namespace ts.tscWatch {
}`
};
const host = createWatchedSystem([commonFile1, commonFile2, libFile, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramRootFiles(watch(), [commonFile1.path, commonFile2.path]);
});
@ -453,7 +440,7 @@ namespace ts.tscWatch {
content: `export let y = 1;`
};
const host = createWatchedSystem([file1, file2, file3]);
const watch = createWatchModeWithoutConfigFile([file1.path], host);
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
checkProgramRootFiles(watch(), [file1.path]);
checkProgramActualFiles(watch(), [file1.path, file2.path]);
@ -482,7 +469,7 @@ namespace ts.tscWatch {
content: `export let y = 1;`
};
const host = createWatchedSystem([file1, file2, file3]);
const watch = createWatchModeWithoutConfigFile([file1.path], host);
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
checkProgramActualFiles(watch(), [file1.path, file2.path, file3.path]);
host.reloadFS([file1, file3]);
@ -505,7 +492,7 @@ namespace ts.tscWatch {
content: `export let y = 1;`
};
const host = createWatchedSystem([file1, file2, file3]);
const watch = createWatchModeWithoutConfigFile([file1.path, file3.path], host);
const watch = createWatchOfFilesAndCompilerOptions([file1.path, file3.path], host);
checkProgramActualFiles(watch(), [file1.path, file2.path, file3.path]);
host.reloadFS([file1, file3]);
@ -533,7 +520,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([file1, file2, file3, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramRootFiles(watch(), [file2.path, file3.path]);
checkProgramActualFiles(watch(), [file1.path, file2.path, file3.path]);
@ -555,10 +542,10 @@ namespace ts.tscWatch {
content: "export let y = 1;"
};
const host = createWatchedSystem([file1, file2, file3]);
const watch = createWatchModeWithoutConfigFile([file2.path, file3.path], host);
const watch = createWatchOfFilesAndCompilerOptions([file2.path, file3.path], host);
checkProgramActualFiles(watch(), [file2.path, file3.path]);
const watch2 = createWatchModeWithoutConfigFile([file1.path], host);
const watch2 = createWatchOfFilesAndCompilerOptions([file1.path], host);
checkProgramActualFiles(watch2(), [file1.path, file2.path, file3.path]);
// Previous program shouldnt be updated
@ -581,7 +568,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([file1, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), [file1.path]);
host.reloadFS([file1, file2, configFile]);
@ -606,7 +593,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([file1, file2, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), [file1.path]);
@ -636,7 +623,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([file1, file2, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), [file1.path, file2.path]);
const modifiedConfigFile = {
@ -664,7 +651,7 @@ namespace ts.tscWatch {
content: JSON.stringify({ compilerOptions: {} })
};
const host = createWatchedSystem([file1, file2, libFile, config]);
const watch = createWatchModeWithConfigFile(config.path, host);
const watch = createWatchOfConfigFile(config.path, host);
checkProgramActualFiles(watch(), [file1.path, file2.path, libFile.path]);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
@ -688,7 +675,7 @@ namespace ts.tscWatch {
content: "{"
};
const host = createWatchedSystem([file1, corruptedConfig]);
const watch = createWatchModeWithConfigFile(corruptedConfig.path, host);
const watch = createWatchOfConfigFile(corruptedConfig.path, host);
checkProgramActualFiles(watch(), [file1.path]);
});
@ -738,7 +725,7 @@ namespace ts.tscWatch {
})
};
const host = createWatchedSystem([libES5, libES2015Promise, app, config1], { executingFilePath: "/compiler/tsc.js" });
const watch = createWatchModeWithConfigFile(config1.path, host);
const watch = createWatchOfConfigFile(config1.path, host);
checkProgramActualFiles(watch(), [libES5.path, app.path]);
@ -763,7 +750,7 @@ namespace ts.tscWatch {
})
};
const host = createWatchedSystem([f, config]);
const watch = createWatchModeWithConfigFile(config.path, host);
const watch = createWatchOfConfigFile(config.path, host);
checkProgramActualFiles(watch(), [f.path]);
});
@ -777,7 +764,7 @@ namespace ts.tscWatch {
content: 'import * as T from "./moduleFile"; T.bar();'
};
const host = createWatchedSystem([moduleFile, file1, libFile]);
const watch = createWatchModeWithoutConfigFile([file1.path], host);
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
const moduleFileOldPath = moduleFile.path;
@ -809,7 +796,7 @@ namespace ts.tscWatch {
content: `{}`
};
const host = createWatchedSystem([moduleFile, file1, configFile, libFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
const moduleFileOldPath = moduleFile.path;
@ -844,7 +831,7 @@ namespace ts.tscWatch {
path: "/a/c"
};
const host = createWatchedSystem([f1, config, node, cwd], { currentDirectory: cwd.path });
const watch = createWatchModeWithConfigFile(config.path, host);
const watch = createWatchOfConfigFile(config.path, host);
checkProgramActualFiles(watch(), [f1.path, node.path]);
});
@ -859,7 +846,7 @@ namespace ts.tscWatch {
content: 'import * as T from "./moduleFile"; T.bar();'
};
const host = createWatchedSystem([file1, libFile]);
const watch = createWatchModeWithoutConfigFile([file1.path], host);
const watch = createWatchOfFilesAndCompilerOptions([file1.path], host);
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), file1, "./moduleFile")
@ -886,7 +873,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([file, configFile, libFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkOutputErrors(host, [
getUnknownCompilerOption(watch(), configFile, "foo"),
getUnknownCompilerOption(watch(), configFile, "allowJS")
@ -906,7 +893,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([file, configFile, libFile]);
createWatchModeWithConfigFile(configFile.path, host);
createWatchOfConfigFile(configFile.path, host);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
});
@ -923,7 +910,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([file, configFile, libFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
configFile.content = `{
@ -959,7 +946,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([file1, configFile, libFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), [libFile.path]);
});
@ -985,7 +972,7 @@ namespace ts.tscWatch {
content: `export const x: number`
};
const host = createWatchedSystem([f, config, t1, t2], { currentDirectory: getDirectoryPath(f.path) });
const watch = createWatchModeWithConfigFile(config.path, host);
const watch = createWatchOfConfigFile(config.path, host);
checkProgramActualFiles(watch(), [t1.path, t2.path]);
});
@ -996,7 +983,7 @@ namespace ts.tscWatch {
content: "let x = 1"
};
const host = createWatchedSystem([f, libFile]);
const watch = createWatchModeWithoutConfigFile([f.path], host, { allowNonTsExtensions: true });
const watch = createWatchOfFilesAndCompilerOptions([f.path], host, { allowNonTsExtensions: true });
checkProgramActualFiles(watch(), [f.path, libFile.path]);
});
@ -1024,7 +1011,7 @@ namespace ts.tscWatch {
const files = [file, libFile, configFile];
const host = createWatchedSystem(files);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
const errors = () => [
getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"allowJs"'), '"allowJs"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"),
getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"declaration"'), '"declaration"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration")
@ -1080,7 +1067,7 @@ namespace ts.tscWatch {
const files = [f1, f2, config, libFile];
host.reloadFS(files);
createWatchModeWithConfigFile(config.path, host);
createWatchOfConfigFile(config.path, host);
const allEmittedLines = getEmittedLines(files);
checkOutputContains(host, allEmittedLines);
@ -1142,7 +1129,7 @@ namespace ts.tscWatch {
mapOfFilesWritten.set(p, count ? count + 1 : 1);
return originalWriteFile(p, content);
};
createWatchModeWithConfigFile(configFile.path, host);
createWatchOfConfigFile(configFile.path, host);
if (useOutFile) {
// Only out file
assert.equal(mapOfFilesWritten.size, 1);
@ -1226,7 +1213,7 @@ namespace ts.tscWatch {
host.reloadFS(firstReloadFileList ? getFiles(firstReloadFileList) : files);
// Initial compile
createWatchModeWithConfigFile(configFile.path, host);
createWatchOfConfigFile(configFile.path, host);
if (firstCompilationEmitFiles) {
checkAffectedLines(host, getFiles(firstCompilationEmitFiles), allEmittedFiles);
}
@ -1537,11 +1524,11 @@ namespace ts.tscWatch {
// Initial compile
if (configFile) {
createWatchModeWithConfigFile(configFile.path, host);
createWatchOfConfigFile(configFile.path, host);
}
else {
// First file as the root
createWatchModeWithoutConfigFile([files[0].path], host, { listEmittedFiles: true });
createWatchOfFilesAndCompilerOptions([files[0].path], host, { listEmittedFiles: true });
}
checkOutputContains(host, allEmittedFiles);
@ -1661,7 +1648,7 @@ namespace ts.tscWatch {
const files = [root, imported, libFile];
const host = createWatchedSystem(files);
const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD });
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");
@ -1762,7 +1749,7 @@ namespace ts.tscWatch {
return originalFileExists.call(host, fileName);
};
const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD });
const watch = createWatchOfFilesAndCompilerOptions([root.path], host, { module: ModuleKind.AMD });
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
checkOutputErrors(host, [
@ -1804,7 +1791,7 @@ namespace ts.tscWatch {
return originalFileExists.call(host, fileName);
};
const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD });
const watch = createWatchOfFilesAndCompilerOptions([root.path], host, { module: ModuleKind.AMD });
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
@ -1853,7 +1840,7 @@ declare module "fs" {
const filesWithNodeType = files.concat(packageJson, nodeType);
const host = createWatchedSystem(files, { currentDirectory: "/a/b" });
const watch = createWatchModeWithoutConfigFile([root.path], host, { });
const watch = createWatchOfFilesAndCompilerOptions([root.path], host, { });
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "fs")
@ -1895,7 +1882,7 @@ declare module "fs" {
const files = [root, file, libFile];
const host = createWatchedSystem(files, { currentDirectory: "/a/b" });
const watch = createWatchModeWithoutConfigFile([root.path, file.path], host, {});
const watch = createWatchOfFilesAndCompilerOptions([root.path, file.path], host, {});
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "fs")
@ -1937,7 +1924,7 @@ declare module "fs" {
const outDirFolder = "/a/b/projects/myProject/dist/";
const programFiles = [file1, file2, module1, libFile];
const host = createWatchedSystem(programFiles.concat(configFile), { currentDirectory: "/a/b/projects/myProject/" });
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), programFiles.map(f => f.path));
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
const expectedFiles: ExpectedFile[] = [
@ -2014,7 +2001,7 @@ declare module "fs" {
};
const files = [configFile, file1, file2, libFile];
const host = createWatchedSystem(files);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
file1.content = "var zz30 = 100;";

View File

@ -460,7 +460,7 @@ interface Array<T> {}`
private invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind) {
const callbacks = this.watchedFiles.get(this.toPath(fileFullPath));
invokeWatcherCallbacks(callbacks, ({ cb, fileName }) => cb(fileName, eventKind));
invokeWatcherCallbacks(callbacks, ({ cb }) => cb(fileFullPath, eventKind));
}
private getRelativePathToDirectory(directoryFullPath: string, fileFullPath: string) {

View File

@ -1,4 +1,4 @@
{
{
"extends": "../tsconfig-base",
"compilerOptions": {
"removeComments": false,
@ -37,6 +37,10 @@
"../compiler/declarationEmitter.ts",
"../compiler/emitter.ts",
"../compiler/program.ts",
"../compiler/builder.ts",
"../compiler/resolutionCache.ts",
"../compiler/watch.ts",
"../compiler/watchUtilities.ts",
"../compiler/commandLineParser.ts",
"../compiler/diagnosticInformationMap.generated.ts",
"types.ts",

View File

@ -3812,6 +3812,72 @@ declare namespace ts {
*/
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program;
}
declare namespace ts {
type DiagnosticReporter = (diagnostic: Diagnostic) => void;
/**
* Creates the function that compiles the program by maintaining the builder state and also return diagnostic reporter
*/
function createProgramCompilerWithBuilderState(system?: System, reportDiagnostic?: DiagnosticReporter): (host: DirectoryStructureHost, program: Program) => void;
interface WatchHost {
/** FS system to use */
system: System;
/** Custom action before creating the program */
beforeProgramCreate(compilerOptions: CompilerOptions): void;
/** Custom action after new program creation is successful */
afterProgramCreate(host: DirectoryStructureHost, program: Program): void;
}
/**
* Host to create watch with root files and options
*/
interface WatchOfFilesAndCompilerOptionsHost extends WatchHost {
/** root files to use to generate program */
rootFiles: string[];
/** Compiler options */
options: CompilerOptions;
}
/**
* Host to create watch with config file
*/
interface WatchOfConfigFileHost extends WatchHost {
/** Name of the config file to compile */
configFileName: string;
/** Options to extend */
optionsToExtend?: CompilerOptions;
onConfigFileDiagnostic(diagnostic: Diagnostic): void;
}
interface Watch {
/** Synchronize the program with the changes */
synchronizeProgram(): void;
}
/**
* Creates the watch what generates program using the config file
*/
interface WatchOfConfigFile extends Watch {
}
/**
* Creates the watch that generates program using the root files and compiler options
*/
interface WatchOfFilesAndCompilerOptions extends Watch {
/** Updates the root files in the program, only if this is not config file compilation */
updateRootFileNames(fileNames: string[]): void;
}
/**
* Create the watched program for config file
*/
function createWatchOfConfigFile(configFileName: string, optionsToExtend?: CompilerOptions, system?: System, reportDiagnostic?: DiagnosticReporter): WatchOfConfigFile;
/**
* Create the watched program for root files and compiler options
*/
function createWatchOfFilesAndCompilerOptions(rootFiles: string[], options: CompilerOptions, system?: System, reportDiagnostic?: DiagnosticReporter): WatchOfFilesAndCompilerOptions;
/**
* Creates the watch from the host for root files and compiler options
*/
function createWatch(host: WatchOfFilesAndCompilerOptionsHost): WatchOfFilesAndCompilerOptions;
/**
* Creates the watch from the host for config file
*/
function createWatch(host: WatchOfConfigFileHost): WatchOfConfigFile;
}
declare namespace ts {
function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine;
/**