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 }
// 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) } }
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 }
// 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() }
// 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 } }
func labelType(t reflect.Type) bool { switch t.Kind() { case reflect.Interface, reflect.Struct: return true } return false }
// 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()) } }
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} }
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 }
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 }
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 }
// 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 }
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 }
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 }
// 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()) }
// 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 }
// 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 }
// 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 }
// 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 }
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 }
// 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} }
// 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 }
// 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 }
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 }
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 }
// 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") }
func newMapEncoder(t reflect.Type) encoderFunc { if t.Key().Kind() != reflect.String { return unsupportedTypeEncoder } me := &mapEncoder{typeEncoder(t.Elem())} return me.encode }
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 }
// 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 }