mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Expose the watch and builder API in the typescript.d.ts
This commit is contained in:
parent
a06f0c3d9f
commit
576fe1e995
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -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;";
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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",
|
||||
|
||||
66
tests/baselines/reference/api/typescript.d.ts
vendored
66
tests/baselines/reference/api/typescript.d.ts
vendored
@ -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;
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user