Handle dts emit time errors for incremental scenarios and buildInfo (#56295)

This commit is contained in:
Sheetal Nandi 2023-11-02 18:35:28 -07:00 committed by GitHub
parent d86bddec5e
commit e58d8fd635
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1477 additions and 194 deletions

View File

@ -133,6 +133,8 @@ export interface ReusableBuilderProgramState extends BuilderState {
* Cache of bind and check diagnostics for files with their Path being the key
*/
semanticDiagnosticsPerFile?: Map<Path, readonly ReusableDiagnostic[] | readonly Diagnostic[]> | undefined;
/** Cache of dts emit diagnostics for files with their Path being the key */
emitDiagnosticsPerFile?: Map<Path, readonly ReusableDiagnostic[] | readonly Diagnostic[]> | undefined;
/**
* The map has key by source file's path that has been changed
*/
@ -202,6 +204,8 @@ export interface BuilderProgramState extends BuilderState, ReusableBuilderProgra
* Cache of bind and check diagnostics for files with their Path being the key
*/
semanticDiagnosticsPerFile: Map<Path, readonly Diagnostic[]> | undefined;
/** Cache of dts emit diagnostics for files with their Path being the key */
emitDiagnosticsPerFile?: Map<Path, readonly Diagnostic[]> | undefined;
/**
* The map has key by source file's path that has been changed
*/
@ -261,6 +265,8 @@ export type SavedBuildProgramEmitState =
| "outSignature"
| "latestChangedDtsFile"
| "hasChangedEmitSignature"
| "buildInfoEmitPending"
| "emitDiagnosticsPerFile"
>
& { changedFilesSet: BuilderProgramState["changedFilesSet"] | undefined; };
@ -376,25 +382,33 @@ function createBuilderProgramState(newProgram: Program, oldState: Readonly<Reusa
// Register file as changed file and do not copy semantic diagnostics, since all changed files need to be re-evaluated
addFileToChangeSet(state, sourceFilePath);
}
else if (canCopySemanticDiagnostics) {
else {
const sourceFile = newProgram.getSourceFileByPath(sourceFilePath)!;
if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) return;
if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) return;
// Unchanged file copy diagnostics
const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath);
if (diagnostics) {
state.semanticDiagnosticsPerFile!.set(
const emitDiagnostics = oldState!.emitDiagnosticsPerFile?.get(sourceFilePath);
if (emitDiagnostics) {
(state.emitDiagnosticsPerFile ??= new Map()).set(
sourceFilePath,
oldState!.hasReusableDiagnostic ?
convertToDiagnostics(diagnostics as readonly ReusableDiagnostic[], newProgram) :
repopulateDiagnostics(diagnostics as readonly Diagnostic[], newProgram),
convertToDiagnostics(emitDiagnostics as readonly ReusableDiagnostic[], newProgram) :
repopulateDiagnostics(emitDiagnostics as readonly Diagnostic[], newProgram),
);
if (!state.semanticDiagnosticsFromOldState) {
state.semanticDiagnosticsFromOldState = new Set();
}
if (canCopySemanticDiagnostics) {
if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) return;
if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) return;
// Unchanged file copy diagnostics
const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath);
if (diagnostics) {
state.semanticDiagnosticsPerFile!.set(
sourceFilePath,
oldState!.hasReusableDiagnostic ?
convertToDiagnostics(diagnostics as readonly ReusableDiagnostic[], newProgram) :
repopulateDiagnostics(diagnostics as readonly Diagnostic[], newProgram),
);
(state.semanticDiagnosticsFromOldState ??= new Set()).add(sourceFilePath);
}
state.semanticDiagnosticsFromOldState.add(sourceFilePath);
}
}
if (canCopyEmitSignatures) {
@ -570,6 +584,8 @@ function backupBuilderProgramEmitState(state: Readonly<BuilderProgramState>): Sa
latestChangedDtsFile: state.latestChangedDtsFile,
hasChangedEmitSignature: state.hasChangedEmitSignature,
changedFilesSet: outFilePath ? new Set(state.changedFilesSet) : undefined,
buildInfoEmitPending: state.buildInfoEmitPending,
emitDiagnosticsPerFile: state.emitDiagnosticsPerFile && new Map(state.emitDiagnosticsPerFile),
};
}
@ -581,6 +597,8 @@ function restoreBuilderProgramEmitState(state: BuilderProgramState, savedEmitSta
state.outSignature = savedEmitState.outSignature;
state.latestChangedDtsFile = savedEmitState.latestChangedDtsFile;
state.hasChangedEmitSignature = savedEmitState.hasChangedEmitSignature;
state.buildInfoEmitPending = savedEmitState.buildInfoEmitPending;
state.emitDiagnosticsPerFile = savedEmitState.emitDiagnosticsPerFile;
if (savedEmitState.changedFilesSet) state.changedFilesSet = savedEmitState.changedFilesSet;
}
@ -692,6 +710,19 @@ function getNextAffectedFilePendingEmit(state: BuilderProgramState, emitOnlyDtsF
});
}
function getNextPendingEmitDiagnosticsFile(state: BuilderProgramState) {
if (!state.emitDiagnosticsPerFile?.size) return undefined;
return forEachEntry(state.emitDiagnosticsPerFile, (diagnostics, path) => {
const affectedFile = state.program!.getSourceFileByPath(path);
if (!affectedFile || !sourceFileMayBeEmitted(affectedFile, state.program!)) {
state.emitDiagnosticsPerFile!.delete(path);
return undefined;
}
const seenKind = state.seenEmittedFiles?.get(affectedFile.resolvedPath) || BuilderFileEmit.None;
if (!(seenKind & BuilderFileEmit.AllDts)) return { affectedFile, diagnostics, seenKind };
});
}
function removeDiagnosticsOfLibraryFiles(state: BuilderProgramState) {
if (!state.cleanedDiagnosticsOfLibFiles) {
state.cleanedDiagnosticsOfLibFiles = true;
@ -997,6 +1028,7 @@ export interface ProgramMultiFileEmitBuildInfo {
referencedMap: ProgramBuildInfoReferencedMap | undefined;
exportedModulesMap: ProgramBuildInfoReferencedMap | undefined;
semanticDiagnosticsPerFile: ProgramBuildInfoDiagnostic[] | undefined;
emitDiagnosticsPerFile: ProgramBuildInfoDiagnostic[] | undefined;
affectedFilesPendingEmit: ProgramBuilderInfoFilePendingEmit[] | undefined;
changeFileSet: readonly ProgramBuildInfoFileId[] | undefined;
emitSignatures: readonly ProgramBuildInfoEmitSignature[] | undefined;
@ -1140,21 +1172,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
});
}
let semanticDiagnosticsPerFile: ProgramBuildInfoDiagnostic[] | undefined;
if (state.semanticDiagnosticsPerFile) {
for (const key of arrayFrom(state.semanticDiagnosticsPerFile.keys()).sort(compareStringsCaseSensitive)) {
const value = state.semanticDiagnosticsPerFile.get(key)!;
(semanticDiagnosticsPerFile ||= []).push(
value.length ?
[
toFileId(key),
convertToReusableDiagnostics(value, relativeToBuildInfo),
] :
toFileId(key),
);
}
}
const semanticDiagnosticsPerFile = convertToProgramBuildInfoDiagnostics(state.semanticDiagnosticsPerFile);
let affectedFilesPendingEmit: ProgramBuilderInfoFilePendingEmit[] | undefined;
if (state.affectedFilesPendingEmit?.size) {
const fullEmitForOptions = getBuilderFileEmit(state.compilerOptions);
@ -1181,7 +1199,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
(changeFileSet ||= []).push(toFileId(path));
}
}
const emitDiagnosticsPerFile = convertToProgramBuildInfoDiagnostics(state.emitDiagnosticsPerFile);
const program: ProgramMultiFileEmitBuildInfo = {
fileNames,
fileInfos,
@ -1191,6 +1209,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
referencedMap,
exportedModulesMap,
semanticDiagnosticsPerFile,
emitDiagnosticsPerFile,
affectedFilesPendingEmit,
changeFileSet,
emitSignatures,
@ -1257,80 +1276,97 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
(result ||= {})[name] = convertToReusableCompilerOptionValue(
optionInfo,
options[name] as CompilerOptionsValue,
relativeToBuildInfoEnsuringAbsolutePath,
);
}
}
return result;
}
}
function convertToReusableCompilerOptionValue(option: CommandLineOption | undefined, value: CompilerOptionsValue, relativeToBuildInfo: (path: string) => string) {
if (option) {
Debug.assert(option.type !== "listOrElement");
if (option.type === "list") {
const values = value as readonly string[];
if (option.element.isFilePath && values.length) {
return values.map(relativeToBuildInfo);
function convertToReusableCompilerOptionValue(option: CommandLineOption | undefined, value: CompilerOptionsValue) {
if (option) {
Debug.assert(option.type !== "listOrElement");
if (option.type === "list") {
const values = value as readonly string[];
if (option.element.isFilePath && values.length) {
return values.map(relativeToBuildInfoEnsuringAbsolutePath);
}
}
else if (option.isFilePath) {
return relativeToBuildInfoEnsuringAbsolutePath(value as string);
}
}
else if (option.isFilePath) {
return relativeToBuildInfo(value as string);
}
return value;
}
return value;
}
function convertToReusableDiagnostics(diagnostics: readonly Diagnostic[], relativeToBuildInfo: (path: string) => string): readonly ReusableDiagnostic[] {
Debug.assert(!!diagnostics.length);
return diagnostics.map(diagnostic => {
const result: ReusableDiagnostic = convertToReusableDiagnosticRelatedInformation(diagnostic, relativeToBuildInfo);
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
result.reportDeprecated = diagnostic.reportsDeprecated;
result.source = diagnostic.source;
result.skippedOn = diagnostic.skippedOn;
const { relatedInformation } = diagnostic;
result.relatedInformation = relatedInformation ?
relatedInformation.length ?
relatedInformation.map(r => convertToReusableDiagnosticRelatedInformation(r, relativeToBuildInfo)) :
[] :
undefined;
function convertToProgramBuildInfoDiagnostics(diagnostics: Map<Path, readonly Diagnostic[]> | undefined) {
let result: ProgramBuildInfoDiagnostic[] | undefined;
if (diagnostics) {
for (const key of arrayFrom(diagnostics.keys()).sort(compareStringsCaseSensitive)) {
const value = diagnostics.get(key)!;
(result ||= []).push(
value.length ?
[
toFileId(key),
convertToReusableDiagnostics(value),
] :
toFileId(key),
);
}
}
return result;
});
}
}
function convertToReusableDiagnosticRelatedInformation(diagnostic: DiagnosticRelatedInformation, relativeToBuildInfo: (path: string) => string): ReusableDiagnosticRelatedInformation {
const { file } = diagnostic;
return {
...diagnostic,
file: file ? relativeToBuildInfo(file.resolvedPath) : undefined,
messageText: isString(diagnostic.messageText) ? diagnostic.messageText : convertToReusableDiagnosticMessageChain(diagnostic.messageText),
};
}
function convertToReusableDiagnostics(diagnostics: readonly Diagnostic[]): readonly ReusableDiagnostic[] {
Debug.assert(!!diagnostics.length);
return diagnostics.map(diagnostic => {
const result: ReusableDiagnostic = convertToReusableDiagnosticRelatedInformation(diagnostic);
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
result.reportDeprecated = diagnostic.reportsDeprecated;
result.source = diagnostic.source;
result.skippedOn = diagnostic.skippedOn;
const { relatedInformation } = diagnostic;
result.relatedInformation = relatedInformation ?
relatedInformation.length ?
relatedInformation.map(r => convertToReusableDiagnosticRelatedInformation(r)) :
[] :
undefined;
return result;
});
}
function convertToReusableDiagnosticMessageChain(chain: DiagnosticMessageChain): ReusableDiagnosticMessageChain {
if (chain.repopulateInfo) {
function convertToReusableDiagnosticRelatedInformation(diagnostic: DiagnosticRelatedInformation): ReusableDiagnosticRelatedInformation {
const { file } = diagnostic;
return {
info: chain.repopulateInfo(),
next: convertToReusableDiagnosticMessageChainArray(chain.next),
...diagnostic,
file: file ? relativeToBuildInfo(file.resolvedPath) : undefined,
messageText: isString(diagnostic.messageText) ? diagnostic.messageText : convertToReusableDiagnosticMessageChain(diagnostic.messageText),
};
}
const next = convertToReusableDiagnosticMessageChainArray(chain.next);
return next === chain.next ? chain : { ...chain, next };
}
function convertToReusableDiagnosticMessageChainArray(array: DiagnosticMessageChain[] | undefined): ReusableDiagnosticMessageChain[] | undefined {
if (!array) return array;
return forEach(array, (chain, index) => {
const reusable = convertToReusableDiagnosticMessageChain(chain);
if (chain === reusable) return undefined;
const result: ReusableDiagnosticMessageChain[] = index > 0 ? array.slice(0, index - 1) : [];
result.push(reusable);
for (let i = index + 1; i < array.length; i++) {
result.push(convertToReusableDiagnosticMessageChain(array[i]));
function convertToReusableDiagnosticMessageChain(chain: DiagnosticMessageChain): ReusableDiagnosticMessageChain {
if (chain.repopulateInfo) {
return {
info: chain.repopulateInfo(),
next: convertToReusableDiagnosticMessageChainArray(chain.next),
};
}
return result;
}) || array;
const next = convertToReusableDiagnosticMessageChainArray(chain.next);
return next === chain.next ? chain : { ...chain, next };
}
function convertToReusableDiagnosticMessageChainArray(array: DiagnosticMessageChain[] | undefined): ReusableDiagnosticMessageChain[] | undefined {
if (!array) return array;
return forEach(array, (chain, index) => {
const reusable = convertToReusableDiagnosticMessageChain(chain);
if (chain === reusable) return undefined;
const result: ReusableDiagnosticMessageChain[] = index > 0 ? array.slice(0, index - 1) : [];
result.push(reusable);
for (let i = index + 1; i < array.length; i++) {
result.push(convertToReusableDiagnosticMessageChain(array[i]));
}
return result;
}) || array;
}
}
/** @internal */
@ -1497,6 +1533,14 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
if (!outFile(state.compilerOptions)) {
const pendingAffectedFile = getNextAffectedFilePendingEmit(state, emitOnlyDtsFiles);
if (!pendingAffectedFile) {
const pendingForDiagnostics = getNextPendingEmitDiagnosticsFile(state);
if (pendingForDiagnostics) {
(state.seenEmittedFiles ??= new Map()).set(pendingForDiagnostics.affectedFile.resolvedPath, pendingForDiagnostics.seenKind | BuilderFileEmit.AllDts);
return {
result: { emitSkipped: true, diagnostics: pendingForDiagnostics.diagnostics },
affected: pendingForDiagnostics.affectedFile,
};
}
// Emit buildinfo if pending
if (!state.buildInfoEmitPending) return undefined;
const affected = state.program!;
@ -1550,6 +1594,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
const pendingKind = getPendingEmitKind(existingPending, emitKind | existing);
if (pendingKind) (state.affectedFilesPendingEmit ??= new Map()).set(affectedSourceFile.resolvedPath, pendingKind);
else state.affectedFilesPendingEmit?.delete(affectedSourceFile.resolvedPath);
if (result.diagnostics.length) (state.emitDiagnosticsPerFile ??= new Map()).set(affectedSourceFile.resolvedPath, result.diagnostics);
}
else {
// In program clear our changed files since any emit handles all changes
@ -1765,6 +1810,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
function addToAffectedFilesPendingEmit(state: BuilderProgramState, affectedFilePendingEmit: Path, kind: BuilderFileEmit) {
const existingKind = state.affectedFilesPendingEmit?.get(affectedFilePendingEmit) || BuilderFileEmit.None;
(state.affectedFilesPendingEmit ??= new Map()).set(affectedFilePendingEmit, existingKind | kind);
state.emitDiagnosticsPerFile?.delete(affectedFilePendingEmit);
}
/** @internal */
@ -1840,7 +1886,8 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {},
referencedMap: toManyToManyPathMap(program.referencedMap),
exportedModulesMap: toManyToManyPathMap(program.exportedModulesMap),
semanticDiagnosticsPerFile: program.semanticDiagnosticsPerFile && arrayToMap(program.semanticDiagnosticsPerFile, value => toFilePath(isNumber(value) ? value : value[0]), value => isNumber(value) ? emptyArray : value[1]),
semanticDiagnosticsPerFile: toPerFileDiagnostics(program.semanticDiagnosticsPerFile),
emitDiagnosticsPerFile: toPerFileDiagnostics(program.emitDiagnosticsPerFile),
hasReusableDiagnostic: true,
affectedFilesPendingEmit: program.affectedFilesPendingEmit && arrayToMap(program.affectedFilesPendingEmit, value => toFilePath(isNumber(value) ? value : value[0]), value => toBuilderFileEmit(value, fullEmitForOptions!)),
changedFilesSet: new Set(map(program.changeFileSet, toFilePath)),
@ -1900,6 +1947,10 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
referenceMap.forEach(([fileId, fileIdListId]) => map.set(toFilePath(fileId), toFilePathsSet(fileIdListId)));
return map;
}
function toPerFileDiagnostics(diagnostics: readonly ProgramBuildInfoDiagnostic[] | undefined): Map<Path, readonly ReusableDiagnostic[]> | undefined {
return diagnostics && arrayToMap(diagnostics, value => toFilePath(isNumber(value) ? value : value[0]), value => isNumber(value) ? emptyArray : value[1]);
}
}
/** @internal */

View File

@ -800,28 +800,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
emitBuildInfo(bundleBuildInfo, buildInfoPath);
tracing?.pop();
if (!emitSkipped && emittedFilesList) {
if (!emitOnly) {
if (jsFilePath) {
emittedFilesList.push(jsFilePath);
}
if (sourceMapFilePath) {
emittedFilesList.push(sourceMapFilePath);
}
if (buildInfoPath) {
emittedFilesList.push(buildInfoPath);
}
}
if (emitOnly !== EmitOnly.Js) {
if (declarationFilePath) {
emittedFilesList.push(declarationFilePath);
}
if (declarationMapPath) {
emittedFilesList.push(declarationMapPath);
}
}
}
function relativeToBuildInfo(path: string) {
return ensurePathIsNonModuleName(getRelativePathFromDirectory(buildInfoDirectory!, path, host.getCanonicalFileName));
}
@ -837,6 +815,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
const buildInfo = host.getBuildInfo(bundle) || createBuildInfo(/*program*/ undefined, bundle);
// Pass buildinfo as additional data to avoid having to reparse
writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText(buildInfo), /*writeByteOrderMark*/ false, /*sourceFiles*/ undefined, { buildInfo });
emittedFilesList?.push(buildInfoPath);
}
function emitJsFileOrBundle(
@ -888,6 +867,13 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
// Clean up emit nodes on parse tree
transform.dispose();
if (bundleBuildInfo) bundleBuildInfo.js = printer.bundleFileInfo;
if (emittedFilesList) {
emittedFilesList.push(jsFilePath);
if (sourceMapFilePath) {
emittedFilesList.push(sourceMapFilePath);
}
}
}
function emitDeclarationFileOrBundle(
@ -917,35 +903,35 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
}
}
const printerOptions: PrinterOptions = {
removeComments: compilerOptions.removeComments,
newLine: compilerOptions.newLine,
noEmitHelpers: true,
module: compilerOptions.module,
target: compilerOptions.target,
sourceMap: !forceDtsEmit && compilerOptions.declarationMap,
inlineSourceMap: compilerOptions.inlineSourceMap,
extendedDiagnostics: compilerOptions.extendedDiagnostics,
onlyPrintJsDocStyle: true,
omitBraceSourceMapPositions: true,
writeBundleFileInfo: !!bundleBuildInfo,
recordInternalSection: !!bundleBuildInfo,
relativeToBuildInfo,
};
const declarationPrinter = createPrinter(printerOptions, {
// resolver hooks
hasGlobalName: resolver.hasGlobalName,
// transform hooks
onEmitNode: declarationTransform.emitNodeWithNotification,
isEmitNotificationEnabled: declarationTransform.isEmitNotificationEnabled,
substituteNode: declarationTransform.substituteNode,
});
const declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit;
emitSkipped = emitSkipped || declBlocked;
if (!declBlocked || forceDtsEmit) {
Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform");
const printerOptions: PrinterOptions = {
removeComments: compilerOptions.removeComments,
newLine: compilerOptions.newLine,
noEmitHelpers: true,
module: compilerOptions.module,
target: compilerOptions.target,
sourceMap: !forceDtsEmit && compilerOptions.declarationMap,
inlineSourceMap: compilerOptions.inlineSourceMap,
extendedDiagnostics: compilerOptions.extendedDiagnostics,
onlyPrintJsDocStyle: true,
omitBraceSourceMapPositions: true,
writeBundleFileInfo: !!bundleBuildInfo,
recordInternalSection: !!bundleBuildInfo,
relativeToBuildInfo,
};
const declarationPrinter = createPrinter(printerOptions, {
// resolver hooks
hasGlobalName: resolver.hasGlobalName,
// transform hooks
onEmitNode: declarationTransform.emitNodeWithNotification,
isEmitNotificationEnabled: declarationTransform.isEmitNotificationEnabled,
substituteNode: declarationTransform.substituteNode,
});
printSourceFileOrBundle(
declarationFilePath,
declarationMapPath,
@ -959,9 +945,15 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
// Explicitly do not passthru either `inline` option
},
);
if (emittedFilesList) {
emittedFilesList.push(declarationFilePath);
if (declarationMapPath) {
emittedFilesList.push(declarationMapPath);
}
}
if (bundleBuildInfo) bundleBuildInfo.dts = declarationPrinter.bundleFileInfo;
}
declarationTransform.dispose();
if (bundleBuildInfo) bundleBuildInfo.dts = declarationPrinter.bundleFileInfo;
}
function collectLinkedAliases(node: Node) {

View File

@ -1809,7 +1809,8 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
if (
(buildInfo.program as ProgramMultiFileEmitBuildInfo).changeFileSet?.length ||
(!project.options.noEmit ?
(buildInfo.program as ProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit?.length :
(buildInfo.program as ProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit?.length ||
(buildInfo.program as ProgramMultiFileEmitBuildInfo).emitDiagnosticsPerFile?.length :
some((buildInfo.program as ProgramMultiFileEmitBuildInfo).semanticDiagnosticsPerFile, isArray))
) {
return {

View File

@ -180,13 +180,14 @@ export type ReadableProgramBuildInfoFileInfo<T> = Omit<ts.BuilderState.FileInfo,
export type ReadableProgramBuildInfoRoot =
| [original: ts.ProgramBuildInfoFileId, readable: string]
| [original: ts.ProgramBuildInfoRootStartEnd, readable: readonly string[]];
export type ReadableProgramMultiFileEmitBuildInfo = Omit<ts.ProgramMultiFileEmitBuildInfo, "fileIdsList" | "fileInfos" | "root" | "referencedMap" | "exportedModulesMap" | "semanticDiagnosticsPerFile" | "affectedFilesPendingEmit" | "changeFileSet" | "emitSignatures"> & {
export type ReadableProgramMultiFileEmitBuildInfo = Omit<ts.ProgramMultiFileEmitBuildInfo, "fileIdsList" | "fileInfos" | "root" | "referencedMap" | "exportedModulesMap" | "semanticDiagnosticsPerFile" | "emitDiagnosticsPerFile" | "affectedFilesPendingEmit" | "changeFileSet" | "emitSignatures"> & {
fileNamesList: readonly (readonly string[])[] | undefined;
fileInfos: ts.MapLike<ReadableProgramBuildInfoFileInfo<ts.ProgramMultiFileEmitBuildInfoFileInfo>>;
root: readonly ReadableProgramBuildInfoRoot[];
referencedMap: ts.MapLike<string[]> | undefined;
exportedModulesMap: ts.MapLike<string[]> | undefined;
semanticDiagnosticsPerFile: readonly ReadableProgramBuildInfoDiagnostic[] | undefined;
emitDiagnosticsPerFile: readonly ReadableProgramBuildInfoDiagnostic[] | undefined;
affectedFilesPendingEmit: readonly ReadableProgramBuilderInfoFilePendingEmit[] | undefined;
changeFileSet: readonly string[] | undefined;
emitSignatures: readonly ReadableProgramBuildInfoEmitSignature[] | undefined;
@ -240,11 +241,8 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
options: buildInfo.program.options,
referencedMap: toMapOfReferencedSet(buildInfo.program.referencedMap),
exportedModulesMap: toMapOfReferencedSet(buildInfo.program.exportedModulesMap),
semanticDiagnosticsPerFile: buildInfo.program.semanticDiagnosticsPerFile?.map(d =>
ts.isNumber(d) ?
toFileName(d) :
[toFileName(d[0]), d[1]]
),
semanticDiagnosticsPerFile: toReadableProgramBuildInfoDiagnosticsPerFile(buildInfo.program.semanticDiagnosticsPerFile),
emitDiagnosticsPerFile: toReadableProgramBuildInfoDiagnosticsPerFile(buildInfo.program.emitDiagnosticsPerFile),
affectedFilesPendingEmit: buildInfo.program.affectedFilesPendingEmit?.map(value => toReadableProgramBuilderInfoFilePendingEmit(value, fullEmitForOptions!)),
changeFileSet: buildInfo.program.changeFileSet?.map(toFileName),
emitSignatures: buildInfo.program.emitSignatures?.map(s =>
@ -334,6 +332,14 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
result = result ? `${result} | ${flag}` : flag;
}
}
function toReadableProgramBuildInfoDiagnosticsPerFile(diagnostics: ts.ProgramBuildInfoDiagnostic[] | undefined): readonly ReadableProgramBuildInfoDiagnostic[] | undefined {
return diagnostics?.map(d =>
ts.isNumber(d) ?
toFileName(d) :
[toFileName(d[0]), d[1]]
);
}
}
export function toPathWithSystem(sys: ts.System, fileName: string): ts.Path {

View File

@ -364,6 +364,26 @@ function verifyTscEditDiscrepancies({
expectedIndex++;
});
}
if (incrementalReadableBuildInfo?.program?.emitDiagnosticsPerFile) {
incrementalReadableBuildInfo.program.emitDiagnosticsPerFile.forEach(([actualFileOrArray]) => {
const actualFile = ts.isString(actualFileOrArray) ? actualFileOrArray : actualFileOrArray[0];
if (
!ts.find(
(cleanReadableBuildInfo!.program! as ReadableProgramMultiFileEmitBuildInfo).emitDiagnosticsPerFile,
([expectedFileOrArray]) => actualFile === (ts.isString(expectedFileOrArray) ? expectedFileOrArray : expectedFileOrArray[0]),
) && !ts.find(
(cleanReadableBuildInfo!.program! as ReadableProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit,
([expectedFileOrArray]) => actualFile === (ts.isString(expectedFileOrArray) ? expectedFileOrArray : expectedFileOrArray[0]),
)
) {
addBaseline(
`Incremental build contains ${actualFile} file has errors, clean build does not have errors or does not mark is as pending emit: ${outputFile}::`,
`Incremental buildInfoText:: ${incrementalBuildText}`,
`Clean buildInfoText:: ${cleanBuildText}`,
);
}
});
}
}
}
}
@ -453,6 +473,7 @@ function getBuildInfoForIncrementalCorrectnessCheck(text: string | undefined): {
options: { ...readableBuildInfo.program.options, noEmit: undefined },
exportedModulesMap: undefined,
affectedFilesPendingEmit: undefined,
emitDiagnosticsPerFile: undefined,
latestChangedDtsFile: readableBuildInfo.program.latestChangedDtsFile ? "FakeFileName" : undefined,
},
size: undefined, // Size doesnt need to be equal

View File

@ -8,6 +8,10 @@ import {
jsonToReadableText,
} from "../helpers";
import {
libContent,
} from "../helpers/contents";
import {
noChangeOnlyRuns,
verifyTsc,
} from "../helpers/tsc";
import {
@ -132,3 +136,43 @@ export function fn4() {
commandLineArgs: ["--b", "/src/packages/pkg2/tsconfig.json", "--verbose"],
});
});
verifyTsc({
scenario: "declarationEmit",
subScenario: "reports dts generation errors with incremental",
commandLineArgs: ["-b", `/src/project`, "--explainFiles", "--listEmittedFiles", "--v"],
fs: () =>
loadProjectFromFiles({
"/src/project/tsconfig.json": jsonToReadableText({
compilerOptions: {
module: "NodeNext",
moduleResolution: "NodeNext",
incremental: true,
declaration: true,
skipLibCheck: true,
skipDefaultLibCheck: true,
},
}),
"/src/project/index.ts": dedent`
import ky from 'ky';
export const api = ky.extend({});
`,
"/src/project/package.json": jsonToReadableText({
type: "module",
}),
"/src/project/node_modules/ky/distribution/index.d.ts": dedent`
type KyInstance = {
extend(options: Record<string,unknown>): KyInstance;
}
declare const ky: KyInstance;
export default ky;
`,
"/src/project/node_modules/ky/package.json": jsonToReadableText({
name: "ky",
type: "module",
main: "./distribution/index.js",
}),
"/lib/lib.esnext.full.d.ts": libContent,
}),
edits: noChangeOnlyRuns,
});

View File

@ -618,14 +618,17 @@ console.log(a);`,
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;`,
),
edits: [
noChangeRun,
{
caption: "modify public to protected",
edit: fs => replaceText(fs, "/src/project/MessageablePerson.ts", "public", "protected"),
},
noChangeRun,
{
caption: "modify protected to public",
edit: fs => replaceText(fs, "/src/project/MessageablePerson.ts", "protected", "public"),
},
noChangeRun,
],
});
}
@ -959,4 +962,49 @@ console.log(a);`,
edit: fs => appendText(fs, "/src/project/src/bug.js", `export const something = 1;`),
}],
});
verifyTsc({
scenario: "incremental",
subScenario: "reports dts generation errors",
commandLineArgs: ["-p", `/src/project`, "--explainFiles", "--listEmittedFiles"],
fs: () =>
loadProjectFromFiles({
"/src/project/tsconfig.json": jsonToReadableText({
compilerOptions: {
module: "NodeNext",
moduleResolution: "NodeNext",
composite: true,
skipLibCheck: true,
skipDefaultLibCheck: true,
},
}),
"/src/project/index.ts": Utils.dedent`
import ky from 'ky';
export const api = ky.extend({});
`,
"/src/project/package.json": jsonToReadableText({
type: "module",
}),
"/src/project/node_modules/ky/distribution/index.d.ts": Utils.dedent`
type KyInstance = {
extend(options: Record<string,unknown>): KyInstance;
}
declare const ky: KyInstance;
export default ky;
`,
"/src/project/node_modules/ky/package.json": jsonToReadableText({
name: "ky",
type: "module",
main: "./distribution/index.js",
}),
"/lib/lib.esnext.full.d.ts": libContent,
}),
edits: [
noChangeRun,
{
...noChangeRun,
commandLineArgs: ["-b", `/src/project`, "--explainFiles", "--listEmittedFiles", "-v"],
},
],
});
});

View File

@ -0,0 +1,219 @@
currentDirectory:: / useCaseSensitiveFileNames: false
Input::
//// [/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };
//// [/lib/lib.esnext.full.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };
//// [/src/project/index.ts]
import ky from 'ky';
export const api = ky.extend({});
//// [/src/project/node_modules/ky/distribution/index.d.ts]
type KyInstance = {
extend(options: Record<string,unknown>): KyInstance;
}
declare const ky: KyInstance;
export default ky;
//// [/src/project/node_modules/ky/package.json]
{
"name": "ky",
"type": "module",
"main": "./distribution/index.js"
}
//// [/src/project/package.json]
{
"type": "module"
}
//// [/src/project/tsconfig.json]
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"incremental": true,
"declaration": true,
"skipLibCheck": true,
"skipDefaultLibCheck": true
}
}
Output::
/lib/tsc -b /src/project --explainFiles --listEmittedFiles --v
[12:00:16 AM] Projects in this build:
* src/project/tsconfig.json
[12:00:17 AM] Project 'src/project/tsconfig.json' is out of date because output file 'src/project/tsconfig.tsbuildinfo' does not exist
[12:00:18 AM] Building project '/src/project/tsconfig.json'...
src/project/index.ts:2:14 - error TS4023: Exported variable 'api' has or is using name 'KyInstance' from external module "/src/project/node_modules/ky/distribution/index" but cannot be named.
2 export const api = ky.extend({});
   ~~~
TSFILE: /src/project/tsconfig.tsbuildinfo
lib/lib.esnext.full.d.ts
Default library for target 'esnext'
src/project/node_modules/ky/distribution/index.d.ts
Imported via 'ky' from file 'src/project/index.ts'
File is ECMAScript module because 'src/project/node_modules/ky/package.json' has field "type" with value "module"
src/project/index.ts
Matched by default include pattern '**/*'
File is ECMAScript module because 'src/project/package.json' has field "type" with value "module"
Found 1 error.
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
//// [/src/project/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../lib/lib.esnext.full.d.ts","./node_modules/ky/distribution/index.d.ts","./index.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedFormat":1},{"version":"20726041391-type KyInstance = {\n extend(options: Record<string,unknown>): KyInstance;\n }\n declare const ky: KyInstance;\n export default ky;\n","impliedFormat":99},{"version":"-383421929-import ky from 'ky';\nexport const api = ky.extend({});\n","impliedFormat":99}],"root":[3],"options":{"declaration":true,"module":199,"skipDefaultLibCheck":true,"skipLibCheck":true},"fileIdsList":[[2]],"referencedMap":[[3,1]],"exportedModulesMap":[[3,1]],"semanticDiagnosticsPerFile":[1,3,2],"affectedFilesPendingEmit":[3]},"version":"FakeTSVersion"}
//// [/src/project/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../lib/lib.esnext.full.d.ts",
"./node_modules/ky/distribution/index.d.ts",
"./index.ts"
],
"fileNamesList": [
[
"./node_modules/ky/distribution/index.d.ts"
]
],
"fileInfos": {
"../../lib/lib.esnext.full.d.ts": {
"original": {
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"affectsGlobalScope": true,
"impliedFormat": 1
},
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"affectsGlobalScope": true,
"impliedFormat": "commonjs"
},
"./node_modules/ky/distribution/index.d.ts": {
"original": {
"version": "20726041391-type KyInstance = {\n extend(options: Record<string,unknown>): KyInstance;\n }\n declare const ky: KyInstance;\n export default ky;\n",
"impliedFormat": 99
},
"version": "20726041391-type KyInstance = {\n extend(options: Record<string,unknown>): KyInstance;\n }\n declare const ky: KyInstance;\n export default ky;\n",
"signature": "20726041391-type KyInstance = {\n extend(options: Record<string,unknown>): KyInstance;\n }\n declare const ky: KyInstance;\n export default ky;\n",
"impliedFormat": "esnext"
},
"./index.ts": {
"original": {
"version": "-383421929-import ky from 'ky';\nexport const api = ky.extend({});\n",
"impliedFormat": 99
},
"version": "-383421929-import ky from 'ky';\nexport const api = ky.extend({});\n",
"signature": "-383421929-import ky from 'ky';\nexport const api = ky.extend({});\n",
"impliedFormat": "esnext"
}
},
"root": [
[
3,
"./index.ts"
]
],
"options": {
"declaration": true,
"module": 199,
"skipDefaultLibCheck": true,
"skipLibCheck": true
},
"referencedMap": {
"./index.ts": [
"./node_modules/ky/distribution/index.d.ts"
]
},
"exportedModulesMap": {
"./index.ts": [
"./node_modules/ky/distribution/index.d.ts"
]
},
"semanticDiagnosticsPerFile": [
"../../lib/lib.esnext.full.d.ts",
"./index.ts",
"./node_modules/ky/distribution/index.d.ts"
],
"affectedFilesPendingEmit": [
[
"./index.ts",
"Js | Dts"
]
]
},
"version": "FakeTSVersion",
"size": 1182
}
Change:: no-change-run
Input::
Output::
/lib/tsc -b /src/project --explainFiles --listEmittedFiles --v
[12:00:22 AM] Projects in this build:
* src/project/tsconfig.json
[12:00:23 AM] Project 'src/project/tsconfig.json' is out of date because buildinfo file 'src/project/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted
[12:00:24 AM] Building project '/src/project/tsconfig.json'...
src/project/index.ts:2:14 - error TS4023: Exported variable 'api' has or is using name 'KyInstance' from external module "/src/project/node_modules/ky/distribution/index" but cannot be named.
2 export const api = ky.extend({});
   ~~~
lib/lib.esnext.full.d.ts
Default library for target 'esnext'
src/project/node_modules/ky/distribution/index.d.ts
Imported via 'ky' from file 'src/project/index.ts'
File is ECMAScript module because 'src/project/node_modules/ky/package.json' has field "type" with value "module"
src/project/index.ts
Matched by default include pattern '**/*'
File is ECMAScript module because 'src/project/package.json' has field "type" with value "module"
Found 1 error.
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped

View File

@ -202,7 +202,7 @@ Output::
1 export var myClassWithError = class {
   ~~~~~~~~~~~~~~~~
[12:00:44 AM] Found 1 error. Watching for file changes.
[12:00:51 AM] Found 1 error. Watching for file changes.
@ -229,6 +229,82 @@ Shape signatures in builder refreshed for::
exitCode:: ExitStatus.undefined
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../a/lib/lib.d.ts","./filewitherror.ts","./filewithouterror.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };","signature":"7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."},{"version":"-11785903855-export class myClass { }","signature":"-7432826827-export declare class myClass {\n}\n"}],"root":[2,3],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"affectedFilesPendingEmit":[2],"emitSignatures":[[2,"6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"]],"latestChangedDtsFile":"./fileWithoutError.d.ts"},"version":"FakeTSVersion"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"fileInfos": {
"../../../../../a/lib/lib.d.ts": {
"original": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"./filewitherror.ts": {
"original": {
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."
},
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."
},
"./filewithouterror.ts": {
"original": {
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
},
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
}
},
"root": [
[
2,
"./filewitherror.ts"
],
[
3,
"./filewithouterror.ts"
]
],
"options": {
"composite": true
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"affectedFilesPendingEmit": [
[
"./filewitherror.ts",
"Js | Dts"
]
],
"emitSignatures": [
[
"./filewitherror.ts",
"6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"
]
],
"latestChangedDtsFile": "./fileWithoutError.d.ts"
},
"version": "FakeTSVersion",
"size": 1330
}
Change:: Change fileWithoutError
@ -242,14 +318,14 @@ Before running Timeout callback:: count: 1
After running Timeout callback:: count: 0
Output::
>> Screen clear
[12:00:48 AM] File change detected. Starting incremental compilation...
[12:00:55 AM] File change detected. Starting incremental compilation...
app/fileWithError.ts:1:12 - error TS4094: Property 'p' of exported class expression may not be private or protected.
1 export var myClassWithError = class {
   ~~~~~~~~~~~~~~~~
[12:00:49 AM] Found 1 error. Watching for file changes.
[12:01:03 AM] Found 1 error. Watching for file changes.
@ -276,3 +352,87 @@ Shape signatures in builder refreshed for::
exitCode:: ExitStatus.undefined
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../a/lib/lib.d.ts","./filewitherror.ts","./filewithouterror.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };","signature":"7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."},{"version":"-10959532701-export class myClass2 { }","signature":"-8459626297-export declare class myClass2 {\n}\n"}],"root":[2,3],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"affectedFilesPendingEmit":[2,3],"emitSignatures":[[2,"6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"],[3,"-7432826827-export declare class myClass {\n}\n"]],"latestChangedDtsFile":"./fileWithoutError.d.ts"},"version":"FakeTSVersion"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"fileInfos": {
"../../../../../a/lib/lib.d.ts": {
"original": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"./filewitherror.ts": {
"original": {
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."
},
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."
},
"./filewithouterror.ts": {
"original": {
"version": "-10959532701-export class myClass2 { }",
"signature": "-8459626297-export declare class myClass2 {\n}\n"
},
"version": "-10959532701-export class myClass2 { }",
"signature": "-8459626297-export declare class myClass2 {\n}\n"
}
},
"root": [
[
2,
"./filewitherror.ts"
],
[
3,
"./filewithouterror.ts"
]
],
"options": {
"composite": true
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"affectedFilesPendingEmit": [
[
"./filewitherror.ts",
"Js | Dts"
],
[
"./filewithouterror.ts",
"Js | Dts"
]
],
"emitSignatures": [
[
"./filewitherror.ts",
"6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"
],
[
"./filewithouterror.ts",
"-7432826827-export declare class myClass {\n}\n"
]
],
"latestChangedDtsFile": "./fileWithoutError.d.ts"
},
"version": "FakeTSVersion",
"size": 1388
}

View File

@ -202,7 +202,7 @@ Output::
1 export var myClassWithError = class {
   ~~~~~~~~~~~~~~~~
[12:00:44 AM] Found 1 error. Watching for file changes.
[12:00:51 AM] Found 1 error. Watching for file changes.
@ -229,6 +229,82 @@ Shape signatures in builder refreshed for::
exitCode:: ExitStatus.undefined
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../a/lib/lib.d.ts","./filewitherror.ts","./filewithouterror.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };","signature":"7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."},{"version":"-11785903855-export class myClass { }","signature":"-7432826827-export declare class myClass {\n}\n"}],"root":[2,3],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"affectedFilesPendingEmit":[2],"emitSignatures":[[2,"6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"]],"latestChangedDtsFile":"./fileWithoutError.d.ts"},"version":"FakeTSVersion"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"fileInfos": {
"../../../../../a/lib/lib.d.ts": {
"original": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"./filewitherror.ts": {
"original": {
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."
},
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "7927555551-export declare var myClassWithError: {\n new (): {\n tags(): void;\n p: number;\n };\n};\n(11,16)Error4094: Property 'p' of exported class expression may not be private or protected."
},
"./filewithouterror.ts": {
"original": {
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
},
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
}
},
"root": [
[
2,
"./filewitherror.ts"
],
[
3,
"./filewithouterror.ts"
]
],
"options": {
"composite": true
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"affectedFilesPendingEmit": [
[
"./filewitherror.ts",
"Js | Dts"
]
],
"emitSignatures": [
[
"./filewitherror.ts",
"6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"
]
],
"latestChangedDtsFile": "./fileWithoutError.d.ts"
},
"version": "FakeTSVersion",
"size": 1330
}
Change:: Fix error in fileWithError
@ -245,12 +321,97 @@ Before running Timeout callback:: count: 1
After running Timeout callback:: count: 0
Output::
>> Screen clear
[12:00:48 AM] File change detected. Starting incremental compilation...
[12:00:55 AM] File change detected. Starting incremental compilation...
[12:00:50 AM] Found 0 errors. Watching for file changes.
[12:01:06 AM] Found 0 errors. Watching for file changes.
Program root files: [
"/user/username/projects/solution/app/fileWithError.ts",
"/user/username/projects/solution/app/fileWithoutError.ts"
]
Program options: {
"composite": true,
"watch": true,
"configFilePath": "/user/username/projects/solution/app/tsconfig.json"
}
Program structureReused: Not
Program files::
/a/lib/lib.d.ts
/user/username/projects/solution/app/fileWithError.ts
/user/username/projects/solution/app/fileWithoutError.ts
Semantic diagnostics in builder refreshed for::
/user/username/projects/solution/app/fileWithError.ts
Shape signatures in builder refreshed for::
/user/username/projects/solution/app/filewitherror.ts (computed .d.ts)
exitCode:: ExitStatus.undefined
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo] file changed its modified time
//// [/user/username/projects/solution/app/fileWithError.js] file written with same contents
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../a/lib/lib.d.ts","./filewitherror.ts","./filewithouterror.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"-8106435186-export var myClassWithError = class {\n tags() { }\n \n };","signature":"6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"},{"version":"-11785903855-export class myClass { }","signature":"-7432826827-export declare class myClass {\n}\n"}],"root":[2,3],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"latestChangedDtsFile":"./fileWithoutError.d.ts"},"version":"FakeTSVersion"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"fileInfos": {
"../../../../../a/lib/lib.d.ts": {
"original": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"./filewitherror.ts": {
"original": {
"version": "-8106435186-export var myClassWithError = class {\n tags() { }\n \n };",
"signature": "6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"
},
"version": "-8106435186-export var myClassWithError = class {\n tags() { }\n \n };",
"signature": "6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"
},
"./filewithouterror.ts": {
"original": {
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
},
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
}
},
"root": [
[
2,
"./filewitherror.ts"
],
[
3,
"./filewithouterror.ts"
]
],
"options": {
"composite": true
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"latestChangedDtsFile": "./fileWithoutError.d.ts"
},
"version": "FakeTSVersion",
"size": 1046
}

View File

@ -40,7 +40,7 @@ Output::
1 export var myClassWithError = class {
   ~~~~~~~~~~~~~~~~
[12:00:26 AM] Found 1 error. Watching for file changes.
[12:00:31 AM] Found 1 error. Watching for file changes.
@ -83,6 +83,79 @@ FsWatchesRecursive::
exitCode:: ExitStatus.undefined
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../a/lib/lib.d.ts","./filewitherror.ts","./filewithouterror.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},"-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",{"version":"-11785903855-export class myClass { }","signature":"-7432826827-export declare class myClass {\n}\n"}],"root":[2,3],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"affectedFilesPendingEmit":[2,3],"emitSignatures":[2,3]},"version":"FakeTSVersion"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"fileInfos": {
"../../../../../a/lib/lib.d.ts": {
"original": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"./filewitherror.ts": {
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };"
},
"./filewithouterror.ts": {
"original": {
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
},
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
}
},
"root": [
[
2,
"./filewitherror.ts"
],
[
3,
"./filewithouterror.ts"
]
],
"options": {
"composite": true
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"affectedFilesPendingEmit": [
[
"./filewitherror.ts",
"Js | Dts"
],
[
"./filewithouterror.ts",
"Js | Dts"
]
],
"emitSignatures": [
"./filewitherror.ts",
"./filewithouterror.ts"
]
},
"version": "FakeTSVersion",
"size": 939
}
Change:: Change fileWithoutError
@ -96,14 +169,14 @@ Before running Timeout callback:: count: 1
After running Timeout callback:: count: 0
Output::
>> Screen clear
[12:00:30 AM] File change detected. Starting incremental compilation...
[12:00:35 AM] File change detected. Starting incremental compilation...
app/fileWithError.ts:1:12 - error TS4094: Property 'p' of exported class expression may not be private or protected.
1 export var myClassWithError = class {
   ~~~~~~~~~~~~~~~~
[12:00:31 AM] Found 1 error. Watching for file changes.
[12:00:43 AM] Found 1 error. Watching for file changes.
@ -130,3 +203,76 @@ Shape signatures in builder refreshed for::
exitCode:: ExitStatus.undefined
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../a/lib/lib.d.ts","./filewitherror.ts","./filewithouterror.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},"-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",{"version":"-10959532701-export class myClass2 { }","signature":"-8459626297-export declare class myClass2 {\n}\n"}],"root":[2,3],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"affectedFilesPendingEmit":[2,3],"emitSignatures":[2,3]},"version":"FakeTSVersion"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"fileInfos": {
"../../../../../a/lib/lib.d.ts": {
"original": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"./filewitherror.ts": {
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };"
},
"./filewithouterror.ts": {
"original": {
"version": "-10959532701-export class myClass2 { }",
"signature": "-8459626297-export declare class myClass2 {\n}\n"
},
"version": "-10959532701-export class myClass2 { }",
"signature": "-8459626297-export declare class myClass2 {\n}\n"
}
},
"root": [
[
2,
"./filewitherror.ts"
],
[
3,
"./filewithouterror.ts"
]
],
"options": {
"composite": true
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"affectedFilesPendingEmit": [
[
"./filewitherror.ts",
"Js | Dts"
],
[
"./filewithouterror.ts",
"Js | Dts"
]
],
"emitSignatures": [
"./filewitherror.ts",
"./filewithouterror.ts"
]
},
"version": "FakeTSVersion",
"size": 941
}

View File

@ -40,7 +40,7 @@ Output::
1 export var myClassWithError = class {
   ~~~~~~~~~~~~~~~~
[12:00:26 AM] Found 1 error. Watching for file changes.
[12:00:31 AM] Found 1 error. Watching for file changes.
@ -83,6 +83,79 @@ FsWatchesRecursive::
exitCode:: ExitStatus.undefined
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../a/lib/lib.d.ts","./filewitherror.ts","./filewithouterror.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},"-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",{"version":"-11785903855-export class myClass { }","signature":"-7432826827-export declare class myClass {\n}\n"}],"root":[2,3],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"affectedFilesPendingEmit":[2,3],"emitSignatures":[2,3]},"version":"FakeTSVersion"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"fileInfos": {
"../../../../../a/lib/lib.d.ts": {
"original": {
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"version": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"signature": "-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }",
"affectsGlobalScope": true
},
"./filewitherror.ts": {
"version": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };",
"signature": "-8103865863-export var myClassWithError = class {\n tags() { }\n private p = 12\n };"
},
"./filewithouterror.ts": {
"original": {
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
},
"version": "-11785903855-export class myClass { }",
"signature": "-7432826827-export declare class myClass {\n}\n"
}
},
"root": [
[
2,
"./filewitherror.ts"
],
[
3,
"./filewithouterror.ts"
]
],
"options": {
"composite": true
},
"referencedMap": {},
"exportedModulesMap": {},
"semanticDiagnosticsPerFile": [
"../../../../../a/lib/lib.d.ts",
"./filewitherror.ts",
"./filewithouterror.ts"
],
"affectedFilesPendingEmit": [
[
"./filewitherror.ts",
"Js | Dts"
],
[
"./filewithouterror.ts",
"Js | Dts"
]
],
"emitSignatures": [
"./filewitherror.ts",
"./filewithouterror.ts"
]
},
"version": "FakeTSVersion",
"size": 939
}
Change:: Fix error in fileWithError
@ -99,9 +172,9 @@ Before running Timeout callback:: count: 1
After running Timeout callback:: count: 0
Output::
>> Screen clear
[12:00:30 AM] File change detected. Starting incremental compilation...
[12:00:35 AM] File change detected. Starting incremental compilation...
[12:00:44 AM] Found 0 errors. Watching for file changes.
[12:00:51 AM] Found 0 errors. Watching for file changes.
@ -128,43 +201,6 @@ Shape signatures in builder refreshed for::
exitCode:: ExitStatus.undefined
//// [/user/username/projects/solution/app/fileWithError.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.myClassWithError = void 0;
exports.myClassWithError = /** @class */ (function () {
function myClassWithError() {
}
myClassWithError.prototype.tags = function () { };
return myClassWithError;
}());
//// [/user/username/projects/solution/app/fileWithError.d.ts]
export declare var myClassWithError: {
new (): {
tags(): void;
};
};
//// [/user/username/projects/solution/app/fileWithoutError.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.myClass = void 0;
var myClass = /** @class */ (function () {
function myClass() {
}
return myClass;
}());
exports.myClass = myClass;
//// [/user/username/projects/solution/app/fileWithoutError.d.ts]
export declare class myClass {
}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../a/lib/lib.d.ts","./filewitherror.ts","./filewithouterror.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true},{"version":"-8106435186-export var myClassWithError = class {\n tags() { }\n \n };","signature":"6892461904-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n"},{"version":"-11785903855-export class myClass { }","signature":"-7432826827-export declare class myClass {\n}\n"}],"root":[2,3],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"latestChangedDtsFile":"./fileWithoutError.d.ts"},"version":"FakeTSVersion"}
@ -229,3 +265,40 @@ export declare class myClass {
"size": 1046
}
//// [/user/username/projects/solution/app/fileWithError.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.myClassWithError = void 0;
exports.myClassWithError = /** @class */ (function () {
function myClassWithError() {
}
myClassWithError.prototype.tags = function () { };
return myClassWithError;
}());
//// [/user/username/projects/solution/app/fileWithError.d.ts]
export declare var myClassWithError: {
new (): {
tags(): void;
};
};
//// [/user/username/projects/solution/app/fileWithoutError.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.myClass = void 0;
var myClass = /** @class */ (function () {
function myClass() {
}
return myClass;
}());
exports.myClass = myClass;
//// [/user/username/projects/solution/app/fileWithoutError.d.ts]
export declare class myClass {
}

View File

@ -156,6 +156,17 @@ var wrapper = function () { return Messageable(); };
Change:: no-change-run
Input::
Output::
/lib/tsc -p src/project --incremental
exitCode:: ExitStatus.Success
Change:: modify public to protected
Input::
//// [/src/project/MessageablePerson.ts]
@ -195,7 +206,7 @@ exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
//// [/src/project/main.js] file written with same contents
//// [/src/project/MessageablePerson.js] file written with same contents
//// [/src/project/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../lib/lib.d.ts","./messageableperson.ts","./main.ts"],"fileInfos":[{"version":"5700251342-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;\ntype InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;","affectsGlobalScope":true},{"version":"3462418372-const Messageable = () => {\n return class MessageableClass {\n protected message = 'hello';\n }\n};\nconst wrapper = () => Messageable();\ntype MessageablePerson = InstanceType<ReturnType<typeof wrapper>>;\nexport default MessageablePerson;","signature":"-21450256696-declare const wrapper: () => {\n new (): {\n message: string;\n };\n};\ntype MessageablePerson = InstanceType<ReturnType<typeof wrapper>>;\nexport default MessageablePerson;\n(116,7)Error4094: Property 'message' of exported class expression may not be private or protected."},{"version":"4191603667-import MessageablePerson from './MessageablePerson.js';\nfunction logMessage( person: MessageablePerson ) {\n console.log( person.message );\n}","signature":"-3531856636-export {};\n"}],"root":[2,3],"options":{"declaration":true},"fileIdsList":[[2]],"referencedMap":[[3,1]],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,[3,[{"file":"./main.ts","start":131,"length":7,"messageText":"Property 'message' is protected and only accessible within class 'MessageableClass' and its subclasses.","category":1,"code":2445}]],2]},"version":"FakeTSVersion"}
{"program":{"fileNames":["../../lib/lib.d.ts","./messageableperson.ts","./main.ts"],"fileInfos":[{"version":"5700251342-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;\ntype InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;","affectsGlobalScope":true},{"version":"3462418372-const Messageable = () => {\n return class MessageableClass {\n protected message = 'hello';\n }\n};\nconst wrapper = () => Messageable();\ntype MessageablePerson = InstanceType<ReturnType<typeof wrapper>>;\nexport default MessageablePerson;","signature":"-21450256696-declare const wrapper: () => {\n new (): {\n message: string;\n };\n};\ntype MessageablePerson = InstanceType<ReturnType<typeof wrapper>>;\nexport default MessageablePerson;\n(116,7)Error4094: Property 'message' of exported class expression may not be private or protected."},{"version":"4191603667-import MessageablePerson from './MessageablePerson.js';\nfunction logMessage( person: MessageablePerson ) {\n console.log( person.message );\n}","signature":"-3531856636-export {};\n"}],"root":[2,3],"options":{"declaration":true},"fileIdsList":[[2]],"referencedMap":[[3,1]],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,[3,[{"file":"./main.ts","start":131,"length":7,"messageText":"Property 'message' is protected and only accessible within class 'MessageableClass' and its subclasses.","category":1,"code":2445}]],2],"emitDiagnosticsPerFile":[[2,[{"file":"./messageableperson.ts","start":116,"length":7,"messageText":"Property 'message' of exported class expression may not be private or protected.","category":1,"code":4094}]]]},"version":"FakeTSVersion"}
//// [/src/project/tsconfig.tsbuildinfo.readable.baseline.txt]
{
@ -272,14 +283,56 @@ exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
]
],
"./messageableperson.ts"
],
"emitDiagnosticsPerFile": [
[
"./messageableperson.ts",
[
{
"file": "./messageableperson.ts",
"start": 116,
"length": 7,
"messageText": "Property 'message' of exported class expression may not be private or protected.",
"category": 1,
"code": 4094
}
]
]
]
},
"version": "FakeTSVersion",
"size": 1975
"size": 2187
}
Change:: no-change-run
Input::
Output::
/lib/tsc -p src/project --incremental
src/project/main.ts:3:25 - error TS2445: Property 'message' is protected and only accessible within class 'MessageableClass' and its subclasses.
3 console.log( person.message );
   ~~~~~~~
src/project/MessageablePerson.ts:6:7 - error TS4094: Property 'message' of exported class expression may not be private or protected.
6 const wrapper = () => Messageable();
   ~~~~~~~
Found 2 errors in 2 files.
Errors Files
1 src/project/main.ts:3
1 src/project/MessageablePerson.ts:6
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
Change:: modify protected to public
Input::
//// [/src/project/MessageablePerson.ts]
@ -375,3 +428,14 @@ exitCode:: ExitStatus.Success
"size": 1682
}
Change:: no-change-run
Input::
Output::
/lib/tsc -p src/project --incremental
exitCode:: ExitStatus.Success

View File

@ -138,6 +138,17 @@ var wrapper = function () { return Messageable(); };
Change:: no-change-run
Input::
Output::
/lib/tsc -p src/project --incremental
exitCode:: ExitStatus.Success
Change:: modify public to protected
Input::
//// [/src/project/MessageablePerson.ts]
@ -253,6 +264,25 @@ exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated
Change:: no-change-run
Input::
Output::
/lib/tsc -p src/project --incremental
src/project/main.ts:3:25 - error TS2445: Property 'message' is protected and only accessible within class 'MessageableClass' and its subclasses.
3 console.log( person.message );
   ~~~~~~~
Found 1 error in src/project/main.ts:3
exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated
Change:: modify protected to public
Input::
//// [/src/project/MessageablePerson.ts]
@ -346,3 +376,14 @@ exitCode:: ExitStatus.Success
"size": 1683
}
Change:: no-change-run
Input::
Output::
/lib/tsc -p src/project --incremental
exitCode:: ExitStatus.Success

View File

@ -0,0 +1,256 @@
currentDirectory:: / useCaseSensitiveFileNames: false
Input::
//// [/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };
//// [/lib/lib.esnext.full.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };
//// [/src/project/index.ts]
import ky from 'ky';
export const api = ky.extend({});
//// [/src/project/node_modules/ky/distribution/index.d.ts]
type KyInstance = {
extend(options: Record<string,unknown>): KyInstance;
}
declare const ky: KyInstance;
export default ky;
//// [/src/project/node_modules/ky/package.json]
{
"name": "ky",
"type": "module",
"main": "./distribution/index.js"
}
//// [/src/project/package.json]
{
"type": "module"
}
//// [/src/project/tsconfig.json]
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"composite": true,
"skipLibCheck": true,
"skipDefaultLibCheck": true
}
}
Output::
/lib/tsc -p /src/project --explainFiles --listEmittedFiles
src/project/index.ts:2:14 - error TS4023: Exported variable 'api' has or is using name 'KyInstance' from external module "/src/project/node_modules/ky/distribution/index" but cannot be named.
2 export const api = ky.extend({});
   ~~~
TSFILE: /src/project/index.js
TSFILE: /src/project/tsconfig.tsbuildinfo
lib/lib.esnext.full.d.ts
Default library for target 'esnext'
src/project/node_modules/ky/distribution/index.d.ts
Imported via 'ky' from file 'src/project/index.ts'
File is ECMAScript module because 'src/project/node_modules/ky/package.json' has field "type" with value "module"
src/project/index.ts
Matched by default include pattern '**/*'
File is ECMAScript module because 'src/project/package.json' has field "type" with value "module"
Found 1 error in src/project/index.ts:2
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
//// [/src/project/index.js]
import ky from 'ky';
export const api = ky.extend({});
//// [/src/project/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../lib/lib.esnext.full.d.ts","./node_modules/ky/distribution/index.d.ts","./index.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedFormat":1},{"version":"20726041391-type KyInstance = {\n extend(options: Record<string,unknown>): KyInstance;\n }\n declare const ky: KyInstance;\n export default ky;\n","impliedFormat":99},{"version":"-383421929-import ky from 'ky';\nexport const api = ky.extend({});\n","impliedFormat":99}],"root":[3],"options":{"composite":true,"module":199,"skipDefaultLibCheck":true,"skipLibCheck":true},"fileIdsList":[[2]],"referencedMap":[[3,1]],"exportedModulesMap":[[3,1]],"semanticDiagnosticsPerFile":[1,3,2],"emitDiagnosticsPerFile":[[3,[{"file":"./index.ts","start":34,"length":3,"messageText":"Exported variable 'api' has or is using name 'KyInstance' from external module \"/src/project/node_modules/ky/distribution/index\" but cannot be named.","category":1,"code":4023}]]],"emitSignatures":[3]},"version":"FakeTSVersion"}
//// [/src/project/tsconfig.tsbuildinfo.readable.baseline.txt]
{
"program": {
"fileNames": [
"../../lib/lib.esnext.full.d.ts",
"./node_modules/ky/distribution/index.d.ts",
"./index.ts"
],
"fileNamesList": [
[
"./node_modules/ky/distribution/index.d.ts"
]
],
"fileInfos": {
"../../lib/lib.esnext.full.d.ts": {
"original": {
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"affectsGlobalScope": true,
"impliedFormat": 1
},
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
"affectsGlobalScope": true,
"impliedFormat": "commonjs"
},
"./node_modules/ky/distribution/index.d.ts": {
"original": {
"version": "20726041391-type KyInstance = {\n extend(options: Record<string,unknown>): KyInstance;\n }\n declare const ky: KyInstance;\n export default ky;\n",
"impliedFormat": 99
},
"version": "20726041391-type KyInstance = {\n extend(options: Record<string,unknown>): KyInstance;\n }\n declare const ky: KyInstance;\n export default ky;\n",
"signature": "20726041391-type KyInstance = {\n extend(options: Record<string,unknown>): KyInstance;\n }\n declare const ky: KyInstance;\n export default ky;\n",
"impliedFormat": "esnext"
},
"./index.ts": {
"original": {
"version": "-383421929-import ky from 'ky';\nexport const api = ky.extend({});\n",
"impliedFormat": 99
},
"version": "-383421929-import ky from 'ky';\nexport const api = ky.extend({});\n",
"signature": "-383421929-import ky from 'ky';\nexport const api = ky.extend({});\n",
"impliedFormat": "esnext"
}
},
"root": [
[
3,
"./index.ts"
]
],
"options": {
"composite": true,
"module": 199,
"skipDefaultLibCheck": true,
"skipLibCheck": true
},
"referencedMap": {
"./index.ts": [
"./node_modules/ky/distribution/index.d.ts"
]
},
"exportedModulesMap": {
"./index.ts": [
"./node_modules/ky/distribution/index.d.ts"
]
},
"semanticDiagnosticsPerFile": [
"../../lib/lib.esnext.full.d.ts",
"./index.ts",
"./node_modules/ky/distribution/index.d.ts"
],
"emitDiagnosticsPerFile": [
[
"./index.ts",
[
{
"file": "./index.ts",
"start": 34,
"length": 3,
"messageText": "Exported variable 'api' has or is using name 'KyInstance' from external module \"/src/project/node_modules/ky/distribution/index\" but cannot be named.",
"category": 1,
"code": 4023
}
]
]
],
"emitSignatures": [
"./index.ts"
]
},
"version": "FakeTSVersion",
"size": 1440
}
Change:: no-change-run
Input::
Output::
/lib/tsc -p /src/project --explainFiles --listEmittedFiles
src/project/index.ts:2:14 - error TS4023: Exported variable 'api' has or is using name 'KyInstance' from external module "/src/project/node_modules/ky/distribution/index" but cannot be named.
2 export const api = ky.extend({});
   ~~~
lib/lib.esnext.full.d.ts
Default library for target 'esnext'
src/project/node_modules/ky/distribution/index.d.ts
Imported via 'ky' from file 'src/project/index.ts'
File is ECMAScript module because 'src/project/node_modules/ky/package.json' has field "type" with value "module"
src/project/index.ts
Matched by default include pattern '**/*'
File is ECMAScript module because 'src/project/package.json' has field "type" with value "module"
Found 1 error in src/project/index.ts:2
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
Change:: no-change-run
Input::
Output::
/lib/tsc -b /src/project --explainFiles --listEmittedFiles -v
[12:00:19 AM] Projects in this build:
* src/project/tsconfig.json
[12:00:20 AM] Project 'src/project/tsconfig.json' is out of date because buildinfo file 'src/project/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted
[12:00:21 AM] Building project '/src/project/tsconfig.json'...
src/project/index.ts:2:14 - error TS4023: Exported variable 'api' has or is using name 'KyInstance' from external module "/src/project/node_modules/ky/distribution/index" but cannot be named.
2 export const api = ky.extend({});
   ~~~
lib/lib.esnext.full.d.ts
Default library for target 'esnext'
src/project/node_modules/ky/distribution/index.d.ts
Imported via 'ky' from file 'src/project/index.ts'
File is ECMAScript module because 'src/project/node_modules/ky/package.json' has field "type" with value "module"
src/project/index.ts
Matched by default include pattern '**/*'
File is ECMAScript module because 'src/project/package.json' has field "type" with value "module"
Found 1 error.
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped