diff --git a/codebuild.go b/codebuild.go index 5699b959..3902cc4e 100644 --- a/codebuild.go +++ b/codebuild.go @@ -1676,32 +1676,40 @@ func (p *CodeBuilder) allowAccess(pkg *types.Package, name string) bool { func (p *CodeBuilder) method( o methodList, name, aliasName string, flag MemberFlag, arg *Element, src ast.Node) (kind MemberKind) { + var found *types.Func for i, n := 0, o.NumMethods(); i < n; i++ { method := o.Method(i) v := method.Name() if !p.allowAccess(method.Pkg(), v) { continue } - if v == name || (flag > 0 && v == aliasName) { - autoprop := flag == MemberFlagAutoProperty && v == aliasName - typ := method.Type() - if autoprop && !methodHasAutoProperty(typ, 0) { - return memberBad - } - p.stk.Ret(1, &internal.Elem{ - Val: selector(arg, v), - Type: methodTypeOf(typ), - Src: src, - }) - if p.rec != nil { - p.rec.Member(src, method) - } - if autoprop { - p.Call(0) - return MemberAutoProperty - } - return MemberMethod + if v == name { + found = method + break + } else if flag > 0 && v == aliasName { + found = method + } + } + if found != nil { + v := found.Name() + autoprop := flag == MemberFlagAutoProperty && v == aliasName + typ := found.Type() + if autoprop && !methodHasAutoProperty(typ, 0) { + return memberBad + } + p.stk.Ret(1, &internal.Elem{ + Val: selector(arg, v), + Type: methodTypeOf(typ), + Src: src, + }) + if p.rec != nil { + p.rec.Member(src, found) + } + if autoprop { + p.Call(0) + return MemberAutoProperty } + return MemberMethod } if t, ok := o.(*types.Named); ok { kind = p.btiMethod(p.getBuiltinTI(t), name, aliasName, flag, arg, src) diff --git a/package_test.go b/package_test.go index 8c126660..d93447c8 100644 --- a/package_test.go +++ b/package_test.go @@ -3567,4 +3567,49 @@ func main() { `) } +func TestMethodAlias(t *testing.T) { + pkg := newMainPackage() + + typ := types.NewStruct(nil, nil) + tyM := pkg.NewType("M").InitType(pkg, typ) + recv := pkg.NewParam(token.NoPos, "p", types.NewPointer(tyM)) + pkg.NewFunc(recv, "SetValue", nil, nil, false).BodyStart(pkg).End() + pkg.NewFunc(recv, "setValue", nil, nil, false).BodyStart(pkg).End() + pkg.NewFunc(recv, "Value", nil, nil, false).BodyStart(pkg).End() + + pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). + NewVar(tyM, "m"). + VarVal("m").Debug( + func(cb *gox.CodeBuilder) { + cb.Member("setValue", gox.MemberFlagMethodAlias) + }).Call(0).EndStmt(). + VarVal("m").Debug( + func(cb *gox.CodeBuilder) { + cb.Member("SetValue", gox.MemberFlagMethodAlias) + }).Call(0).EndStmt(). + VarVal("m").Debug( + func(cb *gox.CodeBuilder) { + cb.Member("value", gox.MemberFlagMethodAlias) + }).Call(0).EndStmt(). + End() + domTest(t, pkg, `package main + +type M struct { +} + +func (p *M) SetValue() { +} +func (p *M) setValue() { +} +func (p *M) Value() { +} +func main() { + var m M + m.setValue() + m.SetValue() + m.Value() +} +`) +} + // ----------------------------------------------------------------------------