Add in before after panic and finally, recursive call Befores are ordered in revers, everything else is in order of first encountered.
(theType reflect.Type, fieldPath []int)
| 100 | // Add in before after panic and finally, recursive call |
| 101 | // Befores are ordered in revers, everything else is in order of first encountered. |
| 102 | func (cte *ControllerTypeEvents) check(theType reflect.Type, fieldPath []int) { |
| 103 | typeChecker := func(checkType reflect.Type) { |
| 104 | for index := 0; index < checkType.NumMethod(); index++ { |
| 105 | m := checkType.Method(index) |
| 106 | // Must be two arguments, the second returns the controller type |
| 107 | // Go cannot differentiate between promoted methods and |
| 108 | // embedded methods, this allows the embedded method to be run |
| 109 | // https://github.com/golang/go/issues/21162 |
| 110 | if m.Type.NumOut() == 2 && m.Type.Out(1) == checkType { |
| 111 | if checkType.Kind() == reflect.Ptr { |
| 112 | controllerLog.Debug("Found controller type event method pointer", "name", checkType.Elem().Name(), "methodname", m.Name) |
| 113 | } else { |
| 114 | controllerLog.Debug("Found controller type event method", "name", checkType.Name(), "methodname", m.Name) |
| 115 | } |
| 116 | controllerFieldPath := newFieldPath(checkType.Kind() == reflect.Ptr, m.Func, fieldPath) |
| 117 | switch strings.ToLower(m.Name) { |
| 118 | case "before": |
| 119 | cte.Before = append([]*ControllerFieldPath{controllerFieldPath}, cte.Before...) |
| 120 | case "after": |
| 121 | cte.After = append(cte.After, controllerFieldPath) |
| 122 | case "panic": |
| 123 | cte.Panic = append(cte.Panic, controllerFieldPath) |
| 124 | case "finally": |
| 125 | cte.Finally = append(cte.Finally, controllerFieldPath) |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | // Check methods of both types |
| 132 | typeChecker(theType) |
| 133 | typeChecker(reflect.PtrTo(theType)) |
| 134 | |
| 135 | // Check for any sub controllers, ignore any pointers to controllers revel.Controller |
| 136 | for i := 0; i < theType.NumField(); i++ { |
| 137 | v := theType.Field(i) |
| 138 | |
| 139 | switch v.Type.Kind() { |
| 140 | case reflect.Struct: |
| 141 | cte.check(v.Type, append(fieldPath, i)) |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | func newFieldPath(isPointer bool, value reflect.Value, fieldPath []int) *ControllerFieldPath { |
| 147 | return &ControllerFieldPath{IsPointer: isPointer, FunctionCall: value, FieldIndexPath: fieldPath} |
no test coverage detected