@@ -656,46 +656,33 @@ namespace ts {
656
656
fileExists : ( fileName : string ) => boolean ,
657
657
hasInvalidatedResolution : HasInvalidatedResolution ,
658
658
hasChangedAutomaticTypeDirectiveNames : HasChangedAutomaticTypeDirectiveNames | undefined ,
659
+ getParsedCommandLine : ( fileName : string ) => ParsedCommandLine | undefined ,
659
660
projectReferences : readonly ProjectReference [ ] | undefined
660
661
) : boolean {
661
662
// If we haven't created a program yet or have changed automatic type directives, then it is not up-to-date
662
- if ( ! program || hasChangedAutomaticTypeDirectiveNames ?.( ) ) {
663
- return false ;
664
- }
663
+ if ( ! program || hasChangedAutomaticTypeDirectiveNames ?.( ) ) return false ;
665
664
666
665
// If root file names don't match
667
- if ( ! arrayIsEqualTo ( program . getRootFileNames ( ) , rootFileNames ) ) {
668
- return false ;
669
- }
666
+ if ( ! arrayIsEqualTo ( program . getRootFileNames ( ) , rootFileNames ) ) return false ;
670
667
671
668
let seenResolvedRefs : ResolvedProjectReference [ ] | undefined ;
672
669
673
670
// If project references don't match
674
- if ( ! arrayIsEqualTo ( program . getProjectReferences ( ) , projectReferences , projectReferenceUptoDate ) ) {
675
- return false ;
676
- }
671
+ if ( ! arrayIsEqualTo ( program . getProjectReferences ( ) , projectReferences , projectReferenceUptoDate ) ) return false ;
677
672
678
673
// If any file is not up-to-date, then the whole program is not up-to-date
679
- if ( program . getSourceFiles ( ) . some ( sourceFileNotUptoDate ) ) {
680
- return false ;
681
- }
674
+ if ( program . getSourceFiles ( ) . some ( sourceFileNotUptoDate ) ) return false ;
682
675
683
676
// If any of the missing file paths are now created
684
- if ( program . getMissingFilePaths ( ) . some ( fileExists ) ) {
685
- return false ;
686
- }
677
+ if ( program . getMissingFilePaths ( ) . some ( fileExists ) ) return false ;
687
678
688
679
const currentOptions = program . getCompilerOptions ( ) ;
689
680
// If the compilation settings do no match, then the program is not up-to-date
690
- if ( ! compareDataObjects ( currentOptions , newOptions ) ) {
691
- return false ;
692
- }
681
+ if ( ! compareDataObjects ( currentOptions , newOptions ) ) return false ;
693
682
694
683
// If everything matches but the text of config file is changed,
695
684
// error locations can change for program options, so update the program
696
- if ( currentOptions . configFile && newOptions . configFile ) {
697
- return currentOptions . configFile . text === newOptions . configFile . text ;
698
- }
685
+ if ( currentOptions . configFile && newOptions . configFile ) return currentOptions . configFile . text === newOptions . configFile . text ;
699
686
700
687
return true ;
701
688
@@ -709,23 +696,26 @@ namespace ts {
709
696
}
710
697
711
698
function projectReferenceUptoDate ( oldRef : ProjectReference , newRef : ProjectReference , index : number ) {
712
- if ( ! projectReferenceIsEqualTo ( oldRef , newRef ) ) {
713
- return false ;
714
- }
715
- return resolvedProjectReferenceUptoDate ( program ! . getResolvedProjectReferences ( ) ! [ index ] , oldRef ) ;
699
+ return projectReferenceIsEqualTo ( oldRef , newRef ) &&
700
+ resolvedProjectReferenceUptoDate ( program ! . getResolvedProjectReferences ( ) ! [ index ] , oldRef ) ;
716
701
}
717
702
718
703
function resolvedProjectReferenceUptoDate ( oldResolvedRef : ResolvedProjectReference | undefined , oldRef : ProjectReference ) : boolean {
719
704
if ( oldResolvedRef ) {
720
- if ( contains ( seenResolvedRefs , oldResolvedRef ) ) {
721
705
// Assume true
722
- return true ;
723
- }
706
+ if ( contains ( seenResolvedRefs , oldResolvedRef ) ) return true ;
724
707
725
- // If sourceFile for the oldResolvedRef existed, check the version for uptodate
726
- if ( ! sourceFileVersionUptoDate ( oldResolvedRef . sourceFile ) ) {
727
- return false ;
728
- }
708
+ const refPath = resolveProjectReferencePath ( oldRef ) ;
709
+ const newParsedCommandLine = getParsedCommandLine ( refPath ) ;
710
+
711
+ // Check if config file exists
712
+ if ( ! newParsedCommandLine ) return false ;
713
+
714
+ // If change in source file
715
+ if ( oldResolvedRef . commandLine . options . configFile !== newParsedCommandLine . options . configFile ) return false ;
716
+
717
+ // check file names
718
+ if ( ! arrayIsEqualTo ( oldResolvedRef . commandLine . fileNames , newParsedCommandLine . fileNames ) ) return false ;
729
719
730
720
// Add to seen before checking the referenced paths of this config file
731
721
( seenResolvedRefs || ( seenResolvedRefs = [ ] ) ) . push ( oldResolvedRef ) ;
@@ -737,7 +727,8 @@ namespace ts {
737
727
738
728
// In old program, not able to resolve project reference path,
739
729
// so if config file doesnt exist, it is uptodate.
740
- return ! fileExists ( resolveProjectReferencePath ( oldRef ) ) ;
730
+ const refPath = resolveProjectReferencePath ( oldRef ) ;
731
+ return ! getParsedCommandLine ( refPath ) ;
741
732
}
742
733
}
743
734
@@ -1021,11 +1012,28 @@ namespace ts {
1021
1012
host . onReleaseOldSourceFile ( oldSourceFile , oldProgram . getCompilerOptions ( ) , ! ! getSourceFileByPath ( oldSourceFile . path ) ) ;
1022
1013
}
1023
1014
}
1024
- oldProgram . forEachResolvedProjectReference ( resolvedProjectReference => {
1025
- if ( ! getResolvedProjectReferenceByPath ( resolvedProjectReference . sourceFile . path ) ) {
1026
- host . onReleaseOldSourceFile ! ( resolvedProjectReference . sourceFile , oldProgram ! . getCompilerOptions ( ) , /*hasSourceFileByPath*/ false ) ;
1015
+ if ( ! host . getParsedCommandLine ) {
1016
+ oldProgram . forEachResolvedProjectReference ( resolvedProjectReference => {
1017
+ if ( ! getResolvedProjectReferenceByPath ( resolvedProjectReference . sourceFile . path ) ) {
1018
+ host . onReleaseOldSourceFile ! ( resolvedProjectReference . sourceFile , oldProgram ! . getCompilerOptions ( ) , /*hasSourceFileByPath*/ false ) ;
1019
+ }
1020
+ } ) ;
1021
+ }
1022
+ }
1023
+
1024
+ // Release commandlines that new program does not use
1025
+ if ( oldProgram && host . onReleaseParsedCommandLine ) {
1026
+ forEachProjectReference (
1027
+ oldProgram . getProjectReferences ( ) ,
1028
+ oldProgram . getResolvedProjectReferences ( ) ,
1029
+ ( oldResolvedRef , parent , index ) => {
1030
+ const oldReference = parent ?. commandLine . projectReferences ! [ index ] || oldProgram ! . getProjectReferences ( ) ! [ index ] ;
1031
+ const oldRefPath = resolveProjectReferencePath ( oldReference ) ;
1032
+ if ( ! projectReferenceRedirects ?. has ( toPath ( oldRefPath ) ) ) {
1033
+ host . onReleaseParsedCommandLine ! ( oldRefPath , oldResolvedRef , oldProgram ! . getCompilerOptions ( ) ) ;
1034
+ }
1027
1035
}
1028
- } ) ;
1036
+ ) ;
1029
1037
}
1030
1038
1031
1039
// unconditionally set oldProgram to undefined to prevent it from being captured in closure
@@ -1367,7 +1375,9 @@ namespace ts {
1367
1375
const newResolvedRef = parseProjectReferenceConfigFile ( newRef ) ;
1368
1376
if ( oldResolvedRef ) {
1369
1377
// Resolved project reference has gone missing or changed
1370
- return ! newResolvedRef || newResolvedRef . sourceFile !== oldResolvedRef . sourceFile ;
1378
+ return ! newResolvedRef ||
1379
+ newResolvedRef . sourceFile !== oldResolvedRef . sourceFile ||
1380
+ ! arrayIsEqualTo ( oldResolvedRef . commandLine . fileNames , newResolvedRef . commandLine . fileNames ) ;
1371
1381
}
1372
1382
else {
1373
1383
// A previously-unresolved reference may be resolved now
0 commit comments