// Run recevies the argument and func (m *mqueSub) Run(d interface{}, ctype reflect.Type) { if !m.has { for _, tm := range m.tms { tm.Call([]reflect.Value{}) } return } var configVal reflect.Value if !ctype.AssignableTo(m.am) { if !ctype.ConvertibleTo(m.am) { return } vum := reflect.ValueOf(d) configVal = vum.Convert(m.am) } else { configVal = reflect.ValueOf(d) } for _, tm := range m.tms { tm.Call([]reflect.Value{configVal}) } }
func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) { kind := typ.Kind() switch { case typ == rawValueType: return decodeRawValue, nil case typ.Implements(decoderInterface): return decodeDecoder, nil case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(decoderInterface): return decodeDecoderNoPtr, nil case typ.AssignableTo(reflect.PtrTo(bigInt)): return decodeBigInt, nil case typ.AssignableTo(bigInt): return decodeBigIntNoPtr, nil case isUint(kind): return decodeUint, nil case kind == reflect.Bool: return decodeBool, nil case kind == reflect.String: return decodeString, nil case kind == reflect.Slice || kind == reflect.Array: return makeListDecoder(typ, tags) case kind == reflect.Struct: return makeStructDecoder(typ) case kind == reflect.Ptr: if tags.nilOK { return makeOptionalPtrDecoder(typ) } return makePtrDecoder(typ) case kind == reflect.Interface: return decodeInterface, nil default: return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) } }
// makeWriter creates a writer function for the given type. func makeWriter(typ reflect.Type) (writer, error) { kind := typ.Kind() switch { case typ.Implements(encoderInterface): return writeEncoder, nil case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): return writeEncoderNoPtr, nil case kind == reflect.Interface: return writeInterface, nil case typ.AssignableTo(reflect.PtrTo(bigInt)): return writeBigIntPtr, nil case typ.AssignableTo(bigInt): return writeBigIntNoPtr, nil case isUint(kind): return writeUint, nil case kind == reflect.Bool: return writeBool, nil case kind == reflect.String: return writeString, nil case kind == reflect.Slice && isByte(typ.Elem()): return writeBytes, nil case kind == reflect.Array && isByte(typ.Elem()): return writeByteArray, nil case kind == reflect.Slice || kind == reflect.Array: return makeSliceWriter(typ) case kind == reflect.Struct: return makeStructWriter(typ) case kind == reflect.Ptr: return makePtrWriter(typ) default: return nil, fmt.Errorf("rlp: type %v is not RLP-serializable", typ) } }
func mustBeCompatible(a, b reflect.Type) { if !a.ConvertibleTo(b) || !a.AssignableTo(b) { panic(errors.New(fmt.Sprintf( "Types '%v' and '%v' is not compatile to each other! "+ "It is no possible to make a swap function that "+ "return or receive different kinds of objects!", a.Name(), b.Name()))) } }
func assignable(to, from reflect.Type) bool { if from == nil { switch to.Kind() { case reflect.Chan, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.Func: return true } return false } return from.AssignableTo(to) }
// CanRun returns whether the argument can be used with this subscriber. func (m *mqueSub) CanRun(d reflect.Type) bool { if !d.AssignableTo(m.am) { // if d.ConvertibleTo(m.am) { // return true // } return false } return true }
// CanSetForType checks if a val reflect.Type can be used for the target type. // It returns true bool, where the first returns if the value can be used and if // it must be converted into the type first. func CanSetForType(target, val reflect.Type) (canSet bool, mustConvert bool) { if val.AssignableTo(target) { canSet = true return } if val.ConvertibleTo(target) { canSet = true mustConvert = true return } return }
func unmarshalToType(typ reflect.Type, value string) (val interface{}, err error) { // If we get a pointer in, we'll return a pointer out if typ.Kind() == reflect.Ptr { val = reflect.New(typ.Elem()).Interface() } else { val = reflect.New(typ).Interface() } defer func() { if err == nil && typ.Kind() != reflect.Ptr { val = reflect.Indirect(reflect.ValueOf(val)).Interface() } }() // If we can just assign the value, return the value if typ.AssignableTo(reflect.TypeOf(value)) { return value, nil } // Try Unmarshalers if um, ok := val.(encoding.TextUnmarshaler); ok { if err = um.UnmarshalText([]byte(value)); err == nil { return val, nil } } if um, ok := val.(json.Unmarshaler); ok { if err = um.UnmarshalJSON([]byte(value)); err == nil { return val, nil } } // Try conversion if typ.ConvertibleTo(reflect.TypeOf(value)) { return reflect.ValueOf(value).Convert(typ).Interface(), nil } // Try JSON if err = json.Unmarshal([]byte(value), val); err == nil { return val, nil } // Return error if we have one if err != nil { return nil, err } return val, fmt.Errorf("No way to unmarshal \"%s\" to %s", value, typ.Name()) }
func (s *schemaField) check(ft reflect.Type, v interface{}) error { t := reflect.TypeOf(v) if !ft.AssignableTo(t) { if !ft.ConvertibleTo(t) { return fmt.Errorf("type %s (%v) cannot be converted to %T", ft.Name(), ft.Kind(), t.Name()) } s.marshalType = t } if !t.AssignableTo(ft) { if !t.ConvertibleTo(ft) { return fmt.Errorf("type %s (%v) cannot be converted to %T", t.Name(), t.Kind(), ft.Name()) } s.unmarshalType = ft } return nil }
// converts in to an expression of type OutT. // also serves as type check (not convertible == type error) // pos is used for error message on impossible conversion. func typeConv(pos token.Pos, in Expr, outT reflect.Type) Expr { inT := in.Type() switch { default: panic(err(pos, "type mismatch: can not use type", inT, "as", outT)) // treat 'void' (type nil) separately: case inT == nil && outT != nil: panic(err(pos, "void used as value")) case inT != nil && outT == nil: panic("script internal bug: void input type") // strict go conversions: case inT == outT: return in case inT.AssignableTo(outT): return in // extra conversions for ease-of-use: // int -> float64 case outT == float64_t && inT == int_t: return &intToFloat64{in} // float64 -> int case outT == int_t && inT == float64_t: return &float64ToInt{in} case outT == float64_t && inT.AssignableTo(ScalarIf_t): return &getScalar{in.Eval().(ScalarIf)} case outT == float64_t && inT.AssignableTo(VectorIf_t): return &getVector{in.Eval().(VectorIf)} // magical expression -> function conversions case inT == float64_t && outT.AssignableTo(ScalarFunction_t): return &scalFn{in} case inT == int_t && outT.AssignableTo(ScalarFunction_t): return &scalFn{&intToFloat64{in}} case inT == vector_t && outT.AssignableTo(VectorFunction_t): return &vecFn{in} case inT == bool_t && outT == func_bool_t: return &boolToFunc{in} } }
func isDurationField(t reflect.Type) bool { return t.AssignableTo(durationType) }
func (state *unmarshalState) unmarshalValue(cfObj cfTypeRef, v reflect.Value) error { vType := v.Type() var unmarshaler Unmarshaler if u, ok := v.Interface().(Unmarshaler); ok { unmarshaler = u } else if vType.Kind() != reflect.Ptr && vType.Name() != "" && v.CanAddr() { // matching the encoding/json behavior here // If v is a named type and is addressable, check its address for Unmarshaler. vA := v.Addr() if u, ok := vA.Interface().(Unmarshaler); ok { unmarshaler = u } } if unmarshaler != nil { // flip over to the dumb conversion routine so we have something to give UnmarshalPlist() plist, err := convertCFTypeToInterface(cfObj) if err != nil { return err } if vType.Kind() == reflect.Ptr && v.IsNil() { v.Set(reflect.New(vType.Elem())) unmarshaler = v.Interface().(Unmarshaler) } return unmarshaler.UnmarshalPlist(plist) } if vType.Kind() == reflect.Ptr { if v.IsNil() { v.Set(reflect.New(vType.Elem())) } return state.unmarshalValue(cfObj, v.Elem()) } typeID := C.CFGetTypeID(C.CFTypeRef(cfObj)) vSetter := v // receiver of any Set* calls vAddr := v.Addr() // used for re-setting v for maps/slices if vType.Kind() == reflect.Interface { if v.IsNil() { // pick an appropriate type based on the cfobj var typ reflect.Type if typeID == cfNumberTypeID { typ = cfNumberTypeToType(C.CFNumberGetType(C.CFNumberRef(cfObj))) } else { var ok bool typ, ok = cfTypeMap[typeID] if !ok { return &UnknownCFTypeError{typeID} } } if !typ.AssignableTo(vType) { // v must be some interface that our object doesn't conform to state.recordError(&UnmarshalTypeError{cfTypeNames[typeID], vType}) return nil } vSetter.Set(reflect.Zero(typ)) } vAddr = v v = v.Elem() vType = v.Type() } switch typeID { case cfArrayTypeID: if vType.Kind() != reflect.Slice && vType.Kind() != reflect.Array { state.recordError(&UnmarshalTypeError{cfTypeNames[typeID], vType}) return nil } return convertCFArrayToSliceHelper(C.CFArrayRef(cfObj), func(elem cfTypeRef, idx, count int) (bool, error) { if idx == 0 && vType.Kind() == reflect.Slice { vSetter.Set(reflect.MakeSlice(vType, count, count)) v = vAddr.Elem() } else if vType.Kind() == reflect.Array && idx >= v.Len() { return false, nil } if err := state.unmarshalValue(elem, v.Index(idx)); err != nil { return false, err } return true, nil }) case cfBooleanTypeID: if vType.Kind() != reflect.Bool { state.recordError(&UnmarshalTypeError{cfTypeNames[typeID], vType}) return nil } vSetter.Set(reflect.ValueOf(C.CFBooleanGetValue(C.CFBooleanRef(cfObj)) != C.false)) return nil case cfDataTypeID: if !byteSliceType.AssignableTo(vType) { state.recordError(&UnmarshalTypeError{cfTypeNames[typeID], vType}) return nil } vSetter.Set(reflect.ValueOf(convertCFDataToBytes(C.CFDataRef(cfObj)))) return nil case cfDateTypeID: if !timeType.AssignableTo(vType) { state.recordError(&UnmarshalTypeError{cfTypeNames[typeID], vType}) return nil } vSetter.Set(reflect.ValueOf(convertCFDateToTime(C.CFDateRef(cfObj)))) return nil case cfDictionaryTypeID: if vType.Kind() == reflect.Map { // it's a map. Check its key type first if !stringType.AssignableTo(vType.Key()) { state.recordError(&UnmarshalTypeError{cfTypeNames[cfStringTypeID], vType.Key()}) return nil } if v.IsNil() { vSetter.Set(reflect.MakeMap(vType)) v = vAddr.Elem() } return convertCFDictionaryToMapHelper(C.CFDictionaryRef(cfObj), func(key string, value cfTypeRef, count int) error { keyVal := reflect.ValueOf(key) val := reflect.New(vType.Elem()) if err := state.unmarshalValue(value, val); err != nil { return err } v.SetMapIndex(keyVal, val.Elem()) return nil }) } else if vType.Kind() == reflect.Struct { return convertCFDictionaryToMapHelper(C.CFDictionaryRef(cfObj), func(key string, value cfTypeRef, count int) error { // we need to iterate the fields because the tag might rename the key var f reflect.StructField var ok bool for i := 0; i < vType.NumField(); i++ { sf := vType.Field(i) tag := sf.Tag.Get("plist") if tag == "-" { // Pretend this field doesn't exist continue } if sf.Anonymous { // Match encoding/json's behavior here and pretend it doesn't exist continue } name, _ := parseTag(tag) if name == key { f = sf ok = true // This is unambiguously the right match break } if sf.Name == key { f = sf ok = true } // encoding/json does a case-insensitive match. Lets do that too if !ok && strings.EqualFold(sf.Name, key) { f = sf ok = true } } if ok { if f.PkgPath != "" { // this is an unexported field return &UnmarshalFieldError{key, vType, f} } vElem := v.FieldByIndex(f.Index) if err := state.unmarshalValue(value, vElem); err != nil { return err } } return nil }) } state.recordError(&UnmarshalTypeError{cfTypeNames[typeID], vType}) return nil case cfNumberTypeID: switch vType.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: i := convertCFNumberToInt64(C.CFNumberRef(cfObj)) if v.OverflowInt(i) { state.recordError(&UnmarshalTypeError{cfTypeNames[typeID] + " " + strconv.FormatInt(i, 10), vType}) return nil } if vSetter.Kind() == reflect.Interface { vSetter.Set(reflect.ValueOf(i)) } else { vSetter.SetInt(i) } return nil case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: u := uint64(convertCFNumberToUInt32(C.CFNumberRef(cfObj))) if v.OverflowUint(u) { state.recordError(&UnmarshalTypeError{cfTypeNames[typeID] + " " + strconv.FormatUint(u, 10), vType}) return nil } if vSetter.Kind() == reflect.Interface { vSetter.Set(reflect.ValueOf(u)) } else { vSetter.SetUint(u) } return nil case reflect.Float32, reflect.Float64: f := convertCFNumberToFloat64(C.CFNumberRef(cfObj)) if v.OverflowFloat(f) { state.recordError(&UnmarshalTypeError{cfTypeNames[typeID] + " " + strconv.FormatFloat(f, 'f', -1, 64), vType}) return nil } if vSetter.Kind() == reflect.Interface { vSetter.Set(reflect.ValueOf(f)) } else { vSetter.SetFloat(f) } return nil } state.recordError(&UnmarshalTypeError{cfTypeNames[typeID], vType}) return nil case cfStringTypeID: if vType.Kind() != reflect.String { state.recordError(&UnmarshalTypeError{cfTypeNames[typeID], vType}) return nil } vSetter.Set(reflect.ValueOf(convertCFStringToString(C.CFStringRef(cfObj)))) return nil } return &UnknownCFTypeError{typeID} }
// suitableMethods returns suitable Rpc methods of typ, it will report // error using logger if reportErr is true. func (server *Server) suitableMethods(rcvr interface{}, s *service, typ reflect.Type, reportErr bool, rcvrFns ...interface{}) map[uint32]*methodType { methods := s.method if typ.AssignableTo(reflect.TypeOf((**lua.LTable)(nil)).Elem()) { if len(rcvrFns) > 0 { rcvrFns[0].(*lua.LTable).ForEach(func(key, value lua.LValue) { //logger.Debug("ForEach LTable :%v, %v", key, value) if key.Type() == lua.LTString && value.Type() == lua.LTFunction && value.(*lua.LFunction).Proto.NumParameters == 3 { method, ok := reflect.TypeOf(server).MethodByName("CallLua") if !ok { logger.Debug("regist MethodByName error :%v", key.String()) } mtype := method.Type mname := method.Name // Second arg need not be a pointer. argType := mtype.In(2) if !isExportedOrBuiltinType(argType) { if reportErr { logger.Info("%s argument type not exported: %s", mname, argType) } //continue } methods[server.protocol[key.String()]] = &methodType{method: method, ArgType: argType, luaMethod: value.(*lua.LFunction)} logger.Debug("regist %v", key.String()) } }) } } else { for m := 0; m < typ.NumMethod(); m++ { method := typ.Method(m) mtype := method.Type mname := method.Name //fmt.Printf("suitableMethods %s, %s, %s, %d \n", mtype, mname, method.PkgPath, mtype.NumIn()) // Method must be exported. if method.PkgPath != "" { continue } // Method needs three ins: receiver, connid, *args. if mtype.NumIn() != 3 { if reportErr { logger.Info("method %s has wrong number of ins: %v", mname, mtype.NumIn()) } continue } idType := mtype.In(1) if !idType.AssignableTo(reflect.TypeOf((*RpcConn)(nil)).Elem()) { if reportErr { logger.Info("%s conn %s must be %s", mname, idType.Name(), reflect.TypeOf((*RpcConn)(nil)).Elem().Name()) } continue } // Second arg need not be a pointer. argType := mtype.In(2) if !isExportedOrBuiltinType(argType) { if reportErr { logger.Info("%s argument type not exported: %s", mname, argType) } continue } // Method needs one out. if mtype.NumOut() != 1 { if reportErr { logger.Info("method %s has wrong number of outs: %v", mname, mtype.NumOut()) } continue } // The return type of the method must be error. if returnType := mtype.Out(0); returnType != typeOfError { if reportErr { logger.Info("method %s returns %s not error", mname, returnType.String()) } continue } methods[server.protocol[mname]] = &methodType{method: method, ArgType: argType} logger.Debug("suitableMethods protocol %v, %d, %v", mname, server.protocol[mname], methods[server.protocol[mname]]) } } return methods }
// Determines if two types can be automatically converted between. func areTypesCompatible(xt, yt reflect.Type) bool { return xt.AssignableTo(unhackType(yt)) || yt.AssignableTo(unhackType(xt)) }
// newTypeDecoder constructs an decoderFunc for a type. func newTypeDecoder(dt, st reflect.Type, blank bool) decoderFunc { if reflect.PtrTo(dt).Implements(unmarshalerType) || dt.Implements(unmarshalerType) { return unmarshalerDecoder } if st.Kind() == reflect.Interface { return newInterfaceAsTypeDecoder(blank) } switch dt.Kind() { case reflect.Bool: switch st.Kind() { case reflect.Bool: return boolAsBoolDecoder case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return intAsBoolDecoder case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return uintAsBoolDecoder case reflect.Float32, reflect.Float64: return floatAsBoolDecoder case reflect.String: return stringAsBoolDecoder default: return decodeTypeError } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: switch st.Kind() { case reflect.Bool: return boolAsIntDecoder case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return intAsIntDecoder case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return uintAsIntDecoder case reflect.Float32, reflect.Float64: return floatAsIntDecoder case reflect.String: return stringAsIntDecoder default: return decodeTypeError } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: switch st.Kind() { case reflect.Bool: return boolAsUintDecoder case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return intAsUintDecoder case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return uintAsUintDecoder case reflect.Float32, reflect.Float64: return floatAsUintDecoder case reflect.String: return stringAsUintDecoder default: return decodeTypeError } case reflect.Float32, reflect.Float64: switch st.Kind() { case reflect.Bool: return boolAsFloatDecoder case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return intAsFloatDecoder case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return uintAsFloatDecoder case reflect.Float32, reflect.Float64: return floatAsFloatDecoder case reflect.String: return stringAsFloatDecoder default: return decodeTypeError } case reflect.String: switch st.Kind() { case reflect.Bool: return boolAsStringDecoder case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return intAsStringDecoder case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return uintAsStringDecoder case reflect.Float32, reflect.Float64: return floatAsStringDecoder case reflect.String: return stringAsStringDecoder default: return decodeTypeError } case reflect.Interface: if !st.AssignableTo(dt) { return decodeTypeError } return interfaceDecoder case reflect.Ptr: return newPtrDecoder(dt, st, blank) case reflect.Map: if st.AssignableTo(dt) { return interfaceDecoder } switch st.Kind() { case reflect.Map: return newMapAsMapDecoder(dt, st, blank) default: return decodeTypeError } case reflect.Struct: if st.AssignableTo(dt) { return interfaceDecoder } switch st.Kind() { case reflect.Map: if kind := st.Key().Kind(); kind != reflect.String && kind != reflect.Interface { return newDecodeTypeError(fmt.Errorf("map needs string keys")) } return newMapAsStructDecoder(dt, st, blank) default: return decodeTypeError } case reflect.Slice: if st.AssignableTo(dt) { return interfaceDecoder } switch st.Kind() { case reflect.Array, reflect.Slice: return newSliceDecoder(dt, st) default: return decodeTypeError } case reflect.Array: if st.AssignableTo(dt) { return interfaceDecoder } switch st.Kind() { case reflect.Array, reflect.Slice: return newArrayDecoder(dt, st) default: return decodeTypeError } default: return unsupportedTypeDecoder } }
// When implements Resolver.WhenT(). func (s *turnResolver) WhenT(in, out, outR reflect.Type, f interface{}) async.ResultT { // Validate function type - this is in lieu of static type checking from generics. fType := reflect.TypeOf(f) assert.True(fType.Kind() == reflect.Func, "f MUST be a WhenFunc") // Validate inputs - this is in lieu of static type checking from generics. assert.True(fType.NumIn() <= 2, "f MUST take val, err, both or neither") takeValue, takeError := true, true if numIn := fType.NumIn(); numIn == 2 { assert.True(in.AssignableTo(fType.In(0)), "in MUST be assignable to value") assert.True(fType.In(1) == reflectTypeError, "f MUST take err") } else if numIn == 1 { takeError = (fType.In(0) == reflectTypeError) takeValue = !takeError if takeValue { assert.True(in.AssignableTo(fType.In(0)), "in MUST be assignable to value") } else { assert.True(fType.In(0) == reflectTypeError, "f MUST take err") } } else if numIn == 0 { takeValue, takeError = false, false } // Validate outputs - this is in lieu of static type checking from generics. assert.True(fType.NumOut() <= 2, "f MUST return val, (val, err), or async") returnsResult := false if numOut := fType.NumOut(); numOut == 2 { assert.True(fType.Out(0).AssignableTo(out), "value MUST be assignable to out") assert.True(fType.Out(1) == reflectTypeError, "err MUST be error") } else if numOut == 1 { if fType.Out(0).Implements(reflectTypeAwaitableT) { returnsResult = true assert.True(fType.Out(0) == outR, "result MUST be ResultT") } else if fType.Out(0) == reflectTypeError { assert.True(out == reflectTypeInterface, "func() error ONLY allowed on void results") } else { assert.True(fType.Out(0).AssignableTo(out), "value MUST be assignable to out") } } else { assert.True(out == reflectTypeInterface, "func() ONLY allowed on void results") } // If this result is already forwarded then just forward the When as well. if s.next != nil { return s.getShortest().WhenT(in, out, outR, f) } // Create a new turn that will run once the result is resolved. outer := newTurnResolver(s.manager) turn := NewTurn("When"+s.manager.NewID().String(), func() { // Find the resolved value. final := s.getShortest() assert.True(final.isResolved(), "When's shouldn't run if the target is not resolved.") // Distinguish the error from the value. value := final.outcome err, isError := final.outcome.(error) if isError { value = nil } // If f doesn't take an error but the previous computation failed, then just flow it through to // the output by failing immediately. This allows for null-style error propagation which // simplifies handlers since that is a very common case. f is NEVER called in this case under // the assumption that its first line would be: if err != nil { return err }. if !takeError { if err != nil { outer.Fail(err) return } } // Convert the arguments into an array of Values args := make([]reflect.Value, 0, 2) if takeValue { if value == nil { args = append(args, reflect.New(in).Elem()) } else { args = append(args, reflect.ValueOf(value)) } } if takeError { if err == nil { args = append(args, reflect.New(reflectTypeError).Elem()) } else { args = append(args, reflect.ValueOf(err)) } } // Dispatch the result to the WhenFunc. retvals := reflect.ValueOf(f).Call(args) // Resolve the outer result. if returnsResult { outer.Forward(retvals[0].Interface().(async.AwaitableT).Base()) return } if numRets := len(retvals); numRets == 2 { if err, _ = retvals[1].Interface().(error); err != nil { outer.resolve(err) } else { outer.resolve(retvals[0].Interface()) } } else if numRets == 1 { outer.resolve(retvals[0].Interface()) } else { outer.resolve(nil) } }) s.queue(turn) return async.NewResultT(outer) }
func isStorageType(typ reflect.Type) bool { return typ == storageType || typ.AssignableTo(storageType) }
func AdaptToValue(fr *Frame, a T, ty R.Type) R.Value { switch ty.Kind() { case R.Bool: var tmp bool = a.Bool() return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Int: var tmp int = int(a.Int()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Int8: var tmp int8 = int8(a.Int()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Int16: var tmp int16 = int16(a.Int()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Int32: var tmp int32 = int32(a.Int()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Int64: var tmp int64 = a.Int() return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Uint: var tmp uint = uint(a.Uint()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Uint8: var tmp uint8 = uint8(a.Uint()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Uint16: var tmp uint16 = uint16(a.Uint()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Uint32: var tmp uint32 = uint32(a.Uint()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Uint64: var tmp uint64 = a.Uint() return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Uintptr: var tmp uintptr = uintptr(a.Uint()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Float32: var tmp float32 = float32(a.Float()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Float64: var tmp float64 = a.Float() return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() case R.Complex64: case R.Complex128: case R.Array: case R.Chan: if a.IsEmpty() { log.Printf("AdaptToValue: Nil for Chan (%s), due to IsEmpty.", ty) return R.Zero(ty) } case R.Func: if a.IsEmpty() { log.Printf("AdaptToValue: Nil for Func (%s), due to IsEmpty.", ty) return R.Zero(ty) } v := R.ValueOf(a) if v.Kind() == R.Func { return v } case R.Interface: if a.IsEmpty() { log.Printf("AdaptToValue: Nil for Interface (%s), due to IsEmpty.", ty) return R.Zero(ty) } // Very special case of T: Return arg as a Value. if ty == TypeT { // TODO: why doesn't this work? return R.ValueOf(a) } if ty.AssignableTo(TypeT) { // TODO: why doesn't this work? return R.ValueOf(a) } if ty.String() == "chirp.T" { // TODO: This is fragile & lame, but it works. return R.ValueOf(a) } case R.Map: case R.Ptr: if a.IsEmpty() { log.Printf("AdaptToValue: Nil for Ptr (%s), due to IsEmpty.", ty) return R.Zero(ty) } // Very special case of *Frame: framePtrValue := R.ValueOf(fr) framePtrType := framePtrValue.Type() if ty == framePtrType { return framePtrValue } case R.Slice: raw := a.Raw() val := R.ValueOf(raw) switch ty.Elem().Kind() { case R.Uint8: var tmp []byte = make([]byte, val.Len()) copy(tmp, val.String()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() } case R.String: raw := a.Raw() val := R.ValueOf(raw) switch val.Kind() { case R.Slice: switch val.Elem().Kind() { case R.Uint8: var tmp string = string(val.Bytes()) return R.NewAt(ty, unsafe.Pointer(&tmp)).Elem() } } case R.Struct: case R.UnsafePointer: } // We haven't checked this is correct; // cmdCall will reject it, if it won't work. // But maybe we can do better, so log it. if Debug['r'] { log.Printf("AdaptToValue: Default: for type <%s>: %s", ty, Show(a)) } return R.ValueOf(a.Raw()) }
// Determine if type from is assignable to type to. From and To must not be ConstTypes func typeAssignableTo(from, to reflect.Type) bool { return from.AssignableTo(unhackType(to)) }