(ctrlType reflect.Type, m reflect.Method)
| 24 | } |
| 25 | |
| 26 | func getSourceFileLine(ctrlType reflect.Type, m reflect.Method) (string, int) { // used for debug logs. |
| 27 | sourceFileName, sourceLineNumber := context.HandlerFileLineRel(m.Func) |
| 28 | if sourceFileName == "<autogenerated>" { |
| 29 | elem := indirectType(ctrlType) |
| 30 | |
| 31 | for i, n := 0, elem.NumField(); i < n; i++ { |
| 32 | if f := elem.Field(i); f.Anonymous { |
| 33 | typ := indirectType(f.Type) |
| 34 | if typ.Kind() != reflect.Struct { |
| 35 | continue // field is not a struct. |
| 36 | } |
| 37 | |
| 38 | // why we do that? |
| 39 | // because if the element is not Ptr |
| 40 | // then it's probably used as: |
| 41 | // type ctrl { |
| 42 | // BaseCtrl |
| 43 | // } |
| 44 | // but BaseCtrl has not the method, *BaseCtrl does: |
| 45 | // (c *BaseCtrl) HandleHTTPError(...) |
| 46 | // so we are creating a new temporary value ptr of that type |
| 47 | // and searching inside it for the method instead. |
| 48 | typ = reflect.New(typ).Type() |
| 49 | |
| 50 | if embeddedMethod, ok := typ.MethodByName(m.Name); ok { |
| 51 | sourceFileName, sourceLineNumber = context.HandlerFileLineRel(embeddedMethod.Func) |
| 52 | } |
| 53 | } |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | return sourceFileName, sourceLineNumber |
| 58 | } |
no test coverage detected
searching dependent graphs…