@@ -530,6 +530,51 @@ namespace ts {
530530 return resolutions ;
531531 }
532532
533+ /* @internal */
534+ export function forEachResolvedProjectReference < T > (
535+ resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ,
536+ cb : ( resolvedProjectReference : ResolvedProjectReference , parent : ResolvedProjectReference | undefined ) => T | undefined
537+ ) : T | undefined {
538+ return forEachProjectReference ( /*projectReferences*/ undefined , resolvedProjectReferences , ( resolvedRef , parent ) => resolvedRef && cb ( resolvedRef , parent ) ) ;
539+ }
540+
541+ function forEachProjectReference < T > (
542+ projectReferences : readonly ProjectReference [ ] | undefined ,
543+ resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ,
544+ cbResolvedRef : ( resolvedRef : ResolvedProjectReference | undefined , parent : ResolvedProjectReference | undefined , index : number ) => T | undefined ,
545+ cbRef ?: ( projectReferences : readonly ProjectReference [ ] | undefined , parent : ResolvedProjectReference | undefined ) => T | undefined
546+ ) : T | undefined {
547+ let seenResolvedRefs : Set < Path > | undefined ;
548+
549+ return worker ( projectReferences , resolvedProjectReferences , /*parent*/ undefined ) ;
550+
551+ function worker (
552+ projectReferences : readonly ProjectReference [ ] | undefined ,
553+ resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ,
554+ parent : ResolvedProjectReference | undefined ,
555+ ) : T | undefined {
556+
557+ // Visit project references first
558+ if ( cbRef ) {
559+ const result = cbRef ( projectReferences , parent ) ;
560+ if ( result ) { return result ; }
561+ }
562+
563+ return forEach ( resolvedProjectReferences , ( resolvedRef , index ) => {
564+ if ( resolvedRef && seenResolvedRefs ?. has ( resolvedRef . sourceFile . path ) ) {
565+ // ignore recursives
566+ return undefined ;
567+ }
568+
569+ const result = cbResolvedRef ( resolvedRef , parent , index ) ;
570+ if ( result || ! resolvedRef ) return result ;
571+
572+ ( seenResolvedRefs ||= new Set ( ) ) . add ( resolvedRef . sourceFile . path ) ;
573+ return worker ( resolvedRef . commandLine . projectReferences , resolvedRef . references , resolvedRef ) ;
574+ } ) ;
575+ }
576+ }
577+
533578 /* @internal */
534579 export const inferredTypesContainingFile = "__inferred type names__.ts" ;
535580
@@ -914,8 +959,8 @@ namespace ts {
914959 host . onReleaseOldSourceFile ( oldSourceFile , oldProgram . getCompilerOptions ( ) , ! ! getSourceFileByPath ( oldSourceFile . path ) ) ;
915960 }
916961 }
917- oldProgram . forEachResolvedProjectReference ( ( resolvedProjectReference , resolvedProjectReferencePath ) => {
918- if ( resolvedProjectReference && ! getResolvedProjectReferenceByPath ( resolvedProjectReferencePath ) ) {
962+ oldProgram . forEachResolvedProjectReference ( resolvedProjectReference => {
963+ if ( ! getResolvedProjectReferenceByPath ( resolvedProjectReference . sourceFile . path ) ) {
919964 host . onReleaseOldSourceFile ! ( resolvedProjectReference . sourceFile , oldProgram ! . getCompilerOptions ( ) , /*hasSourceFileByPath*/ false ) ;
920965 }
921966 } ) ;
@@ -1038,7 +1083,6 @@ namespace ts {
10381083 if ( ! source ) return undefined ;
10391084 // Output of .d.ts file so return resolved ref that matches the out file name
10401085 return forEachResolvedProjectReference ( resolvedRef => {
1041- if ( ! resolvedRef ) return undefined ;
10421086 const out = outFile ( resolvedRef . commandLine . options ) ;
10431087 if ( ! out ) return undefined ;
10441088 return toPath ( out ) === filePath ? resolvedRef : undefined ;
@@ -1251,7 +1295,7 @@ namespace ts {
12511295 return ! forEachProjectReference (
12521296 oldProgram ! . getProjectReferences ( ) ,
12531297 oldProgram ! . getResolvedProjectReferences ( ) ,
1254- ( oldResolvedRef , index , parent ) => {
1298+ ( oldResolvedRef , parent , index ) => {
12551299 const newRef = ( parent ? parent . commandLine . projectReferences : projectReferences ) ! [ index ] ;
12561300 const newResolvedRef = parseProjectReferenceConfigFile ( newRef ) ;
12571301 if ( oldResolvedRef ) {
@@ -2115,9 +2159,7 @@ namespace ts {
21152159 if ( ! options . configFile ) { return emptyArray ; }
21162160 let diagnostics = programDiagnostics . getDiagnostics ( options . configFile . fileName ) ;
21172161 forEachResolvedProjectReference ( resolvedRef => {
2118- if ( resolvedRef ) {
2119- diagnostics = concatenate ( diagnostics , programDiagnostics . getDiagnostics ( resolvedRef . sourceFile . fileName ) ) ;
2120- }
2162+ diagnostics = concatenate ( diagnostics , programDiagnostics . getDiagnostics ( resolvedRef . sourceFile . fileName ) ) ;
21212163 } ) ;
21222164 return diagnostics ;
21232165 }
@@ -2597,12 +2639,11 @@ namespace ts {
25972639 function getResolvedProjectReferenceToRedirect ( fileName : string ) {
25982640 if ( mapFromFileToProjectReferenceRedirects === undefined ) {
25992641 mapFromFileToProjectReferenceRedirects = new Map ( ) ;
2600- forEachResolvedProjectReference ( ( referencedProject , referenceProjectPath ) => {
2642+ forEachResolvedProjectReference ( referencedProject => {
26012643 // not input file from the referenced project, ignore
2602- if ( referencedProject &&
2603- toPath ( options . configFilePath ! ) !== referenceProjectPath ) {
2644+ if ( toPath ( options . configFilePath ! ) !== referencedProject . sourceFile . path ) {
26042645 referencedProject . commandLine . fileNames . forEach ( f =>
2605- mapFromFileToProjectReferenceRedirects ! . set ( toPath ( f ) , referenceProjectPath ) ) ;
2646+ mapFromFileToProjectReferenceRedirects ! . set ( toPath ( f ) , referencedProject . sourceFile . path ) ) ;
26062647 }
26072648 } ) ;
26082649 }
@@ -2612,35 +2653,29 @@ namespace ts {
26122653 }
26132654
26142655 function forEachResolvedProjectReference < T > (
2615- cb : ( resolvedProjectReference : ResolvedProjectReference | undefined , resolvedProjectReferencePath : Path ) => T | undefined
2656+ cb : ( resolvedProjectReference : ResolvedProjectReference ) => T | undefined
26162657 ) : T | undefined {
2617- return forEachProjectReference ( projectReferences , resolvedProjectReferences , ( resolvedRef , index , parent ) => {
2618- const ref = ( parent ? parent . commandLine . projectReferences : projectReferences ) ! [ index ] ;
2619- const resolvedRefPath = toPath ( resolveProjectReferencePath ( ref ) ) ;
2620- return cb ( resolvedRef , resolvedRefPath ) ;
2621- } ) ;
2658+ return ts . forEachResolvedProjectReference ( resolvedProjectReferences , cb ) ;
26222659 }
26232660
26242661 function getSourceOfProjectReferenceRedirect ( file : string ) {
26252662 if ( ! isDeclarationFileName ( file ) ) return undefined ;
26262663 if ( mapFromToProjectReferenceRedirectSource === undefined ) {
26272664 mapFromToProjectReferenceRedirectSource = new Map ( ) ;
26282665 forEachResolvedProjectReference ( resolvedRef => {
2629- if ( resolvedRef ) {
2630- const out = outFile ( resolvedRef . commandLine . options ) ;
2631- if ( out ) {
2632- // Dont know which source file it means so return true?
2633- const outputDts = changeExtension ( out , Extension . Dts ) ;
2634- mapFromToProjectReferenceRedirectSource ! . set ( toPath ( outputDts ) , true ) ;
2635- }
2636- else {
2637- forEach ( resolvedRef . commandLine . fileNames , fileName => {
2638- if ( ! fileExtensionIs ( fileName , Extension . Dts ) && ! fileExtensionIs ( fileName , Extension . Json ) ) {
2639- const outputDts = getOutputDeclarationFileName ( fileName , resolvedRef . commandLine , host . useCaseSensitiveFileNames ( ) ) ;
2640- mapFromToProjectReferenceRedirectSource ! . set ( toPath ( outputDts ) , fileName ) ;
2641- }
2642- } ) ;
2643- }
2666+ const out = outFile ( resolvedRef . commandLine . options ) ;
2667+ if ( out ) {
2668+ // Dont know which source file it means so return true?
2669+ const outputDts = changeExtension ( out , Extension . Dts ) ;
2670+ mapFromToProjectReferenceRedirectSource ! . set ( toPath ( outputDts ) , true ) ;
2671+ }
2672+ else {
2673+ forEach ( resolvedRef . commandLine . fileNames , fileName => {
2674+ if ( ! fileExtensionIs ( fileName , Extension . Dts ) && ! fileExtensionIs ( fileName , Extension . Json ) ) {
2675+ const outputDts = getOutputDeclarationFileName ( fileName , resolvedRef . commandLine , host . useCaseSensitiveFileNames ( ) ) ;
2676+ mapFromToProjectReferenceRedirectSource ! . set ( toPath ( outputDts ) , fileName ) ;
2677+ }
2678+ } ) ;
26442679 }
26452680 } ) ;
26462681 }
@@ -2651,49 +2686,6 @@ namespace ts {
26512686 return useSourceOfProjectReferenceRedirect && ! ! getResolvedProjectReferenceToRedirect ( fileName ) ;
26522687 }
26532688
2654- function forEachProjectReference < T > (
2655- projectReferences : readonly ProjectReference [ ] | undefined ,
2656- resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ,
2657- cbResolvedRef : ( resolvedRef : ResolvedProjectReference | undefined , index : number , parent : ResolvedProjectReference | undefined ) => T | undefined ,
2658- cbRef ?: ( projectReferences : readonly ProjectReference [ ] | undefined , parent : ResolvedProjectReference | undefined ) => T | undefined
2659- ) : T | undefined {
2660- let seenResolvedRefs : ResolvedProjectReference [ ] | undefined ;
2661-
2662- return worker ( projectReferences , resolvedProjectReferences , /*parent*/ undefined , cbResolvedRef , cbRef ) ;
2663-
2664- function worker (
2665- projectReferences : readonly ProjectReference [ ] | undefined ,
2666- resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ,
2667- parent : ResolvedProjectReference | undefined ,
2668- cbResolvedRef : ( resolvedRef : ResolvedProjectReference | undefined , index : number , parent : ResolvedProjectReference | undefined ) => T | undefined ,
2669- cbRef ?: ( projectReferences : readonly ProjectReference [ ] | undefined , parent : ResolvedProjectReference | undefined ) => T | undefined ,
2670- ) : T | undefined {
2671-
2672- // Visit project references first
2673- if ( cbRef ) {
2674- const result = cbRef ( projectReferences , parent ) ;
2675- if ( result ) { return result ; }
2676- }
2677-
2678- return forEach ( resolvedProjectReferences , ( resolvedRef , index ) => {
2679- if ( contains ( seenResolvedRefs , resolvedRef ) ) {
2680- // ignore recursives
2681- return undefined ;
2682- }
2683-
2684- const result = cbResolvedRef ( resolvedRef , index , parent ) ;
2685- if ( result ) {
2686- return result ;
2687- }
2688-
2689- if ( ! resolvedRef ) return undefined ;
2690-
2691- ( seenResolvedRefs || ( seenResolvedRefs = [ ] ) ) . push ( resolvedRef ) ;
2692- return worker ( resolvedRef . commandLine . projectReferences , resolvedRef . references , resolvedRef , cbResolvedRef , cbRef ) ;
2693- } ) ;
2694- }
2695- }
2696-
26972689 function getResolvedProjectReferenceByPath ( projectReferencePath : Path ) : ResolvedProjectReference | undefined {
26982690 if ( ! projectReferenceRedirects ) {
26992691 return undefined ;
@@ -3348,7 +3340,7 @@ namespace ts {
33483340
33493341 function verifyProjectReferences ( ) {
33503342 const buildInfoPath = ! options . suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath ( options ) : undefined ;
3351- forEachProjectReference ( projectReferences , resolvedProjectReferences , ( resolvedRef , index , parent ) => {
3343+ forEachProjectReference ( projectReferences , resolvedProjectReferences , ( resolvedRef , parent , index ) => {
33523344 const ref = ( parent ? parent . commandLine . projectReferences : projectReferences ) ! [ index ] ;
33533345 const parentFile = parent && parent . sourceFile as JsonSourceFile ;
33543346 if ( ! resolvedRef ) {
@@ -3546,7 +3538,7 @@ namespace ts {
35463538 toPath ( fileName : string ) : Path ;
35473539 getResolvedProjectReferences ( ) : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ;
35483540 getSourceOfProjectReferenceRedirect ( fileName : string ) : SourceOfProjectReferenceRedirect | undefined ;
3549- forEachResolvedProjectReference < T > ( cb : ( resolvedProjectReference : ResolvedProjectReference | undefined , resolvedProjectReferencePath : Path ) => T | undefined ) : T | undefined ;
3541+ forEachResolvedProjectReference < T > ( cb : ( resolvedProjectReference : ResolvedProjectReference ) => T | undefined ) : T | undefined ;
35503542 }
35513543
35523544 function updateHostForUseSourceOfProjectReferenceRedirect ( host : HostForUseSourceOfProjectReferenceRedirect ) {
@@ -3576,7 +3568,6 @@ namespace ts {
35763568 if ( ! setOfDeclarationDirectories ) {
35773569 setOfDeclarationDirectories = new Set ( ) ;
35783570 host . forEachResolvedProjectReference ( ref => {
3579- if ( ! ref ) return ;
35803571 const out = outFile ( ref . commandLine . options ) ;
35813572 if ( out ) {
35823573 setOfDeclarationDirectories ! . add ( getDirectoryPath ( host . toPath ( out ) ) ) ;
0 commit comments