@@ -3,6 +3,7 @@ package kong
33import (
44 "fmt"
55 "reflect"
6+ "runtime"
67 "strings"
78)
89
@@ -127,13 +128,38 @@ func getMethod(value reflect.Value, name string) reflect.Value {
127128 return method
128129}
129130
131+ func getExplicitMethod (value reflect.Value , name string ) reflect.Value {
132+ if isExplicitMethod (value .Type (), name ) {
133+ return value .MethodByName (name )
134+ }
135+ if value .CanAddr () && isExplicitMethod (value .Addr ().Type (), name ) {
136+ return value .Addr ().MethodByName (name )
137+ }
138+ return reflect.Value {}
139+ }
140+
141+ func isExplicitMethod (t reflect.Type , name string ) bool {
142+ method , ok := t .MethodByName (name )
143+ if ! ok {
144+ return false
145+ }
146+ // Promoted embedded methods are compiler-generated wrappers. The embedded
147+ // value itself is visited separately, so skip those wrappers here.
148+ fn := runtime .FuncForPC (method .Func .Pointer ())
149+ if fn == nil {
150+ return true
151+ }
152+ file , _ := fn .FileLine (method .Func .Pointer ())
153+ return file != "<autogenerated>"
154+ }
155+
130156// getMethods gets all methods with the given name from the given value
131157// and any embedded fields.
132158//
133159// Returns a slice of bound methods that can be called directly.
134160func getMethods (value reflect.Value , name string ) (methods []reflect.Value ) {
135161 walkEmbedded (value , func (v reflect.Value ) {
136- if method := getMethod (v , name ); method .IsValid () {
162+ if method := getExplicitMethod (v , name ); method .IsValid () {
137163 methods = append (methods , method )
138164 }
139165 })
0 commit comments