Merge pull request #513 from WUMUXIAN/develop

Swagger Enum Fix:
This commit is contained in:
astaxie 2018-03-13 16:51:32 +08:00 committed by GitHub
commit be6186155f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 40 additions and 6 deletions

View File

@ -27,6 +27,7 @@ import (
"reflect" "reflect"
"regexp" "regexp"
"runtime" "runtime"
"sort"
"strconv" "strconv"
"strings" "strings"
"unicode" "unicode"
@ -93,6 +94,7 @@ func init() {
astPkgs = make([]*ast.Package, 0) astPkgs = make([]*ast.Package, 0)
} }
// ParsePackagesFromDir parses packages from a given directory
func ParsePackagesFromDir(dirpath string) { func ParsePackagesFromDir(dirpath string) {
c := make(chan error) c := make(chan error)
@ -145,6 +147,7 @@ func parsePackageFromDir(path string) error {
return nil return nil
} }
// GenerateDocs generates documentations for a given path.
func GenerateDocs(curpath string) { func GenerateDocs(curpath string) {
fset := token.NewFileSet() fset := token.NewFileSet()
@ -931,7 +934,7 @@ func parseObject(d *ast.Object, k string, m *swagger.Schema, realTypes *[]string
} }
} }
// parse as enum // parse as enum, in the package, find out all consts with the same type
func parseIdent(st *ast.Ident, k string, m *swagger.Schema, astPkgs []*ast.Package) { func parseIdent(st *ast.Ident, k string, m *swagger.Schema, astPkgs []*ast.Package) {
m.Title = k m.Title = k
basicType := fmt.Sprint(st) basicType := fmt.Sprint(st)
@ -943,6 +946,8 @@ func parseIdent(st *ast.Ident, k string, m *swagger.Schema, astPkgs []*ast.Packa
m.Type = typeFormat[0] m.Type = typeFormat[0]
m.Format = typeFormat[1] m.Format = typeFormat[1]
} }
enums := make(map[int]string)
enumValues := make(map[int]string)
for _, pkg := range astPkgs { for _, pkg := range astPkgs {
for _, fl := range pkg.Files { for _, fl := range pkg.Files {
for _, obj := range fl.Scope.Objects { for _, obj := range fl.Scope.Objects {
@ -951,16 +956,45 @@ func parseIdent(st *ast.Ident, k string, m *swagger.Schema, astPkgs []*ast.Packa
if !ok { if !ok {
beeLogger.Log.Fatalf("Unknown type without ValueSpec: %v\n", vs) beeLogger.Log.Fatalf("Unknown type without ValueSpec: %v\n", vs)
} }
enum := fmt.Sprintf("%s = %v", vs.Names[0].Name, vs.Names[0].Obj.Data)
m.Enum = append(m.Enum, enum) ti, ok := vs.Type.(*ast.Ident)
// Automatically give an example. if !ok {
if m.Example == nil { // TODO type inference, iota not support yet
m.Example = vs.Names[0].Obj.Data continue
}
// Only add the enums that are defined by the current identifier
if ti.Name != k {
continue
}
// For all names and values, aggregate them by it's position so that we can sort them later.
for i, val := range vs.Values {
v, ok := val.(*ast.BasicLit)
if !ok {
beeLogger.Log.Warnf("Unknown type without BasicLit: %v\n", v)
continue
}
enums[int(val.Pos())] = fmt.Sprintf("%s = %s", vs.Names[i].Name, v.Value)
enumValues[int(val.Pos())] = v.Value
} }
} }
} }
} }
} }
// Sort the enums by position
if len(enums) > 0 {
var keys []int
for k := range enums {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
m.Enum = append(m.Enum, enums[k])
}
// Automatically use the first enum value as the example.
m.Example = enumValues[keys[0]]
}
} }
func parseStruct(st *ast.StructType, k string, m *swagger.Schema, realTypes *[]string, astPkgs []*ast.Package, packageName string) { func parseStruct(st *ast.StructType, k string, m *swagger.Schema, realTypes *[]string, astPkgs []*ast.Package, packageName string) {