loadPackageEx: dedup

This commit is contained in:
xushiwei
2024-06-15 23:27:41 +08:00
parent 1b48b98e22
commit 2b1da5b231
2 changed files with 51 additions and 14 deletions

View File

@@ -19,7 +19,6 @@ package cl_test
import (
"os"
"path/filepath"
"runtime"
"testing"
"github.com/goplus/llgo/cl"
@@ -71,13 +70,11 @@ func TestPython(t *testing.T) {
cltest.Pkg(t, ssa.PkgPython, "../py/llgo_autogen.ll")
}
func TestGoLibMath(t *testing.T) {
if runtime.GOOS == "darwin" { // TODO(xsw): support linux/windows
root, _ := filepath.Abs("..")
os.Setenv("LLGOROOT", root)
conf := build.NewDefaultConf(build.ModeInstall)
build.Do([]string{"math"}, conf)
}
func TestGoPkgMath(t *testing.T) {
root, _ := filepath.Abs("..")
os.Setenv("LLGOROOT", root)
conf := build.NewDefaultConf(build.ModeInstall)
build.Do([]string{"math"}, conf)
}
func TestVar(t *testing.T) {

View File

@@ -99,13 +99,33 @@ type loader struct {
requestedMode LoadMode
}
type Deduper struct {
type cachedPackage struct {
Types *types.Package
TypesInfo *types.Info
Syntax []*ast.File
}
func NewDeduper() *Deduper {
type aDeduper struct {
cache sync.Map
}
type Deduper = *aDeduper
func NewDeduper() Deduper {
return &aDeduper{}
}
func (p Deduper) check(pkgPath string) *cachedPackage {
if v, ok := p.cache.Load(pkgPath); ok {
return v.(*cachedPackage)
}
return nil
}
func (p Deduper) set(pkgPath string, cp *cachedPackage) {
p.cache.Store(pkgPath, cp)
}
//go:linkname defaultDriver golang.org/x/tools/go/packages.defaultDriver
func defaultDriver(cfg *Config, patterns ...string) (*packages.DriverResponse, bool, error)
@@ -130,7 +150,7 @@ type importerFunc func(path string) (*types.Package, error)
func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
func loadPackageEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
func loadPackageEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
if lpkg.PkgPath == "unsafe" {
// Fill in the blanks to avoid surprises.
lpkg.Types = types.Unsafe
@@ -141,6 +161,26 @@ func loadPackageEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
return
}
if dedup != nil {
if cp := dedup.check(lpkg.PkgPath); cp != nil {
lpkg.Types = cp.Types
lpkg.Fset = ld.Fset
lpkg.TypesInfo = cp.TypesInfo
lpkg.Syntax = cp.Syntax
lpkg.TypesSizes = ld.sizes
return
}
defer func() {
if !lpkg.IllTyped && lpkg.needtypes && lpkg.needsrc {
dedup.set(lpkg.PkgPath, &cachedPackage{
Types: lpkg.Types,
TypesInfo: lpkg.TypesInfo,
Syntax: lpkg.Syntax,
})
}
}()
}
// Call NewPackage directly with explicit name.
// This avoids skew between golist and go/types when the files'
// package declarations are inconsistent.
@@ -404,7 +444,7 @@ func loadPackageEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
lpkg.IllTyped = illTyped
}
func loadRecursiveEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
func loadRecursiveEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
lpkg.loadOnce.Do(func() {
// Load the direct dependencies, in parallel.
var wg sync.WaitGroup
@@ -421,7 +461,7 @@ func loadRecursiveEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
})
}
func refineEx(dedup *Deduper, ld *loader, response *packages.DriverResponse) ([]*Package, error) {
func refineEx(dedup Deduper, ld *loader, response *packages.DriverResponse) ([]*Package, error) {
roots := response.Roots
rootMap := make(map[string]int, len(roots))
for i, root := range roots {
@@ -641,7 +681,7 @@ func refineEx(dedup *Deduper, ld *loader, response *packages.DriverResponse) ([]
// return an error. Clients may need to handle such errors before
// proceeding with further analysis. The PrintErrors function is
// provided for convenient display of all errors.
func LoadEx(dedup *Deduper, sizes func(types.Sizes) types.Sizes, cfg *Config, patterns ...string) ([]*Package, error) {
func LoadEx(dedup Deduper, sizes func(types.Sizes) types.Sizes, cfg *Config, patterns ...string) ([]*Package, error) {
ld := newLoader(cfg)
response, external, err := defaultDriver(&ld.Config, patterns...)
if err != nil {