Skip to content

Commit

Permalink
fix: the go+ code will not be updated after the dependent package exi…
Browse files Browse the repository at this point in the history
…sts in autogen
  • Loading branch information
LiusCraft committed Mar 19, 2024
1 parent cf873f6 commit dbec0f6
Showing 1 changed file with 14 additions and 66 deletions.
80 changes: 14 additions & 66 deletions packages/imp.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,19 @@ import (
"go/types"
"os"
"os/exec"
"strings"
"sync"

"golang.org/x/tools/go/gcexportdata"
)

// pkgPath Caches
var (
dirCache = map[string]bool{}
dirCacheMutex = sync.RWMutex{}
packageCacheMap = map[string]string{}
packageCacheMutex = sync.RWMutex{}
waitCache = sync.WaitGroup{}
)

// ----------------------------------------------------------------------------

type Importer struct {
loaded map[string]*types.Package
fset *token.FileSet
dir string
m sync.RWMutex
loaded map[string]*types.Package
fset *token.FileSet
dir string
m sync.RWMutex
pkgCache *Cache
}

// NewImporter creates an Importer object that meets types.Importer interface.
Expand All @@ -50,15 +41,12 @@ func NewImporter(fset *token.FileSet, workDir ...string) *Importer {
if len(workDir) > 0 {
dir = workDir[0]
}
if len(packageCacheMap) == 0 {
initGoListCache(dir)
}
if fset == nil {
fset = token.NewFileSet()
}
loaded := make(map[string]*types.Package)
loaded["unsafe"] = types.Unsafe
return &Importer{loaded: loaded, fset: fset, dir: dir}
return &Importer{loaded: loaded, fset: fset, dir: dir, pkgCache: NewGoListCache(dir)}
}

func (p *Importer) Import(pkgPath string) (pkg *types.Package, err error) {
Expand All @@ -81,6 +69,10 @@ func (p *Importer) ImportFrom(pkgPath, dir string, mode types.ImportMode) (*type
return ret, nil
}
p.m.RUnlock()
cacheInfo, ok := p.pkgCache.GetPkgCache(pkgPath)
if ok {
return p.loadByExport(cacheInfo.PkgExport, pkgPath)
}
expfile, err := FindExport(dir, pkgPath)
if err != nil {
return nil, err
Expand All @@ -104,16 +96,15 @@ func (p *Importer) loadByExport(expfile string, pkgPath string) (ret *types.Pack
return
}

func (p *Importer) GetPkgCache() *Cache {
return p.pkgCache
}

// ----------------------------------------------------------------------------

// FindExport lookups export file (.a) of a package by its pkgPath.
// It returns empty if pkgPath not found.
func FindExport(dir, pkgPath string) (expfile string, err error) {
waitCache.Wait()
expfile = packageCacheMap[pkgPath]
if len(expfile) > 0 {
return expfile, nil
}
data, err := golistExport(dir, pkgPath)
if err != nil {
return
Expand All @@ -122,49 +113,6 @@ func FindExport(dir, pkgPath string) (expfile string, err error) {
return
}

// https://github.com/goplus/gop/issues/1710
// Not fully optimized
// Retrieve all imports in the specified directory and cache them
func goListExportCache(dir string, pkgs ...string) {
dirCacheMutex.Lock()
if dirCache[dir] {
dirCacheMutex.Unlock()
return
}
dirCache[dir] = true
dirCacheMutex.Unlock()
var stdout, stderr bytes.Buffer
commandStr := []string{"list", "-f", "{{.ImportPath}},{{.Export}}", "-export", "-e"}
commandStr = append(commandStr, pkgs...)
commandStr = append(commandStr, "all")
cmd := exec.Command("go", commandStr...)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
cmd.Dir = dir
err := cmd.Run()
if err == nil {
ret := stdout.String()
for _, v := range strings.Split(ret, "\n") {
s := strings.Split(v, ",")
if len(s) != 2 {
continue
}
packageCacheMutex.Lock()
packageCacheMap[s[0]] = s[1]
packageCacheMutex.Unlock()
}
}
}
func GoListExportCacheSync(dir string, pkgs ...string) {
waitCache.Add(1)
go func() {
defer waitCache.Done()
goListExportCache(dir, pkgs...)
}()
}
func initGoListCache(dir string) {
goListExportCache(dir)
}
func golistExport(dir, pkgPath string) (ret []byte, err error) {
var stdout, stderr bytes.Buffer
cmd := exec.Command("go", "list", "-f={{.Export}}", "-export", pkgPath)
Expand Down

0 comments on commit dbec0f6

Please sign in to comment.