已开启
补充 getBuilderCreationParameters 和 getOldProgram 的 [SIR] 诊断日志 #871
补充 getBuilderCreationParameters 和 getOldProgram 的 [SIR] 诊断日志 #871
已开启
liyancheng创建于 13 天前
4 个文件变更+44-6
@@ -1339,14 +1339,18 @@ export function getBuilderCreationParameters(newProgramOrRootNames: Program | re
1339 oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;1339 oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;
1340 Debug.assert(!!oldProgram);1340 Debug.assert(!!oldProgram);
1341 newProgram = oldProgram.getProgram();1341 newProgram = oldProgram.getProgram();
1342+ console.warn(`[SIR] getBuilderCreationParameters(case1-undefined): reusing program from oldProgram.getProgram(), no createProgram call, oldProgram=${!!oldProgram}`);
1342 }1343 }
1343 else if (isArray(newProgramOrRootNames)) {1344 else if (isArray(newProgramOrRootNames)) {
1344 oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;1345 oldProgram = configFileParsingDiagnosticsOrOldProgram as BuilderProgram;
1346+ const oldProgramForCreate = oldProgram && oldProgram.getProgramOrUndefined();
1347+ console.warn(`[SIR] getBuilderCreationParameters: oldProgram=${!!oldProgram}, ` +
1348+ `oldProgram.getProgramOrUndefined()=${!!oldProgramForCreate}, rootNames.length=${(newProgramOrRootNames as readonly string[]).length}`);
1345 newProgram = createProgram({1349 newProgram = createProgram({
1346 rootNames: newProgramOrRootNames,1350 rootNames: newProgramOrRootNames,
1347 options: hostOrOptions as CompilerOptions,1351 options: hostOrOptions as CompilerOptions,
1348 host: oldProgramOrHost as CompilerHost,1352 host: oldProgramOrHost as CompilerHost,
1349- oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),1353+ oldProgram: oldProgramForCreate,
1350 configFileParsingDiagnostics,1354 configFileParsingDiagnostics,
1351 projectReferences1355 projectReferences
1352 });1356 });
@@ -1357,6 +1361,7 @@ export function getBuilderCreationParameters(newProgramOrRootNames: Program | re
1357 host = hostOrOptions as BuilderProgramHost;1361 host = hostOrOptions as BuilderProgramHost;
1358 oldProgram = oldProgramOrHost as BuilderProgram;1362 oldProgram = oldProgramOrHost as BuilderProgram;
1359 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram as readonly Diagnostic[];1363 configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram as readonly Diagnostic[];
1364+ console.warn(`[SIR] getBuilderCreationParameters(case3-Program): program already created externally, no createProgram call, oldProgram=${!!oldProgram}`);
1360 }1365 }
1361 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };1366 return { host, newProgram, oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || emptyArray };
1362}1367}
@@ -2064,6 +2064,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2064 2064 
2065 function tryReuseStructureFromOldProgram(): StructureIsReused {2065 function tryReuseStructureFromOldProgram(): StructureIsReused {
2066 if (!oldProgram) {2066 if (!oldProgram) {
2067+ console.warn('[SIR] Not #1: oldProgram is null/undefined (first build or .tsbuildinfo missing/deleted/corrupt)');
2067 return StructureIsReused.Not;2068 return StructureIsReused.Not;
2068 }2069 }
2069 2070 
@@ -2071,17 +2072,22 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2071 // if any of these properties has changed - structure cannot be reused2072 // if any of these properties has changed - structure cannot be reused
2072 const oldOptions = oldProgram.getCompilerOptions();2073 const oldOptions = oldProgram.getCompilerOptions();
2073 if (changesAffectModuleResolution(oldOptions, options)) {2074 if (changesAffectModuleResolution(oldOptions, options)) {
2075+ console.warn('[SIR] Not #2: changesAffectModuleResolution - ' +
2076+ `configFilePath: ${oldOptions.configFilePath} -> ${options.configFilePath}`);
2074 return StructureIsReused.Not;2077 return StructureIsReused.Not;
2075 }2078 }
2076 2079 
2077 // there is an old program, check if we can reuse its structure2080 // there is an old program, check if we can reuse its structure
2078 const oldRootNames = oldProgram.getRootFileNames();2081 const oldRootNames = oldProgram.getRootFileNames();
2079 if (!arrayIsEqualTo(oldRootNames, rootNames)) {2082 if (!arrayIsEqualTo(oldRootNames, rootNames)) {
2083+ console.warn('[SIR] Not #3: rootFileNames changed - ' +
2084+ `oldCount=${oldRootNames.length}, newCount=${rootNames.length}`);
2080 return StructureIsReused.Not;2085 return StructureIsReused.Not;
2081 }2086 }
2082 2087 
2083 // Check if any referenced project tsconfig files are different2088 // Check if any referenced project tsconfig files are different
2084 if (!canReuseProjectReferences()) {2089 if (!canReuseProjectReferences()) {
2090+ console.warn('[SIR] Not #4: canReuseProjectReferences returned false (project references changed)');
2085 return StructureIsReused.Not;2091 return StructureIsReused.Not;
2086 }2092 }
2087 if (projectReferences) {2093 if (projectReferences) {
@@ -2097,6 +2103,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2097 // and hence cant reuse the structure.2103 // and hence cant reuse the structure.
2098 // This is same as how we dont reuse the structure if one of the file from old program is now missing2104 // This is same as how we dont reuse the structure if one of the file from old program is now missing
2099 if (oldProgram.getMissingFilePaths().some(missingFilePath => host.fileExists(missingFilePath))) {2105 if (oldProgram.getMissingFilePaths().some(missingFilePath => host.fileExists(missingFilePath))) {
2106+ console.warn('[SIR] Not #5: a previously missing file now exists');
2100 return StructureIsReused.Not;2107 return StructureIsReused.Not;
2101 }2108 }
2102 2109 
@@ -2111,6 +2118,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2111 : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, /*onError*/ undefined, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat); // TODO: GH#182172118 : host.getSourceFile(oldSourceFile.fileName, sourceFileOptions, /*onError*/ undefined, shouldCreateNewSourceFile || sourceFileOptions.impliedNodeFormat !== oldSourceFile.impliedNodeFormat); // TODO: GH#18217
2112 2119 
2113 if (!newSourceFile) {2120 if (!newSourceFile) {
2121+ console.warn(`[SIR] Not #6: source file no longer exists: ${oldSourceFile.fileName}`);
2114 return StructureIsReused.Not;2122 return StructureIsReused.Not;
2115 }2123 }
2116 newSourceFile.packageJsonLocations = sourceFileOptions.packageJsonLocations?.length ? sourceFileOptions.packageJsonLocations : undefined;2124 newSourceFile.packageJsonLocations = sourceFileOptions.packageJsonLocations?.length ? sourceFileOptions.packageJsonLocations : undefined;
@@ -2124,6 +2132,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2124 // This lets us know if the unredirected file has changed. If it has we should break the redirect.2132 // This lets us know if the unredirected file has changed. If it has we should break the redirect.
2125 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {2133 if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
2126 // Underlying file has changed. Might not redirect anymore. Must rebuild program.2134 // Underlying file has changed. Might not redirect anymore. Must rebuild program.
2135+ console.warn(`[SIR] Not #7: redirect underlying file changed: ${oldSourceFile.fileName}`);
2127 return StructureIsReused.Not;2136 return StructureIsReused.Not;
2128 }2137 }
2129 fileChanged = false;2138 fileChanged = false;
@@ -2132,6 +2141,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2132 else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {2141 else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
2133 // If a redirected-to source file changes, the redirect may be broken.2142 // If a redirected-to source file changes, the redirect may be broken.
2134 if (newSourceFile !== oldSourceFile) {2143 if (newSourceFile !== oldSourceFile) {
2144+ console.warn(`[SIR] Not #8: redirected-to file changed: ${oldSourceFile.fileName}`);
2135 return StructureIsReused.Not;2145 return StructureIsReused.Not;
2136 }2146 }
2137 fileChanged = false;2147 fileChanged = false;
@@ -2153,6 +2163,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2153 const prevKind = seenPackageNames.get(packageName);2163 const prevKind = seenPackageNames.get(packageName);
2154 const newKind = fileChanged ? SeenPackageName.Modified : SeenPackageName.Exists;2164 const newKind = fileChanged ? SeenPackageName.Modified : SeenPackageName.Exists;
2155 if ((prevKind !== undefined && newKind === SeenPackageName.Modified) || prevKind === SeenPackageName.Modified) {2165 if ((prevKind !== undefined && newKind === SeenPackageName.Modified) || prevKind === SeenPackageName.Modified) {
2166+ console.warn(`[SIR] Not #9: package name conflict (two files for package "${packageName}", at least one changed): ${oldSourceFile.fileName}`);
2156 return StructureIsReused.Not;2167 return StructureIsReused.Not;
2157 }2168 }
2158 seenPackageNames.set(packageName, newKind);2169 seenPackageNames.set(packageName, newKind);
@@ -2214,6 +2225,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2214 }2225 }
2215 2226 
2216 if (structureIsReused !== StructureIsReused.Completely) {2227 if (structureIsReused !== StructureIsReused.Completely) {
2228+ console.warn(`[SIR] SafeModules: file content changed but module resolution reusable (${structureIsReused === StructureIsReused.SafeModules ? 'SafeModules' : 'unknown'}), modifiedFiles=${modifiedSourceFiles.length}`);
2217 return structureIsReused;2229 return structureIsReused;
2218 }2230 }
2219 2231 
@@ -2252,10 +2264,12 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2252 }2264 }
2253 2265 
2254 if (structureIsReused !== StructureIsReused.Completely) {2266 if (structureIsReused !== StructureIsReused.Completely) {
2267+ console.warn(`[SIR] SafeModules: module resolution changed for modified files, modifiedFiles=${modifiedSourceFiles.length}`);
2255 return structureIsReused;2268 return structureIsReused;
2256 }2269 }
2257 2270 
2258 if (changesAffectingProgramStructure(oldOptions, options) || host.hasChangedAutomaticTypeDirectiveNames?.()) {2271 if (changesAffectingProgramStructure(oldOptions, options) || host.hasChangedAutomaticTypeDirectiveNames?.()) {
2272+ console.warn('[SIR] SafeModules: changesAffectingProgramStructure or hasChangedAutomaticTypeDirectiveNames');
2259 return StructureIsReused.SafeModules;2273 return StructureIsReused.SafeModules;
2260 }2274 }
2261 2275 
@@ -2291,6 +2305,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
2291 redirectTargetsMap = oldProgram.redirectTargetsMap;2305 redirectTargetsMap = oldProgram.redirectTargetsMap;
2292 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;2306 usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;
2293 2307 
2308+ console.warn('[SIR] Completely: structure fully reused from old program');
2294 return StructureIsReused.Completely;2309 return StructureIsReused.Completely;
2295 }2310 }
2296 2311 
@@ -1494,9 +1494,15 @@ function listEmittedFile({ write }: SolutionBuilderState, proj: ParsedCommandLin
1494}1494}
1495 1495 
1496function getOldProgram<T extends BuilderProgram>({ options, builderPrograms, compilerHost }: SolutionBuilderState<T>, proj: ResolvedConfigFilePath, parsed: ParsedCommandLine) {1496function getOldProgram<T extends BuilderProgram>({ options, builderPrograms, compilerHost }: SolutionBuilderState<T>, proj: ResolvedConfigFilePath, parsed: ParsedCommandLine) {
1497- if (options.force) return undefined;1497+ if (options.force) {
1498+ console.warn(`[SIR] getOldProgram: --force flag set, returning undefined for ${proj}`);
1499+ return undefined;
1500+ }
1498 const value = builderPrograms.get(proj);1501 const value = builderPrograms.get(proj);
1499- if (value) return value;1502+ if (value) {
1503+ console.warn(`[SIR] getOldProgram: reused cached builderProgram from builderPrograms map for ${proj}`);
1504+ return value;
1505+ }
1500 return readBuilderProgram(parsed.options, compilerHost) as any as T;1506 return readBuilderProgram(parsed.options, compilerHost) as any as T;
1501}1507}
1502 1508 
@@ -106,7 +106,10 @@ export interface ReadBuildProgramHost {
106export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost, isForLinter?: boolean) {106export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost, isForLinter?: boolean) {
107 let buildInfoPath = getTsBuildInfoEmitOutputFilePath(compilerOptions);107 let buildInfoPath = getTsBuildInfoEmitOutputFilePath(compilerOptions);
108 108 
109- if (!buildInfoPath) return undefined;109+ if (!buildInfoPath) {
110+ console.warn('[SIR] readBuilderProgram: buildInfoPath is empty (tsBuildInfoFile not set in compilerOptions)');
111+ return undefined;
112+ }
110 113 
111 if (isForLinter) {114 if (isForLinter) {
112 buildInfoPath = getTsBuildInfoEmitOutputFilePathForLinter(buildInfoPath);115 buildInfoPath = getTsBuildInfoEmitOutputFilePathForLinter(buildInfoPath);
@@ -119,10 +122,19 @@ export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadB
119 }122 }
120 else {123 else {
121 const content = host.readFile(buildInfoPath);124 const content = host.readFile(buildInfoPath);
122- if (!content) return undefined;125+ if (!content) {
126+ console.warn(`[SIR] readBuilderProgram: .tsbuildinfo file not found or empty: ${buildInfoPath}`);
127+ return undefined;
128+ }
123 buildInfo = getBuildInfo(buildInfoPath, content);129 buildInfo = getBuildInfo(buildInfoPath, content);
124 }130 }
125- if (!buildInfo || buildInfo.version !== version || !buildInfo.program) return undefined;131+ if (!buildInfo || buildInfo.version !== version || !buildInfo.program) {
132+ console.warn(`[SIR] readBuilderProgram: buildInfo invalid - ` +
133+ `buildInfo=${!!buildInfo}, versionMatch=${buildInfo?.version === version}, hasProgram=${!!buildInfo?.program}, ` +
134+ `expectedVersion=${version}, actualVersion=${buildInfo?.version}, path=${buildInfoPath}`);
135+ return undefined;
136+ }
137+ console.warn(`[SIR] readBuilderProgram: SUCCESS - loaded oldProgram from ${buildInfoPath}`);
126 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);138 return createBuilderProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
127}139}
128 140