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

View File

@@ -99,13 +99,33 @@ type loader struct {
requestedMode LoadMode 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 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 //go:linkname defaultDriver golang.org/x/tools/go/packages.defaultDriver
func defaultDriver(cfg *Config, patterns ...string) (*packages.DriverResponse, bool, error) 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 (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" { if lpkg.PkgPath == "unsafe" {
// Fill in the blanks to avoid surprises. // Fill in the blanks to avoid surprises.
lpkg.Types = types.Unsafe lpkg.Types = types.Unsafe
@@ -141,6 +161,26 @@ func loadPackageEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
return 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. // Call NewPackage directly with explicit name.
// This avoids skew between golist and go/types when the files' // This avoids skew between golist and go/types when the files'
// package declarations are inconsistent. // package declarations are inconsistent.
@@ -404,7 +444,7 @@ func loadPackageEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
lpkg.IllTyped = illTyped lpkg.IllTyped = illTyped
} }
func loadRecursiveEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) { func loadRecursiveEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
lpkg.loadOnce.Do(func() { lpkg.loadOnce.Do(func() {
// Load the direct dependencies, in parallel. // Load the direct dependencies, in parallel.
var wg sync.WaitGroup 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 roots := response.Roots
rootMap := make(map[string]int, len(roots)) rootMap := make(map[string]int, len(roots))
for i, root := range 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 // return an error. Clients may need to handle such errors before
// proceeding with further analysis. The PrintErrors function is // proceeding with further analysis. The PrintErrors function is
// provided for convenient display of all errors. // 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) ld := newLoader(cfg)
response, external, err := defaultDriver(&ld.Config, patterns...) response, external, err := defaultDriver(&ld.Config, patterns...)
if err != nil { if err != nil {