github.com/switchupcb/yaegi@v0.10.2/interp/type.go (about)

     1  package interp
     2  
     3  import (
     4  	"fmt"
     5  	"go/constant"
     6  	"path/filepath"
     7  	"reflect"
     8  	"strconv"
     9  	"sync"
    10  
    11  	"github.com/switchupcb/yaegi/internal/unsafe2"
    12  )
    13  
    14  // tcat defines interpreter type categories.
    15  type tcat uint
    16  
    17  // Types for go language.
    18  const (
    19  	nilT tcat = iota
    20  	aliasT
    21  	arrayT
    22  	binT
    23  	binPkgT
    24  	boolT
    25  	builtinT
    26  	chanT
    27  	chanSendT
    28  	chanRecvT
    29  	complex64T
    30  	complex128T
    31  	errorT
    32  	float32T
    33  	float64T
    34  	funcT
    35  	interfaceT
    36  	intT
    37  	int8T
    38  	int16T
    39  	int32T
    40  	int64T
    41  	mapT
    42  	ptrT
    43  	sliceT
    44  	srcPkgT
    45  	stringT
    46  	structT
    47  	uintT
    48  	uint8T
    49  	uint16T
    50  	uint32T
    51  	uint64T
    52  	uintptrT
    53  	valueT
    54  	variadicT
    55  	maxT
    56  )
    57  
    58  var cats = [...]string{
    59  	nilT:        "nilT",
    60  	aliasT:      "aliasT",
    61  	arrayT:      "arrayT",
    62  	binT:        "binT",
    63  	binPkgT:     "binPkgT",
    64  	boolT:       "boolT",
    65  	builtinT:    "builtinT",
    66  	chanT:       "chanT",
    67  	complex64T:  "complex64T",
    68  	complex128T: "complex128T",
    69  	errorT:      "errorT",
    70  	float32T:    "float32",
    71  	float64T:    "float64T",
    72  	funcT:       "funcT",
    73  	interfaceT:  "interfaceT",
    74  	intT:        "intT",
    75  	int8T:       "int8T",
    76  	int16T:      "int16T",
    77  	int32T:      "int32T",
    78  	int64T:      "int64T",
    79  	mapT:        "mapT",
    80  	ptrT:        "ptrT",
    81  	sliceT:      "sliceT",
    82  	srcPkgT:     "srcPkgT",
    83  	stringT:     "stringT",
    84  	structT:     "structT",
    85  	uintT:       "uintT",
    86  	uint8T:      "uint8T",
    87  	uint16T:     "uint16T",
    88  	uint32T:     "uint32T",
    89  	uint64T:     "uint64T",
    90  	uintptrT:    "uintptrT",
    91  	valueT:      "valueT",
    92  	variadicT:   "variadicT",
    93  }
    94  
    95  func (c tcat) String() string {
    96  	if c < tcat(len(cats)) {
    97  		return cats[c]
    98  	}
    99  	return "Cat(" + strconv.Itoa(int(c)) + ")"
   100  }
   101  
   102  // structField type defines a field in a struct.
   103  type structField struct {
   104  	name  string
   105  	tag   string
   106  	embed bool
   107  	typ   *itype
   108  }
   109  
   110  // itype defines the internal representation of types in the interpreter.
   111  type itype struct {
   112  	mu          *sync.Mutex
   113  	cat         tcat          // Type category
   114  	field       []structField // Array of struct fields if structT or interfaceT
   115  	key         *itype        // Type of key element if MapT or nil
   116  	val         *itype        // Type of value element if chanT, chanSendT, chanRecvT, mapT, ptrT, aliasT, arrayT, sliceT or variadicT
   117  	recv        *itype        // Receiver type for funcT or nil
   118  	arg         []*itype      // Argument types if funcT or nil
   119  	ret         []*itype      // Return types if funcT or nil
   120  	ptr         *itype        // Pointer to this type. Might be nil
   121  	method      []*node       // Associated methods or nil
   122  	name        string        // name of type within its package for a defined type
   123  	path        string        // for a defined type, the package import path
   124  	length      int           // length of array if ArrayT
   125  	rtype       reflect.Type  // Reflection type if ValueT, or nil
   126  	node        *node         // root AST node of type definition
   127  	scope       *scope        // type declaration scope (in case of re-parse incomplete type)
   128  	str         string        // String representation of the type
   129  	incomplete  bool          // true if type must be parsed again (out of order declarations)
   130  	untyped     bool          // true for a literal value (string or number)
   131  	isBinMethod bool          // true if the type refers to a bin method function
   132  }
   133  
   134  func untypedBool() *itype {
   135  	return &itype{cat: boolT, name: "bool", untyped: true, str: "untyped bool"}
   136  }
   137  
   138  func untypedString() *itype {
   139  	return &itype{cat: stringT, name: "string", untyped: true, str: "untyped string"}
   140  }
   141  
   142  func untypedRune() *itype {
   143  	return &itype{cat: int32T, name: "int32", untyped: true, str: "untyped rune"}
   144  }
   145  
   146  func untypedInt() *itype {
   147  	return &itype{cat: intT, name: "int", untyped: true, str: "untyped int"}
   148  }
   149  
   150  func untypedFloat() *itype {
   151  	return &itype{cat: float64T, name: "float64", untyped: true, str: "untyped float"}
   152  }
   153  
   154  func untypedComplex() *itype {
   155  	return &itype{cat: complex128T, name: "complex128", untyped: true, str: "untyped complex"}
   156  }
   157  
   158  func errorMethodType(sc *scope) *itype {
   159  	return &itype{cat: funcT, ret: []*itype{sc.getType("string")}, str: "func() string"}
   160  }
   161  
   162  type itypeOption func(*itype)
   163  
   164  func isBinMethod() itypeOption {
   165  	return func(t *itype) {
   166  		t.isBinMethod = true
   167  	}
   168  }
   169  
   170  func withRecv(typ *itype) itypeOption {
   171  	return func(t *itype) {
   172  		t.recv = typ
   173  	}
   174  }
   175  
   176  func withNode(n *node) itypeOption {
   177  	return func(t *itype) {
   178  		t.node = n
   179  	}
   180  }
   181  
   182  func withScope(sc *scope) itypeOption {
   183  	return func(t *itype) {
   184  		t.scope = sc
   185  	}
   186  }
   187  
   188  func withUntyped(b bool) itypeOption {
   189  	return func(t *itype) {
   190  		t.untyped = b
   191  	}
   192  }
   193  
   194  // valueTOf returns a valueT itype.
   195  func valueTOf(rtype reflect.Type, opts ...itypeOption) *itype {
   196  	t := &itype{cat: valueT, rtype: rtype, str: rtype.String()}
   197  	for _, opt := range opts {
   198  		opt(t)
   199  	}
   200  	if t.untyped {
   201  		t.str = "untyped " + t.str
   202  	}
   203  	return t
   204  }
   205  
   206  // wrapperValueTOf returns a valueT itype wrapping an itype.
   207  func wrapperValueTOf(rtype reflect.Type, val *itype, opts ...itypeOption) *itype {
   208  	t := &itype{cat: valueT, rtype: rtype, val: val, str: rtype.String()}
   209  	for _, opt := range opts {
   210  		opt(t)
   211  	}
   212  	return t
   213  }
   214  
   215  func variadicOf(val *itype, opts ...itypeOption) *itype {
   216  	t := &itype{cat: variadicT, val: val, str: "..." + val.str}
   217  	for _, opt := range opts {
   218  		opt(t)
   219  	}
   220  	return t
   221  }
   222  
   223  // ptrOf returns a pointer to t.
   224  func ptrOf(val *itype, opts ...itypeOption) *itype {
   225  	if val.ptr != nil {
   226  		return val.ptr
   227  	}
   228  	t := &itype{cat: ptrT, val: val, str: "*" + val.str}
   229  	for _, opt := range opts {
   230  		opt(t)
   231  	}
   232  	val.ptr = t
   233  	return t
   234  }
   235  
   236  // namedOf returns a named type of val.
   237  func namedOf(val *itype, path, name string, opts ...itypeOption) *itype {
   238  	str := name
   239  	if path != "" {
   240  		str = path + "." + name
   241  	}
   242  	for val.cat == aliasT {
   243  		val = val.val
   244  	}
   245  	t := &itype{cat: aliasT, val: val, path: path, name: name, str: str}
   246  	for _, opt := range opts {
   247  		opt(t)
   248  	}
   249  	return t
   250  }
   251  
   252  // funcOf returns a function type with the given args and returns.
   253  func funcOf(args []*itype, ret []*itype, opts ...itypeOption) *itype {
   254  	b := []byte{}
   255  	b = append(b, "func("...)
   256  	b = append(b, paramsTypeString(args)...)
   257  	b = append(b, ')')
   258  	if len(ret) != 0 {
   259  		b = append(b, ' ')
   260  		if len(ret) > 1 {
   261  			b = append(b, '(')
   262  		}
   263  		b = append(b, paramsTypeString(ret)...)
   264  		if len(ret) > 1 {
   265  			b = append(b, ')')
   266  		}
   267  	}
   268  
   269  	t := &itype{cat: funcT, arg: args, ret: ret, str: string(b)}
   270  	for _, opt := range opts {
   271  		opt(t)
   272  	}
   273  	return t
   274  }
   275  
   276  type chanDir uint8
   277  
   278  const (
   279  	chanSendRecv chanDir = iota
   280  	chanSend
   281  	chanRecv
   282  )
   283  
   284  // chanOf returns a channel of the underlying type val.
   285  func chanOf(val *itype, dir chanDir, opts ...itypeOption) *itype {
   286  	cat := chanT
   287  	str := "chan "
   288  	switch dir {
   289  	case chanSend:
   290  		cat = chanSendT
   291  		str = "chan<- "
   292  	case chanRecv:
   293  		cat = chanRecvT
   294  		str = "<-chan "
   295  	}
   296  	t := &itype{cat: cat, val: val, str: str + val.str}
   297  	for _, opt := range opts {
   298  		opt(t)
   299  	}
   300  	return t
   301  }
   302  
   303  // arrayOf returns am array type of the underlying val with the given length.
   304  func arrayOf(val *itype, l int, opts ...itypeOption) *itype {
   305  	lstr := strconv.Itoa(l)
   306  	t := &itype{cat: arrayT, val: val, length: l, str: "[" + lstr + "]" + val.str}
   307  	for _, opt := range opts {
   308  		opt(t)
   309  	}
   310  	return t
   311  }
   312  
   313  // sliceOf returns a slice type of the underlying val.
   314  func sliceOf(val *itype, opts ...itypeOption) *itype {
   315  	t := &itype{cat: sliceT, val: val, str: "[]" + val.str}
   316  	for _, opt := range opts {
   317  		opt(t)
   318  	}
   319  	return t
   320  }
   321  
   322  // mapOf returns a map type of the underlying key and val.
   323  func mapOf(key, val *itype, opts ...itypeOption) *itype {
   324  	t := &itype{cat: mapT, key: key, val: val, str: "map[" + key.str + "]" + val.str}
   325  	for _, opt := range opts {
   326  		opt(t)
   327  	}
   328  	return t
   329  }
   330  
   331  // interfaceOf returns an interface type with the given fields.
   332  func interfaceOf(t *itype, fields []structField, opts ...itypeOption) *itype {
   333  	str := "interface{}"
   334  	if len(fields) > 0 {
   335  		str = "interface { " + methodsTypeString(fields) + "}"
   336  	}
   337  	if t == nil {
   338  		t = &itype{}
   339  	}
   340  	t.cat = interfaceT
   341  	t.field = fields
   342  	t.str = str
   343  	for _, opt := range opts {
   344  		opt(t)
   345  	}
   346  	return t
   347  }
   348  
   349  // structOf returns a struct type with the given fields.
   350  func structOf(t *itype, fields []structField, opts ...itypeOption) *itype {
   351  	str := "struct {}"
   352  	if len(fields) > 0 {
   353  		str = "struct { " + fieldsTypeString(fields) + "}"
   354  	}
   355  	if t == nil {
   356  		t = &itype{}
   357  	}
   358  	t.cat = structT
   359  	t.field = fields
   360  	t.str = str
   361  	for _, opt := range opts {
   362  		opt(t)
   363  	}
   364  	return t
   365  }
   366  
   367  // seenNode determines if a node has been seen.
   368  //
   369  // seenNode treats the slice of nodes as the path traveled down a node
   370  // tree.
   371  func seenNode(ns []*node, n *node) bool {
   372  	for _, nn := range ns {
   373  		if nn == n {
   374  			return true
   375  		}
   376  	}
   377  	return false
   378  }
   379  
   380  // nodeType returns a type definition for the corresponding AST subtree.
   381  func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
   382  	return nodeType2(interp, sc, n, nil)
   383  }
   384  
   385  func nodeType2(interp *Interpreter, sc *scope, n *node, seen []*node) (t *itype, err error) {
   386  	if n.typ != nil && !n.typ.incomplete {
   387  		return n.typ, nil
   388  	}
   389  	if sname := typeName(n); sname != "" {
   390  		sym, _, found := sc.lookup(sname)
   391  		if found && sym.kind == typeSym && sym.typ != nil {
   392  			if sym.typ.isComplete() {
   393  				return sym.typ, nil
   394  			}
   395  			if seenNode(seen, n) {
   396  				// We have seen this node in our tree, so it must be recursive.
   397  				sym.typ.incomplete = false
   398  				return sym.typ, nil
   399  			}
   400  		}
   401  	}
   402  	seen = append(seen, n)
   403  	defer func() { seen = seen[:len(seen)-1] }()
   404  
   405  	switch n.kind {
   406  	case addressExpr, starExpr:
   407  		val, err := nodeType2(interp, sc, n.child[0], seen)
   408  		if err != nil {
   409  			return nil, err
   410  		}
   411  		t = ptrOf(val, withNode(n), withScope(sc))
   412  		t.incomplete = val.incomplete
   413  
   414  	case arrayType:
   415  		c0 := n.child[0]
   416  		if len(n.child) == 1 {
   417  			val, err := nodeType2(interp, sc, c0, seen)
   418  			if err != nil {
   419  				return nil, err
   420  			}
   421  			t = sliceOf(val, withNode(n), withScope(sc))
   422  			t.incomplete = val.incomplete
   423  			break
   424  		}
   425  		// Array size is defined.
   426  		var (
   427  			length     int
   428  			incomplete bool
   429  		)
   430  		switch v := c0.rval; {
   431  		case v.IsValid():
   432  			// Size if defined by a constant litteral value.
   433  			if isConstantValue(v.Type()) {
   434  				c := v.Interface().(constant.Value)
   435  				length = constToInt(c)
   436  			} else {
   437  				length = int(v.Int())
   438  			}
   439  		case c0.kind == ellipsisExpr:
   440  			// [...]T expression, get size from the length of composite array.
   441  			length, err = arrayTypeLen(n.anc, sc)
   442  			if err != nil {
   443  				incomplete = true
   444  			}
   445  		case c0.kind == identExpr:
   446  			sym, _, ok := sc.lookup(c0.ident)
   447  			if !ok {
   448  				incomplete = true
   449  				break
   450  			}
   451  			// Size is defined by a symbol which must be a constant integer.
   452  			if sym.kind != constSym {
   453  				return nil, c0.cfgErrorf("non-constant array bound %q", c0.ident)
   454  			}
   455  			if sym.typ == nil || !isInt(sym.typ.TypeOf()) || !sym.rval.IsValid() {
   456  				incomplete = true
   457  				break
   458  			}
   459  			length = int(vInt(sym.rval))
   460  		default:
   461  			// Size is defined by a numeric constant expression.
   462  			if _, err = interp.cfg(c0, sc, sc.pkgID, sc.pkgName); err != nil {
   463  				return nil, err
   464  			}
   465  			v, ok := c0.rval.Interface().(constant.Value)
   466  			if !ok {
   467  				incomplete = true
   468  				break
   469  			}
   470  			length = constToInt(v)
   471  		}
   472  		val, err := nodeType2(interp, sc, n.child[1], seen)
   473  		if err != nil {
   474  			return nil, err
   475  		}
   476  		t = arrayOf(val, length, withNode(n), withScope(sc))
   477  		t.incomplete = incomplete || val.incomplete
   478  
   479  	case basicLit:
   480  		switch v := n.rval.Interface().(type) {
   481  		case bool:
   482  			n.rval = reflect.ValueOf(constant.MakeBool(v))
   483  			t = untypedBool()
   484  		case rune:
   485  			// It is impossible to work out rune const literals in AST
   486  			// with the correct type so we must make the const type here.
   487  			n.rval = reflect.ValueOf(constant.MakeInt64(int64(v)))
   488  			t = untypedRune()
   489  		case constant.Value:
   490  			switch v.Kind() {
   491  			case constant.Bool:
   492  				t = untypedBool()
   493  			case constant.String:
   494  				t = untypedString()
   495  			case constant.Int:
   496  				t = untypedInt()
   497  			case constant.Float:
   498  				t = untypedFloat()
   499  			case constant.Complex:
   500  				t = untypedComplex()
   501  			default:
   502  				err = n.cfgErrorf("missing support for type %v", n.rval)
   503  			}
   504  		default:
   505  			err = n.cfgErrorf("missing support for type %T: %v", v, n.rval)
   506  		}
   507  
   508  	case unaryExpr:
   509  		t, err = nodeType2(interp, sc, n.child[0], seen)
   510  
   511  	case binaryExpr:
   512  		// Get type of first operand.
   513  		if t, err = nodeType2(interp, sc, n.child[0], seen); err != nil {
   514  			return nil, err
   515  		}
   516  		// For operators other than shift, get the type from the 2nd operand if the first is untyped.
   517  		if t.untyped && !isShiftNode(n) {
   518  			var t1 *itype
   519  			t1, err = nodeType2(interp, sc, n.child[1], seen)
   520  			if !(t1.untyped && isInt(t1.TypeOf()) && isFloat(t.TypeOf())) {
   521  				t = t1
   522  			}
   523  		}
   524  
   525  		// If the node is to be assigned or returned, the node type is the destination type.
   526  		dt := t
   527  
   528  		switch a := n.anc; {
   529  		case a.kind == assignStmt && isEmptyInterface(a.child[0].typ):
   530  			// Because an empty interface concrete type "mutates" as different values are
   531  			// assigned to it, we need to make a new itype from scratch everytime a new
   532  			// assignment is made, and not let different nodes (of the same variable) share the
   533  			// same itype. Otherwise they would overwrite each other.
   534  			a.child[0].typ = &itype{cat: interfaceT, val: dt, str: "interface{}"}
   535  
   536  		case a.kind == defineStmt && len(a.child) > a.nleft+a.nright:
   537  			if dt, err = nodeType2(interp, sc, a.child[a.nleft], seen); err != nil {
   538  				return nil, err
   539  			}
   540  
   541  		case a.kind == returnStmt:
   542  			dt = sc.def.typ.ret[childPos(n)]
   543  		}
   544  
   545  		if isInterfaceSrc(dt) {
   546  			dt.val = t
   547  		}
   548  		t = dt
   549  
   550  	case callExpr:
   551  		if isBuiltinCall(n, sc) {
   552  			// Builtin types are special and may depend from their input arguments.
   553  			switch n.child[0].ident {
   554  			case bltnComplex:
   555  				var nt0, nt1 *itype
   556  				if nt0, err = nodeType2(interp, sc, n.child[1], seen); err != nil {
   557  					return nil, err
   558  				}
   559  				if nt1, err = nodeType2(interp, sc, n.child[2], seen); err != nil {
   560  					return nil, err
   561  				}
   562  				if nt0.incomplete || nt1.incomplete {
   563  					t.incomplete = true
   564  				} else {
   565  					switch t0, t1 := nt0.TypeOf(), nt1.TypeOf(); {
   566  					case isFloat32(t0) && isFloat32(t1):
   567  						t = sc.getType("complex64")
   568  					case isFloat64(t0) && isFloat64(t1):
   569  						t = sc.getType("complex128")
   570  					case nt0.untyped && isNumber(t0) && nt1.untyped && isNumber(t1):
   571  						t = untypedComplex()
   572  					case nt0.untyped && isFloat32(t1) || nt1.untyped && isFloat32(t0):
   573  						t = sc.getType("complex64")
   574  					case nt0.untyped && isFloat64(t1) || nt1.untyped && isFloat64(t0):
   575  						t = sc.getType("complex128")
   576  					default:
   577  						err = n.cfgErrorf("invalid types %s and %s", t0.Kind(), t1.Kind())
   578  					}
   579  					if nt0.untyped && nt1.untyped {
   580  						t = untypedComplex()
   581  					}
   582  				}
   583  			case bltnReal, bltnImag:
   584  				if t, err = nodeType2(interp, sc, n.child[1], seen); err != nil {
   585  					return nil, err
   586  				}
   587  				if !t.incomplete {
   588  					switch k := t.TypeOf().Kind(); {
   589  					case k == reflect.Complex64:
   590  						t = sc.getType("float32")
   591  					case k == reflect.Complex128:
   592  						t = sc.getType("float64")
   593  					case t.untyped && isNumber(t.TypeOf()):
   594  						t = valueTOf(floatType, withUntyped(true), withScope(sc))
   595  					default:
   596  						err = n.cfgErrorf("invalid complex type %s", k)
   597  					}
   598  				}
   599  			case bltnCap, bltnCopy, bltnLen:
   600  				t = sc.getType("int")
   601  			case bltnAppend, bltnMake:
   602  				t, err = nodeType2(interp, sc, n.child[1], seen)
   603  			case bltnNew:
   604  				t, err = nodeType2(interp, sc, n.child[1], seen)
   605  				incomplete := t.incomplete
   606  				t = ptrOf(t, withScope(sc))
   607  				t.incomplete = incomplete
   608  			case bltnRecover:
   609  				t = sc.getType("interface{}")
   610  			default:
   611  				t = &itype{cat: builtinT}
   612  			}
   613  			if err != nil {
   614  				return nil, err
   615  			}
   616  		} else {
   617  			if t, err = nodeType2(interp, sc, n.child[0], seen); err != nil || t == nil {
   618  				return nil, err
   619  			}
   620  			switch t.cat {
   621  			case valueT:
   622  				if rt := t.rtype; rt.Kind() == reflect.Func && rt.NumOut() == 1 {
   623  					t = valueTOf(rt.Out(0), withScope(sc))
   624  				}
   625  			default:
   626  				if len(t.ret) == 1 {
   627  					t = t.ret[0]
   628  				}
   629  			}
   630  		}
   631  
   632  	case compositeLitExpr:
   633  		t, err = nodeType2(interp, sc, n.child[0], seen)
   634  
   635  	case chanType, chanTypeRecv, chanTypeSend:
   636  		dir := chanSendRecv
   637  		switch n.kind {
   638  		case chanTypeRecv:
   639  			dir = chanRecv
   640  		case chanTypeSend:
   641  			dir = chanSend
   642  		}
   643  		val, err := nodeType2(interp, sc, n.child[0], seen)
   644  		if err != nil {
   645  			return nil, err
   646  		}
   647  		t = chanOf(val, dir, withNode(n), withScope(sc))
   648  		t.incomplete = val.incomplete
   649  
   650  	case ellipsisExpr:
   651  		val, err := nodeType2(interp, sc, n.child[0], seen)
   652  		if err != nil {
   653  			return nil, err
   654  		}
   655  		t = variadicOf(val, withNode(n), withScope(sc))
   656  		t.incomplete = t.val.incomplete
   657  
   658  	case funcLit:
   659  		t, err = nodeType2(interp, sc, n.child[2], seen)
   660  
   661  	case funcType:
   662  		var incomplete bool
   663  		// Handle input parameters
   664  		args := make([]*itype, 0, len(n.child[0].child))
   665  		for _, arg := range n.child[0].child {
   666  			cl := len(arg.child) - 1
   667  			typ, err := nodeType2(interp, sc, arg.child[cl], seen)
   668  			if err != nil {
   669  				return nil, err
   670  			}
   671  			args = append(args, typ)
   672  			for i := 1; i < cl; i++ {
   673  				// Several arguments may be factorized on the same field type
   674  				args = append(args, typ)
   675  			}
   676  			incomplete = incomplete || typ.incomplete
   677  		}
   678  
   679  		var rets []*itype
   680  		if len(n.child) == 2 {
   681  			// Handle returned values
   682  			for _, ret := range n.child[1].child {
   683  				cl := len(ret.child) - 1
   684  				typ, err := nodeType2(interp, sc, ret.child[cl], seen)
   685  				if err != nil {
   686  					return nil, err
   687  				}
   688  				rets = append(rets, typ)
   689  				for i := 1; i < cl; i++ {
   690  					// Several arguments may be factorized on the same field type
   691  					rets = append(rets, typ)
   692  				}
   693  				incomplete = incomplete || typ.incomplete
   694  			}
   695  		}
   696  		t = funcOf(args, rets, withNode(n), withScope(sc))
   697  		t.incomplete = incomplete
   698  
   699  	case identExpr:
   700  		sym, _, found := sc.lookup(n.ident)
   701  		if !found {
   702  			// retry with the filename, in case ident is a package name.
   703  			baseName := filepath.Base(interp.fset.Position(n.pos).Filename)
   704  			ident := filepath.Join(n.ident, baseName)
   705  			sym, _, found = sc.lookup(ident)
   706  			if !found {
   707  				t = &itype{name: n.ident, path: sc.pkgName, node: n, incomplete: true, scope: sc}
   708  				sc.sym[n.ident] = &symbol{kind: typeSym, typ: t}
   709  				break
   710  			}
   711  		}
   712  		t = sym.typ
   713  		if t.incomplete && t.cat == aliasT && t.val != nil && t.val.cat != nilT {
   714  			t.incomplete = false
   715  		}
   716  		if t.incomplete && t.node != n {
   717  			m := t.method
   718  			if t, err = nodeType2(interp, sc, t.node, seen); err != nil {
   719  				return nil, err
   720  			}
   721  			t.method = m
   722  			sym.typ = t
   723  		}
   724  		if t.node == nil {
   725  			t.node = n
   726  		}
   727  
   728  	case indexExpr:
   729  		var lt *itype
   730  		if lt, err = nodeType2(interp, sc, n.child[0], seen); err != nil {
   731  			return nil, err
   732  		}
   733  		if lt.incomplete {
   734  			t.incomplete = true
   735  			break
   736  		}
   737  		switch lt.cat {
   738  		case arrayT, mapT, sliceT, variadicT:
   739  			t = lt.val
   740  		}
   741  
   742  	case interfaceType:
   743  		if sname := typeName(n); sname != "" {
   744  			if sym, _, found := sc.lookup(sname); found && sym.kind == typeSym {
   745  				t = interfaceOf(sym.typ, sym.typ.field, withNode(n), withScope(sc))
   746  			}
   747  		}
   748  		var incomplete bool
   749  		fields := make([]structField, 0, len(n.child[0].child))
   750  		for _, field := range n.child[0].child {
   751  			f0 := field.child[0]
   752  			if len(field.child) == 1 {
   753  				if f0.ident == "error" {
   754  					// Unwrap error interface inplace rather than embedding it, because
   755  					// "error" is lower case which may cause problems with reflect for method lookup.
   756  					typ := errorMethodType(sc)
   757  					fields = append(fields, structField{name: "Error", typ: typ})
   758  					continue
   759  				}
   760  				typ, err := nodeType2(interp, sc, f0, seen)
   761  				if err != nil {
   762  					return nil, err
   763  				}
   764  				fields = append(fields, structField{name: fieldName(f0), embed: true, typ: typ})
   765  				incomplete = incomplete || typ.incomplete
   766  				continue
   767  			}
   768  			typ, err := nodeType2(interp, sc, field.child[1], seen)
   769  			if err != nil {
   770  				return nil, err
   771  			}
   772  			fields = append(fields, structField{name: f0.ident, typ: typ})
   773  			incomplete = incomplete || typ.incomplete
   774  		}
   775  		t = interfaceOf(t, fields, withNode(n), withScope(sc))
   776  		t.incomplete = incomplete
   777  
   778  	case landExpr, lorExpr:
   779  		t = sc.getType("bool")
   780  
   781  	case mapType:
   782  		key, err := nodeType2(interp, sc, n.child[0], seen)
   783  		if err != nil {
   784  			return nil, err
   785  		}
   786  		val, err := nodeType2(interp, sc, n.child[1], seen)
   787  		if err != nil {
   788  			return nil, err
   789  		}
   790  		t = mapOf(key, val, withNode(n), withScope(sc))
   791  		t.incomplete = key.incomplete || val.incomplete
   792  
   793  	case parenExpr:
   794  		t, err = nodeType2(interp, sc, n.child[0], seen)
   795  
   796  	case selectorExpr:
   797  		// Resolve the left part of selector, then lookup the right part on it
   798  		var lt *itype
   799  
   800  		// Lookup the package symbol first if we are in a field expression as
   801  		// a previous parameter has the same name as the package, we need to
   802  		// prioritize the package type.
   803  		if n.anc.kind == fieldExpr {
   804  			lt = findPackageType(interp, sc, n.child[0])
   805  		}
   806  		if lt == nil {
   807  			// No package was found or we are not in a field expression, we are looking for a variable.
   808  			if lt, err = nodeType2(interp, sc, n.child[0], seen); err != nil {
   809  				return nil, err
   810  			}
   811  		}
   812  
   813  		if lt.incomplete {
   814  			break
   815  		}
   816  		name := n.child[1].ident
   817  		switch lt.cat {
   818  		case binPkgT:
   819  			pkg := interp.binPkg[lt.path]
   820  			if v, ok := pkg[name]; ok {
   821  				rtype := v.Type()
   822  				if isBinType(v) {
   823  					// A bin type is encoded as a pointer on a typed nil value.
   824  					rtype = rtype.Elem()
   825  				}
   826  				t = valueTOf(rtype, withNode(n), withScope(sc))
   827  			} else {
   828  				err = n.cfgErrorf("undefined selector %s.%s", lt.path, name)
   829  			}
   830  		case srcPkgT:
   831  			pkg := interp.srcPkg[lt.path]
   832  			if s, ok := pkg[name]; ok {
   833  				t = s.typ
   834  			} else {
   835  				err = n.cfgErrorf("undefined selector %s.%s", lt.path, name)
   836  			}
   837  		default:
   838  			if m, _ := lt.lookupMethod(name); m != nil {
   839  				t, err = nodeType2(interp, sc, m.child[2], seen)
   840  			} else if bm, _, _, ok := lt.lookupBinMethod(name); ok {
   841  				t = valueTOf(bm.Type, isBinMethod(), withRecv(lt), withScope(sc))
   842  			} else if ti := lt.lookupField(name); len(ti) > 0 {
   843  				t = lt.fieldSeq(ti)
   844  			} else if bs, _, ok := lt.lookupBinField(name); ok {
   845  				t = valueTOf(bs.Type, withScope(sc))
   846  			} else {
   847  				err = lt.node.cfgErrorf("undefined selector %s", name)
   848  			}
   849  		}
   850  
   851  	case sliceExpr:
   852  		t, err = nodeType2(interp, sc, n.child[0], seen)
   853  		if err != nil {
   854  			return nil, err
   855  		}
   856  		if t.cat == ptrT {
   857  			t = t.val
   858  		}
   859  		if t.cat == arrayT {
   860  			incomplete := t.incomplete
   861  			t = sliceOf(t.val, withNode(n), withScope(sc))
   862  			t.incomplete = incomplete
   863  		}
   864  
   865  	case structType:
   866  		if sname := typeName(n); sname != "" {
   867  			if sym, _, found := sc.lookup(sname); found && sym.kind == typeSym {
   868  				t = structOf(sym.typ, sym.typ.field, withNode(n), withScope(sc))
   869  			}
   870  		}
   871  		var incomplete bool
   872  		fields := make([]structField, 0, len(n.child[0].child))
   873  		for _, c := range n.child[0].child {
   874  			switch {
   875  			case len(c.child) == 1:
   876  				typ, err := nodeType2(interp, sc, c.child[0], seen)
   877  				if err != nil {
   878  					return nil, err
   879  				}
   880  				fields = append(fields, structField{name: fieldName(c.child[0]), embed: true, typ: typ})
   881  				incomplete = incomplete || typ.incomplete
   882  			case len(c.child) == 2 && c.child[1].kind == basicLit:
   883  				tag := vString(c.child[1].rval)
   884  				typ, err := nodeType2(interp, sc, c.child[0], seen)
   885  				if err != nil {
   886  					return nil, err
   887  				}
   888  				fields = append(fields, structField{name: fieldName(c.child[0]), embed: true, typ: typ, tag: tag})
   889  				incomplete = incomplete || typ.incomplete
   890  			default:
   891  				var tag string
   892  				l := len(c.child)
   893  				if c.lastChild().kind == basicLit {
   894  					tag = vString(c.lastChild().rval)
   895  					l--
   896  				}
   897  				typ, err := nodeType2(interp, sc, c.child[l-1], seen)
   898  				if err != nil {
   899  					return nil, err
   900  				}
   901  				incomplete = incomplete || typ.incomplete
   902  				for _, d := range c.child[:l-1] {
   903  					fields = append(fields, structField{name: d.ident, typ: typ, tag: tag})
   904  				}
   905  			}
   906  		}
   907  		t = structOf(t, fields, withNode(n), withScope(sc))
   908  		t.incomplete = incomplete
   909  
   910  	default:
   911  		err = n.cfgErrorf("type definition not implemented: %s", n.kind)
   912  	}
   913  
   914  	if err == nil && t != nil && t.cat == nilT && !t.incomplete {
   915  		err = n.cfgErrorf("use of untyped nil %s", t.name)
   916  	}
   917  
   918  	// The existing symbol data needs to be recovered, but not in the
   919  	// case where we are aliasing another type.
   920  	if n.anc.kind == typeSpec && n.kind != selectorExpr && n.kind != identExpr {
   921  		name := n.anc.child[0].ident
   922  		if sym := sc.sym[name]; sym != nil {
   923  			t.path = sc.pkgName
   924  			t.name = name
   925  		}
   926  	}
   927  
   928  	switch {
   929  	case t == nil:
   930  	case t.name != "" && t.path != "":
   931  		t.str = t.path + "." + t.name
   932  	case t.cat == nilT:
   933  		t.str = "nil"
   934  	}
   935  
   936  	return t, err
   937  }
   938  
   939  // findPackageType searches the top level scope for a package type.
   940  func findPackageType(interp *Interpreter, sc *scope, n *node) *itype {
   941  	// Find the root scope, the package symbols will exist there.
   942  	for {
   943  		if sc.level == 0 {
   944  			break
   945  		}
   946  		sc = sc.anc
   947  	}
   948  
   949  	baseName := filepath.Base(interp.fset.Position(n.pos).Filename)
   950  	sym, _, found := sc.lookup(filepath.Join(n.ident, baseName))
   951  	if !found || sym.typ == nil && sym.typ.cat != srcPkgT && sym.typ.cat != binPkgT {
   952  		return nil
   953  	}
   954  	return sym.typ
   955  }
   956  
   957  func isBuiltinCall(n *node, sc *scope) bool {
   958  	if n.kind != callExpr {
   959  		return false
   960  	}
   961  	s := n.child[0].sym
   962  	if s == nil {
   963  		if sym, _, found := sc.lookup(n.child[0].ident); found {
   964  			s = sym
   965  		}
   966  	}
   967  	return s != nil && s.kind == bltnSym
   968  }
   969  
   970  // struct name returns the name of a struct type.
   971  func typeName(n *node) string {
   972  	if n.anc.kind == typeSpec {
   973  		return n.anc.child[0].ident
   974  	}
   975  	return ""
   976  }
   977  
   978  // fieldName returns an implicit struct field name according to node kind.
   979  func fieldName(n *node) string {
   980  	switch n.kind {
   981  	case selectorExpr:
   982  		return fieldName(n.child[1])
   983  	case starExpr:
   984  		return fieldName(n.child[0])
   985  	case identExpr:
   986  		return n.ident
   987  	default:
   988  		return ""
   989  	}
   990  }
   991  
   992  var zeroValues [maxT]reflect.Value
   993  
   994  func init() {
   995  	zeroValues[boolT] = reflect.ValueOf(false)
   996  	zeroValues[complex64T] = reflect.ValueOf(complex64(0))
   997  	zeroValues[complex128T] = reflect.ValueOf(complex128(0))
   998  	zeroValues[errorT] = reflect.ValueOf(new(error)).Elem()
   999  	zeroValues[float32T] = reflect.ValueOf(float32(0))
  1000  	zeroValues[float64T] = reflect.ValueOf(float64(0))
  1001  	zeroValues[intT] = reflect.ValueOf(int(0))
  1002  	zeroValues[int8T] = reflect.ValueOf(int8(0))
  1003  	zeroValues[int16T] = reflect.ValueOf(int16(0))
  1004  	zeroValues[int32T] = reflect.ValueOf(int32(0))
  1005  	zeroValues[int64T] = reflect.ValueOf(int64(0))
  1006  	zeroValues[stringT] = reflect.ValueOf("")
  1007  	zeroValues[uintT] = reflect.ValueOf(uint(0))
  1008  	zeroValues[uint8T] = reflect.ValueOf(uint8(0))
  1009  	zeroValues[uint16T] = reflect.ValueOf(uint16(0))
  1010  	zeroValues[uint32T] = reflect.ValueOf(uint32(0))
  1011  	zeroValues[uint64T] = reflect.ValueOf(uint64(0))
  1012  	zeroValues[uintptrT] = reflect.ValueOf(uintptr(0))
  1013  }
  1014  
  1015  // Finalize returns a type pointer and error. It reparses a type from the
  1016  // partial AST if necessary (after missing dependecy data is available).
  1017  // If error is nil, the type is guarranteed to be completely defined and
  1018  // usable for CFG.
  1019  func (t *itype) finalize() (*itype, error) {
  1020  	var err error
  1021  	if t.incomplete {
  1022  		sym, _, found := t.scope.lookup(t.name)
  1023  		if found && !sym.typ.incomplete {
  1024  			sym.typ.method = append(sym.typ.method, t.method...)
  1025  			t.method = sym.typ.method
  1026  			t.incomplete = false
  1027  			return sym.typ, nil
  1028  		}
  1029  		m := t.method
  1030  		if t, err = nodeType(t.node.interp, t.scope, t.node); err != nil {
  1031  			return nil, err
  1032  		}
  1033  		if t.incomplete {
  1034  			return nil, t.node.cfgErrorf("incomplete type %s", t.name)
  1035  		}
  1036  		t.method = m
  1037  		t.node.typ = t
  1038  		if sym != nil {
  1039  			sym.typ = t
  1040  		}
  1041  	}
  1042  	return t, err
  1043  }
  1044  
  1045  func (t *itype) addMethod(n *node) {
  1046  	for _, m := range t.method {
  1047  		if m == n {
  1048  			return
  1049  		}
  1050  	}
  1051  	t.method = append(t.method, n)
  1052  }
  1053  
  1054  func (t *itype) numIn() int {
  1055  	switch t.cat {
  1056  	case funcT:
  1057  		return len(t.arg)
  1058  	case valueT:
  1059  		if t.rtype.Kind() != reflect.Func {
  1060  			return 0
  1061  		}
  1062  		in := t.rtype.NumIn()
  1063  		if t.recv != nil {
  1064  			in--
  1065  		}
  1066  		return in
  1067  	}
  1068  	return 0
  1069  }
  1070  
  1071  func (t *itype) in(i int) *itype {
  1072  	switch t.cat {
  1073  	case funcT:
  1074  		return t.arg[i]
  1075  	case valueT:
  1076  		if t.rtype.Kind() == reflect.Func {
  1077  			if t.recv != nil && !isInterface(t.recv) {
  1078  				i++
  1079  			}
  1080  			if t.rtype.IsVariadic() && i == t.rtype.NumIn()-1 {
  1081  				val := valueTOf(t.rtype.In(i).Elem())
  1082  				return &itype{cat: variadicT, val: val, str: "..." + val.str}
  1083  			}
  1084  			return valueTOf(t.rtype.In(i))
  1085  		}
  1086  	}
  1087  	return nil
  1088  }
  1089  
  1090  func (t *itype) numOut() int {
  1091  	switch t.cat {
  1092  	case funcT:
  1093  		return len(t.ret)
  1094  	case valueT:
  1095  		if t.rtype.Kind() == reflect.Func {
  1096  			return t.rtype.NumOut()
  1097  		}
  1098  	}
  1099  	return 1
  1100  }
  1101  
  1102  func (t *itype) out(i int) *itype {
  1103  	switch t.cat {
  1104  	case funcT:
  1105  		return t.ret[i]
  1106  	case valueT:
  1107  		if t.rtype.Kind() == reflect.Func {
  1108  			return valueTOf(t.rtype.Out(i))
  1109  		}
  1110  	}
  1111  	return nil
  1112  }
  1113  
  1114  func (t *itype) concrete() *itype {
  1115  	if isInterface(t) && t.val != nil {
  1116  		return t.val.concrete()
  1117  	}
  1118  	return t
  1119  }
  1120  
  1121  // isVariadic returns true if the function type is variadic.
  1122  // If the type is not a function or is not variadic, it will
  1123  // return false.
  1124  func (t *itype) isVariadic() bool {
  1125  	switch t.cat {
  1126  	case funcT:
  1127  		return len(t.arg) > 0 && t.arg[len(t.arg)-1].cat == variadicT
  1128  	case valueT:
  1129  		if t.rtype.Kind() == reflect.Func {
  1130  			return t.rtype.IsVariadic()
  1131  		}
  1132  	}
  1133  	return false
  1134  }
  1135  
  1136  // isComplete returns true if type definition is complete.
  1137  func (t *itype) isComplete() bool { return isComplete(t, map[string]bool{}) }
  1138  
  1139  func isComplete(t *itype, visited map[string]bool) bool {
  1140  	if t.incomplete {
  1141  		return false
  1142  	}
  1143  	name := t.path + "/" + t.name
  1144  	if visited[name] {
  1145  		return true
  1146  	}
  1147  	if t.name != "" {
  1148  		visited[name] = true
  1149  	}
  1150  	switch t.cat {
  1151  	case aliasT:
  1152  		if t.val != nil && t.val.cat != nilT {
  1153  			// A type aliased to a partially defined type is considered complete, to allow recursivity.
  1154  			return true
  1155  		}
  1156  		fallthrough
  1157  	case arrayT, chanT, chanRecvT, chanSendT, ptrT, sliceT, variadicT:
  1158  		return isComplete(t.val, visited)
  1159  	case funcT:
  1160  		complete := true
  1161  		for _, a := range t.arg {
  1162  			complete = complete && isComplete(a, visited)
  1163  		}
  1164  		for _, a := range t.ret {
  1165  			complete = complete && isComplete(a, visited)
  1166  		}
  1167  		return complete
  1168  	case interfaceT, structT:
  1169  		complete := true
  1170  		for _, f := range t.field {
  1171  			// Field implicit type names must be marked as visited, to break false circles.
  1172  			visited[f.typ.path+"/"+f.typ.name] = true
  1173  			complete = complete && isComplete(f.typ, visited)
  1174  		}
  1175  		return complete
  1176  	case mapT:
  1177  		return isComplete(t.key, visited) && isComplete(t.val, visited)
  1178  	case nilT:
  1179  		return false
  1180  	}
  1181  	return true
  1182  }
  1183  
  1184  // comparable returns true if the type is comparable.
  1185  func (t *itype) comparable() bool {
  1186  	typ := t.TypeOf()
  1187  	return t.cat == nilT || typ != nil && typ.Comparable()
  1188  }
  1189  
  1190  func (t *itype) assignableTo(o *itype) bool {
  1191  	if t.equals(o) {
  1192  		return true
  1193  	}
  1194  	if t.cat == aliasT && o.cat == aliasT {
  1195  		// If alias types are not identical, it is not assignable.
  1196  		return false
  1197  	}
  1198  	if t.isNil() && o.hasNil() || o.isNil() && t.hasNil() {
  1199  		return true
  1200  	}
  1201  
  1202  	if t.TypeOf().AssignableTo(o.TypeOf()) {
  1203  		return true
  1204  	}
  1205  
  1206  	if isInterface(o) && t.implements(o) {
  1207  		return true
  1208  	}
  1209  
  1210  	if t.isBinMethod && isFunc(o) {
  1211  		// TODO (marc): check that t without receiver as first parameter is equivalent to o.
  1212  		return true
  1213  	}
  1214  
  1215  	n := t.node
  1216  	if n == nil || !n.rval.IsValid() {
  1217  		return false
  1218  	}
  1219  	con, ok := n.rval.Interface().(constant.Value)
  1220  	if !ok {
  1221  		return false
  1222  	}
  1223  	if con == nil || !isConstType(o) {
  1224  		return false
  1225  	}
  1226  	return representableConst(con, o.TypeOf())
  1227  }
  1228  
  1229  // convertibleTo returns true if t is convertible to o.
  1230  func (t *itype) convertibleTo(o *itype) bool {
  1231  	if t.assignableTo(o) {
  1232  		return true
  1233  	}
  1234  
  1235  	// unsafe checks
  1236  	tt, ot := t.TypeOf(), o.TypeOf()
  1237  	if (tt.Kind() == reflect.Ptr || tt.Kind() == reflect.Uintptr) && ot.Kind() == reflect.UnsafePointer {
  1238  		return true
  1239  	}
  1240  	if tt.Kind() == reflect.UnsafePointer && (ot.Kind() == reflect.Ptr || ot.Kind() == reflect.Uintptr) {
  1241  		return true
  1242  	}
  1243  
  1244  	return t.TypeOf().ConvertibleTo(o.TypeOf())
  1245  }
  1246  
  1247  // ordered returns true if the type is ordered.
  1248  func (t *itype) ordered() bool {
  1249  	typ := t.TypeOf()
  1250  	return isInt(typ) || isFloat(typ) || isString(typ)
  1251  }
  1252  
  1253  // Equals returns true if the given type is identical to the receiver one.
  1254  func (t *itype) equals(o *itype) bool {
  1255  	switch ti, oi := isInterface(t), isInterface(o); {
  1256  	case ti && oi:
  1257  		return t.methods().equals(o.methods())
  1258  	case ti && !oi:
  1259  		return o.methods().contains(t.methods())
  1260  	case oi && !ti:
  1261  		return t.methods().contains(o.methods())
  1262  	default:
  1263  		return t.id() == o.id()
  1264  	}
  1265  }
  1266  
  1267  // MethodSet defines the set of methods signatures as strings, indexed per method name.
  1268  type methodSet map[string]string
  1269  
  1270  // Contains returns true if the method set m contains the method set n.
  1271  func (m methodSet) contains(n methodSet) bool {
  1272  	for k, v := range n {
  1273  		if m[k] != v {
  1274  			return false
  1275  		}
  1276  	}
  1277  	return true
  1278  }
  1279  
  1280  // Equal returns true if the method set m is equal to the method set n.
  1281  func (m methodSet) equals(n methodSet) bool {
  1282  	return m.contains(n) && n.contains(m)
  1283  }
  1284  
  1285  // Methods returns a map of method type strings, indexed by method names.
  1286  func (t *itype) methods() methodSet {
  1287  	seen := map[*itype]bool{}
  1288  	var getMethods func(typ *itype) methodSet
  1289  
  1290  	getMethods = func(typ *itype) methodSet {
  1291  		res := make(methodSet)
  1292  
  1293  		if seen[typ] {
  1294  			// Stop the recursion, we have seen this type.
  1295  			return res
  1296  		}
  1297  		seen[typ] = true
  1298  
  1299  		switch typ.cat {
  1300  		case aliasT:
  1301  			for k, v := range getMethods(typ.val) {
  1302  				res[k] = v
  1303  			}
  1304  		case interfaceT:
  1305  			// Get methods from recursive analysis of interface fields.
  1306  			for _, f := range typ.field {
  1307  				if f.typ.cat == funcT {
  1308  					res[f.name] = f.typ.TypeOf().String()
  1309  				} else {
  1310  					for k, v := range getMethods(f.typ) {
  1311  						res[k] = v
  1312  					}
  1313  				}
  1314  			}
  1315  		case valueT, errorT:
  1316  			// Get method from corresponding reflect.Type.
  1317  			for i := typ.TypeOf().NumMethod() - 1; i >= 0; i-- {
  1318  				m := typ.rtype.Method(i)
  1319  				res[m.Name] = m.Type.String()
  1320  			}
  1321  		case ptrT:
  1322  			if typ.val.cat == valueT {
  1323  				// Ptr receiver methods need to be found with the ptr type.
  1324  				typ.TypeOf() // Ensure the rtype exists.
  1325  				for i := typ.rtype.NumMethod() - 1; i >= 0; i-- {
  1326  					m := typ.rtype.Method(i)
  1327  					res[m.Name] = m.Type.String()
  1328  				}
  1329  			}
  1330  			for k, v := range getMethods(typ.val) {
  1331  				res[k] = v
  1332  			}
  1333  		case structT:
  1334  			for _, f := range typ.field {
  1335  				if !f.embed {
  1336  					continue
  1337  				}
  1338  				for k, v := range getMethods(f.typ) {
  1339  					res[k] = v
  1340  				}
  1341  			}
  1342  		}
  1343  		// Get all methods defined on this type.
  1344  		for _, m := range typ.method {
  1345  			res[m.ident] = m.typ.TypeOf().String()
  1346  		}
  1347  		return res
  1348  	}
  1349  
  1350  	return getMethods(t)
  1351  }
  1352  
  1353  // id returns a unique type identificator string.
  1354  func (t *itype) id() (res string) {
  1355  	// Prefer the wrapped type string over the rtype string.
  1356  	if t.cat == valueT && t.val != nil {
  1357  		return t.val.str
  1358  	}
  1359  	return t.str
  1360  }
  1361  
  1362  // fixPossibleConstType returns the input type if it not a constant value,
  1363  // otherwise, it returns the default Go type corresponding to the
  1364  // constant.Value.
  1365  func fixPossibleConstType(t reflect.Type) (r reflect.Type) {
  1366  	cv, ok := reflect.New(t).Elem().Interface().(constant.Value)
  1367  	if !ok {
  1368  		return t
  1369  	}
  1370  	switch cv.Kind() {
  1371  	case constant.Bool:
  1372  		r = reflect.TypeOf(true)
  1373  	case constant.Int:
  1374  		r = reflect.TypeOf(0)
  1375  	case constant.String:
  1376  		r = reflect.TypeOf("")
  1377  	case constant.Float:
  1378  		r = reflect.TypeOf(float64(0))
  1379  	case constant.Complex:
  1380  		r = reflect.TypeOf(complex128(0))
  1381  	}
  1382  	return r
  1383  }
  1384  
  1385  // zero instantiates and return a zero value object for the given type during execution.
  1386  func (t *itype) zero() (v reflect.Value, err error) {
  1387  	if t, err = t.finalize(); err != nil {
  1388  		return v, err
  1389  	}
  1390  	switch t.cat {
  1391  	case aliasT:
  1392  		v, err = t.val.zero()
  1393  
  1394  	case arrayT, ptrT, structT, sliceT:
  1395  		v = reflect.New(t.frameType()).Elem()
  1396  
  1397  	case valueT:
  1398  		v = reflect.New(t.rtype).Elem()
  1399  
  1400  	default:
  1401  		v = zeroValues[t.cat]
  1402  	}
  1403  	return v, err
  1404  }
  1405  
  1406  // fieldIndex returns the field index from name in a struct, or -1 if not found.
  1407  func (t *itype) fieldIndex(name string) int {
  1408  	switch t.cat {
  1409  	case aliasT, ptrT:
  1410  		return t.val.fieldIndex(name)
  1411  	}
  1412  	for i, field := range t.field {
  1413  		if name == field.name {
  1414  			return i
  1415  		}
  1416  	}
  1417  	return -1
  1418  }
  1419  
  1420  // fieldSeq returns the field type from the list of field indexes.
  1421  func (t *itype) fieldSeq(seq []int) *itype {
  1422  	ft := t
  1423  	for _, i := range seq {
  1424  		if ft.cat == ptrT {
  1425  			ft = ft.val
  1426  		}
  1427  		ft = ft.field[i].typ
  1428  	}
  1429  	return ft
  1430  }
  1431  
  1432  // lookupField returns a list of indices, i.e. a path to access a field in a struct object.
  1433  func (t *itype) lookupField(name string) []int {
  1434  	seen := map[*itype]bool{}
  1435  	var lookup func(*itype) []int
  1436  
  1437  	lookup = func(typ *itype) []int {
  1438  		if seen[typ] {
  1439  			return nil
  1440  		}
  1441  		seen[typ] = true
  1442  
  1443  		switch typ.cat {
  1444  		case aliasT, ptrT:
  1445  			return lookup(typ.val)
  1446  		}
  1447  		if fi := typ.fieldIndex(name); fi >= 0 {
  1448  			return []int{fi}
  1449  		}
  1450  
  1451  		for i, f := range typ.field {
  1452  			switch f.typ.cat {
  1453  			case ptrT, structT, interfaceT, aliasT:
  1454  				if index2 := lookup(f.typ); len(index2) > 0 {
  1455  					return append([]int{i}, index2...)
  1456  				}
  1457  			}
  1458  		}
  1459  
  1460  		return nil
  1461  	}
  1462  
  1463  	return lookup(t)
  1464  }
  1465  
  1466  // lookupBinField returns a structfield and a path to access an embedded binary field in a struct object.
  1467  func (t *itype) lookupBinField(name string) (s reflect.StructField, index []int, ok bool) {
  1468  	if t.cat == ptrT {
  1469  		return t.val.lookupBinField(name)
  1470  	}
  1471  	if !isStruct(t) {
  1472  		return
  1473  	}
  1474  	rt := t.TypeOf()
  1475  	for t.cat == valueT && rt.Kind() == reflect.Ptr {
  1476  		rt = rt.Elem()
  1477  	}
  1478  	if rt.Kind() != reflect.Struct {
  1479  		return
  1480  	}
  1481  	s, ok = rt.FieldByName(name)
  1482  	if !ok {
  1483  		for i, f := range t.field {
  1484  			if f.embed {
  1485  				if s2, index2, ok2 := f.typ.lookupBinField(name); ok2 {
  1486  					index = append([]int{i}, index2...)
  1487  					return s2, index, ok2
  1488  				}
  1489  			}
  1490  		}
  1491  	}
  1492  	return s, index, ok
  1493  }
  1494  
  1495  // MethodCallType returns a method function type without the receiver defined.
  1496  // The input type must be a method function type with the receiver as the first input argument.
  1497  func (t *itype) methodCallType() reflect.Type {
  1498  	it := []reflect.Type{}
  1499  	ni := t.rtype.NumIn()
  1500  	for i := 1; i < ni; i++ {
  1501  		it = append(it, t.rtype.In(i))
  1502  	}
  1503  	ot := []reflect.Type{}
  1504  	no := t.rtype.NumOut()
  1505  	for i := 0; i < no; i++ {
  1506  		ot = append(ot, t.rtype.Out(i))
  1507  	}
  1508  	return reflect.FuncOf(it, ot, t.rtype.IsVariadic())
  1509  }
  1510  
  1511  func (t *itype) resolveAlias() *itype {
  1512  	for t.cat == aliasT {
  1513  		t = t.val
  1514  	}
  1515  	return t
  1516  }
  1517  
  1518  // GetMethod returns a pointer to the method definition.
  1519  func (t *itype) getMethod(name string) *node {
  1520  	for _, m := range t.method {
  1521  		if name == m.ident {
  1522  			return m
  1523  		}
  1524  	}
  1525  	return nil
  1526  }
  1527  
  1528  // LookupMethod returns a pointer to method definition associated to type t
  1529  // and the list of indices to access the right struct field, in case of an embedded method.
  1530  func (t *itype) lookupMethod(name string) (*node, []int) {
  1531  	if t.cat == ptrT {
  1532  		return t.val.lookupMethod(name)
  1533  	}
  1534  	var index []int
  1535  	m := t.getMethod(name)
  1536  	if m == nil {
  1537  		for i, f := range t.field {
  1538  			if f.embed {
  1539  				if n, index2 := f.typ.lookupMethod(name); n != nil {
  1540  					index = append([]int{i}, index2...)
  1541  					return n, index
  1542  				}
  1543  			}
  1544  		}
  1545  		if t.cat == aliasT || isInterfaceSrc(t) && t.val != nil {
  1546  			return t.val.lookupMethod(name)
  1547  		}
  1548  	}
  1549  	return m, index
  1550  }
  1551  
  1552  // methodDepth returns a depth greater or equal to 0, or -1 if no match.
  1553  func (t *itype) methodDepth(name string) int {
  1554  	if m, lint := t.lookupMethod(name); m != nil {
  1555  		return len(lint)
  1556  	}
  1557  	if _, lint, _, ok := t.lookupBinMethod(name); ok {
  1558  		return len(lint)
  1559  	}
  1560  	return -1
  1561  }
  1562  
  1563  // LookupBinMethod returns a method and a path to access a field in a struct object (the receiver).
  1564  func (t *itype) lookupBinMethod(name string) (m reflect.Method, index []int, isPtr, ok bool) {
  1565  	if t.cat == ptrT {
  1566  		return t.val.lookupBinMethod(name)
  1567  	}
  1568  	for i, f := range t.field {
  1569  		if f.embed {
  1570  			if m2, index2, isPtr2, ok2 := f.typ.lookupBinMethod(name); ok2 {
  1571  				index = append([]int{i}, index2...)
  1572  				return m2, index, isPtr2, ok2
  1573  			}
  1574  		}
  1575  	}
  1576  	m, ok = t.TypeOf().MethodByName(name)
  1577  	if !ok {
  1578  		m, ok = reflect.PtrTo(t.TypeOf()).MethodByName(name)
  1579  		isPtr = ok
  1580  	}
  1581  	return m, index, isPtr, ok
  1582  }
  1583  
  1584  func lookupFieldOrMethod(t *itype, name string) *itype {
  1585  	switch {
  1586  	case t.cat == valueT || t.cat == ptrT && t.val.cat == valueT:
  1587  		m, _, isPtr, ok := t.lookupBinMethod(name)
  1588  		if !ok {
  1589  			return nil
  1590  		}
  1591  		var recv *itype
  1592  		if t.rtype.Kind() != reflect.Interface {
  1593  			recv = t
  1594  			if isPtr && t.cat != ptrT && t.rtype.Kind() != reflect.Ptr {
  1595  				recv = ptrOf(t)
  1596  			}
  1597  		}
  1598  		return valueTOf(m.Type, withRecv(recv))
  1599  	case t.cat == interfaceT:
  1600  		seq := t.lookupField(name)
  1601  		if seq == nil {
  1602  			return nil
  1603  		}
  1604  		return t.fieldSeq(seq)
  1605  	default:
  1606  		n, _ := t.lookupMethod(name)
  1607  		if n == nil {
  1608  			return nil
  1609  		}
  1610  		return n.typ
  1611  	}
  1612  }
  1613  
  1614  func exportName(s string) string {
  1615  	if canExport(s) {
  1616  		return s
  1617  	}
  1618  	return "X" + s
  1619  }
  1620  
  1621  var (
  1622  	// TODO(mpl): generators.
  1623  	interf   = reflect.TypeOf((*interface{})(nil)).Elem()
  1624  	constVal = reflect.TypeOf((*constant.Value)(nil)).Elem()
  1625  )
  1626  
  1627  type fieldRebuild struct {
  1628  	typ *itype
  1629  	idx int
  1630  }
  1631  
  1632  type refTypeContext struct {
  1633  	defined    map[string]*itype
  1634  	refs       map[string][]fieldRebuild
  1635  	rebuilding bool
  1636  }
  1637  
  1638  // Clone creates a copy of the ref type context.
  1639  func (c *refTypeContext) Clone() *refTypeContext {
  1640  	return &refTypeContext{defined: c.defined, refs: c.refs, rebuilding: c.rebuilding}
  1641  }
  1642  
  1643  // RefType returns a reflect.Type representation from an interpreter type.
  1644  // In simple cases, reflect types are directly mapped from the interpreter
  1645  // counterpart.
  1646  // For recursive named struct or interfaces, as reflect does not permit to
  1647  // create a recursive named struct, a nil type is set temporarily for each recursive
  1648  // field. When done, the nil type fields are updated with the original reflect type
  1649  // pointer using unsafe. We thus obtain a usable recursive type definition, except
  1650  // for string representation, as created reflect types are still unnamed.
  1651  func (t *itype) refType(ctx *refTypeContext) reflect.Type {
  1652  	if ctx == nil {
  1653  		ctx = &refTypeContext{
  1654  			defined: map[string]*itype{},
  1655  			refs:    map[string][]fieldRebuild{},
  1656  		}
  1657  	}
  1658  	if t.incomplete || t.cat == nilT {
  1659  		var err error
  1660  		if t, err = t.finalize(); err != nil {
  1661  			panic(err)
  1662  		}
  1663  	}
  1664  	name := t.path + "/" + t.name
  1665  
  1666  	if t.rtype != nil && !ctx.rebuilding {
  1667  		return t.rtype
  1668  	}
  1669  	if dt := ctx.defined[name]; dt != nil {
  1670  		if dt.rtype != nil {
  1671  			t.rtype = dt.rtype
  1672  			return dt.rtype
  1673  		}
  1674  
  1675  		// To indicate that a rebuild is needed on the nearest struct
  1676  		// field, create an entry with a nil type.
  1677  		flds := ctx.refs[name]
  1678  		ctx.refs[name] = append(flds, fieldRebuild{})
  1679  		return unsafe2.DummyType
  1680  	}
  1681  	switch t.cat {
  1682  	case aliasT:
  1683  		t.rtype = t.val.refType(ctx)
  1684  	case arrayT:
  1685  		t.rtype = reflect.ArrayOf(t.length, t.val.refType(ctx))
  1686  	case sliceT, variadicT:
  1687  		t.rtype = reflect.SliceOf(t.val.refType(ctx))
  1688  	case chanT:
  1689  		t.rtype = reflect.ChanOf(reflect.BothDir, t.val.refType(ctx))
  1690  	case chanRecvT:
  1691  		t.rtype = reflect.ChanOf(reflect.RecvDir, t.val.refType(ctx))
  1692  	case chanSendT:
  1693  		t.rtype = reflect.ChanOf(reflect.SendDir, t.val.refType(ctx))
  1694  	case errorT:
  1695  		t.rtype = reflect.TypeOf(new(error)).Elem()
  1696  	case funcT:
  1697  		variadic := false
  1698  		in := make([]reflect.Type, len(t.arg))
  1699  		out := make([]reflect.Type, len(t.ret))
  1700  		for i, v := range t.arg {
  1701  			in[i] = v.refType(ctx)
  1702  			variadic = v.cat == variadicT
  1703  		}
  1704  		for i, v := range t.ret {
  1705  			out[i] = v.refType(ctx)
  1706  		}
  1707  		t.rtype = reflect.FuncOf(in, out, variadic)
  1708  	case interfaceT:
  1709  		t.rtype = interf
  1710  	case mapT:
  1711  		t.rtype = reflect.MapOf(t.key.refType(ctx), t.val.refType(ctx))
  1712  	case ptrT:
  1713  		t.rtype = reflect.PtrTo(t.val.refType(ctx))
  1714  	case structT:
  1715  		if t.name != "" {
  1716  			ctx.defined[name] = t
  1717  		}
  1718  		var fields []reflect.StructField
  1719  		for i, f := range t.field {
  1720  			fctx := ctx.Clone()
  1721  			field := reflect.StructField{
  1722  				Name: exportName(f.name), Type: f.typ.refType(fctx),
  1723  				Tag: reflect.StructTag(f.tag), Anonymous: f.embed,
  1724  			}
  1725  			fields = append(fields, field)
  1726  			// Find any nil type refs that indicates a rebuild is needed on this field.
  1727  			for _, flds := range ctx.refs {
  1728  				for j, fld := range flds {
  1729  					if fld.typ == nil {
  1730  						flds[j] = fieldRebuild{typ: t, idx: i}
  1731  					}
  1732  				}
  1733  			}
  1734  		}
  1735  		t.rtype = reflect.StructOf(fields)
  1736  
  1737  		// The rtype has now been built, we can go back and rebuild
  1738  		// all the recursive types that relied on this type.
  1739  		for _, f := range ctx.refs[name] {
  1740  			ftyp := f.typ.field[f.idx].typ.refType(&refTypeContext{defined: ctx.defined, rebuilding: true})
  1741  			unsafe2.SwapFieldType(f.typ.rtype, f.idx, ftyp)
  1742  		}
  1743  	default:
  1744  		if z, _ := t.zero(); z.IsValid() {
  1745  			t.rtype = z.Type()
  1746  		}
  1747  	}
  1748  	return t.rtype
  1749  }
  1750  
  1751  // TypeOf returns the reflection type of dynamic interpreter type t.
  1752  func (t *itype) TypeOf() reflect.Type {
  1753  	return t.refType(nil)
  1754  }
  1755  
  1756  func (t *itype) frameType() (r reflect.Type) {
  1757  	var err error
  1758  	if t, err = t.finalize(); err != nil {
  1759  		panic(err)
  1760  	}
  1761  	switch t.cat {
  1762  	case aliasT:
  1763  		r = t.val.frameType()
  1764  	case arrayT:
  1765  		r = reflect.ArrayOf(t.length, t.val.frameType())
  1766  	case sliceT, variadicT:
  1767  		r = reflect.SliceOf(t.val.frameType())
  1768  	case funcT:
  1769  		r = reflect.TypeOf((*node)(nil))
  1770  	case interfaceT:
  1771  		if len(t.field) == 0 {
  1772  			// empty interface, do not wrap it
  1773  			r = reflect.TypeOf((*interface{})(nil)).Elem()
  1774  			break
  1775  		}
  1776  		r = reflect.TypeOf((*valueInterface)(nil)).Elem()
  1777  	case mapT:
  1778  		r = reflect.MapOf(t.key.frameType(), t.val.frameType())
  1779  	case ptrT:
  1780  		r = reflect.PtrTo(t.val.frameType())
  1781  	default:
  1782  		r = t.TypeOf()
  1783  	}
  1784  	return r
  1785  }
  1786  
  1787  func (t *itype) implements(it *itype) bool {
  1788  	if isBin(t) {
  1789  		return t.TypeOf().Implements(it.TypeOf())
  1790  	}
  1791  	return t.methods().contains(it.methods())
  1792  }
  1793  
  1794  // defaultType returns the default type of an untyped type.
  1795  func (t *itype) defaultType(v reflect.Value, sc *scope) *itype {
  1796  	if !t.untyped {
  1797  		return t
  1798  	}
  1799  
  1800  	typ := t
  1801  	// The default type can also be derived from a constant value.
  1802  	if v.IsValid() && v.Type().Implements(constVal) {
  1803  		switch v.Interface().(constant.Value).Kind() {
  1804  		case constant.String:
  1805  			typ = sc.getType("string")
  1806  		case constant.Bool:
  1807  			typ = sc.getType("bool")
  1808  		case constant.Int:
  1809  			switch t.cat {
  1810  			case int32T:
  1811  				typ = sc.getType("int32")
  1812  			default:
  1813  				typ = sc.getType("int")
  1814  			}
  1815  		case constant.Float:
  1816  			typ = sc.getType("float64")
  1817  		case constant.Complex:
  1818  			typ = sc.getType("complex128")
  1819  		}
  1820  	}
  1821  	if typ.untyped {
  1822  		switch t.cat {
  1823  		case stringT:
  1824  			typ = sc.getType("string")
  1825  		case boolT:
  1826  			typ = sc.getType("bool")
  1827  		case intT:
  1828  			typ = sc.getType("int")
  1829  		case float64T:
  1830  			typ = sc.getType("float64")
  1831  		case complex128T:
  1832  			typ = sc.getType("complex128")
  1833  		default:
  1834  			*typ = *t
  1835  			typ.untyped = false
  1836  		}
  1837  	}
  1838  	return typ
  1839  }
  1840  
  1841  func (t *itype) isNil() bool { return t.cat == nilT }
  1842  
  1843  func (t *itype) hasNil() bool {
  1844  	switch t.TypeOf().Kind() {
  1845  	case reflect.UnsafePointer:
  1846  		return true
  1847  	case reflect.Slice, reflect.Ptr, reflect.Func, reflect.Interface, reflect.Map, reflect.Chan:
  1848  		return true
  1849  	}
  1850  	return false
  1851  }
  1852  
  1853  func (t *itype) elem() *itype {
  1854  	if t.cat == valueT {
  1855  		return valueTOf(t.rtype.Elem())
  1856  	}
  1857  	return t.val
  1858  }
  1859  
  1860  func hasElem(t reflect.Type) bool {
  1861  	switch t.Kind() {
  1862  	case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:
  1863  		return true
  1864  	}
  1865  	return false
  1866  }
  1867  
  1868  func constToInt(c constant.Value) int {
  1869  	if constant.BitLen(c) > 64 {
  1870  		panic(fmt.Sprintf("constant %s overflows int64", c.ExactString()))
  1871  	}
  1872  	i, _ := constant.Int64Val(c)
  1873  	return int(i)
  1874  }
  1875  
  1876  func constToString(v reflect.Value) string {
  1877  	c := v.Interface().(constant.Value)
  1878  	return constant.StringVal(c)
  1879  }
  1880  
  1881  func defRecvType(n *node) *itype {
  1882  	if n.kind != funcDecl || len(n.child[0].child) == 0 {
  1883  		return nil
  1884  	}
  1885  	if r := n.child[0].child[0].lastChild(); r != nil {
  1886  		return r.typ
  1887  	}
  1888  	return nil
  1889  }
  1890  
  1891  func wrappedType(n *node) *itype {
  1892  	if n.typ.cat != valueT {
  1893  		return nil
  1894  	}
  1895  	return n.typ.val
  1896  }
  1897  
  1898  func isShiftNode(n *node) bool {
  1899  	switch n.action {
  1900  	case aShl, aShr, aShlAssign, aShrAssign:
  1901  		return true
  1902  	}
  1903  	return false
  1904  }
  1905  
  1906  // chanElement returns the channel element type.
  1907  func chanElement(t *itype) *itype {
  1908  	switch t.cat {
  1909  	case aliasT:
  1910  		return chanElement(t.val)
  1911  	case chanT, chanSendT, chanRecvT:
  1912  		return t.val
  1913  	case valueT:
  1914  		return valueTOf(t.rtype.Elem(), withNode(t.node), withScope(t.scope))
  1915  	}
  1916  	return nil
  1917  }
  1918  
  1919  func isBool(t *itype) bool { return t.TypeOf().Kind() == reflect.Bool }
  1920  func isChan(t *itype) bool { return t.TypeOf().Kind() == reflect.Chan }
  1921  func isFunc(t *itype) bool { return t.TypeOf().Kind() == reflect.Func }
  1922  func isMap(t *itype) bool  { return t.TypeOf().Kind() == reflect.Map }
  1923  func isPtr(t *itype) bool  { return t.TypeOf().Kind() == reflect.Ptr }
  1924  
  1925  func isEmptyInterface(t *itype) bool {
  1926  	return t.cat == interfaceT && len(t.field) == 0
  1927  }
  1928  
  1929  func isFuncSrc(t *itype) bool {
  1930  	return t.cat == funcT || (t.cat == aliasT && isFuncSrc(t.val))
  1931  }
  1932  
  1933  func isPtrSrc(t *itype) bool {
  1934  	return t.cat == ptrT || (t.cat == aliasT && isPtrSrc(t.val))
  1935  }
  1936  
  1937  func isSendChan(t *itype) bool {
  1938  	rt := t.TypeOf()
  1939  	return rt.Kind() == reflect.Chan && rt.ChanDir() == reflect.SendDir
  1940  }
  1941  
  1942  func isArray(t *itype) bool {
  1943  	if t.cat == nilT {
  1944  		return false
  1945  	}
  1946  	k := t.TypeOf().Kind()
  1947  	return k == reflect.Array || k == reflect.Slice
  1948  }
  1949  
  1950  func isInterfaceSrc(t *itype) bool {
  1951  	return t.cat == interfaceT || (t.cat == aliasT && isInterfaceSrc(t.val))
  1952  }
  1953  
  1954  func isInterfaceBin(t *itype) bool {
  1955  	return t.cat == valueT && t.rtype.Kind() == reflect.Interface || t.cat == errorT
  1956  }
  1957  
  1958  func isInterface(t *itype) bool {
  1959  	return isInterfaceSrc(t) || t.TypeOf() != nil && t.TypeOf().Kind() == reflect.Interface
  1960  }
  1961  
  1962  func isBin(t *itype) bool {
  1963  	switch t.cat {
  1964  	case valueT:
  1965  		return true
  1966  	case aliasT, ptrT:
  1967  		return isBin(t.val)
  1968  	default:
  1969  		return false
  1970  	}
  1971  }
  1972  
  1973  func isStruct(t *itype) bool {
  1974  	// Test first for a struct category, because a recursive interpreter struct may be
  1975  	// represented by an interface{} at reflect level.
  1976  	switch t.cat {
  1977  	case structT:
  1978  		return true
  1979  	case aliasT, ptrT:
  1980  		return isStruct(t.val)
  1981  	case valueT:
  1982  		k := t.rtype.Kind()
  1983  		return k == reflect.Struct || (k == reflect.Ptr && t.rtype.Elem().Kind() == reflect.Struct)
  1984  	default:
  1985  		return false
  1986  	}
  1987  }
  1988  
  1989  func isConstType(t *itype) bool {
  1990  	rt := t.TypeOf()
  1991  	return isBoolean(rt) || isString(rt) || isNumber(rt)
  1992  }
  1993  
  1994  func isInt(t reflect.Type) bool {
  1995  	if t == nil {
  1996  		return false
  1997  	}
  1998  	switch t.Kind() {
  1999  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  2000  		return true
  2001  	}
  2002  	return false
  2003  }
  2004  
  2005  func isUint(t reflect.Type) bool {
  2006  	if t == nil {
  2007  		return false
  2008  	}
  2009  	switch t.Kind() {
  2010  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  2011  		return true
  2012  	}
  2013  	return false
  2014  }
  2015  
  2016  func isComplex(t reflect.Type) bool {
  2017  	if t == nil {
  2018  		return false
  2019  	}
  2020  	switch t.Kind() {
  2021  	case reflect.Complex64, reflect.Complex128:
  2022  		return true
  2023  	}
  2024  	return false
  2025  }
  2026  
  2027  func isFloat(t reflect.Type) bool {
  2028  	if t == nil {
  2029  		return false
  2030  	}
  2031  	switch t.Kind() {
  2032  	case reflect.Float32, reflect.Float64:
  2033  		return true
  2034  	}
  2035  	return false
  2036  }
  2037  
  2038  func isByteArray(t reflect.Type) bool {
  2039  	if t == nil {
  2040  		return false
  2041  	}
  2042  	k := t.Kind()
  2043  	return (k == reflect.Array || k == reflect.Slice) && t.Elem().Kind() == reflect.Uint8
  2044  }
  2045  
  2046  func isFloat32(t reflect.Type) bool { return t != nil && t.Kind() == reflect.Float32 }
  2047  func isFloat64(t reflect.Type) bool { return t != nil && t.Kind() == reflect.Float64 }
  2048  func isNumber(t reflect.Type) bool {
  2049  	return isInt(t) || isFloat(t) || isComplex(t) || isConstantValue(t)
  2050  }
  2051  func isBoolean(t reflect.Type) bool       { return t != nil && t.Kind() == reflect.Bool }
  2052  func isString(t reflect.Type) bool        { return t != nil && t.Kind() == reflect.String }
  2053  func isConstantValue(t reflect.Type) bool { return t != nil && t.Implements(constVal) }