2017-12-16 05:38:28 +01:00
|
|
|
package mvc
|
|
|
|
|
2019-04-16 17:01:48 +02:00
|
|
|
import (
|
|
|
|
"reflect"
|
2020-08-28 15:02:14 +02:00
|
|
|
|
|
|
|
"github.com/kataras/iris/v12/context"
|
2019-04-16 17:01:48 +02:00
|
|
|
)
|
|
|
|
|
2020-03-01 07:34:53 +01:00
|
|
|
var baseControllerTyp = reflect.TypeOf((*BaseController)(nil)).Elem()
|
2017-12-16 05:38:28 +01:00
|
|
|
|
|
|
|
func isBaseController(ctrlTyp reflect.Type) bool {
|
|
|
|
return ctrlTyp.Implements(baseControllerTyp)
|
|
|
|
}
|
|
|
|
|
2020-02-29 13:18:15 +01:00
|
|
|
// indirectType returns the value of a pointer-type "typ".
|
|
|
|
// If "typ" is a pointer, array, chan, map or slice it returns its Elem,
|
|
|
|
// otherwise returns the typ as it's.
|
|
|
|
func indirectType(typ reflect.Type) reflect.Type {
|
|
|
|
switch typ.Kind() {
|
|
|
|
case reflect.Ptr, reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
|
|
|
|
return typ.Elem()
|
|
|
|
}
|
|
|
|
return typ
|
|
|
|
}
|
2020-08-28 15:02:14 +02:00
|
|
|
|
|
|
|
func getSourceFileLine(ctrlType reflect.Type, m reflect.Method) (string, int) { // used for debug logs.
|
|
|
|
sourceFileName, sourceLineNumber := context.HandlerFileLineRel(m.Func)
|
|
|
|
if sourceFileName == "<autogenerated>" {
|
|
|
|
elem := indirectType(ctrlType)
|
|
|
|
|
|
|
|
for i, n := 0, elem.NumField(); i < n; i++ {
|
|
|
|
if f := elem.Field(i); f.Anonymous {
|
|
|
|
typ := indirectType(f.Type)
|
|
|
|
if typ.Kind() != reflect.Struct {
|
|
|
|
continue // field is not a struct.
|
|
|
|
}
|
|
|
|
|
|
|
|
// why we do that?
|
|
|
|
// because if the element is not Ptr
|
|
|
|
// then it's probably used as:
|
|
|
|
// type ctrl {
|
|
|
|
// BaseCtrl
|
|
|
|
// }
|
|
|
|
// but BaseCtrl has not the method, *BaseCtrl does:
|
|
|
|
// (c *BaseCtrl) HandleHTTPError(...)
|
2020-08-29 00:21:42 +02:00
|
|
|
// so we are creating a new temporary value ptr of that type
|
2020-08-28 15:02:14 +02:00
|
|
|
// and searching inside it for the method instead.
|
|
|
|
typ = reflect.New(typ).Type()
|
|
|
|
|
|
|
|
if embeddedMethod, ok := typ.MethodByName(m.Name); ok {
|
|
|
|
sourceFileName, sourceLineNumber = context.HandlerFileLineRel(embeddedMethod.Func)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return sourceFileName, sourceLineNumber
|
|
|
|
}
|