@@ -632,8 +632,15 @@ type PackageData struct {
632632 * build.Package
633633 JSFiles []incjs.File
634634 // IsTest is true if the package is being built for running tests.
635- IsTest bool
636- SrcModTime time.Time
635+ IsTest bool
636+ // NoCache indicates that the package should not be cached because
637+ // it is being built for running tests or depends on a package being
638+ // run for tests. Should be true if IsTest is true.
639+ NoCache bool
640+ // StaleCache is true if the cached of the package is stale, i.e.,
641+ // needs to be rebuilt since sources have been updated, dependencies have
642+ // stale caches, or the gopherjs executable has been updated.
643+ StaleCache bool
637644 UpToDate bool
638645 // If true, the package does not have a corresponding physical directory on disk.
639646 IsVirtual bool
@@ -702,6 +709,7 @@ func (p *PackageData) TestPackage() *PackageData {
702709 EmbedPatternPos : joinEmbedPatternPos (p .EmbedPatternPos , p .TestEmbedPatternPos ),
703710 },
704711 IsTest : true ,
712+ NoCache : true ,
705713 JSFiles : p .JSFiles ,
706714 bctx : p .bctx ,
707715 }
@@ -718,8 +726,9 @@ func (p *PackageData) XTestPackage() *PackageData {
718726 Imports : p .XTestImports ,
719727 EmbedPatternPos : p .XTestEmbedPatternPos ,
720728 },
721- IsTest : true ,
722- bctx : p .bctx ,
729+ IsTest : true ,
730+ NoCache : true ,
731+ bctx : p .bctx ,
723732 }
724733}
725734
@@ -897,8 +906,8 @@ func (s *Session) BuildFiles(filenames []string, pkgObj string, cwd string) erro
897906 Package : p ,
898907 // This ephemeral package doesn't have a unique import path to be used as a
899908 // build cache key, so we never cache it.
900- SrcModTime : time . Now (). Add ( time . Hour ) ,
901- bctx : & goCtx (s .xctx .Env ()).bctx ,
909+ NoCache : true ,
910+ bctx : & goCtx (s .xctx .Env ()).bctx ,
902911 }
903912
904913 for _ , file := range filenames {
@@ -1063,10 +1072,6 @@ func (s *Session) LoadPackages(pkg *PackageData) (*sources.Sources, error) {
10631072 return srcs , nil // already loaded
10641073 }
10651074
1066- if exeModTime := getExeModTime (); exeModTime .After (pkg .SrcModTime ) {
1067- pkg .SrcModTime = exeModTime
1068- }
1069-
10701075 for _ , importedPkgPath := range pkg .Imports {
10711076 if importedPkgPath == "unsafe" {
10721077 continue
@@ -1076,13 +1081,12 @@ func (s *Session) LoadPackages(pkg *PackageData) (*sources.Sources, error) {
10761081 return nil , err
10771082 }
10781083
1079- if impModTime := importedPkg .SrcModTime ; impModTime .After (pkg .SrcModTime ) {
1080- pkg .SrcModTime = impModTime
1084+ if importedPkg .NoCache {
1085+ pkg .NoCache = true
1086+ }
1087+ if importedPkg .StaleCache {
1088+ pkg .StaleCache = true
10811089 }
1082- }
1083-
1084- if fileModTime := pkg .FileModTime (); fileModTime .After (pkg .SrcModTime ) {
1085- pkg .SrcModTime = fileModTime
10861090 }
10871091
10881092 // If the package was not found in the cache, build the package
@@ -1112,9 +1116,30 @@ func (s *Session) LoadPackages(pkg *PackageData) (*sources.Sources, error) {
11121116 s .sources [pkg .ImportPath ] = srcs
11131117
11141118 // Try to load the cached decls from the build cache.
1115- if s .buildCache != nil {
1119+ if s .buildCache != nil && ! pkg . NoCache {
11161120 declCache := & compiler.DeclCache {}
1117- s .buildCache .Load (declCache , pkg .ImportPath , pkg .SrcModTime )
1121+
1122+ // If none of the dependencies were stale, then try to populate the cache.
1123+ // Calculate the most recent mod time of the package's sources
1124+ // and the gopherjs executable.
1125+ // If the cache is older than that or fails to load, then the cache is stale.
1126+ if ! pkg .StaleCache {
1127+ var srcModTime time.Time
1128+ if exeModTime := getExeModTime (); exeModTime .After (srcModTime ) {
1129+ srcModTime = exeModTime
1130+ }
1131+ if fileModTime := pkg .FileModTime (); fileModTime .After (srcModTime ) {
1132+ srcModTime = fileModTime
1133+ }
1134+
1135+ if ! s .buildCache .Load (declCache , pkg .ImportPath , srcModTime ) {
1136+ pkg .StaleCache = true
1137+ // set a new empty declCache incase the Load left it in a
1138+ // partially filled state.
1139+ declCache = & compiler.DeclCache {}
1140+ }
1141+ }
1142+
11181143 s .cachedDecls [pkg .ImportPath ] = declCache
11191144 }
11201145
@@ -1177,10 +1202,10 @@ func (s *Session) CompilePackage(srcs *sources.Sources, tContext *types.Context)
11771202
11781203 // Store the built package sources in the cache for future use.
11791204 // The sources should contain all cachable declarations at this point.
1180- // Skip storing cache if the sources haven't changed since read from cache.
1205+ // Skip storing cache if the sources haven't changed since read from cache
1206+ // or the cache is disabled for this package (i.e. `dc` is nil).
11811207 if s .buildCache != nil {
1182- dc := s .cachedDecls [srcs .ImportPath ]
1183- if dc != nil && dc .Changed () {
1208+ if dc := s .cachedDecls [srcs .ImportPath ]; dc != nil && dc .Changed () {
11841209 s .buildCache .Store (dc , srcs .ImportPath , time .Now ())
11851210 }
11861211 }
0 commit comments