@@ -1137,7 +1137,11 @@ export function forEachResolvedProjectReference<T>(
1137
1137
resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ,
1138
1138
cb : ( resolvedProjectReference : ResolvedProjectReference , parent : ResolvedProjectReference | undefined ) => T | undefined ,
1139
1139
) : T | undefined {
1140
- return forEachProjectReference ( /*projectReferences*/ undefined , resolvedProjectReferences , ( resolvedRef , parent ) => resolvedRef && cb ( resolvedRef , parent ) ) ;
1140
+ return forEachProjectReference (
1141
+ /*projectReferences*/ undefined ,
1142
+ resolvedProjectReferences ,
1143
+ ( resolvedRef , parent ) => resolvedRef && cb ( resolvedRef , parent ) ,
1144
+ ) ;
1141
1145
}
1142
1146
1143
1147
function forEachProjectReference < T > (
@@ -1147,7 +1151,6 @@ function forEachProjectReference<T>(
1147
1151
cbRef ?: ( projectReferences : readonly ProjectReference [ ] | undefined , parent : ResolvedProjectReference | undefined ) => T | undefined ,
1148
1152
) : T | undefined {
1149
1153
let seenResolvedRefs : Set < Path > | undefined ;
1150
-
1151
1154
return worker ( projectReferences , resolvedProjectReferences , /*parent*/ undefined ) ;
1152
1155
1153
1156
function worker (
@@ -1160,19 +1163,26 @@ function forEachProjectReference<T>(
1160
1163
const result = cbRef ( projectReferences , parent ) ;
1161
1164
if ( result ) return result ;
1162
1165
}
1163
-
1164
- return forEach ( resolvedProjectReferences , ( resolvedRef , index ) => {
1165
- if ( resolvedRef && seenResolvedRefs ?. has ( resolvedRef . sourceFile . path ) ) {
1166
- // ignore recursives
1167
- return undefined ;
1168
- }
1169
-
1170
- const result = cbResolvedRef ( resolvedRef , parent , index ) ;
1171
- if ( result || ! resolvedRef ) return result ;
1172
-
1173
- ( seenResolvedRefs ||= new Set ( ) ) . add ( resolvedRef . sourceFile . path ) ;
1174
- return worker ( resolvedRef . commandLine . projectReferences , resolvedRef . references , resolvedRef ) ;
1175
- } ) ;
1166
+ let skipChildren : Set < ResolvedProjectReference > | undefined ;
1167
+ return forEach (
1168
+ resolvedProjectReferences ,
1169
+ ( resolvedRef , index ) => {
1170
+ if ( resolvedRef && seenResolvedRefs ?. has ( resolvedRef . sourceFile . path ) ) {
1171
+ ( skipChildren ??= new Set ( ) ) . add ( resolvedRef ) ;
1172
+ // ignore recursives
1173
+ return undefined ;
1174
+ }
1175
+ const result = cbResolvedRef ( resolvedRef , parent , index ) ;
1176
+ if ( result || ! resolvedRef ) return result ;
1177
+ ( seenResolvedRefs ||= new Set ( ) ) . add ( resolvedRef . sourceFile . path ) ;
1178
+ } ,
1179
+ ) || forEach (
1180
+ resolvedProjectReferences ,
1181
+ resolvedRef =>
1182
+ resolvedRef && ! skipChildren ?. has ( resolvedRef ) ?
1183
+ worker ( resolvedRef . commandLine . projectReferences , resolvedRef . references , resolvedRef ) :
1184
+ undefined ,
1185
+ ) ;
1176
1186
}
1177
1187
}
1178
1188
@@ -1354,7 +1364,14 @@ export function isProgramUptoDate(
1354
1364
( seenResolvedRefs || ( seenResolvedRefs = [ ] ) ) . push ( oldResolvedRef ) ;
1355
1365
1356
1366
// If child project references are upto date, this project reference is uptodate
1357
- return ! forEach ( oldResolvedRef . references , ( childResolvedRef , index ) => ! resolvedProjectReferenceUptoDate ( childResolvedRef , oldResolvedRef . commandLine . projectReferences ! [ index ] ) ) ;
1367
+ return ! forEach (
1368
+ oldResolvedRef . references ,
1369
+ ( childResolvedRef , index ) =>
1370
+ ! resolvedProjectReferenceUptoDate (
1371
+ childResolvedRef ,
1372
+ oldResolvedRef . commandLine . projectReferences ! [ index ] ,
1373
+ ) ,
1374
+ ) ;
1358
1375
}
1359
1376
1360
1377
// In old program, not able to resolve project reference path,
@@ -4883,7 +4900,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
4883
4900
case FileIncludeKind . SourceFromProjectReference :
4884
4901
case FileIncludeKind . OutputFromProjectReference :
4885
4902
const referencedResolvedRef = Debug . checkDefined ( resolvedProjectReferences ?. [ reason . index ] ) ;
4886
- const referenceInfo = forEachProjectReference ( projectReferences , resolvedProjectReferences , ( resolvedRef , parent , index ) => resolvedRef === referencedResolvedRef ? { sourceFile : parent ?. sourceFile || options . configFile ! , index } : undefined ) ;
4903
+ const referenceInfo = forEachProjectReference (
4904
+ projectReferences ,
4905
+ resolvedProjectReferences ,
4906
+ ( resolvedRef , parent , index ) =>
4907
+ resolvedRef === referencedResolvedRef ?
4908
+ { sourceFile : parent ?. sourceFile || options . configFile ! , index } :
4909
+ undefined ,
4910
+ ) ;
4887
4911
if ( ! referenceInfo ) return undefined ;
4888
4912
const { sourceFile, index } = referenceInfo ;
4889
4913
const referencesSyntax = forEachTsConfigPropArray ( sourceFile as TsConfigSourceFile , "references" , property => isArrayLiteralExpression ( property . initializer ) ? property . initializer : undefined ) ;
@@ -4923,28 +4947,32 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
4923
4947
4924
4948
function verifyProjectReferences ( ) {
4925
4949
const buildInfoPath = ! options . suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath ( options ) : undefined ;
4926
- forEachProjectReference ( projectReferences , resolvedProjectReferences , ( resolvedRef , parent , index ) => {
4927
- const ref = ( parent ? parent . commandLine . projectReferences : projectReferences ) ! [ index ] ;
4928
- const parentFile = parent && parent . sourceFile as JsonSourceFile ;
4929
- verifyDeprecatedProjectReference ( ref , parentFile , index ) ;
4930
- if ( ! resolvedRef ) {
4931
- createDiagnosticForReference ( parentFile , index , Diagnostics . File_0_not_found , ref . path ) ;
4932
- return ;
4933
- }
4934
- const options = resolvedRef . commandLine . options ;
4935
- if ( ! options . composite || options . noEmit ) {
4936
- // ok to not have composite if the current program is container only
4937
- const inputs = parent ? parent . commandLine . fileNames : rootNames ;
4938
- if ( inputs . length ) {
4939
- if ( ! options . composite ) createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_must_have_setting_composite_Colon_true , ref . path ) ;
4940
- if ( options . noEmit ) createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_may_not_disable_emit , ref . path ) ;
4950
+ forEachProjectReference (
4951
+ projectReferences ,
4952
+ resolvedProjectReferences ,
4953
+ ( resolvedRef , parent , index ) => {
4954
+ const ref = ( parent ? parent . commandLine . projectReferences : projectReferences ) ! [ index ] ;
4955
+ const parentFile = parent && parent . sourceFile as JsonSourceFile ;
4956
+ verifyDeprecatedProjectReference ( ref , parentFile , index ) ;
4957
+ if ( ! resolvedRef ) {
4958
+ createDiagnosticForReference ( parentFile , index , Diagnostics . File_0_not_found , ref . path ) ;
4959
+ return ;
4941
4960
}
4942
- }
4943
- if ( ! parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath ( options ) ) {
4944
- createDiagnosticForReference ( parentFile , index , Diagnostics . Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1 , buildInfoPath , ref . path ) ;
4945
- hasEmitBlockingDiagnostics . set ( toPath ( buildInfoPath ) , true ) ;
4946
- }
4947
- } ) ;
4961
+ const options = resolvedRef . commandLine . options ;
4962
+ if ( ! options . composite || options . noEmit ) {
4963
+ // ok to not have composite if the current program is container only
4964
+ const inputs = parent ? parent . commandLine . fileNames : rootNames ;
4965
+ if ( inputs . length ) {
4966
+ if ( ! options . composite ) createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_must_have_setting_composite_Colon_true , ref . path ) ;
4967
+ if ( options . noEmit ) createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_may_not_disable_emit , ref . path ) ;
4968
+ }
4969
+ }
4970
+ if ( ! parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath ( options ) ) {
4971
+ createDiagnosticForReference ( parentFile , index , Diagnostics . Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1 , buildInfoPath , ref . path ) ;
4972
+ hasEmitBlockingDiagnostics . set ( toPath ( buildInfoPath ) , true ) ;
4973
+ }
4974
+ } ,
4975
+ ) ;
4948
4976
}
4949
4977
4950
4978
function createDiagnosticForOptionPathKeyValue ( key : string , valueIndex : number , message : DiagnosticMessage , ...args : DiagnosticArguments ) {
0 commit comments