github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/compiler/types.go (about) 1 package compiler 2 3 import ( 4 "go/ast" 5 "go/types" 6 7 "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" 8 ) 9 10 func (c *codegen) typeAndValueOf(e ast.Expr) types.TypeAndValue { 11 for i := len(c.pkgInfoInline) - 1; i >= 0; i-- { 12 if tv, ok := c.pkgInfoInline[i].TypesInfo.Types[e]; ok { 13 return tv 14 } 15 } 16 17 if tv, ok := c.typeInfo.Types[e]; ok { 18 return tv 19 } 20 21 se, ok := e.(*ast.SelectorExpr) 22 if ok { 23 if tv, ok := c.typeInfo.Selections[se]; ok { 24 return types.TypeAndValue{Type: tv.Type()} 25 } 26 } 27 return types.TypeAndValue{} 28 } 29 30 func (c *codegen) typeOf(e ast.Expr) types.Type { 31 for i := len(c.pkgInfoInline) - 1; i >= 0; i-- { 32 if typ := c.pkgInfoInline[i].TypesInfo.TypeOf(e); typ != nil { 33 return typ 34 } 35 } 36 for _, p := range c.packageCache { 37 typ := p.TypesInfo.TypeOf(e) 38 if typ != nil { 39 return typ 40 } 41 } 42 return nil 43 } 44 45 func isBasicTypeOfKind(typ types.Type, ks ...types.BasicKind) bool { 46 if t, ok := typ.Underlying().(*types.Basic); ok { 47 k := t.Kind() 48 for i := range ks { 49 if k == ks[i] { 50 return true 51 } 52 } 53 } 54 return false 55 } 56 57 func isMap(typ types.Type) bool { 58 _, ok := typ.Underlying().(*types.Map) 59 return ok 60 } 61 62 func isByte(typ types.Type) bool { 63 return isBasicTypeOfKind(typ, types.Uint8, types.Int8) 64 } 65 66 func isBool(typ types.Type) bool { 67 return isBasicTypeOfKind(typ, types.Bool, types.UntypedBool) 68 } 69 70 func isNumber(typ types.Type) bool { 71 t, ok := typ.Underlying().(*types.Basic) 72 return ok && t.Info()&types.IsNumeric != 0 73 } 74 75 func isString(typ types.Type) bool { 76 return isBasicTypeOfKind(typ, types.String) 77 } 78 79 func isCompoundSlice(typ types.Type) bool { 80 t, ok := typ.Underlying().(*types.Slice) 81 return ok && !isByte(t.Elem()) 82 } 83 84 func isByteSlice(typ types.Type) bool { 85 t, ok := typ.Underlying().(*types.Slice) 86 return ok && isByte(t.Elem()) 87 } 88 89 func toNeoType(typ types.Type) stackitem.Type { 90 if typ == nil { 91 return stackitem.AnyT 92 } 93 switch t := typ.Underlying().(type) { 94 case *types.Basic: 95 info := t.Info() 96 switch { 97 case info&types.IsInteger != 0: 98 return stackitem.IntegerT 99 case info&types.IsBoolean != 0: 100 return stackitem.BooleanT 101 case info&types.IsString != 0: 102 return stackitem.ByteArrayT 103 default: 104 return stackitem.AnyT 105 } 106 case *types.Map: 107 return stackitem.MapT 108 case *types.Struct: 109 return stackitem.StructT 110 case *types.Slice: 111 if isByte(t.Elem()) { 112 return stackitem.BufferT 113 } 114 return stackitem.ArrayT 115 default: 116 return stackitem.AnyT 117 } 118 }