@@ -2,6 +2,7 @@ package compiler
22
33import (
44 "bytes"
5+ "encoding/gob"
56 "go/types"
67 "regexp"
78 "sort"
@@ -972,6 +973,49 @@ func Test_IndexedSelectors(t *testing.T) {
972973 )
973974}
974975
976+ func TestArchiveSelectionAfterReadingFromCache (t * testing.T ) {
977+ src := `package main
978+ type Foo interface{ int | string }
979+
980+ type Bar[T Foo] struct{ v T }
981+ func (b Bar[T]) Baz() { println(b.v) }
982+
983+ var ghost = Bar[int]{v: 7} // unused
984+
985+ func main() {
986+ println("do nothing")
987+ }`
988+ srcFiles := []srctesting.Source {{Name : `main.go` , Contents : []byte (src )}}
989+ root := srctesting .ParseSources (t , srcFiles , nil )
990+ rootPath := root .PkgPath
991+
992+ cachedDecls := map [string ]* DeclCache {}
993+ emptyCacheArchives := compileProjectWithCache (t , root , cachedDecls , false )
994+
995+ reloadedCahcedDecls := map [string ]* DeclCache {}
996+ for impPath , dc := range cachedDecls {
997+ buf := bytes.Buffer {}
998+ if err := dc .Write (gob .NewEncoder (& buf ).Encode ); err != nil {
999+ t .Fatalf (`failed to write cache for %q: %v` , impPath , err )
1000+ }
1001+
1002+ dc2 := & DeclCache {}
1003+ if err := dc2 .Read (gob .NewDecoder (bytes .NewReader (buf .Bytes ())).Decode ); err != nil {
1004+ t .Fatalf (`failed to read cache for %q: %v` , impPath , err )
1005+ }
1006+ reloadedCahcedDecls [impPath ] = dc2
1007+ }
1008+
1009+ fullCacheArchives := compileProjectWithCache (t , root , reloadedCahcedDecls , false )
1010+
1011+ emptyCacheJS := renderPackage (t , emptyCacheArchives [rootPath ], false )
1012+ fullCachedJS := renderPackage (t , fullCacheArchives [rootPath ], false )
1013+
1014+ if diff := cmp .Diff (emptyCacheJS , fullCachedJS ); diff != "" {
1015+ t .Errorf ("the reloaded files produce different JS:\n %s" , diff )
1016+ }
1017+ }
1018+
9751019func TestNestedConcreteTypeInGenericFunc (t * testing.T ) {
9761020 // This is a test of a type defined inside a generic function
9771021 // that uses the type parameter of the function as a field type.
@@ -1146,6 +1190,12 @@ func compile(t *testing.T, sourceFiles []srctesting.Source, minify bool) string
11461190// compileProject compiles the given root package and all packages imported by the root.
11471191// This returns the compiled archives of all packages keyed by their import path.
11481192func compileProject (t * testing.T , root * packages.Package , minify bool ) map [string ]* Archive {
1193+ return compileProjectWithCache (t , root , nil , minify )
1194+ }
1195+
1196+ // compileProjectWithCache is similar to compile project excepts allows decls to
1197+ // be read from DeclCaches key'ed with import paths instead of compiling all of them.
1198+ func compileProjectWithCache (t * testing.T , root * packages.Package , cachedDecls map [string ]* DeclCache , minify bool ) map [string ]* Archive {
11491199 t .Helper ()
11501200 pkgMap := map [string ]* packages.Package {}
11511201 packages .Visit ([]* packages.Package {root }, nil , func (pkg * packages.Package ) {
@@ -1182,7 +1232,12 @@ func compileProject(t *testing.T, root *packages.Package, minify bool) map[strin
11821232
11831233 archives := map [string ]* Archive {}
11841234 for _ , srcs := range allSrcs {
1185- a , err := Compile (srcs , nil , tContext , minify )
1235+ declCache := cachedDecls [srcs .ImportPath ]
1236+ if cachedDecls != nil && declCache == nil {
1237+ declCache = & DeclCache {}
1238+ cachedDecls [srcs .ImportPath ] = declCache
1239+ }
1240+ a , err := Compile (srcs , declCache , tContext , minify )
11861241 if err != nil {
11871242 t .Fatal (`failed to compile:` , err )
11881243 }
0 commit comments