@@ -452,28 +452,41 @@ func (c *linkerContext) mangleProps(mangleCache map[string]interface{}) {
452
452
// can cause initialization bugs. So let's forbid these cycles for now to guard
453
453
// against code splitting bugs that could cause us to generate buggy chunks.
454
454
func (c * linkerContext ) enforceNoCyclicChunkImports () {
455
- var validate func (int , []int )
456
- validate = func (chunkIndex int , path []int ) {
457
- for _ , otherChunkIndex := range path {
458
- if chunkIndex == otherChunkIndex {
459
- c .log .AddError (nil , logger.Range {}, "Internal error: generated chunks contain a circular import" )
460
- return
461
- }
455
+ var validate func (int , map [int ]int ) bool
456
+
457
+ // DFS memoization with 3-colors, more space efficient
458
+ // 0: white (unvisited), 1: gray (visiting), 2: black (visited)
459
+ colors := make (map [int ]int )
460
+ validate = func (chunkIndex int , colors map [int ]int ) bool {
461
+ if colors [chunkIndex ] == 1 {
462
+ c .log .AddError (nil , logger.Range {}, "Internal error: generated chunks contain a circular import" )
463
+ return true
462
464
}
463
- path = append (path , chunkIndex )
465
+
466
+ if colors [chunkIndex ] == 2 {
467
+ return false
468
+ }
469
+
470
+ colors [chunkIndex ] = 1
471
+
464
472
for _ , chunkImport := range c .chunks [chunkIndex ].crossChunkImports {
465
- // Ignore cycles caused by dynamic "import()" expressions. These are fine
466
- // because they don't necessarily cause initialization order issues and
467
- // they don't indicate a bug in our chunk generation algorithm. They arise
468
- // normally in real code (e.g. two files that import each other).
469
473
if chunkImport .importKind != ast .ImportDynamic {
470
- validate (int (chunkImport .chunkIndex ), path )
474
+
475
+ // Recursively validate otherChunkIndex
476
+ if validate (int (chunkImport .chunkIndex ), colors ) {
477
+ return true
478
+ }
471
479
}
472
480
}
481
+
482
+ colors [chunkIndex ] = 2
483
+ return false
473
484
}
474
- path := make ([] int , 0 , len ( c . chunks ))
485
+
475
486
for i := range c .chunks {
476
- validate (i , path )
487
+ if validate (i , colors ) {
488
+ break
489
+ }
477
490
}
478
491
}
479
492
0 commit comments