…lines 1–309 unchanged (309 lines)
310 // a struct or its pointer. If obj is a struct,
311 // to check all T and *T method, use obj pointer type Value
312 objPtr := obj
313 if !hreflect.IsInterfaceOrPointer(objPtr.Kind()) && objPtr.CanAddr() {
314 objPtr = objPtr.Addr()
315 }
316
317 mt := hreflect.GetMethodByNameForType(objPtr.Type(), elemName)
318 if mt.Func.IsValid() {
319 // Receiver is the first argument.
320 args := []reflect.Value{objPtr}
321 num := mt.Type.NumIn()
322 maxNumIn := 1
323 if num > 1 && hreflect.IsContextType(mt.Type.In(1)) {
324 args = append(args, ctx)
325 maxNumIn = 2
326 }
327
328 switch {
329 case mt.PkgPath != "":
330 return zero, fmt.Errorf("%s is an unexported method of type %s", elemName, typ)
…lines 331–335 unchanged (5 lines)
336 return zero, fmt.Errorf("%s is a method of type %s but returns more than 2 outputs", elemName, typ)
337 case mt.Type.NumOut() == 1 && mt.Type.Out(0).Implements(errorType):
338 return zero, fmt.Errorf("%s is a method of type %s but only returns an error type", elemName, typ)
339 case mt.Type.NumOut() == 2 && !mt.Type.Out(1).Implements(errorType):
340 return zero, fmt.Errorf("%s is a method of type %s returning two values but the second value is not an error type", elemName, typ)
341 }
342 res := mt.Func.Call(args)
343 if len(res) == 2 && !res[1].IsNil() {
344 return zero, fmt.Errorf("error at calling a method %s of type %s: %s", elemName, typ, res[1].Interface().(error))
345 }
346 return res[0], nil
347 }
348
…lines 349–498 unchanged (150 lines)