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  }