From 685c16d5ebc29b8efc7e16ec46a047b27ca50094 Mon Sep 17 00:00:00 2001 From: Muxian Wu Date: Mon, 12 Mar 2018 15:52:00 +0800 Subject: [PATCH] Swagger Enum Fix: 1. For now the type inference is not supported, they will be skipped. 2. The enums in the documentation will be listed based on it's position. 3. Be able to support multiple values defined. --- generate/swaggergen/g_docs.go | 46 ++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/generate/swaggergen/g_docs.go b/generate/swaggergen/g_docs.go index f55d22c..3750d19 100644 --- a/generate/swaggergen/g_docs.go +++ b/generate/swaggergen/g_docs.go @@ -27,6 +27,7 @@ import ( "reflect" "regexp" "runtime" + "sort" "strconv" "strings" "unicode" @@ -93,6 +94,7 @@ func init() { astPkgs = make([]*ast.Package, 0) } +// ParsePackagesFromDir parses packages from a given directory func ParsePackagesFromDir(dirpath string) { c := make(chan error) @@ -145,6 +147,7 @@ func parsePackageFromDir(path string) error { return nil } +// GenerateDocs generates documentations for a given path. func GenerateDocs(curpath string) { 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) { m.Title = k 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.Format = typeFormat[1] } + enums := make(map[int]string) + enumValues := make(map[int]string) for _, pkg := range astPkgs { for _, fl := range pkg.Files { 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 { 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) - // Automatically give an example. - if m.Example == nil { - m.Example = vs.Names[0].Obj.Data + + ti, ok := vs.Type.(*ast.Ident) + if !ok { + // TODO type inference, iota not support yet + 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) {