bug fix: label pointer-typed receivers correctly

We were trying to convert the object's type to a named type
to iterate through its methods, forgetting that it could also be
a pointer to a named type.

This bug was exposed because we no longer extract an object's
type before extracting it (unless it is a receiver), and when we
extracted a named type we extract its methods and when
extracting a method we extract its receiver and we always give
it the correct label in that situation.
This commit is contained in:
Owen Mansel-Chan
2022-03-31 16:55:47 +01:00
committed by Chris Smowton
parent 92c331402d
commit 63d1663eb2

View File

@@ -154,20 +154,17 @@ func (l *Labeler) ScopedObjectID(object types.Object, getTypeLabel func() Label)
} else {
// associate method receiver objects to special keys, because those can be
// referenced from other files via their method
isRecv := false
if namedType, ok := object.Type().(*types.Named); ok {
for i := 0; i < namedType.NumMethods(); i++ {
meth := namedType.Method(i)
if object == meth.Type().(*types.Signature).Recv() {
isRecv = true
methlbl, _ := l.MethodID(meth, getTypeLabel())
label, _ = l.ReceiverObjectID(object, methlbl)
break
}
meth := findMethodWithGivenReceiver(object.Type(), object)
if meth == nil {
if pointerType, ok := object.Type().(*types.Pointer); ok {
meth = findMethodWithGivenReceiver(pointerType.Elem(), object)
}
}
if !isRecv {
if meth != nil {
methlbl, _ := l.MethodID(meth, getTypeLabel())
label, _ = l.ReceiverObjectID(object, methlbl)
} else {
scopeLbl := l.ScopeID(scope, object.Pkg())
label = l.GlobalID(fmt.Sprintf("{%v},%s;object", scopeLbl, object.Name()))
}
@@ -177,6 +174,18 @@ func (l *Labeler) ScopedObjectID(object types.Object, getTypeLabel func() Label)
return label, exists
}
func findMethodWithGivenReceiver(tp types.Type, object types.Object) *types.Func {
if namedType, ok := tp.(*types.Named); ok {
for i := 0; i < namedType.NumMethods(); i++ {
meth := namedType.Method(i)
if object == meth.Type().(*types.Signature).Recv() {
return meth
}
}
}
return nil
}
// ReceiverObjectID associates a label with the given object and returns it, together with a flag indicating whether
// the object already had a label associated with it; the object must be the receiver of `methlbl`, since that label
// is used to construct the label of the object