@@ -11,10 +11,9 @@ namespace ts {
11
11
message ( diag : DiagnosticMessage , ...args : string [ ] ) : void ;
12
12
}
13
13
14
- type Mapper = ReturnType < typeof createDependencyMapper > ;
15
14
interface DependencyGraph {
16
15
buildQueue : ResolvedConfigFileName [ ] ;
17
- dependencyMap : Mapper ;
16
+ referencingProjectsMap : ConfigFileMap < ConfigFileMap < true > > ;
18
17
}
19
18
20
19
export interface BuildOptions {
@@ -220,40 +219,18 @@ namespace ts {
220
219
}
221
220
}
222
221
223
- function createDependencyMapper ( toPath : ToResolvedConfigFilePath ) {
224
- const childToParents = createFileMap < ResolvedConfigFileName [ ] > ( toPath ) ;
225
- const parentToChildren = createFileMap < ResolvedConfigFileName [ ] > ( toPath ) ;
226
-
227
- function addReference ( childConfigFileName : ResolvedConfigFileName , parentConfigFileName : ResolvedConfigFileName ) : void {
228
- addEntry ( childToParents , childConfigFileName , parentConfigFileName ) ;
229
- addEntry ( parentToChildren , parentConfigFileName , childConfigFileName ) ;
230
- }
231
-
232
- function getReferencesTo ( parentConfigFileName : ResolvedConfigFileName ) : ResolvedConfigFileName [ ] {
233
- return parentToChildren . getValue ( parentConfigFileName ) || [ ] ;
234
- }
235
-
236
- function getReferencesOf ( childConfigFileName : ResolvedConfigFileName ) : ResolvedConfigFileName [ ] {
237
- return childToParents . getValue ( childConfigFileName ) || [ ] ;
238
- }
239
-
240
- function addEntry ( mapToAddTo : typeof childToParents | typeof parentToChildren , key : ResolvedConfigFileName , element : ResolvedConfigFileName ) {
241
- key = normalizePath ( key ) as ResolvedConfigFileName ;
242
- element = normalizePath ( element ) as ResolvedConfigFileName ;
243
- let arr = mapToAddTo . getValue ( key ) ;
244
- if ( arr === undefined ) {
245
- mapToAddTo . setValue ( key , arr = [ ] ) ;
246
- }
247
- if ( arr . indexOf ( element ) < 0 ) {
248
- arr . push ( element ) ;
249
- }
222
+ function getOrCreateValueFromConfigFileMap < T > ( configFileMap : ConfigFileMap < T > , resolved : ResolvedConfigFileName , createT : ( ) => T ) : T {
223
+ const existingValue = configFileMap . getValue ( resolved ) ;
224
+ let newValue : T | undefined ;
225
+ if ( ! existingValue ) {
226
+ newValue = createT ( ) ;
227
+ configFileMap . setValue ( resolved , newValue ) ;
250
228
}
229
+ return existingValue || newValue ! ;
230
+ }
251
231
252
- return {
253
- addReference,
254
- getReferencesTo,
255
- getReferencesOf,
256
- } ;
232
+ function getOrCreateValueMapFromConfigFileMap < T > ( configFileMap : ConfigFileMap < Map < T > > , resolved : ResolvedConfigFileName ) : Map < T > {
233
+ return getOrCreateValueFromConfigFileMap < Map < T > > ( configFileMap , resolved , createMap ) ;
257
234
}
258
235
259
236
function getOutputDeclarationFileName ( inputFileName : string , configFile : ParsedCommandLine ) {
@@ -529,19 +506,9 @@ namespace ts {
529
506
}
530
507
}
531
508
532
- function getOrCreateExistingWatches < T > ( resolved : ResolvedConfigFileName , allWatches : ConfigFileMap < Map < T > > ) {
533
- const existingWatches = allWatches . getValue ( resolved ) ;
534
- let newWatches : Map < T > | undefined ;
535
- if ( ! existingWatches ) {
536
- newWatches = createMap ( ) ;
537
- allWatches . setValue ( resolved , newWatches ) ;
538
- }
539
- return existingWatches || newWatches ! ;
540
- }
541
-
542
509
function watchWildCardDirectories ( resolved : ResolvedConfigFileName , parsed : ParsedCommandLine ) {
543
510
updateWatchingWildcardDirectories (
544
- getOrCreateExistingWatches ( resolved , allWatchedWildcardDirectories ) ,
511
+ getOrCreateValueMapFromConfigFileMap ( allWatchedWildcardDirectories , resolved ) ,
545
512
createMapFromTemplate ( parsed . configFileSpecs ! . wildcardDirectories ) ,
546
513
( dir , flags ) => {
547
514
return hostWithWatch . watchDirectory ( dir , fileOrDirectory => {
@@ -564,7 +531,7 @@ namespace ts {
564
531
565
532
function watchInputFiles ( resolved : ResolvedConfigFileName , parsed : ParsedCommandLine ) {
566
533
mutateMap (
567
- getOrCreateExistingWatches ( resolved , allWatchedInputFiles ) ,
534
+ getOrCreateValueMapFromConfigFileMap ( allWatchedInputFiles , resolved ) ,
568
535
arrayToMap ( parsed . fileNames , toPath ) ,
569
536
{
570
537
createNewValue : ( _key , input ) => hostWithWatch . watchFile ( input , ( ) => {
@@ -818,7 +785,7 @@ namespace ts {
818
785
819
786
if ( addProjToQueue ( resolved , reloadLevel ) ) {
820
787
// TODO: instead of adding the dependent project to queue right away postpone this
821
- queueBuildForDownstreamReferences ( resolved , getGlobalDependencyGraph ( ) ) ;
788
+ queueBuildForDownstreamReferences ( resolved ) ;
822
789
}
823
790
}
824
791
@@ -857,12 +824,15 @@ namespace ts {
857
824
}
858
825
859
826
// Mark all downstream projects of this one needing to be built "later"
860
- function queueBuildForDownstreamReferences ( root : ResolvedConfigFileName , dependencyGraph : DependencyGraph ) {
861
- const deps = dependencyGraph . dependencyMap . getReferencesTo ( root ) ;
862
- for ( const ref of deps ) {
827
+ function queueBuildForDownstreamReferences ( root : ResolvedConfigFileName ) {
828
+ const dependencyGraph = getGlobalDependencyGraph ( ) ;
829
+ const referencingProjects = dependencyGraph . referencingProjectsMap . getValue ( root ) ;
830
+ if ( ! referencingProjects ) return ;
831
+ // Always use build order to queue projects
832
+ for ( const project of dependencyGraph . buildQueue ) {
863
833
// Can skip circular references
864
- if ( addProjToQueue ( ref ) ) {
865
- queueBuildForDownstreamReferences ( ref , dependencyGraph ) ;
834
+ if ( referencingProjects . hasKey ( project ) && addProjToQueue ( project ) ) {
835
+ queueBuildForDownstreamReferences ( project ) ;
866
836
}
867
837
}
868
838
}
@@ -944,14 +914,14 @@ namespace ts {
944
914
const permanentMarks = createFileMap < true > ( toPath ) ;
945
915
const circularityReportStack : string [ ] = [ ] ;
946
916
const buildOrder : ResolvedConfigFileName [ ] = [ ] ;
947
- const graph = createDependencyMapper ( toPath ) ;
917
+ const referencingProjectsMap = createFileMap < ConfigFileMap < true > > ( toPath ) ;
948
918
for ( const root of roots ) {
949
919
visit ( root ) ;
950
920
}
951
921
952
922
return {
953
923
buildQueue : buildOrder ,
954
- dependencyMap : graph ,
924
+ referencingProjectsMap
955
925
} ;
956
926
957
927
function visit ( projPath : ResolvedConfigFileName , inCircularContext = false ) {
@@ -972,7 +942,9 @@ namespace ts {
972
942
for ( const ref of parsed . projectReferences ) {
973
943
const resolvedRefPath = resolveProjectName ( ref . path ) ;
974
944
visit ( resolvedRefPath , inCircularContext || ref . circular ) ;
975
- graph . addReference ( projPath , resolvedRefPath ) ;
945
+ // Get projects referencing resolvedRefPath and add projPath to it
946
+ const referencingProjects = getOrCreateValueFromConfigFileMap ( referencingProjectsMap , resolvedRefPath , ( ) => createFileMap ( toPath ) ) ;
947
+ referencingProjects . setValue ( projPath , true ) ;
976
948
}
977
949
}
978
950
0 commit comments