github.com/klaytn/klaytn@v1.12.1/rlp/rlpgen/types.go (about)

     1  // Copyright 2022 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  	"go/types"
    22  	"reflect"
    23  )
    24  
    25  // typeReflectKind gives the reflect.Kind that represents typ.
    26  func typeReflectKind(typ types.Type) reflect.Kind {
    27  	switch typ := typ.(type) {
    28  	case *types.Basic:
    29  		k := typ.Kind()
    30  		if k >= types.Bool && k <= types.Complex128 {
    31  			// value order matches for Bool..Complex128
    32  			return reflect.Bool + reflect.Kind(k-types.Bool)
    33  		}
    34  		if k == types.String {
    35  			return reflect.String
    36  		}
    37  		if k == types.UnsafePointer {
    38  			return reflect.UnsafePointer
    39  		}
    40  		panic(fmt.Errorf("unhandled BasicKind %v", k))
    41  	case *types.Array:
    42  		return reflect.Array
    43  	case *types.Chan:
    44  		return reflect.Chan
    45  	case *types.Interface:
    46  		return reflect.Interface
    47  	case *types.Map:
    48  		return reflect.Map
    49  	case *types.Pointer:
    50  		return reflect.Ptr
    51  	case *types.Signature:
    52  		return reflect.Func
    53  	case *types.Slice:
    54  		return reflect.Slice
    55  	case *types.Struct:
    56  		return reflect.Struct
    57  	default:
    58  		panic(fmt.Errorf("unhandled type %T", typ))
    59  	}
    60  }
    61  
    62  // nonZeroCheck returns the expression that checks whether 'v' is a non-zero value of type 'vtyp'.
    63  func nonZeroCheck(v string, vtyp types.Type, qualify types.Qualifier) string {
    64  	// Resolve type name.
    65  	typ := resolveUnderlying(vtyp)
    66  	switch typ := typ.(type) {
    67  	case *types.Basic:
    68  		k := typ.Kind()
    69  		switch {
    70  		case k == types.Bool:
    71  			return v
    72  		case k >= types.Uint && k <= types.Complex128:
    73  			return fmt.Sprintf("%s != 0", v)
    74  		case k == types.String:
    75  			return fmt.Sprintf(`%s != ""`, v)
    76  		default:
    77  			panic(fmt.Errorf("unhandled BasicKind %v", k))
    78  		}
    79  	case *types.Array, *types.Struct:
    80  		return fmt.Sprintf("%s != (%s{})", v, types.TypeString(vtyp, qualify))
    81  	case *types.Interface, *types.Pointer, *types.Signature:
    82  		return fmt.Sprintf("%s != nil", v)
    83  	case *types.Slice, *types.Map:
    84  		return fmt.Sprintf("len(%s) > 0", v)
    85  	default:
    86  		panic(fmt.Errorf("unhandled type %T", typ))
    87  	}
    88  }
    89  
    90  // isBigInt checks whether 'typ' is "math/big".Int.
    91  func isBigInt(typ types.Type) bool {
    92  	named, ok := typ.(*types.Named)
    93  	if !ok {
    94  		return false
    95  	}
    96  	name := named.Obj()
    97  	return name.Pkg().Path() == "math/big" && name.Name() == "Int"
    98  }
    99  
   100  // isByte checks whether the underlying type of 'typ' is uint8.
   101  func isByte(typ types.Type) bool {
   102  	basic, ok := resolveUnderlying(typ).(*types.Basic)
   103  	return ok && basic.Kind() == types.Uint8
   104  }
   105  
   106  func resolveUnderlying(typ types.Type) types.Type {
   107  	for {
   108  		t := typ.Underlying()
   109  		if t == typ {
   110  			return t
   111  		}
   112  		typ = t
   113  	}
   114  }