@@ -1139,7 +1139,11 @@ export function forEachResolvedProjectReference<T>(
1139
1139
resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ,
1140
1140
cb : ( resolvedProjectReference : ResolvedProjectReference , parent : ResolvedProjectReference | undefined ) => T | undefined ,
1141
1141
) : T | undefined {
1142
- return forEachProjectReference ( /*projectReferences*/ undefined , resolvedProjectReferences , ( resolvedRef , parent ) => resolvedRef && cb ( resolvedRef , parent ) ) ;
1142
+ return forEachProjectReference (
1143
+ /*projectReferences*/ undefined ,
1144
+ resolvedProjectReferences ,
1145
+ ( resolvedRef , parent ) => resolvedRef && cb ( resolvedRef , parent ) ,
1146
+ ) ;
1143
1147
}
1144
1148
1145
1149
function forEachProjectReference < T > (
@@ -1149,7 +1153,6 @@ function forEachProjectReference<T>(
1149
1153
cbRef ?: ( projectReferences : readonly ProjectReference [ ] | undefined , parent : ResolvedProjectReference | undefined ) => T | undefined ,
1150
1154
) : T | undefined {
1151
1155
let seenResolvedRefs : Set < Path > | undefined ;
1152
-
1153
1156
return worker ( projectReferences , resolvedProjectReferences , /*parent*/ undefined ) ;
1154
1157
1155
1158
function worker (
@@ -1162,19 +1165,26 @@ function forEachProjectReference<T>(
1162
1165
const result = cbRef ( projectReferences , parent ) ;
1163
1166
if ( result ) return result ;
1164
1167
}
1165
-
1166
- return forEach ( resolvedProjectReferences , ( resolvedRef , index ) => {
1167
- if ( resolvedRef && seenResolvedRefs ?. has ( resolvedRef . sourceFile . path ) ) {
1168
- // ignore recursives
1169
- return undefined ;
1170
- }
1171
-
1172
- const result = cbResolvedRef ( resolvedRef , parent , index ) ;
1173
- if ( result || ! resolvedRef ) return result ;
1174
-
1175
- ( seenResolvedRefs ||= new Set ( ) ) . add ( resolvedRef . sourceFile . path ) ;
1176
- return worker ( resolvedRef . commandLine . projectReferences , resolvedRef . references , resolvedRef ) ;
1177
- } ) ;
1168
+ let skipChildren : Set < ResolvedProjectReference > | undefined ;
1169
+ return forEach (
1170
+ resolvedProjectReferences ,
1171
+ ( resolvedRef , index ) => {
1172
+ if ( resolvedRef && seenResolvedRefs ?. has ( resolvedRef . sourceFile . path ) ) {
1173
+ ( skipChildren ??= new Set ( ) ) . add ( resolvedRef ) ;
1174
+ // ignore recursives
1175
+ return undefined ;
1176
+ }
1177
+ const result = cbResolvedRef ( resolvedRef , parent , index ) ;
1178
+ if ( result || ! resolvedRef ) return result ;
1179
+ ( seenResolvedRefs ||= new Set ( ) ) . add ( resolvedRef . sourceFile . path ) ;
1180
+ } ,
1181
+ ) || forEach (
1182
+ resolvedProjectReferences ,
1183
+ resolvedRef =>
1184
+ resolvedRef && ! skipChildren ?. has ( resolvedRef ) ?
1185
+ worker ( resolvedRef . commandLine . projectReferences , resolvedRef . references , resolvedRef ) :
1186
+ undefined ,
1187
+ ) ;
1178
1188
}
1179
1189
}
1180
1190
@@ -1356,7 +1366,14 @@ export function isProgramUptoDate(
1356
1366
( seenResolvedRefs || ( seenResolvedRefs = [ ] ) ) . push ( oldResolvedRef ) ;
1357
1367
1358
1368
// If child project references are upto date, this project reference is uptodate
1359
- return ! forEach ( oldResolvedRef . references , ( childResolvedRef , index ) => ! resolvedProjectReferenceUptoDate ( childResolvedRef , oldResolvedRef . commandLine . projectReferences ! [ index ] ) ) ;
1369
+ return ! forEach (
1370
+ oldResolvedRef . references ,
1371
+ ( childResolvedRef , index ) =>
1372
+ ! resolvedProjectReferenceUptoDate (
1373
+ childResolvedRef ,
1374
+ oldResolvedRef . commandLine . projectReferences ! [ index ] ,
1375
+ ) ,
1376
+ ) ;
1360
1377
}
1361
1378
1362
1379
// In old program, not able to resolve project reference path,
@@ -4894,7 +4911,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
4894
4911
case FileIncludeKind . SourceFromProjectReference :
4895
4912
case FileIncludeKind . OutputFromProjectReference :
4896
4913
const referencedResolvedRef = Debug . checkDefined ( resolvedProjectReferences ?. [ reason . index ] ) ;
4897
- const referenceInfo = forEachProjectReference ( projectReferences , resolvedProjectReferences , ( resolvedRef , parent , index ) => resolvedRef === referencedResolvedRef ? { sourceFile : parent ?. sourceFile || options . configFile ! , index } : undefined ) ;
4914
+ const referenceInfo = forEachProjectReference (
4915
+ projectReferences ,
4916
+ resolvedProjectReferences ,
4917
+ ( resolvedRef , parent , index ) =>
4918
+ resolvedRef === referencedResolvedRef ?
4919
+ { sourceFile : parent ?. sourceFile || options . configFile ! , index } :
4920
+ undefined ,
4921
+ ) ;
4898
4922
if ( ! referenceInfo ) return undefined ;
4899
4923
const { sourceFile, index } = referenceInfo ;
4900
4924
const referencesSyntax = forEachTsConfigPropArray ( sourceFile as TsConfigSourceFile , "references" , property => isArrayLiteralExpression ( property . initializer ) ? property . initializer : undefined ) ;
@@ -4934,28 +4958,32 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
4934
4958
4935
4959
function verifyProjectReferences ( ) {
4936
4960
const buildInfoPath = ! options . suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath ( options ) : undefined ;
4937
- forEachProjectReference ( projectReferences , resolvedProjectReferences , ( resolvedRef , parent , index ) => {
4938
- const ref = ( parent ? parent . commandLine . projectReferences : projectReferences ) ! [ index ] ;
4939
- const parentFile = parent && parent . sourceFile as JsonSourceFile ;
4940
- verifyDeprecatedProjectReference ( ref , parentFile , index ) ;
4941
- if ( ! resolvedRef ) {
4942
- createDiagnosticForReference ( parentFile , index , Diagnostics . File_0_not_found , ref . path ) ;
4943
- return ;
4944
- }
4945
- const options = resolvedRef . commandLine . options ;
4946
- if ( ! options . composite || options . noEmit ) {
4947
- // ok to not have composite if the current program is container only
4948
- const inputs = parent ? parent . commandLine . fileNames : rootNames ;
4949
- if ( inputs . length ) {
4950
- if ( ! options . composite ) createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_must_have_setting_composite_Colon_true , ref . path ) ;
4951
- if ( options . noEmit ) createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_may_not_disable_emit , ref . path ) ;
4961
+ forEachProjectReference (
4962
+ projectReferences ,
4963
+ resolvedProjectReferences ,
4964
+ ( resolvedRef , parent , index ) => {
4965
+ const ref = ( parent ? parent . commandLine . projectReferences : projectReferences ) ! [ index ] ;
4966
+ const parentFile = parent && parent . sourceFile as JsonSourceFile ;
4967
+ verifyDeprecatedProjectReference ( ref , parentFile , index ) ;
4968
+ if ( ! resolvedRef ) {
4969
+ createDiagnosticForReference ( parentFile , index , Diagnostics . File_0_not_found , ref . path ) ;
4970
+ return ;
4952
4971
}
4953
- }
4954
- if ( ! parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath ( options ) ) {
4955
- createDiagnosticForReference ( parentFile , index , Diagnostics . Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1 , buildInfoPath , ref . path ) ;
4956
- hasEmitBlockingDiagnostics . set ( toPath ( buildInfoPath ) , true ) ;
4957
- }
4958
- } ) ;
4972
+ const options = resolvedRef . commandLine . options ;
4973
+ if ( ! options . composite || options . noEmit ) {
4974
+ // ok to not have composite if the current program is container only
4975
+ const inputs = parent ? parent . commandLine . fileNames : rootNames ;
4976
+ if ( inputs . length ) {
4977
+ if ( ! options . composite ) createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_must_have_setting_composite_Colon_true , ref . path ) ;
4978
+ if ( options . noEmit ) createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_may_not_disable_emit , ref . path ) ;
4979
+ }
4980
+ }
4981
+ if ( ! parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath ( options ) ) {
4982
+ createDiagnosticForReference ( parentFile , index , Diagnostics . Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1 , buildInfoPath , ref . path ) ;
4983
+ hasEmitBlockingDiagnostics . set ( toPath ( buildInfoPath ) , true ) ;
4984
+ }
4985
+ } ,
4986
+ ) ;
4959
4987
}
4960
4988
4961
4989
function createDiagnosticForOptionPathKeyValue ( key : string , valueIndex : number , message : DiagnosticMessage , ...args : DiagnosticArguments ) {
0 commit comments