mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Handle dts emit time errors for incremental scenarios and buildInfo (#56295)
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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"],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user