gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/golang.org/x/tools/go/ssa/interp/reflect.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package interp
     6  
     7  // Emulated "reflect" package.
     8  //
     9  // We completely replace the built-in "reflect" package.
    10  // The only thing clients can depend upon are that reflect.Type is an
    11  // interface and reflect.Value is an (opaque) struct.
    12  
    13  import (
    14  	"fmt"
    15  	"go/token"
    16  	"go/types"
    17  	"reflect"
    18  	"unsafe"
    19  
    20  	"golang.org/x/tools/go/ssa"
    21  )
    22  
    23  type opaqueType struct {
    24  	types.Type
    25  	name string
    26  }
    27  
    28  func (t *opaqueType) String() string { return t.name }
    29  
    30  // A bogus "reflect" type-checker package.  Shared across interpreters.
    31  var reflectTypesPackage = types.NewPackage("reflect", "reflect")
    32  
    33  // rtype is the concrete type the interpreter uses to implement the
    34  // reflect.Type interface.
    35  //
    36  // type rtype <opaque>
    37  var rtypeType = makeNamedType("rtype", &opaqueType{nil, "rtype"})
    38  
    39  // error is an (interpreted) named type whose underlying type is string.
    40  // The interpreter uses it for all implementations of the built-in error
    41  // interface that it creates.
    42  // We put it in the "reflect" package for expedience.
    43  //
    44  // type error string
    45  var errorType = makeNamedType("error", &opaqueType{nil, "error"})
    46  
    47  func makeNamedType(name string, underlying types.Type) *types.Named {
    48  	obj := types.NewTypeName(token.NoPos, reflectTypesPackage, name, nil)
    49  	return types.NewNamed(obj, underlying, nil)
    50  }
    51  
    52  func makeReflectValue(t types.Type, v value) value {
    53  	return structure{rtype{t}, v}
    54  }
    55  
    56  // Given a reflect.Value, returns its rtype.
    57  func rV2T(v value) rtype {
    58  	return v.(structure)[0].(rtype)
    59  }
    60  
    61  // Given a reflect.Value, returns the underlying interpreter value.
    62  func rV2V(v value) value {
    63  	return v.(structure)[1]
    64  }
    65  
    66  // makeReflectType boxes up an rtype in a reflect.Type interface.
    67  func makeReflectType(rt rtype) value {
    68  	return iface{rtypeType, rt}
    69  }
    70  
    71  func ext۰reflect۰Init(fr *frame, args []value) value {
    72  	// Signature: func()
    73  	return nil
    74  }
    75  
    76  func ext۰reflect۰rtype۰Bits(fr *frame, args []value) value {
    77  	// Signature: func (t reflect.rtype) int
    78  	rt := args[0].(rtype).t
    79  	basic, ok := rt.Underlying().(*types.Basic)
    80  	if !ok {
    81  		panic(fmt.Sprintf("reflect.Type.Bits(%T): non-basic type", rt))
    82  	}
    83  	return int(fr.i.sizes.Sizeof(basic)) * 8
    84  }
    85  
    86  func ext۰reflect۰rtype۰Elem(fr *frame, args []value) value {
    87  	// Signature: func (t reflect.rtype) reflect.Type
    88  	return makeReflectType(rtype{args[0].(rtype).t.Underlying().(interface {
    89  		Elem() types.Type
    90  	}).Elem()})
    91  }
    92  
    93  func ext۰reflect۰rtype۰Field(fr *frame, args []value) value {
    94  	// Signature: func (t reflect.rtype, i int) reflect.StructField
    95  	st := args[0].(rtype).t.Underlying().(*types.Struct)
    96  	i := args[1].(int)
    97  	f := st.Field(i)
    98  	return structure{
    99  		f.Name(),
   100  		f.Pkg().Path(),
   101  		makeReflectType(rtype{f.Type()}),
   102  		st.Tag(i),
   103  		0,         // TODO(adonovan): offset
   104  		[]value{}, // TODO(adonovan): indices
   105  		f.Anonymous(),
   106  	}
   107  }
   108  
   109  func ext۰reflect۰rtype۰In(fr *frame, args []value) value {
   110  	// Signature: func (t reflect.rtype, i int) int
   111  	i := args[1].(int)
   112  	return makeReflectType(rtype{args[0].(rtype).t.(*types.Signature).Params().At(i).Type()})
   113  }
   114  
   115  func ext۰reflect۰rtype۰Kind(fr *frame, args []value) value {
   116  	// Signature: func (t reflect.rtype) uint
   117  	return uint(reflectKind(args[0].(rtype).t))
   118  }
   119  
   120  func ext۰reflect۰rtype۰NumField(fr *frame, args []value) value {
   121  	// Signature: func (t reflect.rtype) int
   122  	return args[0].(rtype).t.Underlying().(*types.Struct).NumFields()
   123  }
   124  
   125  func ext۰reflect۰rtype۰NumIn(fr *frame, args []value) value {
   126  	// Signature: func (t reflect.rtype) int
   127  	return args[0].(rtype).t.(*types.Signature).Params().Len()
   128  }
   129  
   130  func ext۰reflect۰rtype۰NumMethod(fr *frame, args []value) value {
   131  	// Signature: func (t reflect.rtype) int
   132  	return fr.i.prog.MethodSets.MethodSet(args[0].(rtype).t).Len()
   133  }
   134  
   135  func ext۰reflect۰rtype۰NumOut(fr *frame, args []value) value {
   136  	// Signature: func (t reflect.rtype) int
   137  	return args[0].(rtype).t.(*types.Signature).Results().Len()
   138  }
   139  
   140  func ext۰reflect۰rtype۰Out(fr *frame, args []value) value {
   141  	// Signature: func (t reflect.rtype, i int) int
   142  	i := args[1].(int)
   143  	return makeReflectType(rtype{args[0].(rtype).t.(*types.Signature).Results().At(i).Type()})
   144  }
   145  
   146  func ext۰reflect۰rtype۰Size(fr *frame, args []value) value {
   147  	// Signature: func (t reflect.rtype) uintptr
   148  	return uintptr(fr.i.sizes.Sizeof(args[0].(rtype).t))
   149  }
   150  
   151  func ext۰reflect۰rtype۰String(fr *frame, args []value) value {
   152  	// Signature: func (t reflect.rtype) string
   153  	return args[0].(rtype).t.String()
   154  }
   155  
   156  func ext۰reflect۰New(fr *frame, args []value) value {
   157  	// Signature: func (t reflect.Type) reflect.Value
   158  	t := args[0].(iface).v.(rtype).t
   159  	alloc := zero(t)
   160  	return makeReflectValue(types.NewPointer(t), &alloc)
   161  }
   162  
   163  func ext۰reflect۰SliceOf(fr *frame, args []value) value {
   164  	// Signature: func (t reflect.rtype) Type
   165  	return makeReflectType(rtype{types.NewSlice(args[0].(iface).v.(rtype).t)})
   166  }
   167  
   168  func ext۰reflect۰TypeOf(fr *frame, args []value) value {
   169  	// Signature: func (t reflect.rtype) Type
   170  	return makeReflectType(rtype{args[0].(iface).t})
   171  }
   172  
   173  func ext۰reflect۰ValueOf(fr *frame, args []value) value {
   174  	// Signature: func (interface{}) reflect.Value
   175  	itf := args[0].(iface)
   176  	return makeReflectValue(itf.t, itf.v)
   177  }
   178  
   179  func ext۰reflect۰Zero(fr *frame, args []value) value {
   180  	// Signature: func (t reflect.Type) reflect.Value
   181  	t := args[0].(iface).v.(rtype).t
   182  	return makeReflectValue(t, zero(t))
   183  }
   184  
   185  func reflectKind(t types.Type) reflect.Kind {
   186  	switch t := t.(type) {
   187  	case *types.Named:
   188  		return reflectKind(t.Underlying())
   189  	case *types.Basic:
   190  		switch t.Kind() {
   191  		case types.Bool:
   192  			return reflect.Bool
   193  		case types.Int:
   194  			return reflect.Int
   195  		case types.Int8:
   196  			return reflect.Int8
   197  		case types.Int16:
   198  			return reflect.Int16
   199  		case types.Int32:
   200  			return reflect.Int32
   201  		case types.Int64:
   202  			return reflect.Int64
   203  		case types.Uint:
   204  			return reflect.Uint
   205  		case types.Uint8:
   206  			return reflect.Uint8
   207  		case types.Uint16:
   208  			return reflect.Uint16
   209  		case types.Uint32:
   210  			return reflect.Uint32
   211  		case types.Uint64:
   212  			return reflect.Uint64
   213  		case types.Uintptr:
   214  			return reflect.Uintptr
   215  		case types.Float32:
   216  			return reflect.Float32
   217  		case types.Float64:
   218  			return reflect.Float64
   219  		case types.Complex64:
   220  			return reflect.Complex64
   221  		case types.Complex128:
   222  			return reflect.Complex128
   223  		case types.String:
   224  			return reflect.String
   225  		case types.UnsafePointer:
   226  			return reflect.UnsafePointer
   227  		}
   228  	case *types.Array:
   229  		return reflect.Array
   230  	case *types.Chan:
   231  		return reflect.Chan
   232  	case *types.Signature:
   233  		return reflect.Func
   234  	case *types.Interface:
   235  		return reflect.Interface
   236  	case *types.Map:
   237  		return reflect.Map
   238  	case *types.Pointer:
   239  		return reflect.Ptr
   240  	case *types.Slice:
   241  		return reflect.Slice
   242  	case *types.Struct:
   243  		return reflect.Struct
   244  	}
   245  	panic(fmt.Sprint("unexpected type: ", t))
   246  }
   247  
   248  func ext۰reflect۰Value۰Kind(fr *frame, args []value) value {
   249  	// Signature: func (reflect.Value) uint
   250  	return uint(reflectKind(rV2T(args[0]).t))
   251  }
   252  
   253  func ext۰reflect۰Value۰String(fr *frame, args []value) value {
   254  	// Signature: func (reflect.Value) string
   255  	return toString(rV2V(args[0]))
   256  }
   257  
   258  func ext۰reflect۰Value۰Type(fr *frame, args []value) value {
   259  	// Signature: func (reflect.Value) reflect.Type
   260  	return makeReflectType(rV2T(args[0]))
   261  }
   262  
   263  func ext۰reflect۰Value۰Uint(fr *frame, args []value) value {
   264  	// Signature: func (reflect.Value) uint64
   265  	switch v := rV2V(args[0]).(type) {
   266  	case uint:
   267  		return uint64(v)
   268  	case uint8:
   269  		return uint64(v)
   270  	case uint16:
   271  		return uint64(v)
   272  	case uint32:
   273  		return uint64(v)
   274  	case uint64:
   275  		return uint64(v)
   276  	case uintptr:
   277  		return uint64(v)
   278  	}
   279  	panic("reflect.Value.Uint")
   280  }
   281  
   282  func ext۰reflect۰Value۰Len(fr *frame, args []value) value {
   283  	// Signature: func (reflect.Value) int
   284  	switch v := rV2V(args[0]).(type) {
   285  	case string:
   286  		return len(v)
   287  	case array:
   288  		return len(v)
   289  	case chan value:
   290  		return cap(v)
   291  	case []value:
   292  		return len(v)
   293  	case *hashmap:
   294  		return v.len()
   295  	case map[value]value:
   296  		return len(v)
   297  	default:
   298  		panic(fmt.Sprintf("reflect.(Value).Len(%v)", v))
   299  	}
   300  }
   301  
   302  func ext۰reflect۰Value۰MapIndex(fr *frame, args []value) value {
   303  	// Signature: func (reflect.Value) Value
   304  	tValue := rV2T(args[0]).t.Underlying().(*types.Map).Key()
   305  	k := rV2V(args[1])
   306  	switch m := rV2V(args[0]).(type) {
   307  	case map[value]value:
   308  		if v, ok := m[k]; ok {
   309  			return makeReflectValue(tValue, v)
   310  		}
   311  
   312  	case *hashmap:
   313  		if v := m.lookup(k.(hashable)); v != nil {
   314  			return makeReflectValue(tValue, v)
   315  		}
   316  
   317  	default:
   318  		panic(fmt.Sprintf("(reflect.Value).MapIndex(%T, %T)", m, k))
   319  	}
   320  	return makeReflectValue(nil, nil)
   321  }
   322  
   323  func ext۰reflect۰Value۰MapKeys(fr *frame, args []value) value {
   324  	// Signature: func (reflect.Value) []Value
   325  	var keys []value
   326  	tKey := rV2T(args[0]).t.Underlying().(*types.Map).Key()
   327  	switch v := rV2V(args[0]).(type) {
   328  	case map[value]value:
   329  		for k := range v {
   330  			keys = append(keys, makeReflectValue(tKey, k))
   331  		}
   332  
   333  	case *hashmap:
   334  		for _, e := range v.entries() {
   335  			for ; e != nil; e = e.next {
   336  				keys = append(keys, makeReflectValue(tKey, e.key))
   337  			}
   338  		}
   339  
   340  	default:
   341  		panic(fmt.Sprintf("(reflect.Value).MapKeys(%T)", v))
   342  	}
   343  	return keys
   344  }
   345  
   346  func ext۰reflect۰Value۰NumField(fr *frame, args []value) value {
   347  	// Signature: func (reflect.Value) int
   348  	return len(rV2V(args[0]).(structure))
   349  }
   350  
   351  func ext۰reflect۰Value۰NumMethod(fr *frame, args []value) value {
   352  	// Signature: func (reflect.Value) int
   353  	return fr.i.prog.MethodSets.MethodSet(rV2T(args[0]).t).Len()
   354  }
   355  
   356  func ext۰reflect۰Value۰Pointer(fr *frame, args []value) value {
   357  	// Signature: func (v reflect.Value) uintptr
   358  	switch v := rV2V(args[0]).(type) {
   359  	case *value:
   360  		return uintptr(unsafe.Pointer(v))
   361  	case chan value:
   362  		return reflect.ValueOf(v).Pointer()
   363  	case []value:
   364  		return reflect.ValueOf(v).Pointer()
   365  	case *hashmap:
   366  		return reflect.ValueOf(v.entries()).Pointer()
   367  	case map[value]value:
   368  		return reflect.ValueOf(v).Pointer()
   369  	case *ssa.Function:
   370  		return uintptr(unsafe.Pointer(v))
   371  	case *closure:
   372  		return uintptr(unsafe.Pointer(v))
   373  	default:
   374  		panic(fmt.Sprintf("reflect.(Value).Pointer(%T)", v))
   375  	}
   376  }
   377  
   378  func ext۰reflect۰Value۰Index(fr *frame, args []value) value {
   379  	// Signature: func (v reflect.Value, i int) Value
   380  	i := args[1].(int)
   381  	t := rV2T(args[0]).t.Underlying()
   382  	switch v := rV2V(args[0]).(type) {
   383  	case array:
   384  		return makeReflectValue(t.(*types.Array).Elem(), v[i])
   385  	case []value:
   386  		return makeReflectValue(t.(*types.Slice).Elem(), v[i])
   387  	default:
   388  		panic(fmt.Sprintf("reflect.(Value).Index(%T)", v))
   389  	}
   390  }
   391  
   392  func ext۰reflect۰Value۰Bool(fr *frame, args []value) value {
   393  	// Signature: func (reflect.Value) bool
   394  	return rV2V(args[0]).(bool)
   395  }
   396  
   397  func ext۰reflect۰Value۰CanAddr(fr *frame, args []value) value {
   398  	// Signature: func (v reflect.Value) bool
   399  	// Always false for our representation.
   400  	return false
   401  }
   402  
   403  func ext۰reflect۰Value۰CanInterface(fr *frame, args []value) value {
   404  	// Signature: func (v reflect.Value) bool
   405  	// Always true for our representation.
   406  	return true
   407  }
   408  
   409  func ext۰reflect۰Value۰Elem(fr *frame, args []value) value {
   410  	// Signature: func (v reflect.Value) reflect.Value
   411  	switch x := rV2V(args[0]).(type) {
   412  	case iface:
   413  		return makeReflectValue(x.t, x.v)
   414  	case *value:
   415  		return makeReflectValue(rV2T(args[0]).t.Underlying().(*types.Pointer).Elem(), *x)
   416  	default:
   417  		panic(fmt.Sprintf("reflect.(Value).Elem(%T)", x))
   418  	}
   419  }
   420  
   421  func ext۰reflect۰Value۰Field(fr *frame, args []value) value {
   422  	// Signature: func (v reflect.Value, i int) reflect.Value
   423  	v := args[0]
   424  	i := args[1].(int)
   425  	return makeReflectValue(rV2T(v).t.Underlying().(*types.Struct).Field(i).Type(), rV2V(v).(structure)[i])
   426  }
   427  
   428  func ext۰reflect۰Value۰Float(fr *frame, args []value) value {
   429  	// Signature: func (reflect.Value) float64
   430  	switch v := rV2V(args[0]).(type) {
   431  	case float32:
   432  		return float64(v)
   433  	case float64:
   434  		return float64(v)
   435  	}
   436  	panic("reflect.Value.Float")
   437  }
   438  
   439  func ext۰reflect۰Value۰Interface(fr *frame, args []value) value {
   440  	// Signature: func (v reflect.Value) interface{}
   441  	return ext۰reflect۰valueInterface(fr, args)
   442  }
   443  
   444  func ext۰reflect۰Value۰Int(fr *frame, args []value) value {
   445  	// Signature: func (reflect.Value) int64
   446  	switch x := rV2V(args[0]).(type) {
   447  	case int:
   448  		return int64(x)
   449  	case int8:
   450  		return int64(x)
   451  	case int16:
   452  		return int64(x)
   453  	case int32:
   454  		return int64(x)
   455  	case int64:
   456  		return x
   457  	default:
   458  		panic(fmt.Sprintf("reflect.(Value).Int(%T)", x))
   459  	}
   460  }
   461  
   462  func ext۰reflect۰Value۰IsNil(fr *frame, args []value) value {
   463  	// Signature: func (reflect.Value) bool
   464  	switch x := rV2V(args[0]).(type) {
   465  	case *value:
   466  		return x == nil
   467  	case chan value:
   468  		return x == nil
   469  	case map[value]value:
   470  		return x == nil
   471  	case *hashmap:
   472  		return x == nil
   473  	case iface:
   474  		return x.t == nil
   475  	case []value:
   476  		return x == nil
   477  	case *ssa.Function:
   478  		return x == nil
   479  	case *ssa.Builtin:
   480  		return x == nil
   481  	case *closure:
   482  		return x == nil
   483  	default:
   484  		panic(fmt.Sprintf("reflect.(Value).IsNil(%T)", x))
   485  	}
   486  }
   487  
   488  func ext۰reflect۰Value۰IsValid(fr *frame, args []value) value {
   489  	// Signature: func (reflect.Value) bool
   490  	return rV2V(args[0]) != nil
   491  }
   492  
   493  func ext۰reflect۰Value۰Set(fr *frame, args []value) value {
   494  	// TODO(adonovan): implement.
   495  	return nil
   496  }
   497  
   498  func ext۰reflect۰valueInterface(fr *frame, args []value) value {
   499  	// Signature: func (v reflect.Value, safe bool) interface{}
   500  	v := args[0].(structure)
   501  	return iface{rV2T(v).t, rV2V(v)}
   502  }
   503  
   504  func ext۰reflect۰error۰Error(fr *frame, args []value) value {
   505  	return args[0]
   506  }
   507  
   508  // newMethod creates a new method of the specified name, package and receiver type.
   509  func newMethod(pkg *ssa.Package, recvType types.Type, name string) *ssa.Function {
   510  	// TODO(adonovan): fix: hack: currently the only part of Signature
   511  	// that is needed is the "pointerness" of Recv.Type, and for
   512  	// now, we'll set it to always be false since we're only
   513  	// concerned with rtype.  Encapsulate this better.
   514  	sig := types.NewSignature(types.NewVar(token.NoPos, nil, "recv", recvType), nil, nil, false)
   515  	fn := pkg.Prog.NewFunction(name, sig, "fake reflect method")
   516  	fn.Pkg = pkg
   517  	return fn
   518  }
   519  
   520  func initReflect(i *interpreter) {
   521  	i.reflectPackage = &ssa.Package{
   522  		Prog:    i.prog,
   523  		Pkg:     reflectTypesPackage,
   524  		Members: make(map[string]ssa.Member),
   525  	}
   526  
   527  	// Clobber the type-checker's notion of reflect.Value's
   528  	// underlying type so that it more closely matches the fake one
   529  	// (at least in the number of fields---we lie about the type of
   530  	// the rtype field).
   531  	//
   532  	// We must ensure that calls to (ssa.Value).Type() return the
   533  	// fake type so that correct "shape" is used when allocating
   534  	// variables, making zero values, loading, and storing.
   535  	//
   536  	// TODO(adonovan): obviously this is a hack.  We need a cleaner
   537  	// way to fake the reflect package (almost---DeepEqual is fine).
   538  	// One approach would be not to even load its source code, but
   539  	// provide fake source files.  This would guarantee that no bad
   540  	// information leaks into other packages.
   541  	if r := i.prog.ImportedPackage("reflect"); r != nil {
   542  		rV := r.Pkg.Scope().Lookup("Value").Type().(*types.Named)
   543  
   544  		// delete bodies of the old methods
   545  		mset := i.prog.MethodSets.MethodSet(rV)
   546  		for j := 0; j < mset.Len(); j++ {
   547  			i.prog.MethodValue(mset.At(j)).Blocks = nil
   548  		}
   549  
   550  		tEface := types.NewInterface(nil, nil).Complete()
   551  		rV.SetUnderlying(types.NewStruct([]*types.Var{
   552  			types.NewField(token.NoPos, r.Pkg, "t", tEface, false), // a lie
   553  			types.NewField(token.NoPos, r.Pkg, "v", tEface, false),
   554  		}, nil))
   555  	}
   556  
   557  	i.rtypeMethods = methodSet{
   558  		"Bits":      newMethod(i.reflectPackage, rtypeType, "Bits"),
   559  		"Elem":      newMethod(i.reflectPackage, rtypeType, "Elem"),
   560  		"Field":     newMethod(i.reflectPackage, rtypeType, "Field"),
   561  		"In":        newMethod(i.reflectPackage, rtypeType, "In"),
   562  		"Kind":      newMethod(i.reflectPackage, rtypeType, "Kind"),
   563  		"NumField":  newMethod(i.reflectPackage, rtypeType, "NumField"),
   564  		"NumIn":     newMethod(i.reflectPackage, rtypeType, "NumIn"),
   565  		"NumMethod": newMethod(i.reflectPackage, rtypeType, "NumMethod"),
   566  		"NumOut":    newMethod(i.reflectPackage, rtypeType, "NumOut"),
   567  		"Out":       newMethod(i.reflectPackage, rtypeType, "Out"),
   568  		"Size":      newMethod(i.reflectPackage, rtypeType, "Size"),
   569  		"String":    newMethod(i.reflectPackage, rtypeType, "String"),
   570  	}
   571  	i.errorMethods = methodSet{
   572  		"Error": newMethod(i.reflectPackage, errorType, "Error"),
   573  	}
   574  }