// Add imports for each of the methods of the interface, but not the interface // itself. func addImportsForInterfaceMethods(imports importMap, it reflect.Type) { // Handle each method. for i := 0; i < it.NumMethod(); i++ { m := it.Method(i) addImportsForType(imports, m.Type) } }
// suitableMethods returns suitable Rpc methods of typ, it will report // error using log if reportErr is true. func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType { methods := make(map[string]*methodType) OUTER: for m := 0; m < typ.NumMethod(); m++ { method := typ.Method(m) mtype := method.Type mname := method.Name // Method must be exported. if method.PkgPath != "" { continue } // Method needs at least one ins: receiver if mtype.NumIn() < 1 { if reportErr { log.Println("method", mname, "has wrong number of ins:", mtype.NumIn()) } continue } // check if all args are exported or built in types argTypes := make([]reflect.Type, mtype.NumIn()-1) for i := 1; i < mtype.NumIn(); i++ { // first is the receiver which we don't need if !isExportedOrBuiltinType(mtype.In(i)) { if reportErr { log.Printf("%s argument %d not an exported type - %v\n", mname, i, mtype.In(i)) } continue } argTypes[i-1] = mtype.In(i) } // check if all return values are exported or built in types var hasError bool outTypes := make([]reflect.Type, mtype.NumOut()) for i := 0; i < mtype.NumOut(); i++ { if mtype.Out(i) == typeOfError { if hasError { // verify if there is only a single error returned if reportErr { log.Printf("%s returns multiple errors\n", mname) continue OUTER } } hasError = true outTypes[i] = mtype.Out(i) } else if isExportedOrBuiltinType(mtype.Out(i)) { outTypes[i] = mtype.Out(i) continue } else { if reportErr { log.Printf("Returned argument #%d for %s is of invalid type %v\n", i, mname, mtype.Out(i)) } continue OUTER } } methods[mname] = &methodType{method: method, ArgTypes: argTypes, ReplyTypes: outTypes, CanRetErr: hasError} } return methods }
func deepFieldsImpl(ifaceType reflect.Type) []string { fields := []string{} if ifaceType.Kind() != reflect.Ptr && ifaceType.Kind() != reflect.Struct { return fields } methods := ifaceType.NumMethod() for i := 0; i < methods; i++ { var v reflect.Method v = ifaceType.Method(i) fields = append(fields, v.Name) } if ifaceType.Kind() == reflect.Ptr { return fields } elements := ifaceType.NumField() for i := 0; i < elements; i++ { var v reflect.StructField v = ifaceType.Field(i) fields = append(fields, v.Name) } return fields }
func (c *structCache) Methods(typ reflect.Type) map[string]int { c.methodsl.RLock() indxs, ok := c.methods[typ] c.methodsl.RUnlock() if ok { return indxs } num := typ.NumMethod() indxs = make(map[string]int, num) for i := 0; i < num; i++ { m := typ.Method(i) if m.Type.NumIn() > 1 { continue } if m.Type.NumOut() != 1 { continue } indxs[m.Name] = m.Index } c.methodsl.Lock() c.methods[typ] = indxs c.methodsl.Unlock() return indxs }
func (s *state) evalArg(dot reflect.Value, typ reflect.Type, n parse.Node) reflect.Value { switch arg := n.(type) { case *parse.DotNode: return s.validateType(dot, typ) case *parse.FieldNode: return s.validateType(s.evalFieldNode(dot, arg, []parse.Node{n}, zero), typ) case *parse.VariableNode: return s.validateType(s.evalVariableNode(dot, arg, nil, zero), typ) } switch typ.Kind() { case reflect.Bool: return s.evalBool(typ, n) case reflect.Complex64, reflect.Complex128: return s.evalComplex(typ, n) case reflect.Float32, reflect.Float64: return s.evalFloat(typ, n) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return s.evalInteger(typ, n) case reflect.Interface: if typ.NumMethod() == 0 { return s.evalEmptyInterface(dot, n) } case reflect.String: return s.evalString(typ, n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return s.evalUnsignedInteger(typ, n) } s.errorf("can't handle %s for arg of type %s", n, typ) panic("not reached") }
func callbackArg(typ reflect.Type) (callbackArgConverter, error) { switch typ.Kind() { case reflect.Interface: if typ.NumMethod() != 0 { return nil, errors.New("the only supported interface type is interface{}") } return callbackArgGeneric, nil case reflect.Slice: if typ.Elem().Kind() != reflect.Uint8 { return nil, errors.New("the only supported slice type is []byte") } return callbackArgBytes, nil case reflect.String: return callbackArgString, nil case reflect.Bool: return callbackArgBool, nil case reflect.Int64: return callbackArgInt64, nil case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint: c := callbackArgCast{callbackArgInt64, typ} return c.Run, nil case reflect.Float64: return callbackArgFloat64, nil case reflect.Float32: c := callbackArgCast{callbackArgFloat64, typ} return c.Run, nil default: return nil, fmt.Errorf("don't know how to convert to %s", typ) } }
func generatemethodsEx(t reflect.Type, ignorefunc func(name string) bool, callobject string, name func(t reflect.Type, m reflect.Method) string) (methods string) { t2 := t if t.Kind() == reflect.Ptr { t2 = t.Elem() } for i := 0; i < t.NumMethod(); i++ { var ( m = t.Method(i) reason string ) if m.Name[0] != strings.ToUpper(m.Name[:1])[0] { reason = "unexported" goto skip } if ignorefunc != nil && ignorefunc(m.Name) { reason = "in skip list" goto skip } if m, err := generatemethod(m, t2, callobject, name(t2, m)); err != nil { reason = err.Error() goto skip } else { methods += m } continue skip: fmt.Printf("Skipping method %s.%s: %s\n", t2, m.Name, reason) } return }
func methods(t reflect.Type) []string { res := []string{} for i := 0; i < t.NumMethod(); i++ { res = append(res, t.Method(i).Name) } return res }
func (info *Info) addMethods(jt *Type, t reflect.Type) { // Add any methods. var vt reflect.Type if t.Kind() != reflect.Interface && !isWithoutReceiver(t) { t = reflect.PtrTo(t) vt = t.Elem() } for i := 0; i < t.NumMethod(); i++ { m := t.Method(i) if m.PkgPath != "" { continue } if t.Kind() != reflect.Interface { m.Type = withoutReceiverType{m.Type} } jm := Method{ Name: m.Name, Type: info.Ref(m.Type), } if vt != nil { _, hasValueMethod := vt.MethodByName(m.Name) jm.PtrReceiver = !hasValueMethod } if jt.Methods == nil { jt.Methods = make(map[string]*Method) } jt.Methods[jm.Name] = &jm } }
func newControllerInfo(namespace string, t reflect.Type, defaultAction string) *controllerInfo { typeName := t.String() if strings.HasPrefix(typeName, "*") { panic(errInvalidCtrlType(typeName)) } numMethod := t.NumMethod() if numMethod < 1 { panic(errCtrlNoAction(typeName)) } methods := make([]string, 0, numMethod) for i := 0; i < numMethod; i++ { methodInfo := t.Method(i) numIn := methodInfo.Type.NumIn() numOut := methodInfo.Type.NumOut() if numIn != 1 || numOut != 1 { continue } methodName := methodInfo.Name methods = append(methods, methodName) } if len(methods) < 1 { panic(errCtrlNoAction(typeName)) } actions := make(map[string]string, len(methods)) for _, m := range methods { actions[strings.ToLower(m)] = m } return &controllerInfo{ NsName: namespace, CtrlName: getControllerName(t), CtrlType: t, Actions: actions, DefaultAction: defaultAction, } }
func createEventHandlersForType(sourceType reflect.Type) handlersMap { handlers := make(handlersMap) // Loop through all the methods of the source methodCount := sourceType.NumMethod() for i := 0; i < methodCount; i++ { method := sourceType.Method(i) // Only match methods that satisfy prefix if strings.HasPrefix(method.Name, methodHandlerPrefix) { // Handling methods are defined in code by: // func (source *MySource) HandleMyEvent(e MyEvent). // When getting the type of this methods by reflection the signature // is as following: // func HandleMyEvent(source *MySource, e MyEvent). if method.Type.NumIn() == 2 { eventType := method.Type.In(1) handler := createEventHandler(method) handlers[eventType] = handler } } } return handlers }
func (s *Service) findRPCMethods(typ reflect.Type) { for i := 0; i < typ.NumMethod(); i++ { m := typ.Method(i) // Don't register callbacks if m.Name == "Started" || m.Name == "Stopped" || m.Name == "Registered" || m.Name == "Unregistered" { continue } // Only register exported methods if m.PkgPath != "" { continue } if m.Type.NumOut() != 1 && m.Type.NumOut() != 2 { continue } s.methods[m.Name] = m.Func //s.Log.Println("Registered RPC Method: " + m.Name) s.Log.Item(RegisteredMethod{ Method: m.Name, }) } }
func (s *state) evalArg(data reflect.Value, typ reflect.Type, n node) reflect.Value { if field, ok := n.(*fieldNode); ok { value := s.evalFieldNode(data, field, []node{n}, zero) if !value.Type().AssignableTo(typ) { s.errorf("wrong type for value; expected %s; got %s", typ, value.Type()) } return value } switch typ.Kind() { case reflect.Bool: return s.evalBool(typ, n) case reflect.String: return s.evalString(typ, n) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return s.evalInteger(typ, n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return s.evalUnsignedInteger(typ, n) case reflect.Float32, reflect.Float64: return s.evalFloat(typ, n) case reflect.Complex64, reflect.Complex128: return s.evalComplex(typ, n) case reflect.Interface: if typ.NumMethod() == 0 { return s.evalEmptyInterface(data, typ, n) } } s.errorf("can't handle %s for arg of type %s", n, typ) panic("not reached") }
// TODO: delete when reflect's own MethodByName is released. func methodByName(typ reflect.Type, name string) (reflect.Method, bool) { for i := 0; i < typ.NumMethod(); i++ { if typ.Method(i).Name == name { return typ.Method(i), true } } return reflect.Method{}, false }
func (e *Exchange) getMethodsForType(t reflect.Type) []string { r := []string{} for i := 0; i < t.NumMethod(); i++ { r = append(r, t.Method(i).Name) } return r }
func buildMethodData(t reflect.Type) map[string]reflect.Value { data := make(map[string]reflect.Value) for i, l := 0, t.NumMethod(); i < l; i++ { m := t.Method(i) data[strings.ToLower(m.Name)] = m.Func } return data }
// 合适的方法返回对应的Rpc方法,如果reportError设置为true的话,它会使用log来报告error。 func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType { methods := make(map[string]*methodType) for m := 0; m < typ.NumMethod(); m++ { method := typ.Method(m) mtype := method.Type mname := method.Name // Method must be exported. if method.PkgPath != "" { continue } // Method needs three ins: receiver, *args, *reply. if mtype.NumIn() != 3 { if reportErr { log.Println("method", mname, "has wrong number of ins:", mtype.NumIn()) } continue } // First arg need not be a pointer. argType := mtype.In(1) if !isExportedOrBuiltinType(argType) { if reportErr { log.Println(mname, "argument type not exported:", argType) } continue } // Second arg must be a pointer. replyType := mtype.In(2) if replyType.Kind() != reflect.Ptr { if reportErr { log.Println("method", mname, "reply type not a pointer:", replyType) } continue } // Reply type must be exported. if !isExportedOrBuiltinType(replyType) { if reportErr { log.Println("method", mname, "reply type not exported:", replyType) } continue } // Method needs one out. if mtype.NumOut() != 1 { if reportErr { log.Println("method", mname, "has wrong number of outs:", mtype.NumOut()) } continue } // The return type of the method must be error. if returnType := mtype.Out(0); returnType != typeOfError { if reportErr { log.Println("method", mname, "returns", returnType.String(), "not error") } continue } methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType} } return methods }
// ForeachMethod 遍历instance的所有方法 func ForeachMethod(instance reflect.Type, solve func(method reflect.Method) error) error { for i := 0; i < instance.NumMethod(); i++ { var err = solve(instance.Method(i)) if err != nil { return err } } return nil }
// methodIndex returns which method of rt implements the method. func methodIndex(rt reflect.Type, method string) int { for i := 0; i < rt.NumMethod(); i++ { if rt.Method(i).Name == method { return i } } errorf("internal error: can't find method %s", method) return 0 }
func FindMethod(recvType reflect.Type, funcVal reflect.Value) *reflect.Method { for i := 0; i < recvType.NumMethod(); i++ { method := recvType.Method(i) if method.Func.Pointer() == funcVal.Pointer() { return &method } } return nil }
func (h *Handler) findHandleFunc(t reflect.Type) *reflect.Method { for i := 0; i < t.NumMethod(); i++ { method := t.Method(i) if method.Name == flaglyHandle { return &method } } return nil }
func (d *Decoder) _compileInterface(f *decoder, t reflect.Type) { if t.NumMethod() != 0 { throwf("binn: cannot unmarshal into non-empty interface (%s)", t) } id := new(interfaceDecoder) id.decoder = d *f = id.decode }
func FindMethod(cType reflect.Type, methodName string) *reflect.Method { for i := 0; i < cType.NumMethod(); i++ { method := cType.Method(i) if strings.ToLower(method.Name) == strings.ToLower(methodName) { return &method } } return nil }
func getMethods(it reflect.Type) []reflect.Method { numMethods := it.NumMethod() methods := make([]reflect.Method, numMethods) for i := 0; i < numMethods; i++ { methods[i] = it.Method(i) } return methods }
func missingMethod(iT, xT reflect.Type) (method string) { numMethod := iT.NumMethod() for i := 0; i < numMethod; i += 1 { method = iT.Method(i).Name if _, ok := xT.MethodByName(method); !ok { return } } return "" }
func lookupMethod(t reflect.Type, name string) *reflect.Method { for i := 0; i < t.NumMethod(); i++ { m := t.Method(i) // fmt.Printf("%v: %d: %s\n", t, i, m.Name) if name == m.Name { return &m } } return nil }
// payloadMethods loosly bases around suitableMethods from $GOROOT/src/net/rpc/server.go. func payloadMethods(typ reflect.Type) map[string]reflect.Method { methods := make(map[string]reflect.Method) LoopMethods: for i := 0; i < typ.NumMethod(); i++ { method := typ.Method(i) mtype := method.Type mname := method.Name if method.PkgPath != "" { continue LoopMethods } switch mtype.NumIn() { case 2: eventType := mtype.In(1) if eventType.Kind() != reflect.Ptr { log.Println("method", mname, "takes wrong type of event:", eventType) continue LoopMethods } event, ok := payloads.Name(eventType.Elem()) if !ok { log.Println("method", mname, "takes wrong type of event:", eventType) continue LoopMethods } if _, ok = methods[event]; ok { panic(fmt.Sprintf("there is more than one method handling %v event", eventType)) } methods[event] = method case 3: if mtype.In(1).Implements(contextType) && mtype.In(2).Kind() == reflect.Ptr { eventType := mtype.In(2) event, ok := payloads.Name(eventType.Elem()) if !ok { log.Println("method", mname, "takes wrong type of event:", eventType) continue LoopMethods } if _, ok = methods[event]; ok { panic(fmt.Sprintf("there is more than one method handling %v event", eventType)) } methods[event] = method continue } if mtype.In(1).Kind() != reflect.String || mtype.In(2) != empty { log.Println("wildcard method", mname, "takes wrong types of arguments") continue LoopMethods } if _, ok := methods["*"]; ok { panic("there is more than one method handling all events") } methods["*"] = method default: log.Println("method", mname, "takes wrong number of arguments:", mtype.NumIn()) continue LoopMethods } } return methods }
// Return the reflect.Method, given a Receiver type and Func value. func FindMethod(recvType reflect.Type, funcVal reflect.Value) *reflect.Method { // It is not possible to get the name of the method from the Func. // Instead, compare it to each method of the Controller. for i := 0; i < recvType.NumMethod(); i++ { method := recvType.Method(i) if method.Func.Pointer() == funcVal.Pointer() { return &method } } return nil }
func MethodsMissingFromType(inter, typ reflect.Type) []string { missingMethods := make([]string, 0) for n := 0; n < inter.NumMethod(); n++ { _, present := typ.MethodByName(inter.Method(n).Name) if !present { fmt.Println(inter.Method(n).Name) missingMethods = append(missingMethods, inter.Method(n).Name) } } return missingMethods }
// Given a type t, return all of the methods of t sorted such that source file // order is preserved. Order across files is undefined. Order within lines is // undefined. func getMethodsInSourceOrder(t reflect.Type) []reflect.Method { // Build the list of methods. methods := sortableMethodSet{} for i := 0; i < t.NumMethod(); i++ { methods = append(methods, t.Method(i)) } // Sort it. sort.Sort(methods) return methods }