Skip to content

Commit

Permalink
Merge pull request #363 from goplus/main
Browse files Browse the repository at this point in the history
v1.14.2
  • Loading branch information
xushiwei authored Feb 1, 2024
2 parents 61312d9 + 664927e commit 5992cce
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ jobs:
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...

- name: Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
6 changes: 4 additions & 2 deletions ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ retry:
if recv := denoteRecv(mth); recv != nil {
backup := backupArgs(args)
for i := 0; i < 2; i++ {
tfn := toObject(pkg, ft.Func, nil)
tfn := toObject(pkg, ft.Func, fn.Src)
targs := make([]*internal.Elem, len(args)+1)
targ0 := *recv
if i == 1 {
Expand All @@ -668,7 +668,9 @@ retry:
}
if ret, err = matchFuncCall(pkg, tfn, targs, flags); err == nil {
if pkg.cb.rec != nil {
pkg.cb.rec.Call(fn.Src, ft.Func)
if _, ok := CheckFuncEx(ft.Func.Type().(*types.Signature)); !ok {
pkg.cb.rec.Call(fn.Src, ft.Func)
}
}
return
}
Expand Down
29 changes: 28 additions & 1 deletion builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,33 @@ func TestMethodAutoProperty(t *testing.T) {
}
}

func TestCheckSigFuncExObjects(t *testing.T) {
pkg := types.NewPackage("", "")
objs := []types.Object{
types.NewFunc(0, pkg, "foo", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
types.NewFunc(0, pkg, "bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)),
}
named := types.NewNamed(types.NewTypeName(0, pkg, "named", nil), types.NewSignatureType(nil, nil, nil, nil, nil, false), nil)
fn := types.NewFunc(0, pkg, "fn", sigFuncEx(nil, nil, &TyOverloadFunc{objs}))
tests := []struct {
name string
sig *types.Signature
count int
}{
{"TyOverloadFunc", sigFuncEx(nil, nil, &TyOverloadFunc{objs}), 2},
{"TyOverloadMethod", sigFuncEx(nil, nil, &TyOverloadMethod{objs}), 2},
{"TyTemplateRecvMethod", sigFuncEx(nil, nil, &TyTemplateRecvMethod{types.NewParam(0, nil, "", tyInt)}), 1},
{"TyTemplateRecvMethod", sigFuncEx(nil, nil, &TyTemplateRecvMethod{fn}), 2},
{"TyOverloadNamed", sigFuncEx(nil, nil, &TyOverloadNamed{Types: []*types.Named{named}}), 1},
}
for n, test := range tests {
typ, objs := CheckSigFuncExObjects(test.sig)
if typ == nil || len(objs) != test.count {
t.Fatalf("CheckSigFuncExObjects error: %v %v", n, test.name)
}
}
}

func TestHasAutoProperty(t *testing.T) {
if HasAutoProperty(nil) {
t.Fatal("nil has autoprop?")
Expand Down Expand Up @@ -692,7 +719,7 @@ func TestTypeEx(t *testing.T) {
if fex, ok := typ.(iSubstType); ok {
fex.Obj()
}
if fex, ok := typ.(iOverloadType); ok {
if fex, ok := typ.(OverloadType); ok {
fex.Len()
func() {
defer func() {
Expand Down
4 changes: 2 additions & 2 deletions codebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ func (p *CodeBuilder) method(
p.rec.Member(src, found)
}
if autoprop {
p.Call(0)
p.CallWith(0, 0, src)
return MemberAutoProperty
}
return MemberMethod
Expand Down Expand Up @@ -1746,7 +1746,7 @@ func (p *CodeBuilder) btiMethod(
p.rec.Member(src, method.fn)
}
if autoprop {
p.Call(0)
p.CallWith(0, 0, src)
return MemberAutoProperty
}
return MemberMethod
Expand Down
46 changes: 43 additions & 3 deletions func_ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,53 @@ func IsFunc(t types.Type) bool {

// CheckFuncEx returns if specified function is a FuncEx or not.
func CheckFuncEx(sig *types.Signature) (ext TyFuncEx, ok bool) {
if typ, is := checkSigFuncEx(sig); is {
if typ, is := CheckSigFuncEx(sig); is {
ext, ok = typ.(TyFuncEx)
}
return
}

// CheckSigFuncExObjects retruns hide recv type and objects from func($overloadArgs ...interface{$overloadMethod()})
// The return type can be OverloadType (*TyOverloadFunc, *TyOverloadMethod, *TyOverloadNamed) or
// *TyTemplateRecvMethod.
func CheckSigFuncExObjects(sig *types.Signature) (typ types.Type, objs []types.Object) {
if ext, ok := CheckSigFuncEx(sig); ok {
switch t := ext.(type) {
case *TyOverloadFunc:
typ, objs = t, t.Funcs
case *TyOverloadMethod:
typ, objs = t, t.Methods
case *TyTemplateRecvMethod:
typ = t
if tsig, ok := t.Func.Type().(*types.Signature); ok {
if ex, ok := CheckSigFuncEx(tsig); ok {
if t, ok := ex.(*TyOverloadFunc); ok {
objs = t.Funcs
break
}
}
}
objs = []types.Object{t.Func}
case *TyOverloadNamed:
typ = t
objs = make([]types.Object, len(t.Types))
for i, typ := range t.Types {
objs[i] = typ.Obj()
}
}
}
return
}

const (
overloadArgs = "__gop_overload_args__"
overloadMethod = "_"
)

// checkSigFuncEx retrun hide recv type from func($overloadArgs ...interface{$overloadMethod()})
func checkSigFuncEx(sig *types.Signature) (types.Type, bool) {
// CheckSigFuncEx retrun hide recv type from func($overloadArgs ...interface{$overloadMethod()})
// The return type can be OverloadType (*TyOverloadFunc, *TyOverloadMethod, *TyOverloadNamed) or
// *TyTemplateRecvMethod.
func CheckSigFuncEx(sig *types.Signature) (types.Type, bool) {
if sig.Params().Len() == 1 {
if param := sig.Params().At(0); param.Name() == overloadArgs {
if typ, ok := param.Type().(*types.Interface); ok && typ.NumMethods() == 1 {
Expand Down Expand Up @@ -100,10 +134,13 @@ func (p *TyOverloadFunc) Underlying() types.Type { return p }
func (p *TyOverloadFunc) String() string { return "TyOverloadFunc" }
func (p *TyOverloadFunc) funcEx() {}

// NewOverloadFunc creates an overload func.
func NewOverloadFunc(pos token.Pos, pkg *types.Package, name string, funcs ...types.Object) *types.Func {
return newFuncEx(pos, pkg, nil, name, &TyOverloadFunc{funcs})
}

// CheckOverloadFunc checks a func is overload func or not.
// Deprecated: please use CheckFuncEx.
func CheckOverloadFunc(sig *types.Signature) (funcs []types.Object, ok bool) {
if t, ok := CheckFuncEx(sig); ok {
if oft, ok := t.(*TyOverloadFunc); ok {
Expand All @@ -127,10 +164,13 @@ func (p *TyOverloadMethod) Underlying() types.Type { return p }
func (p *TyOverloadMethod) String() string { return "TyOverloadMethod" }
func (p *TyOverloadMethod) funcEx() {}

// NewOverloadMethod creates an overload method.
func NewOverloadMethod(typ *types.Named, pos token.Pos, pkg *types.Package, name string, methods ...types.Object) *types.Func {
return newMethodEx(typ, pos, pkg, name, &TyOverloadMethod{methods})
}

// CheckOverloadMethod checks a func is overload method or not.
// Deprecated: please use CheckFuncEx.
func CheckOverloadMethod(sig *types.Signature) (methods []types.Object, ok bool) {
if t, ok := CheckFuncEx(sig); ok {
if oft, ok := t.(*TyOverloadMethod); ok {
Expand Down
5 changes: 3 additions & 2 deletions import.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ func isOverload(name string) bool {
return n > 3 && name[n-3:n-1] == "__"
}

func initThisGopPkg(pkg *types.Package) {
// InitThisGopPkg initializes a Go+ package.
func InitThisGopPkg(pkg *types.Package) {
scope := pkg.Scope()
if scope.Lookup(gopPackage) == nil { // not is a Go+ package
return
Expand Down Expand Up @@ -378,7 +379,7 @@ func (p *Context) initGopPkg(importer types.Importer, pkgImp *types.Package) {
if !pkgImp.Complete() {
importer.Import(pkgPath)
}
initThisGopPkg(pkgImp)
InitThisGopPkg(pkgImp)
p.chkGopImports[pkgPath] = true
for _, imp := range pkgImp.Imports() {
p.initGopPkg(importer, imp)
Expand Down
10 changes: 5 additions & 5 deletions type_ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ import (
// ----------------------------------------------------------------------------

// Go+ overload extended types
type iOverloadType interface {
type OverloadType interface {
At(i int) types.Object
Len() int
}

var (
_ iOverloadType = (*TyOverloadNamed)(nil)
_ iOverloadType = (*TyOverloadFunc)(nil)
_ iOverloadType = (*TyOverloadMethod)(nil)
_ OverloadType = (*TyOverloadNamed)(nil)
_ OverloadType = (*TyOverloadFunc)(nil)
_ OverloadType = (*TyOverloadMethod)(nil)
)

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -114,7 +114,7 @@ func NewOverloadNamed(pos token.Pos, pkg *types.Package, name string, typs ...*t
// CheckOverloadNamed returns if specified type is a TyOverloadNamed or not.
func CheckOverloadNamed(typ types.Type) (on *TyOverloadNamed, ok bool) {
if sig, is := typ.(*types.Signature); is {
if typ, is := checkSigFuncEx(sig); is {
if typ, is := CheckSigFuncEx(sig); is {
on, ok = typ.(*TyOverloadNamed)
}
}
Expand Down

0 comments on commit 5992cce

Please sign in to comment.