// 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 }
// Returns the default table name for a type func defaultTableName(typ reflect.Type) string { n := typ.Name() if p := typ.PkgPath(); !strings.HasPrefix(p, "main") { n = strings.Replace(p, "/", "_", -1) + n } return stringutil.CamelCaseToLower(n, "_") }
// Is this typoe exported or a builtin? func isExportedOrBuiltinType(t reflect.Type) bool { for t.Kind() == reflect.Ptr { t = t.Elem() } return isExported(t.Name()) || t.PkgPath() == "" }
func typeNamesEqual(methVal reflect.Type, name2 string) bool { if strings.Index(name2, ".") == -1 { return methVal.Name() == name2 } fullName := strings.Replace(methVal.PkgPath(), "/", ".", -1) + "." + methVal.Name() return fullName == name2 }
func checkStructureIsInTheSamePackage(packagePath string, basicType reflect.Type, encountered map[reflect.Type]bool) error { if encountered == nil { encountered = make(map[reflect.Type]bool) } if encountered[basicType] { return nil } encountered[basicType] = true pkgPath := basicType.PkgPath() if basicType.Kind() == reflect.Slice { return checkStructureIsInTheSamePackage(packagePath, basicType.Elem(), encountered) } else if basicType.Kind() == reflect.Ptr { return checkStructureIsInTheSamePackage(packagePath, basicType.Elem(), encountered) } else if len(pkgPath) == 0 || isPrimitiveType(basicType) { return nil } else if _, exception := isSamePackagePathException[pkgPath]; exception { return nil } else if pkgPath != packagePath { return fmt.Errorf(`Structure must be fully defined in the same package. Type '%s' is not.`, basicType) } else if basicType.Kind() == reflect.Struct { for i := 0; i < basicType.NumField(); i++ { err := checkStructureIsInTheSamePackage(packagePath, basicType.Field(i).Type, encountered) if err != nil { return err } } return nil } return errors.New(`Unreachable code`) }
func checkExternalJsonTags(objType reflect.Type, seen *map[reflect.Type]bool, t *testing.T) { if _, exists := (*seen)[objType]; exists { return } (*seen)[objType] = true if !strings.Contains(objType.PkgPath(), "github.com/openshift/origin/pkg") { return } for i := 0; i < objType.NumField(); i++ { structField := objType.FieldByIndex([]int{i}) jsonTag := structField.Tag.Get("json") if len(jsonTag) == 0 { t.Errorf("%v.%v should have a json tag", objType, structField.Name) } switch structField.Type.Kind() { case reflect.Struct: checkExternalJsonTags(structField.Type, seen, t) case reflect.Ptr: checkExternalJsonTags(structField.Type.Elem(), seen, t) } } }
func defaultType(t reflect.Type) TypeDesc { switch t.Kind() { case reflect.Bool: return BooleanType case reflect.String: return UTF8Type case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return LongType case reflect.Float32: return FloatType case reflect.Float64: return DoubleType case reflect.Array: if t.Name() == "UUID" && t.Size() == 16 { return UUIDType } return UnknownType case reflect.Struct: if t.Name() == "Time" && t.PkgPath() == "time" { return DateType } return UnknownType case reflect.Slice: if et := t.Elem(); et.Kind() == reflect.Uint8 { return BytesType } return UnknownType } return UnknownType }
// GetTypeHash returns the TypeHash for a given reflect.Type func GetTypeHash(t reflect.Type) TypeHash { if t.Kind() == reflect.Ptr { t = t.Elem() } return TypeHash(fmt.Sprintf("%s.%s", t.PkgPath(), t.Name())) }
func (b *Backend) FieldType(typ reflect.Type, t *structs.Tag) (string, error) { if c := codec.FromTag(t); c != nil { if c.Binary || t.PipeName() != "" { return "BLOB", nil } return "TEXT", nil } switch typ.Kind() { case reflect.Bool: return "BOOLEAN", nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return "INTEGER", nil case reflect.Float32, reflect.Float64: return "REAL", nil case reflect.String: return "TEXT", nil case reflect.Slice: // []byte if typ.Elem().Kind() == reflect.Uint8 { return "BLOB", nil } case reflect.Struct: if typ.Name() == "Time" && typ.PkgPath() == "time" { return "INTEGER", nil } } return "", fmt.Errorf("can't map field type %v to a database type", typ) }
func getReflectTypeName(reflectType reflect.Type) (string, error) { buffer := bytes.NewBuffer(nil) for reflectType.Kind() == reflect.Ptr { if _, err := buffer.WriteString("*"); err != nil { return "", err } reflectType = reflectType.Elem() } pkgPath := reflectType.PkgPath() if pkgPath == "" { return "", fmt.Errorf("ledge: no package for type %v", reflectType) } if _, err := buffer.WriteString("\""); err != nil { return "", err } if _, err := buffer.WriteString(pkgPath); err != nil { return "", err } if _, err := buffer.WriteString("\""); err != nil { return "", err } name := reflectType.Name() if name == "" { return "", fmt.Errorf("ledge: no name for type %v", reflectType) } if _, err := buffer.WriteString("."); err != nil { return "", err } if _, err := buffer.WriteString(name); err != nil { return "", err } return buffer.String(), nil }
func getOrCreateSchema(definitions Definitions, t reflect.Type) *Schema { var result Schema if t.Kind() == reflect.Ptr { t = t.Elem() } if t.Kind() == reflect.Map { if t.Key().Kind() != reflect.String { panic("swagger supports only maps with string keys") } result.Type = "object" result.AdditionalProperties = getOrCreateSchema(definitions, t.Elem()) return &result } if t.Kind() == reflect.Interface { result.Type = "object" return &result } result.Type = typeName(t) if result.Type == "object" { name := t.PkgPath() + "/" + t.String() if _, ok := definitions[name]; ok { result = Schema{Ref: "#/definitions/" + name} return &result } definitions[name] = result if t.NumField() > 0 { result.Properties = Properties{} } for i := 0; i < t.NumField(); i++ { field := t.Field(i) if field.PkgPath != "" { continue } name := field.Tag.Get("json") if name == "" { name = field.Tag.Get("key") if name == "" { name = field.Name } } if field.Type.Kind() != reflect.Ptr { result.Required = append(result.Required, name) } fieldSchema := getOrCreateSchema(definitions, field.Type) fieldSchema.Description = field.Tag.Get("description") result.Properties[name] = fieldSchema } definitions[name] = result result = Schema{Ref: "#/definitions/" + name} } else if result.Type == "array" { itemsSchema := getOrCreateSchema(definitions, t.Elem()) result.Items = &Items{*itemsSchema} } return &result }
// GetObjectTemplate retrieves a template given a certain type func (m *Manager) GetTypeTemplate(themeName, packageName string, t reflect.Type, view string) (*template.Template, error) { logger.Debug("Getting type template=%v+%v", t.PkgPath(), t.Name()) name := filepath.Join(t.PkgPath(), t.Name()) logger.Debug("Theme: %v, Package: %v, View: %v, method: %v, tname: %v, pkg: %v", themeName, packageName, name, view, t.Name(), t.PkgPath()) return m.GetTemplate(themeName, packageName, name, view+m.extension) }
// progType returns the go/types type for the given reflect.Type, // which must represent a named non-predeclared Go type. func progType(prog *loader.Program, t reflect.Type) (*types.TypeName, error) { if t.Kind() == reflect.Ptr { t = t.Elem() } typeName := t.Name() if typeName == "" { return nil, errgo.Newf("type %s is not named", t) } pkgPath := t.PkgPath() if pkgPath == "" { // TODO could return types.Basic type here if we needed to. return nil, errgo.Newf("type %s not declared in package", t) } pkgInfo := prog.Package(pkgPath) if pkgInfo == nil { return nil, errgo.Newf("cannot find %q in imported code", pkgPath) } pkg := pkgInfo.Pkg obj := pkg.Scope().Lookup(typeName) if obj == nil { return nil, errgo.Newf("type %s not found in %s", typeName, pkgPath) } objTypeName, ok := obj.(*types.TypeName) if !ok { return nil, errgo.Newf("%s is not a type", typeName) } return objTypeName, nil }
func (this *FileInfo) getAlias(packet string, fieldType reflect.Type) (string, bool) { stdType := true alias := fieldType.String() pktPath := fieldType.PkgPath() if len(pktPath) > 0 { stdType = false if fieldType.Kind() == reflect.Ptr { if pktPath != "" && pktPath != packet { if packet, found := this.Imports[pktPath]; !found { ref := alias if idx := strings.Index(ref, "."); idx >= 0 { ref = ref[:idx] } if _, found := this.RefImport[ref]; found { ref = genPacketAliasMD5(pktPath) alias = ref + "." + fieldType.Name() } this.RefImport[ref] = pktPath this.Imports[pktPath] = packet } else { alias = packet + "." + pktPath } } } } return alias, stdType }
// 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. 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 a named type, especially not a pointer or interface: %T", reflect.Zero(rt).Interface()) return } if o == nil { err = errors.New("codec.Handle.AddExt: Nil (should never happen)") return } rtid := reflect.ValueOf(rt).Pointer() if *o == nil { *o = make(map[uintptr]*extTypeTagFn, 4) } m := *o if encfn == nil || decfn == nil { delete(m, rtid) } else { m[rtid] = &extTypeTagFn{rtid, rt, tag, encfn, decfn} } 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 Tag(t reflect.Type, f reflect.StructField, key string) (value string, faster Faster) { if f.Tag == "" { return "", nil } lock.RLock() name := t.PkgPath() + "." + t.Name() var fast *tagFast if cc, ok := caches[name]; ok { if tf, ok := cc[f.Name]; ok { fast = tf } else { caches[name][f.Name] = nil } } else { caches[name] = make(map[string]*tagFast) } if fast == nil { fast = &tagFast{tag: f.Tag} caches[name][f.Name] = fast } lock.RUnlock() value = fast.Get(key) faster = fast return }
func packageForName(inType reflect.Type) string { if inType.PkgPath() == "" { return "" } slices := strings.Split(inType.PkgPath(), "/") return slices[len(slices)-1] }
func (g *schemaGenerator) javaType(t reflect.Type) string { if t.Kind() == reflect.Ptr { t = t.Elem() } pkgDesc, ok := g.packages[t.PkgPath()] if ok { return pkgDesc.JavaPackage + "." + capitalizeFirst(t.Name()) } else { switch t.Kind() { case reflect.Bool: return "bool" case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: return "int" case reflect.Int64, reflect.Uint64: return "Long" case reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: return "double" case reflect.String: return "String" case reflect.Array, reflect.Slice: return g.javaTypeArrayList(t.Elem()) case reflect.Map: return "java.util.Map<String," + g.javaTypeWrapPrimitive(t.Elem()) + ">" default: if len(t.Name()) == 0 && t.NumField() == 0 { return "Object" } return capitalizeClassName(t.Name()) } } }
func (g *conversionGenerator) typeName(inType reflect.Type) string { switch inType.Kind() { case reflect.Slice: return fmt.Sprintf("[]%s", g.typeName(inType.Elem())) case reflect.Ptr: return fmt.Sprintf("*%s", g.typeName(inType.Elem())) case reflect.Map: if len(inType.Name()) == 0 { return fmt.Sprintf("map[%s]%s", g.typeName(inType.Key()), g.typeName(inType.Elem())) } fallthrough default: pkg, name := inType.PkgPath(), inType.Name() if len(name) == 0 && inType.Kind() == reflect.Struct { return "struct{}" } if len(pkg) == 0 { // Default package. return name } if val, found := g.pkgOverwrites[pkg]; found { pkg = val } if len(pkg) == 0 { return name } short := g.addImportByPath(pkg) if len(short) > 0 { return fmt.Sprintf("%s.%s", short, name) } return name } }
func checkJsonTags(objType reflect.Type, seen *map[reflect.Type]bool, t *testing.T) { if _, exists := (*seen)[objType]; exists { return } (*seen)[objType] = true if !strings.Contains(objType.PkgPath(), "openshift/origin") { return } if internalTypesWithAllowedJsonTags.Has(objType.Name()) { return } for i := 0; i < objType.NumField(); i++ { structField := objType.FieldByIndex([]int{i}) jsonTag := structField.Tag.Get("json") if len(jsonTag) != 0 { t.Errorf("%v.%v should not have a json tag", objType, structField.Name) } switch structField.Type.Kind() { case reflect.Struct: checkJsonTags(structField.Type, seen, t) } } }
func checkDescriptions(objType reflect.Type, seen *map[reflect.Type]bool, t *testing.T) { if _, exists := (*seen)[objType]; exists { return } (*seen)[objType] = true if !strings.Contains(objType.PkgPath(), "openshift/origin") { return } for i := 0; i < objType.NumField(); i++ { structField := objType.FieldByIndex([]int{i}) // these fields don't need descriptions if structField.Name == "TypeMeta" || structField.Name == "ObjectMeta" || structField.Name == "ListMeta" { continue } if structField.Type == reflect.TypeOf(unversioned.Time{}) || structField.Type == reflect.TypeOf(time.Time{}) || structField.Type == reflect.TypeOf(runtime.RawExtension{}) { continue } descriptionTag := structField.Tag.Get("description") if len(descriptionTag) == 0 { t.Errorf("%v", structField.Tag) t.Errorf("%v.%v does not have a description", objType, structField.Name) } switch structField.Type.Kind() { case reflect.Struct: checkDescriptions(structField.Type, seen, t) } } }
// Is this type exported or a builtin? func isExportedOrBuiltinType(t reflect.Type) bool { for t.Kind() == reflect.Ptr { t = t.Elem() } // so we need to check the type name as well. return isExported(t.Name()) || t.PkgPath() == "" }
func (g *schemaGenerator) getStructProperties(t reflect.Type) map[string]JSONPropertyDescriptor { props := map[string]JSONPropertyDescriptor{} for i := 0; i < t.NumField(); i++ { field := t.Field(i) if len(field.PkgPath) > 0 { // Skip private fields continue } name := getFieldName(field) desc := getFieldDescription(field) prop := g.getPropertyDescriptor(field.Type, desc) if field.Anonymous && field.Type.Kind() == reflect.Struct && len(name) == 0 { var newProps map[string]JSONPropertyDescriptor if prop.JSONReferenceDescriptor != nil { pType := field.Type if pType.Kind() == reflect.Ptr { pType = pType.Elem() } newProps = g.types[pType].Properties } else { newProps = prop.Properties } for k, v := range newProps { switch k { case "kind": v = JSONPropertyDescriptor{ JSONDescriptor: &JSONDescriptor{ Type: "string", Default: t.Name(), Required: true, }, } case "apiVersion": apiVersion := filepath.Base(t.PkgPath()) apiGroup := filepath.Base(strings.TrimSuffix(t.PkgPath(), apiVersion)) if apiGroup != "api" { apiVersion = apiGroup + "/" + apiVersion } v = JSONPropertyDescriptor{ JSONDescriptor: &JSONDescriptor{ Type: "string", }, } if apiVersion != "unversioned" { v.Required = true v.Default = apiVersion v.Enum = []interface{}{apiVersion} } default: g.addConstraints(t.Name(), k, &v) } props[k] = v } } else { g.addConstraints(t.Name(), name, &prop) props[name] = prop } } return props }
// isExportedOrBuiltin returns true if a type is exported or a builtin. func isExportedOrBuiltin(t reflect.Type) bool { for t.Kind() == reflect.Ptr { t = t.Elem() } // PkgPath will be non-empty even for an exported type, // so we need to check the type name as well. return isExported(t.Name()) || t.PkgPath() == "" }
func (namer *TypeEventNamer) GetEventNameFromType(t reflect.Type) EventName { if t.Kind() == reflect.Ptr { t = t.Elem() } Log.Notice("Getting name from type: %v", t.String()) return EventName(t.PkgPath() + "/" + t.Name()) }
// Return the string that should be used to refer to the supplied type within // the given package. The output is not guaranteed to be pretty, and should be // run through a tool like gofmt afterward. // // For example, a pointer to an io.Reader may be rendered as "*Reader" or // "*io.Reader" depending on whether the package path is "io" or not. func typeString( t reflect.Type, pkgPath string) (s string) { // Is this type named? If so we use its name, possibly with a package prefix. // // Examples: // // int // string // error // gcs.Bucket // if t.Name() != "" { if t.PkgPath() == pkgPath { s = t.Name() } else { s = t.String() } return } // This type is unnamed. Recurse. switch t.Kind() { case reflect.Array: s = fmt.Sprintf("[%d]%s", t.Len(), typeString(t.Elem(), pkgPath)) case reflect.Chan: s = fmt.Sprintf("%s %s", t.ChanDir(), typeString(t.Elem(), pkgPath)) case reflect.Func: s = typeString_Func(t, pkgPath) case reflect.Interface: s = typeString_Interface(t, pkgPath) case reflect.Map: s = fmt.Sprintf( "map[%s]%s", typeString(t.Key(), pkgPath), typeString(t.Elem(), pkgPath)) case reflect.Ptr: s = fmt.Sprintf("*%s", typeString(t.Elem(), pkgPath)) case reflect.Slice: s = fmt.Sprintf("[]%s", typeString(t.Elem(), pkgPath)) case reflect.Struct: s = typeString_Struct(t, pkgPath) default: log.Panicf("Unhandled kind %v for type: %v", t.Kind(), t) } return }
// Is this type exported or a builtin? func isExportedOrBuiltinType(t reflect.Type) bool { for t.Kind() == reflect.Ptr { // t.Kind() == ptr or struct t = t.Elem() //t.Elem() returns the struct of the pointer bidirpc.Reply } // PkgPath will be non-empty even for an exported type, // so we need to check the type name as well. return isExported(t.Name()) || t.PkgPath() == "" }
func (b *Backend) FieldType(typ reflect.Type, t *structs.Tag) (string, error) { if c := codec.FromTag(t); c != nil { if c.Binary || t.PipeName() != "" { return "BLOB", nil } return "TEXT", nil } var ft string switch typ.Kind() { case reflect.Bool: ft = "BOOL" case reflect.Int8: ft = "TINYINT" case reflect.Uint8: ft = "TINYINT UNSIGNED" case reflect.Int16: ft = "SMALLINT" case reflect.Uint16: ft = "SMALLINT UNSIGNED" case reflect.Int32: ft = "INT" case reflect.Uint32: ft = "INT UNSIGNED" case reflect.Int, reflect.Int64: ft = "BIGINT" case reflect.Uint, reflect.Uint64: ft = "BIGINT UNSIGNED" case reflect.Float32: ft = "FLOAT" case reflect.Float64: ft = "DOUBLE" case reflect.String: if ml, ok := t.MaxLength(); ok { ft = fmt.Sprintf("VARCHAR (%d)", ml) } else if fl, ok := t.Length(); ok { ft = fmt.Sprintf("CHAR (%d)", fl) } else { ft = "TEXT" } case reflect.Slice: etyp := typ.Elem() if etyp.Kind() == reflect.Uint8 { // []byte ft = "BLOB" } case reflect.Struct: if typ.Name() == "Time" && typ.PkgPath() == "time" { ft = "DATETIME" } } if ft != "" { return ft, nil } return "", fmt.Errorf("can't map field type %v to a database type", typ) }
func (g *schemaGenerator) qualifiedName(t reflect.Type) string { pkgDesc, ok := g.packages[t.PkgPath()] if !ok { prefix := strings.Replace(t.PkgPath(), "/", "_", -1) prefix = strings.Replace(prefix, ".", "_", -1) prefix = strings.Replace(prefix, "-", "_", -1) return prefix + "_" + t.Name() } else { return pkgDesc.Prefix + t.Name() } }