Skip to content

Commit

Permalink
Merge pull request #2 from visualfc/main
Browse files Browse the repository at this point in the history
fix gop #757 struct/interface method call bug
  • Loading branch information
xushiwei authored Aug 31, 2021
2 parents 617ff44 + 5fd3072 commit baae9e8
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
23 changes: 21 additions & 2 deletions codebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -1421,10 +1421,29 @@ func (p *CodeBuilder) Member(name string, lhs bool, src ...ast.Node) (kind Membe
if debugInstr {
log.Println("Member", name, lhs, "//", arg.Type)
}
var isTypeType bool
at := arg.Type
if t, ok := at.(*TypeType); ok {
at = t.typ
isTypeType = true
}
if lhs {
kind = p.refMember(arg.Type, name, arg.Val)
kind = p.refMember(at, name, arg.Val)
} else {
kind = p.findMember(arg.Type, name, arg.Val, srcExpr)
kind = p.findMember(at, name, arg.Val, srcExpr)
}
if isTypeType && kind == MemberMethod {
e := p.Get(-1)
if sig, ok := e.Type.(*types.Signature); ok {
var vars []*types.Var
vars = append(vars, types.NewVar(token.NoPos, nil, "recv", at))
sp := sig.Params()
spLen := sp.Len()
for i := 0; i < spLen; i++ {
vars = append(vars, sp.At(i))
}
e.Type = types.NewSignature(nil, types.NewTuple(vars...), sig.Results(), sig.Variadic())
}
}
if kind != MemberInvalid {
return
Expand Down
41 changes: 41 additions & 0 deletions package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2612,6 +2612,47 @@ func main() {
}
}

func TestInterfaceMethodVarCall(t *testing.T) {
pkg := newMainPackage()
fmt := pkg.Import("fmt")
tyInt := types.Typ[types.Int]
tyString := types.Typ[types.String]
methods := []*types.Func{
types.NewFunc(token.NoPos, pkg.Types, "bar", types.NewSignature(nil, types.NewTuple(types.NewVar(token.NoPos, nil, "info", tyString)), nil, false)),
}
tyInterf := types.NewInterfaceType(methods, nil).Complete()
foo := pkg.NewType("foo").InitType(pkg, tyInterf)
_ = foo
tt := pkg.NewType("t").InitType(pkg, tyInt)
recv := pkg.NewParam(token.NoPos, "tt", tt)
pkg.NewFunc(recv, "bar", types.NewTuple(types.NewVar(token.NoPos, nil, "info", tyString)), nil, false).BodyStart(pkg).
Val(fmt.Ref("Println")).Val(recv).Val(pkg.NewParam(token.NoPos, "info", tyString)).Call(2).EndStmt(). // fmt.Println(v)
End()
pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg).
DefineVarStart(0, "v").Val(ctxRef(pkg, "foo")).MemberVal("bar").EndInit(1).
NewVarStart(tt, "tt").Val(123).EndInit(1).
Val(ctxRef(pkg, "v")).Val(ctxRef(pkg, "tt")).Val("hello").Call(2, false).
EndStmt().End()
domTest(t, pkg, `package main
import fmt "fmt"
type foo interface {
bar(info string)
}
type t int
func (tt t) bar(info string) {
fmt.Println(tt, info)
}
func main() {
v := foo.bar
var tt t = 123
v(tt, "hello")
}
`)
}

func TestTypeNamed(t *testing.T) {
pkg := newMainPackage()
fields := []*types.Var{
Expand Down

0 comments on commit baae9e8

Please sign in to comment.