@@ -112,7 +112,7 @@ final class Emitter[E >: Null <: js.Tree](
112
112
}
113
113
114
114
private def emitInternal (moduleSet : ModuleSet ,
115
- logger : Logger ): WithGlobals [Map [ModuleID , List [E ]]] = {
115
+ logger : Logger ): WithGlobals [Map [ModuleID , ( List [E ], Boolean ) ]] = {
116
116
// Reset caching stats.
117
117
statsClassesReused = 0
118
118
statsClassesInvalidated = 0
@@ -169,7 +169,7 @@ final class Emitter[E >: Null <: js.Tree](
169
169
*/
170
170
@ tailrec
171
171
private def emitAvoidGlobalClash (moduleSet : ModuleSet ,
172
- logger : Logger , secondAttempt : Boolean ): WithGlobals [Map [ModuleID , List [E ]]] = {
172
+ logger : Logger , secondAttempt : Boolean ): WithGlobals [Map [ModuleID , ( List [E ], Boolean ) ]] = {
173
173
val result = emitOnce(moduleSet, logger)
174
174
175
175
val mentionedDangerousGlobalRefs =
@@ -194,7 +194,7 @@ final class Emitter[E >: Null <: js.Tree](
194
194
}
195
195
196
196
private def emitOnce (moduleSet : ModuleSet ,
197
- logger : Logger ): WithGlobals [Map [ModuleID , List [E ]]] = {
197
+ logger : Logger ): WithGlobals [Map [ModuleID , ( List [E ], Boolean ) ]] = {
198
198
// Genreate classes first so we can measure time separately.
199
199
val generatedClasses = logger.time(" Emitter: Generate Classes" ) {
200
200
moduleSet.modules.map { module =>
@@ -212,18 +212,26 @@ final class Emitter[E >: Null <: js.Tree](
212
212
213
213
val moduleTrees = logger.time(" Emitter: Write trees" ) {
214
214
moduleSet.modules.map { module =>
215
+ var changed = false
216
+ def extractChangedAndWithGlobals [T ](x : (WithGlobals [T ], Boolean )): T = {
217
+ changed ||= x._2
218
+ extractWithGlobals(x._1)
219
+ }
220
+
215
221
val moduleContext = ModuleContext .fromModule(module)
216
222
val moduleCache = state.moduleCaches.getOrElseUpdate(module.id, new ModuleCache )
217
223
218
224
val moduleClasses = generatedClasses(module.id)
219
225
220
- val moduleImports = extractWithGlobals {
226
+ changed ||= moduleClasses.exists(_.changed)
227
+
228
+ val moduleImports = extractChangedAndWithGlobals {
221
229
moduleCache.getOrComputeImports(module.externalDependencies, module.internalDependencies) {
222
230
genModuleImports(module).map(postTransform(_, 0 ))
223
231
}
224
232
}
225
233
226
- val topLevelExports = extractWithGlobals {
234
+ val topLevelExports = extractChangedAndWithGlobals {
227
235
/* We cache top level exports all together, rather than individually,
228
236
* since typically there are few.
229
237
*/
@@ -233,7 +241,7 @@ final class Emitter[E >: Null <: js.Tree](
233
241
}
234
242
}
235
243
236
- val moduleInitializers = extractWithGlobals {
244
+ val moduleInitializers = extractChangedAndWithGlobals {
237
245
val initializers = module.initializers.toList
238
246
moduleCache.getOrComputeInitializers(initializers) {
239
247
WithGlobals .list(initializers.map { initializer =>
@@ -324,7 +332,7 @@ final class Emitter[E >: Null <: js.Tree](
324
332
trackedGlobalRefs = unionPreserveEmpty(trackedGlobalRefs, genClass.trackedGlobalRefs)
325
333
}
326
334
327
- module.id -> allTrees
335
+ module.id -> ( allTrees, changed)
328
336
}
329
337
}
330
338
@@ -382,8 +390,14 @@ final class Emitter[E >: Null <: js.Tree](
382
390
val classCache = classCaches.getOrElseUpdate(
383
391
new ClassID (linkedClass.ancestors, moduleContext), new ClassCache )
384
392
393
+ var changed = false
394
+ def extractChanged [T ](x : (T , Boolean )): T = {
395
+ changed ||= x._2
396
+ x._1
397
+ }
398
+
385
399
val classTreeCache =
386
- classCache.getCache(linkedClass.version)
400
+ extractChanged( classCache.getCache(linkedClass.version) )
387
401
388
402
val kind = linkedClass.kind
389
403
@@ -396,6 +410,9 @@ final class Emitter[E >: Null <: js.Tree](
396
410
withGlobals.value
397
411
}
398
412
413
+ def extractWithGlobalsAndChanged [T ](x : (WithGlobals [T ], Boolean )): T =
414
+ extractWithGlobals(extractChanged(x))
415
+
399
416
// Main part
400
417
401
418
val main = List .newBuilder[E ]
@@ -426,7 +443,7 @@ final class Emitter[E >: Null <: js.Tree](
426
443
val methodCache =
427
444
classCache.getStaticLikeMethodCache(namespace, methodDef.methodName)
428
445
429
- main ++= extractWithGlobals (methodCache.getOrElseUpdate(methodDef.version, {
446
+ main ++= extractWithGlobalsAndChanged (methodCache.getOrElseUpdate(methodDef.version, {
430
447
classEmitter.genStaticLikeMethod(className, methodDef)(moduleContext, methodCache)
431
448
.map(postTransform(_, 0 ))
432
449
}))
@@ -486,7 +503,7 @@ final class Emitter[E >: Null <: js.Tree](
486
503
}
487
504
488
505
// JS constructor
489
- val ctorWithGlobals = {
506
+ val ctorWithGlobals = extractChanged {
490
507
/* The constructor depends both on the class version, and the version
491
508
* of the inlineable init, if there is one.
492
509
*
@@ -571,13 +588,13 @@ final class Emitter[E >: Null <: js.Tree](
571
588
classCache.getMemberMethodCache(method.methodName)
572
589
573
590
val version = Version .combine(isJSClassVersion, method.version)
574
- methodCache.getOrElseUpdate(version,
591
+ extractChanged( methodCache.getOrElseUpdate(version,
575
592
classEmitter.genMemberMethod(
576
593
className, // invalidated by overall class cache
577
594
isJSClass, // invalidated by isJSClassVersion
578
595
useESClass, // invalidated by isJSClassVersion
579
596
method // invalidated by method.version
580
- )(moduleContext, methodCache).map(postTransform(_, memberIndent)))
597
+ )(moduleContext, methodCache).map(postTransform(_, memberIndent))))
581
598
}
582
599
583
600
// Exported Members
@@ -586,13 +603,13 @@ final class Emitter[E >: Null <: js.Tree](
586
603
} yield {
587
604
val memberCache = classCache.getExportedMemberCache(idx)
588
605
val version = Version .combine(isJSClassVersion, member.version)
589
- memberCache.getOrElseUpdate(version,
606
+ extractChanged( memberCache.getOrElseUpdate(version,
590
607
classEmitter.genExportedMember(
591
608
className, // invalidated by overall class cache
592
609
isJSClass, // invalidated by isJSClassVersion
593
610
useESClass, // invalidated by isJSClassVersion
594
611
member // invalidated by version
595
- )(moduleContext, memberCache).map(postTransform(_, memberIndent)))
612
+ )(moduleContext, memberCache).map(postTransform(_, memberIndent))))
596
613
}
597
614
598
615
val hasClassInitializer : Boolean = {
@@ -602,7 +619,7 @@ final class Emitter[E >: Null <: js.Tree](
602
619
}
603
620
}
604
621
605
- val fullClass = {
622
+ val fullClass = extractChanged {
606
623
val fullClassCache = classCache.getFullClassCache()
607
624
608
625
fullClassCache.getOrElseUpdate(linkedClass.version, ctorWithGlobals,
@@ -714,7 +731,8 @@ final class Emitter[E >: Null <: js.Tree](
714
731
main.result(),
715
732
staticFields,
716
733
staticInitialization,
717
- trackedGlobalRefs
734
+ trackedGlobalRefs,
735
+ changed
718
736
)
719
737
}
720
738
@@ -751,28 +769,33 @@ final class Emitter[E >: Null <: js.Tree](
751
769
}
752
770
753
771
def getOrComputeImports (externalDependencies : Set [String ], internalDependencies : Set [ModuleID ])(
754
- compute : => WithGlobals [List [E ]]): WithGlobals [List [E ]] = {
772
+ compute : => WithGlobals [List [E ]]): ( WithGlobals [List [E ]], Boolean ) = {
755
773
756
774
_cacheUsed = true
757
775
758
776
if (externalDependencies != _lastExternalDependencies || internalDependencies != _lastInternalDependencies) {
759
777
_importsCache = compute
760
778
_lastExternalDependencies = externalDependencies
761
779
_lastInternalDependencies = internalDependencies
780
+ (_importsCache, true )
781
+ } else {
782
+ (_importsCache, false )
762
783
}
763
- _importsCache
784
+
764
785
}
765
786
766
787
def getOrComputeTopLevelExports (topLevelExports : List [LinkedTopLevelExport ])(
767
- compute : => WithGlobals [List [E ]]): WithGlobals [List [E ]] = {
788
+ compute : => WithGlobals [List [E ]]): ( WithGlobals [List [E ]], Boolean ) = {
768
789
769
790
_cacheUsed = true
770
791
771
792
if (! sameTopLevelExports(topLevelExports, _lastTopLevelExports)) {
772
793
_topLevelExportsCache = compute
773
794
_lastTopLevelExports = topLevelExports
795
+ (_topLevelExportsCache, true )
796
+ } else {
797
+ (_topLevelExportsCache, false )
774
798
}
775
- _topLevelExportsCache
776
799
}
777
800
778
801
private def sameTopLevelExports (tles1 : List [LinkedTopLevelExport ], tles2 : List [LinkedTopLevelExport ]): Boolean = {
@@ -803,15 +826,17 @@ final class Emitter[E >: Null <: js.Tree](
803
826
}
804
827
805
828
def getOrComputeInitializers (initializers : List [ModuleInitializer .Initializer ])(
806
- compute : => WithGlobals [List [E ]]): WithGlobals [List [E ]] = {
829
+ compute : => WithGlobals [List [E ]]): ( WithGlobals [List [E ]], Boolean ) = {
807
830
808
831
_cacheUsed = true
809
832
810
833
if (initializers != _lastInitializers) {
811
834
_initializersCache = compute
812
835
_lastInitializers = initializers
836
+ (_initializersCache, true )
837
+ } else {
838
+ (_initializersCache, false )
813
839
}
814
- _initializersCache
815
840
}
816
841
817
842
def cleanAfterRun (): Boolean = {
@@ -856,17 +881,18 @@ final class Emitter[E >: Null <: js.Tree](
856
881
_fullClassCache.foreach(_.startRun())
857
882
}
858
883
859
- def getCache (version : Version ): DesugaredClassCache [List [E ]] = {
884
+ def getCache (version : Version ): (DesugaredClassCache [List [E ]], Boolean ) = {
885
+ _cacheUsed = true
860
886
if (_cache == null || ! _lastVersion.sameVersion(version)) {
861
887
invalidate()
862
888
statsClassesInvalidated += 1
863
889
_lastVersion = version
864
890
_cache = new DesugaredClassCache [List [E ]]
891
+ (_cache, true )
865
892
} else {
866
893
statsClassesReused += 1
894
+ (_cache, false )
867
895
}
868
- _cacheUsed = true
869
- _cache
870
896
}
871
897
872
898
def getMemberMethodCache (
@@ -932,17 +958,18 @@ final class Emitter[E >: Null <: js.Tree](
932
958
def startRun (): Unit = _cacheUsed = false
933
959
934
960
def getOrElseUpdate (version : Version ,
935
- v : => WithGlobals [T ]): WithGlobals [T ] = {
961
+ v : => WithGlobals [T ]): (WithGlobals [T ], Boolean ) = {
962
+ _cacheUsed = true
936
963
if (_tree == null || ! _lastVersion.sameVersion(version)) {
937
964
invalidate()
938
965
statsMethodsInvalidated += 1
939
966
_tree = v
940
967
_lastVersion = version
968
+ (_tree, true )
941
969
} else {
942
970
statsMethodsReused += 1
971
+ (_tree, false )
943
972
}
944
- _cacheUsed = true
945
- _tree
946
973
}
947
974
948
975
def cleanAfterRun (): Boolean = {
@@ -974,7 +1001,7 @@ final class Emitter[E >: Null <: js.Tree](
974
1001
975
1002
def getOrElseUpdate (version : Version , ctor : WithGlobals [List [E ]],
976
1003
memberMethods : List [WithGlobals [List [E ]]], exportedMembers : List [WithGlobals [List [E ]]],
977
- compute : => WithGlobals [List [E ]]): WithGlobals [List [E ]] = {
1004
+ compute : => WithGlobals [List [E ]]): ( WithGlobals [List [E ]], Boolean ) = {
978
1005
979
1006
@ tailrec
980
1007
def allSame [A <: AnyRef ](xs : List [A ], ys : List [A ]): Boolean = {
@@ -984,6 +1011,8 @@ final class Emitter[E >: Null <: js.Tree](
984
1011
}
985
1012
}
986
1013
1014
+ _cacheUsed = true
1015
+
987
1016
if (_tree == null || ! version.sameVersion(_lastVersion) || (_lastCtor ne ctor) ||
988
1017
! allSame(_lastMemberMethods, memberMethods) ||
989
1018
! allSame(_lastExportedMembers, exportedMembers)) {
@@ -993,10 +1022,10 @@ final class Emitter[E >: Null <: js.Tree](
993
1022
_lastCtor = ctor
994
1023
_lastMemberMethods = memberMethods
995
1024
_lastExportedMembers = exportedMembers
1025
+ (_tree, true )
1026
+ } else {
1027
+ (_tree, false )
996
1028
}
997
-
998
- _cacheUsed = true
999
- _tree
1000
1029
}
1001
1030
1002
1031
def cleanAfterRun (): Boolean = {
@@ -1030,7 +1059,7 @@ object Emitter {
1030
1059
/** Result of an emitter run. */
1031
1060
final class Result [E ] private [Emitter ](
1032
1061
val header : String ,
1033
- val body : Map [ModuleID , List [E ]],
1062
+ val body : Map [ModuleID , ( List [E ], Boolean ) ],
1034
1063
val footer : String ,
1035
1064
val topLevelVarDecls : List [String ],
1036
1065
val globalRefs : Set [String ]
@@ -1121,7 +1150,8 @@ object Emitter {
1121
1150
val main : List [E ],
1122
1151
val staticFields : List [E ],
1123
1152
val staticInitialization : List [E ],
1124
- val trackedGlobalRefs : Set [String ]
1153
+ val trackedGlobalRefs : Set [String ],
1154
+ val changed : Boolean
1125
1155
)
1126
1156
1127
1157
private final class OneTimeCache [A >: Null ] {
0 commit comments