github.com/codysnider/go-ethereum@v1.10.18-0.20220420071915-14f4ae99222a/rlp/rlpgen/types.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "go/types" 6 "reflect" 7 ) 8 9 // typeReflectKind gives the reflect.Kind that represents typ. 10 func typeReflectKind(typ types.Type) reflect.Kind { 11 switch typ := typ.(type) { 12 case *types.Basic: 13 k := typ.Kind() 14 if k >= types.Bool && k <= types.Complex128 { 15 // value order matches for Bool..Complex128 16 return reflect.Bool + reflect.Kind(k-types.Bool) 17 } 18 if k == types.String { 19 return reflect.String 20 } 21 if k == types.UnsafePointer { 22 return reflect.UnsafePointer 23 } 24 panic(fmt.Errorf("unhandled BasicKind %v", k)) 25 case *types.Array: 26 return reflect.Array 27 case *types.Chan: 28 return reflect.Chan 29 case *types.Interface: 30 return reflect.Interface 31 case *types.Map: 32 return reflect.Map 33 case *types.Pointer: 34 return reflect.Ptr 35 case *types.Signature: 36 return reflect.Func 37 case *types.Slice: 38 return reflect.Slice 39 case *types.Struct: 40 return reflect.Struct 41 default: 42 panic(fmt.Errorf("unhandled type %T", typ)) 43 } 44 } 45 46 // nonZeroCheck returns the expression that checks whether 'v' is a non-zero value of type 'vtyp'. 47 func nonZeroCheck(v string, vtyp types.Type, qualify types.Qualifier) string { 48 // Resolve type name. 49 typ := resolveUnderlying(vtyp) 50 switch typ := typ.(type) { 51 case *types.Basic: 52 k := typ.Kind() 53 switch { 54 case k == types.Bool: 55 return v 56 case k >= types.Uint && k <= types.Complex128: 57 return fmt.Sprintf("%s != 0", v) 58 case k == types.String: 59 return fmt.Sprintf(`%s != ""`, v) 60 default: 61 panic(fmt.Errorf("unhandled BasicKind %v", k)) 62 } 63 case *types.Array, *types.Struct: 64 return fmt.Sprintf("%s != (%s{})", v, types.TypeString(vtyp, qualify)) 65 case *types.Interface, *types.Pointer, *types.Signature: 66 return fmt.Sprintf("%s != nil", v) 67 case *types.Slice, *types.Map: 68 return fmt.Sprintf("len(%s) > 0", v) 69 default: 70 panic(fmt.Errorf("unhandled type %T", typ)) 71 } 72 } 73 74 // isBigInt checks whether 'typ' is "math/big".Int. 75 func isBigInt(typ types.Type) bool { 76 named, ok := typ.(*types.Named) 77 if !ok { 78 return false 79 } 80 name := named.Obj() 81 return name.Pkg().Path() == "math/big" && name.Name() == "Int" 82 } 83 84 // isByte checks whether the underlying type of 'typ' is uint8. 85 func isByte(typ types.Type) bool { 86 basic, ok := resolveUnderlying(typ).(*types.Basic) 87 return ok && basic.Kind() == types.Uint8 88 } 89 90 func resolveUnderlying(typ types.Type) types.Type { 91 for { 92 t := typ.Underlying() 93 if t == typ { 94 return t 95 } 96 typ = t 97 } 98 }