Skip to content

Commit

Permalink
context: export SourcePackage
Browse files Browse the repository at this point in the history
  • Loading branch information
visualfc committed Aug 28, 2024
1 parent 40e3832 commit 47fed62
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 32 deletions.
46 changes: 27 additions & 19 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ type Context struct {
Lookup func(root, path string) (dir string, found bool) // lookup external import
evalCallFn func(interp *Interp, call *ssa.Call, res ...interface{}) // internal eval func for repl
debugFunc func(*DebugInfo) // debug func
pkgs map[string]*sourcePackage // imports
pkgs map[string]*SourcePackage // imports
override map[string]reflect.Value // override function
evalInit map[string]bool // eval init check
nestedMap map[*types.Named]int // nested named index
Expand Down Expand Up @@ -107,22 +107,26 @@ func (ctx *Context) lookupPath(path string) (dir string, found bool) {
return
}

type sourcePackage struct {
type SourcePackage struct {
Context *Context
Package *types.Package
Info *types.Info
Importer types.Importer
Files []*ast.File
Links []*load.LinkSym
Dir string
Register bool // register package
}

func (sp *sourcePackage) Load() (err error) {
func (sp *SourcePackage) Load() (err error) {
if sp.Info == nil {

Check warning on line 122 in context.go

View check run for this annotation

qiniu-x / golangci-lint

context.go#L122

`if sp.Info == nil` has complex nested blocks (complexity: 14) (nestif)
sp.Info = newTypesInfo()
if sp.Importer == nil {
sp.Importer = NewImporter(sp.Context)
}
conf := &types.Config{
Sizes: sp.Context.sizes,
Importer: NewImporter(sp.Context),
Importer: sp.Importer,
}
if sp.Context.evalMode {
conf.DisableUnusedImportCheck = true
Expand Down Expand Up @@ -161,7 +165,7 @@ func NewContext(mode Mode) *Context {
Mode: mode,
BuilderMode: 0, //ssa.SanityCheckFunctions,
BuildContext: build.Default,
pkgs: make(map[string]*sourcePackage),
pkgs: make(map[string]*SourcePackage),
override: make(map[string]reflect.Value),
nestedMap: make(map[*types.Named]int),
callForPool: 64,
Expand Down Expand Up @@ -245,7 +249,7 @@ func (ctx *Context) LoadDir(dir string, test bool) (pkg *ssa.Package, err error)
return nil, err
}
bp.ImportPath = importPath
var sp *sourcePackage
var sp *SourcePackage
if test {
sp, err = ctx.loadTestPackage(bp, importPath, dir)
} else {
Expand Down Expand Up @@ -293,7 +297,11 @@ func (ctx *Context) AddImport(path string, dir string) (err error) {
return
}

func (ctx *Context) addImportFile(path string, filename string, src interface{}) (*sourcePackage, error) {
func (ctx *Context) SourcePackage(path string) *SourcePackage {
return ctx.pkgs[path]
}

func (ctx *Context) addImportFile(path string, filename string, src interface{}) (*SourcePackage, error) {
tp, err := ctx.loadPackageFile(path, filename, src)
if err != nil {
return nil, err
Expand All @@ -302,7 +310,7 @@ func (ctx *Context) addImportFile(path string, filename string, src interface{})
return tp, nil
}

func (ctx *Context) addImport(path string, dir string) (*sourcePackage, error) {
func (ctx *Context) addImport(path string, dir string) (*SourcePackage, error) {
bp, err := ctx.BuildContext.ImportDir(dir, 0)
if err != nil {
return nil, err
Expand All @@ -316,13 +324,13 @@ func (ctx *Context) addImport(path string, dir string) (*sourcePackage, error) {
return tp, nil
}

func (ctx *Context) loadPackageFile(path string, filename string, src interface{}) (*sourcePackage, error) {
func (ctx *Context) loadPackageFile(path string, filename string, src interface{}) (*SourcePackage, error) {
file, err := ctx.ParseFile(filename, src)
if err != nil {
return nil, err
}
pkg := types.NewPackage(path, file.Name.Name)
tp := &sourcePackage{
tp := &SourcePackage{
Context: ctx,
Package: pkg,
Files: []*ast.File{file},
Expand All @@ -331,7 +339,7 @@ func (ctx *Context) loadPackageFile(path string, filename string, src interface{
return tp, nil
}

func (ctx *Context) loadPackage(bp *build.Package, path string, dir string) (*sourcePackage, error) {
func (ctx *Context) loadPackage(bp *build.Package, path string, dir string) (*SourcePackage, error) {
files, err := ctx.parseGoFiles(dir, append(bp.GoFiles, bp.CgoFiles...))
if err != nil {
return nil, err
Expand All @@ -346,7 +354,7 @@ func (ctx *Context) loadPackage(bp *build.Package, path string, dir string) (*so
if bp.Name == "main" {

Check warning on line 354 in context.go

View check run for this annotation

qiniu-x / golangci-lint

context.go#L354

string `main` has 5 occurrences, make it a constant (goconst)
path = "main"
}
tp := &sourcePackage{
tp := &SourcePackage{
Package: types.NewPackage(path, bp.Name),
Files: files,
Dir: dir,
Expand All @@ -356,7 +364,7 @@ func (ctx *Context) loadPackage(bp *build.Package, path string, dir string) (*so
return tp, nil
}

func (ctx *Context) loadTestPackage(bp *build.Package, path string, dir string) (*sourcePackage, error) {
func (ctx *Context) loadTestPackage(bp *build.Package, path string, dir string) (*SourcePackage, error) {
if len(bp.TestGoFiles) == 0 && len(bp.XTestGoFiles) == 0 {
return nil, ErrNoTestFiles
}
Expand All @@ -371,7 +379,7 @@ func (ctx *Context) loadTestPackage(bp *build.Package, path string, dir string)
if embed != nil {
files = append(files, embed)
}
tp := &sourcePackage{
tp := &SourcePackage{
Package: types.NewPackage(path, bp.Name),
Files: files,
Dir: dir,
Expand All @@ -390,7 +398,7 @@ func (ctx *Context) loadTestPackage(bp *build.Package, path string, dir string)
if embed != nil {
files = append(files, embed)
}
tp := &sourcePackage{
tp := &SourcePackage{
Package: types.NewPackage(path+"_test", bp.Name+"_test"),
Files: files,
Dir: dir,
Expand All @@ -406,7 +414,7 @@ func (ctx *Context) loadTestPackage(bp *build.Package, path string, dir string)
if err != nil {
return nil, err
}
return &sourcePackage{
return &SourcePackage{
Package: types.NewPackage(path+".test", "main"),
Files: []*ast.File{f},
Dir: dir,
Expand Down Expand Up @@ -485,7 +493,7 @@ func (ctx *Context) LoadAstFile(path string, file *ast.File) (*ssa.Package, erro
if embed != nil {
files = append(files, embed)
}
sp := &sourcePackage{
sp := &SourcePackage{
Context: ctx,
Package: types.NewPackage(path, file.Name.Name),
Files: files,
Expand All @@ -507,7 +515,7 @@ func (ctx *Context) LoadAstPackage(path string, apkg *ast.Package) (*ssa.Package
files = append([]*ast.File{f}, files...)
}
}
sp := &sourcePackage{
sp := &SourcePackage{
Context: ctx,
Package: types.NewPackage(path, apkg.Name),
Files: files,
Expand Down Expand Up @@ -668,7 +676,7 @@ func (ctx *Context) RunTest(dir string, args []string) error {
return ctx.TestPkg(pkg, dir, args)
}

func (ctx *Context) buildPackage(sp *sourcePackage) (pkg *ssa.Package, err error) {
func (ctx *Context) buildPackage(sp *SourcePackage) (pkg *ssa.Package, err error) {

Check warning on line 679 in context.go

View check run for this annotation

qiniu-x / golangci-lint

context.go#L679

cognitive complexity 50 of func `(*Context).buildPackage` is high (> 30) (gocognit)
if ctx.Mode&DisableRecover == 0 {
defer func() {
if e := recover(); e != nil {
Expand Down
58 changes: 46 additions & 12 deletions gopbuild/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,17 @@ func NewContext(ctx *igop.Context) *Context {
ctx = igop.NewContext(0)
}
ctx.Mode |= igop.CheckGopOverloadFunc
return &Context{Context: ctx, Importer: igop.NewImporter(ctx), FileSet: token.NewFileSet(),
c := &Context{Context: ctx, Importer: igop.NewImporter(ctx), FileSet: token.NewFileSet(),
Loader: igop.NewTypesLoader(ctx, 0), pkgs: make(map[string]*types.Package)}
return c
}

func RegisterPackagePatch(ctx *igop.Context, path string, src string) error {
return ctx.AddImportFile(path+"@patch", "src.go", src)
func RegisterPackagePatch(ctx *igop.Context, path string, src interface{}) error {
err := ctx.AddImportFile(path+"@patch", "src.go", src)
if err != nil {
return err
}
return ctx.AddImportFile(path+"@patch.gop", "src.go", src)
}

func isGopPackage(path string) bool {
Expand All @@ -204,27 +209,56 @@ func isGopPackage(path string) bool {
return false
}

func (c *Context) importPath(path string) (*types.Package, error) {
func (c *Context) importPath(path string) (gop bool, pkg *types.Package, err error) {
if isGopPackage(path) {
return c.Loader.Import(path)
gop = true
pkg, err = c.Loader.Import(path)
} else {
pkg, err = c.Importer.Import(path)
}
return c.Importer.Import(path)
return
}

func (c *Context) Import(path string) (*types.Package, error) {
if pkg, ok := c.pkgs[path]; ok {
return pkg, nil
}
pkg, err := c.importPath(path)
gop, pkg, err := c.importPath(path)
if err != nil {
return nil, err
return pkg, err
}
if patch, err := c.Context.Loader.Import(path + "@patch"); err == nil {
for _, name := range patch.Scope().Names() {
pkg.Scope().Insert(patch.Scope().Lookup(name))
c.pkgs[path] = pkg
if gop {

Check warning on line 231 in gopbuild/build.go

View check run for this annotation

qiniu-x / golangci-lint

gopbuild/build.go#L231

`if gop` has complex nested blocks (complexity: 5) (nestif)
if sp := c.Context.SourcePackage(path + "@patch.gop"); sp != nil {
sp.Importer = c
err := sp.Load()
if err != nil {
return nil, err
}
patch := types.NewPackage(path+"@patch", pkg.Name())
for _, name := range sp.Package.Scope().Names() {
obj := sp.Package.Scope().Lookup(name)
switch obj.(type) {

Check warning on line 241 in gopbuild/build.go

View check run for this annotation

qiniu-x / golangci-lint

gopbuild/build.go#L241

typeSwitchVar: 1 case can benefit from type switch with assignment (gocritic)
case *types.Func:
obj = types.NewFunc(obj.Pos(), patch, obj.Name(), obj.Type().(*types.Signature))
case *types.TypeName:
named := obj.Type().(*types.Named)
var methods []*types.Func
if n := named.NumMethods(); n > 0 {
methods = make([]*types.Func, n)
for i := 0; i < n; i++ {
methods[i] = named.Method(i)
}
}
obj = types.NewTypeName(obj.Pos(), patch, obj.Name(), nil)
types.NewNamed(obj.(*types.TypeName), named.Underlying(), methods)
default:
continue
}
pkg.Scope().Insert(obj)
}
}
}
c.pkgs[path] = pkg
return pkg, nil
}

Expand Down
21 changes: 20 additions & 1 deletion gopbuild/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,15 @@ func TestPackagePatch(t *testing.T) {
RegisterPackagePatch(ctx, "github.com/qiniu/x/gsh", `package gsh
import "github.com/qiniu/x/gsh"
type Point struct {
X int
Y int
}
func (p *Point) Info() {
println(p.X, p.Y)
}
func Gopt_App_Gopx_GetWidget[T any](app any, name string) {
var _ gsh.App
println(app, name)
Expand All @@ -441,6 +450,7 @@ func Gopt_App_Gopx_GetWidget[T any](app any, name string) {
expected := `package main
import (
"fmt"
"github.com/qiniu/x/gsh"
gsh1 "github.com/qiniu/x/gsh@patch"
)
Expand All @@ -452,6 +462,12 @@ type App struct {
func (this *App) MainEntry() {
//line main.gsh:2:1
gsh1.Gopt_App_Gopx_GetWidget[int](this, "info")
//line main.gsh:3:1
pt := &gsh1.Point{100, 200}
//line main.gsh:4:1
pt.Info()
//line main.gsh:5:1
fmt.Println(pt.X)
}
func (this *App) Main() {
gsh.Gopt_App_Main(this)
Expand All @@ -462,11 +478,14 @@ func main() {
`
data, err := BuildFile(ctx, "main.gsh", `
getWidget(int,"info")
pt := &Point{100,200}
pt.Info()
println(pt.X)
`)
if err != nil {
t.Fatal(err)
}
if string(data) != expected {
t.Fatal("build error", string(data))
t.Fatal("build error:\n", string(data))
}
}

0 comments on commit 47fed62

Please sign in to comment.