示例#1
1
func finishNewTable(b *tablebase, ty reflect.Type) Table {
	id := C.newTable()
	t := &table{
		scroller:  newScroller(id, true), // border on Table
		tablebase: b,
		selected:  newEvent(),
	}
	t.fpreferredSize = t.xpreferredSize
	// also sets the delegate
	C.tableMakeDataSource(t.id, unsafe.Pointer(t))
	for i := 0; i < ty.NumField(); i++ {
		colname := ty.Field(i).Tag.Get("uicolumn")
		if colname == "" {
			colname = ty.Field(i).Name
		}
		cname := C.CString(colname)
		coltype := C.colTypeText
		editable := false
		switch {
		case ty.Field(i).Type == reflect.TypeOf((*image.RGBA)(nil)):
			coltype = C.colTypeImage
		case ty.Field(i).Type.Kind() == reflect.Bool:
			coltype = C.colTypeCheckbox
			editable = true
		}
		C.tableAppendColumn(t.id, C.intptr_t(i), cname, C.int(coltype), toBOOL(editable))
		C.free(unsafe.Pointer(cname)) // free now (not deferred) to conserve memory
	}
	return t
}
示例#2
1
// Add imports for each of the methods of the interface, but not the interface
// itself.
func addImportsForInterfaceMethods(imports importMap, it reflect.Type) {
	// Handle each method.
	for i := 0; i < it.NumMethod(); i++ {
		m := it.Method(i)
		addImportsForType(imports, m.Type)
	}
}
示例#3
1
func sampleFormat(b reflect.Type) (f C.PaSampleFormat) {
	if b.Kind() != reflect.Slice {
		return 0
	}
	b = b.Elem()
	if b.Kind() == reflect.Slice {
		f = C.paNonInterleaved
		b = b.Elem()
	}
	switch b.Kind() {
	case reflect.Float32:
		f |= C.paFloat32
	case reflect.Int32:
		f |= C.paInt32
	default:
		if b == reflect.TypeOf(Int24{}) {
			f |= C.paInt24
		} else {
			return 0
		}
	case reflect.Int16:
		f |= C.paInt16
	case reflect.Int8:
		f |= C.paInt8
	case reflect.Uint8:
		f |= C.paUInt8
	}
	return f
}
示例#4
1
文件: luar.go 项目: imvu/Tetra
// Copy matching Lua table entries to a struct, given the struct type
// and the index on the Lua stack.
func CopyTableToStruct(L *lua.State, t reflect.Type, idx int) interface{} {
	was_ptr := t.Kind() == reflect.Ptr
	if was_ptr {
		t = t.Elem()
	}
	s := reflect.New(t) // T -> *T
	ref := s.Elem()
	L.PushNil()
	if idx < 0 {
		idx--
	}
	for L.Next(idx) != 0 {
		key := L.ToString(-2)
		f := ref.FieldByName(strings.Title(key))
		if f.IsValid() {
			val := luaToGoValue(L, f.Type(), -1)
			f.Set(val)
		}
		L.Pop(1)
	}
	if was_ptr {
		return s.Interface()
	}
	return s.Elem().Interface()
}
示例#5
1
// lessFunc returns a function that implements the "<" operator
// for the given type, or nil if the type doesn't support "<" .
func lessFunc(t reflect.Type) func(v1, v2 interface{}) bool {
	switch t.Kind() {
	case reflect.String:
		return func(v1, v2 interface{}) bool { return v1.(string) < v2.(string) }
	case reflect.Int:
		return func(v1, v2 interface{}) bool { return v1.(int) < v2.(int) }
	case reflect.Int8:
		return func(v1, v2 interface{}) bool { return v1.(int8) < v2.(int8) }
	case reflect.Int16:
		return func(v1, v2 interface{}) bool { return v1.(int16) < v2.(int16) }
	case reflect.Int32:
		return func(v1, v2 interface{}) bool { return v1.(int32) < v2.(int32) }
	case reflect.Int64:
		return func(v1, v2 interface{}) bool { return v1.(int64) < v2.(int64) }
	case reflect.Uint:
		return func(v1, v2 interface{}) bool { return v1.(uint) < v2.(uint) }
	case reflect.Uint8:
		return func(v1, v2 interface{}) bool { return v1.(uint8) < v2.(uint8) }
	case reflect.Uint16:
		return func(v1, v2 interface{}) bool { return v1.(uint16) < v2.(uint16) }
	case reflect.Uint32:
		return func(v1, v2 interface{}) bool { return v1.(uint32) < v2.(uint32) }
	case reflect.Uint64:
		return func(v1, v2 interface{}) bool { return v1.(uint64) < v2.(uint64) }
	case reflect.Float32:
		return func(v1, v2 interface{}) bool { return v1.(float32) < v2.(float32) }
	case reflect.Float64:
		return func(v1, v2 interface{}) bool { return v1.(float64) < v2.(float64) }
	default:
		return nil
	}
}
示例#6
1
func labelType(t reflect.Type) bool {
	switch t.Kind() {
	case reflect.Interface, reflect.Struct:
		return true
	}
	return false
}
示例#7
1
// Add an import for the supplied type, without recursing.
func addImportForType(imports importMap, t reflect.Type) {
	// If there is no package path, this is a built-in type and we don't need an
	// import.
	pkgPath := t.PkgPath()
	if pkgPath == "" {
		return
	}

	// Work around a bug in Go:
	//
	//     http://code.google.com/p/go/issues/detail?id=2660
	//
	var errorPtr *error
	if t == reflect.TypeOf(errorPtr).Elem() {
		return
	}

	// Use the identifier that's part of the type's string representation as the
	// import identifier. This means that we'll do the right thing for package
	// "foo/bar" with declaration "package baz".
	match := typePackageIdentifierRegexp.FindStringSubmatch(t.String())
	if match == nil {
		return
	}

	imports[match[1]] = pkgPath
}
// Recursively check composite literals, where a child composite lit's type depends the
// parent's type For example, the expression [][]int{{1,2},{3,4}} contains two
// slice lits, {1,2} and {3,4}, but their types are inferenced from the parent [][]int{}.
func checkCompositeLitR(lit *ast.CompositeLit, t reflect.Type, env Env) (*CompositeLit, []error) {
	alit := &CompositeLit{CompositeLit: lit}

	// We won't generate any errors here if the given type does not match lit.Type.
	// The caller will need to detect the type incompatibility.
	if lit.Type != nil {
		var errs []error
		lit.Type, t, _, errs = checkType(lit.Type, env)
		if errs != nil {
			return alit, errs
		}
	} else if t == nil {
		return alit, []error{ErrMissingCompositeLitType{alit}}
	}

	alit.knownType = knownType{t}
	if alit.CompositeLit.Elts != nil {
		alit.Elts = make([]Expr, len(alit.CompositeLit.Elts))
	}

	switch t.Kind() {
	case reflect.Map:
		return checkCompositeLitMap(alit, t, env)
	case reflect.Array, reflect.Slice:
		return checkCompositeLitArrayOrSlice(alit, t, env)
	case reflect.Struct:
		return checkCompositeLitStruct(alit, t, env)
	default:
		panic("eval: unimplemented composite lit " + t.Kind().String())
	}
}
示例#9
0
func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) {
	switch val.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return strconv.FormatInt(val.Int(), 10), nil, nil
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return strconv.FormatUint(val.Uint(), 10), nil, nil
	case reflect.Float32, reflect.Float64:
		return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil
	case reflect.String:
		return val.String(), nil, nil
	case reflect.Bool:
		return strconv.FormatBool(val.Bool()), nil, nil
	case reflect.Array:
		if typ.Elem().Kind() != reflect.Uint8 {
			break
		}
		// [...]byte
		var bytes []byte
		if val.CanAddr() {
			bytes = val.Slice(0, val.Len()).Bytes()
		} else {
			bytes = make([]byte, val.Len())
			reflect.Copy(reflect.ValueOf(bytes), val)
		}
		return "", bytes, nil
	case reflect.Slice:
		if typ.Elem().Kind() != reflect.Uint8 {
			break
		}
		// []byte
		return "", val.Bytes(), nil
	}
	return "", nil, &UnsupportedTypeError{typ}
}
示例#10
0
文件: gorp.go 项目: joeshaw/gorp
func readStructColumns(t reflect.Type) (cols []*ColumnMap, version *ColumnMap) {
	n := t.NumField()
	for i := 0; i < n; i++ {
		f := t.Field(i)
		if f.Anonymous && f.Type.Kind() == reflect.Struct {
			// Recursively add nested fields in embedded structs.
			subcols, subversion := readStructColumns(f.Type)
			cols = append(cols, subcols...)
			if subversion != nil {
				version = subversion
			}
		} else {
			columnName := f.Tag.Get("db")
			if columnName == "" {
				columnName = f.Name
			}
			cm := &ColumnMap{
				ColumnName: columnName,
				Transient:  columnName == "-",
				fieldName:  f.Name,
				gotype:     f.Type,
			}
			cols = append(cols, cm)
			if cm.fieldName == "Version" {
				version = cm
			}
		}
	}
	return
}
示例#11
0
文件: object.go 项目: twstrike/coyim
func fixupArgs(t reflect.Type, v ...interface{}) []reflect.Value {
	res := make([]reflect.Value, len(v))
	for ix, vv := range v {
		res[ix] = fixupArg(t.In(ix), vv)
	}
	return res
}
示例#12
0
func getFields(typ reflect.Type) *fields {
	numField := typ.NumField()
	fs := newFields(numField)

	for i := 0; i < numField; i++ {
		f := typ.Field(i)
		if f.PkgPath != "" && !f.Anonymous {
			continue
		}

		name, opts := parseTag(f.Tag.Get("msgpack"))
		if name == "-" {
			continue
		}

		if opts.Contains("inline") {
			inlineFields(fs, f)
			continue
		}

		if name == "" {
			name = f.Name
		}
		field := field{
			name:      name,
			index:     f.Index,
			omitEmpty: opts.Contains("omitempty"),
			encoder:   getEncoder(f.Type),
			decoder:   getDecoder(f.Type),
		}
		fs.Add(&field)
	}
	return fs
}
示例#13
0
文件: patch.go 项目: ncantor/origin
// Returns the type of the elements of N slice(s). If the type is different,
// another slice or undefined, returns an error.
func sliceElementType(slices ...[]interface{}) (reflect.Type, error) {
	var prevType reflect.Type
	for _, s := range slices {
		// Go through elements of all given slices and make sure they are all the same type.
		for _, v := range s {
			currentType := reflect.TypeOf(v)
			if prevType == nil {
				prevType = currentType
				// We don't support lists of lists yet.
				if prevType.Kind() == reflect.Slice {
					return nil, errNoListOfLists
				}
			} else {
				if prevType != currentType {
					return nil, fmt.Errorf("list element types are not identical: %v", fmt.Sprint(slices))
				}
				prevType = currentType
			}
		}
	}

	if prevType == nil {
		return nil, fmt.Errorf("no elements in any of the given slices")
	}

	return prevType, nil
}
示例#14
0
func getParams(elem reflect.Type) []Parameter {
	parameters := []Parameter{}

	l := elem.NumField()

	for i := 0; i < l; i++ {
		f := elem.Field(i)

		jsonName := f.Tag.Get("json")

		if f.Anonymous {
			parameters = append(parameters, getParams(f.Type)...)
		} else if jsonName != "" {
			p := Parameter{}

			p.Name = jsonName
			p.Type = f.Type.String()
			p.Description = f.Tag.Get("description")
			enum := f.Tag.Get("enum")
			if enum != "" {
				p.EnumValues = strings.Split(enum, ",")
				p.Type = "enum"
			} else {
				p.EnumValues = []string{}
			}

			parameters = append(parameters, p)
		}
	}

	return parameters
}
示例#15
0
func fixArgs(args []reflect.Value, lastParamType reflect.Type, context Context) []reflect.Value {
	if lastParamType.String() == "interface {}" ||
		lastParamType.String() == "hprose.Context" {
		args = append(args, reflect.ValueOf(context))
	}
	return args
}
示例#16
0
文件: var.go 项目: TuneLab/env
// Convert a string into the specified type. Return the type's zero value
// if we receive an empty string
func convert(t reflect.Type, value string) (reflect.Value, error) {
	if value == "" {
		return reflect.ValueOf(nil), nil
	}

	var d time.Duration

	switch t {
	case reflect.TypeOf(d):
		result, err := time.ParseDuration(value)
		return reflect.ValueOf(result), err
	default:
	}

	switch t.Kind() {
	case reflect.String:
		return reflect.ValueOf(value), nil
	case reflect.Int:
		return parseInt(value)
	case reflect.Bool:
		return parseBool(value)
	}

	return reflect.ValueOf(nil), conversionError(value, `unsupported `+t.Kind().String())
}
示例#17
0
// implementsInterface reports whether the type implements the
// gobEncoder/gobDecoder interface.
// It also returns the number of indirections required to get to the
// implementation.
func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
	if typ == nil {
		return
	}
	rt := typ
	// The type might be a pointer and we need to keep
	// dereferencing to the base type until we find an implementation.
	for {
		if rt.Implements(gobEncDecType) {
			return true, indir
		}
		if p := rt; p.Kind() == reflect.Ptr {
			indir++
			if indir > 100 { // insane number of indirections
				return false, 0
			}
			rt = p.Elem()
			continue
		}
		break
	}
	// No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
	if typ.Kind() != reflect.Ptr {
		// Not a pointer, but does the pointer work?
		if reflect.PtrTo(typ).Implements(gobEncDecType) {
			return true, -1
		}
	}
	return false, 0
}
示例#18
0
// callSliceRequired returns true if CallSlice is required instead of Call.
func callSliceRequired(param reflect.Type, val reflect.Value) bool {
	vt := val.Type()
	for param.Kind() == reflect.Slice {
		if val.Kind() == reflect.Interface {
			val = reflect.ValueOf(val.Interface())
			vt = val.Type()
		}

		if vt.Kind() != reflect.Slice {
			return false
		}

		vt = vt.Elem()
		if val.Kind() != reflect.Invalid {
			if val.Len() > 0 {
				val = val.Index(0)
			} else {
				val = reflect.Value{}
			}
		}
		param = param.Elem()
	}

	return true
}
示例#19
0
// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
//
// Copied from Go stdlib src/text/template/exec.go.
func canBeNil(typ reflect.Type) bool {
	switch typ.Kind() {
	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return true
	}
	return false
}
示例#20
0
// alignment returns the alignment of values of type t.
func alignment(t reflect.Type) int {
	switch t {
	case variantType:
		return 1
	case objectPathType:
		return 4
	case signatureType:
		return 1
	case interfacesType:
		return 4
	}
	switch t.Kind() {
	case reflect.Uint8:
		return 1
	case reflect.Uint16, reflect.Int16:
		return 2
	case reflect.Uint32, reflect.Int32, reflect.String, reflect.Array, reflect.Slice, reflect.Map:
		return 4
	case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Struct:
		return 8
	case reflect.Ptr:
		return alignment(t.Elem())
	}
	return 1
}
示例#21
0
func checkArrayValue(expr ast.Expr, eltT reflect.Type, env Env) (Expr, []error) {
	switch eltT.Kind() {
	case reflect.Array, reflect.Slice, reflect.Map, reflect.Struct:
		if lit, ok := expr.(*ast.CompositeLit); ok {
			return checkCompositeLitR(lit, eltT, env)
		}
	}

	aexpr, ok, errs := checkExprAssignableTo(expr, eltT, env)
	if !ok {
		// NOTE[crc] this hack removes conversion errors from consts other
		// than strings and nil to match the output of gc.
		if ccerr, ok := errs[0].(ErrBadConstConversion); ok {
			if ccerr.from == ConstNil {
				// No ErrBadArrayValue for nil
				return aexpr, errs
			} else if ccerr.from != ConstString {
				// gc implementation only displays string conversion errors
				errs = nil
			}
		}
		errs = append(errs, ErrBadArrayValue{aexpr, eltT})
	}
	return aexpr, errs
}
示例#22
0
// prepareMethod returns a methodType for the provided method or nil
// in case if the method was unsuitable.
func prepareMethod(method reflect.Method) *methodType {
	mtype := method.Type
	mname := method.Name
	var replyType, argType, contextType reflect.Type

	stream := false
	// Method must be exported.
	if method.PkgPath != "" {
		return nil
	}

	switch mtype.NumIn() {
	case 3:
		// normal method
		argType = mtype.In(1)
		replyType = mtype.In(2)
		contextType = nil
	case 4:
		// method that takes a context
		argType = mtype.In(2)
		replyType = mtype.In(3)
		contextType = mtype.In(1)
	default:
		log.Println("method", mname, "of", mtype, "has wrong number of ins:", mtype.NumIn())
		return nil
	}

	// First arg need not be a pointer.
	if !isExportedOrBuiltinType(argType) {
		log.Println(mname, "argument type not exported:", argType)
		return nil
	}

	// the second argument will tell us if it's a streaming call
	// or a regular call
	if replyType == typeOfStream {
		// this is a streaming call
		stream = true
	} else if replyType.Kind() != reflect.Ptr {
		log.Println("method", mname, "reply type not a pointer:", replyType)
		return nil
	}

	// Reply type must be exported.
	if !isExportedOrBuiltinType(replyType) {
		log.Println("method", mname, "reply type not exported:", replyType)
		return nil
	}
	// Method needs one out.
	if mtype.NumOut() != 1 {
		log.Println("method", mname, "has wrong number of outs:", mtype.NumOut())
		return nil
	}
	// The return type of the method must be error.
	if returnType := mtype.Out(0); returnType != typeOfError {
		log.Println("method", mname, "returns", returnType.String(), "not error")
		return nil
	}
	return &methodType{method: method, ArgType: argType, ReplyType: replyType, ContextType: contextType, stream: stream}
}
示例#23
0
// hasUnrecognizedKeys finds unrecognized keys and warns about them on stderr.
// returns false when no unrecognized keys were found, true otherwise.
func hasUnrecognizedKeys(inCfg interface{}, refType reflect.Type) (warnings bool) {
	if refType.Kind() == reflect.Ptr {
		refType = refType.Elem()
	}
	switch inCfg.(type) {
	case map[interface{}]interface{}:
		ks := inCfg.(map[interface{}]interface{})
	keys:
		for key := range ks {
			for i := 0; i < refType.NumField(); i++ {
				sf := refType.Field(i)
				tv := sf.Tag.Get("yaml")
				if tv == key {
					if warn := hasUnrecognizedKeys(ks[key], sf.Type); warn {
						warnings = true
					}
					continue keys
				}
			}

			glog.Errorf("Unrecognized keyword: %v", key)
			warnings = true
		}
	case []interface{}:
		ks := inCfg.([]interface{})
		for i := range ks {
			if warn := hasUnrecognizedKeys(ks[i], refType.Elem()); warn {
				warnings = true
			}
		}
	default:
	}
	return
}
示例#24
0
// AddExt registers an encode and decode function for a reflect.Type.
// Note that the type must be a named type, and specifically not
// a pointer or Interface. An error is returned if that is not honored.
//
// To Deregister an ext, call AddExt with 0 tag, nil encfn and nil decfn.
func (o *extHandle) AddExt(
	rt reflect.Type,
	tag byte,
	encfn func(reflect.Value) ([]byte, error),
	decfn func(reflect.Value, []byte) error,
) (err error) {
	// o is a pointer, because we may need to initialize it
	if rt.PkgPath() == "" || rt.Kind() == reflect.Interface {
		err = fmt.Errorf("codec.Handle.AddExt: Takes named type, especially not a pointer or interface: %T",
			reflect.Zero(rt).Interface())
		return
	}

	// o cannot be nil, since it is always embedded in a Handle.
	// if nil, let it panic.
	// if o == nil {
	// 	err = errors.New("codec.Handle.AddExt: extHandle cannot be a nil pointer.")
	// 	return
	// }

	rtid := reflect.ValueOf(rt).Pointer()
	for _, v := range *o {
		if v.rtid == rtid {
			v.tag, v.encFn, v.decFn = tag, encfn, decfn
			return
		}
	}

	*o = append(*o, &extTypeTagFn{rtid, rt, tag, encfn, decfn})
	return
}
示例#25
0
文件: typeinfo.go 项目: rsrsps/pg
func (c *structCache) Indexes(typ reflect.Type) map[string][]int {
	c.l.RLock()
	indxs, ok := c.m[typ]
	c.l.RUnlock()
	if ok {
		return indxs
	}

	numField := typ.NumField()
	indxs = make(map[string][]int, numField)
	for i := 0; i < numField; i++ {
		f := typ.Field(i)
		if f.PkgPath != "" {
			continue
		}

		tokens := strings.Split(f.Tag.Get("pg"), ",")
		name := tokens[0]
		if name == "-" {
			continue
		}
		if name == "" {
			name = formatColumnName(f.Name)
		}
		indxs[name] = f.Index
	}

	c.l.Lock()
	c.m[typ] = indxs
	c.l.Unlock()

	return indxs
}
示例#26
0
func decodeArray(r io.Reader, t reflect.Type) (reflect.Value, error) {
	var sz uint32
	if err := binary.Read(r, byteOrder, &sz); err != nil {
		return nullValue, err
	}

	ksz := int(kindSize(t.Elem().Kind()))

	data := make([]byte, int(sz)*ksz)
	_, err := r.Read(data)
	if err != nil {
		return nullValue, err
	}
	slice := reflect.MakeSlice(t, int(sz), int(sz))
	for i := 0; i < int(sz); i++ {
		from := data[i*ksz:]
		var val uint64
		switch ksz {
		case 1:
			val = uint64(from[0])
		case 2:
			val = uint64(byteOrder.Uint16(from[0:]))
		case 4:
			val = uint64(byteOrder.Uint32(from[0:]))
		default:
			panic("unimp")
		}

		slice.Index(i).SetUint(val)
	}
	return slice, nil
}
示例#27
0
文件: help.go 项目: chrjen/btcd
// reflectTypeToJSONType returns a string that represents the JSON type
// associated with the provided Go type.
func reflectTypeToJSONType(xT descLookupFunc, rt reflect.Type) string {
	kind := rt.Kind()
	if isNumeric(kind) {
		return xT("json-type-numeric")
	}

	switch kind {
	case reflect.String:
		return xT("json-type-string")

	case reflect.Bool:
		return xT("json-type-bool")

	case reflect.Array, reflect.Slice:
		return xT("json-type-array") + reflectTypeToJSONType(xT,
			rt.Elem())

	case reflect.Struct:
		return xT("json-type-object")

	case reflect.Map:
		return xT("json-type-object")
	}

	return xT("json-type-value")
}
示例#28
0
func newMapEncoder(t reflect.Type) encoderFunc {
	if t.Key().Kind() != reflect.String {
		return unsupportedTypeEncoder
	}
	me := &mapEncoder{typeEncoder(t.Elem())}
	return me.encode
}
示例#29
0
文件: sqlx.go 项目: nfraenkel/lunch
func baseType(t reflect.Type, expected reflect.Kind) (reflect.Type, error) {
	t = reflectx.Deref(t)
	if t.Kind() != expected {
		return nil, fmt.Errorf("expected %s but got %s", expected, t.Kind())
	}
	return t, nil
}
示例#30
0
// The reflection type must have all its indirections processed out.
// typeLock must be held.
func getTypeInfo(rt reflect.Type) (*typeInfo, os.Error) {
	if _, ok := rt.(*reflect.PtrType); ok {
		panic("pointer type in getTypeInfo: " + rt.String())
	}
	info, ok := typeInfoMap[rt]
	if !ok {
		info = new(typeInfo)
		name := rt.Name()
		gt, err := getType(name, rt)
		if err != nil {
			return nil, err
		}
		info.id = gt.id()
		t := info.id.gobType()
		switch typ := rt.(type) {
		case *reflect.ArrayType:
			info.wire = &wireType{arrayT: t.(*arrayType)}
		case *reflect.MapType:
			info.wire = &wireType{mapT: t.(*mapType)}
		case *reflect.SliceType:
			// []byte == []uint8 is a special case handled separately
			if _, ok := typ.Elem().(*reflect.Uint8Type); !ok {
				info.wire = &wireType{sliceT: t.(*sliceType)}
			}
		case *reflect.StructType:
			info.wire = &wireType{structT: t.(*structType)}
		}
		typeInfoMap[rt] = info
	}
	return info, nil
}