Merge pull request #249 from tnextday/develop

Add array type support in comment param
This commit is contained in:
astaxie 2016-08-22 11:47:44 +08:00 committed by GitHub
commit 73c3b3beaa
1 changed files with 68 additions and 65 deletions

133
g_docs.go
View File

@ -328,6 +328,17 @@ func isSystemPackage(pkgpath string) bool {
return false return false
} }
func peekNextSplitString(ss string) (s string, spacePos int) {
spacePos = strings.IndexFunc(ss, unicode.IsSpace)
if spacePos < 0 {
s = ss
spacePos = len(ss)
} else {
s = strings.TrimSpace(ss[:spacePos])
}
return
}
// parse the func comments // parse the func comments
func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpath string) error { func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpath string) error {
var routerPath string var routerPath string
@ -358,72 +369,48 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
} else if strings.HasPrefix(t, "@Success") { } else if strings.HasPrefix(t, "@Success") {
ss := strings.TrimSpace(t[len("@Success"):]) ss := strings.TrimSpace(t[len("@Success"):])
rs := swagger.Response{} rs := swagger.Response{}
st := make([]string, 3) respCode, pos := peekNextSplitString(ss)
j := 0 ss = strings.TrimSpace(ss[pos:])
var tmp []rune respType, pos := peekNextSplitString(ss)
start := false if respType == "{object}" || respType == "{array}" {
isArray := respType == "{array}"
for i, c := range ss { ss = strings.TrimSpace(ss[pos:])
if unicode.IsSpace(c) { schemaName, pos := peekNextSplitString(ss)
if !start && j < 2 { if schemaName == "" {
continue ColorLog("[ERRO][%s.%s] Schema must follow {object} or {array}\n", controllerName, funcName)
} os.Exit(-1)
if j == 0 || j == 1 {
st[j] = string(tmp)
tmp = make([]rune, 0)
j++
start = false
if j == 1 {
continue
} else {
st[j] = strings.TrimSpace(ss[i+1:])
break
}
}
} else {
start = true
tmp = append(tmp, c)
} }
} if strings.HasPrefix(schemaName, "[]") {
if len(tmp) > 0 && st[2] == "" { schemaName = schemaName[2:]
st[2] = strings.TrimSpace(string(tmp)) isArray = true
}
rs.Description = st[2]
if st[1] == "{object}" {
if st[2] == "" {
panic(controllerName + " " + funcName + " has no object")
} }
cmpath, m, mod, realTypes := getModel(st[2]) schema := swagger.Schema{}
//ll := strings.Split(st[2], ".") if sType, ok := basicTypes[schemaName]; ok {
//opts.Type = ll[len(ll)-1]
rs.Schema = &swagger.Schema{
Ref: "#/definitions/" + m,
}
if _, ok := modelsList[pkgpath+controllerName]; !ok {
modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema, 0)
}
modelsList[pkgpath+controllerName][st[2]] = mod
appendModels(cmpath, pkgpath, controllerName, realTypes)
} else if st[1] == "{array}" {
rs.Schema.Type = "array"
if sType, ok := basicTypes[st[2]]; ok {
typeFormat := strings.Split(sType, ":") typeFormat := strings.Split(sType, ":")
rs.Schema.Type = typeFormat[0] schema.Type = typeFormat[0]
rs.Schema.Format = typeFormat[1] schema.Format = typeFormat[1]
} else { } else {
cmpath, m, mod, realTypes := getModel(st[2]) cmpath, m, mod, realTypes := getModel(schemaName)
rs.Schema.Items = &swagger.Propertie{ schema.Ref = "#/definitions/" + m
Ref: "#/definitions/" + m,
}
if _, ok := modelsList[pkgpath+controllerName]; !ok { if _, ok := modelsList[pkgpath+controllerName]; !ok {
modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema, 0) modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema, 0)
} }
modelsList[pkgpath+controllerName][st[2]] = mod modelsList[pkgpath+controllerName][schemaName] = mod
appendModels(cmpath, pkgpath, controllerName, realTypes) appendModels(cmpath, pkgpath, controllerName, realTypes)
} }
if isArray {
rs.Schema = &swagger.Schema{
Type: "array",
Items: &schema,
}
}else {
rs.Schema = &schema
}
rs.Description = strings.TrimSpace(ss[pos:])
} else {
rs.Description = strings.TrimSpace(ss)
} }
opts.Responses[st[0]] = rs opts.Responses[respCode] = rs
} else if strings.HasPrefix(t, "@Param") { } else if strings.HasPrefix(t, "@Param") {
para := swagger.Parameter{} para := swagger.Parameter{}
p := getparams(strings.TrimSpace(t[len("@Param "):])) p := getparams(strings.TrimSpace(t[len("@Param "):]))
@ -443,7 +430,7 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
case "body": case "body":
break break
default: default:
fmt.Fprintf(os.Stderr, "[%s.%s] Unknow param location: %s, Possible values are `query`, `header`, `path`, `formData` or `body`.\n", controllerName, funcName, p[1]) ColorLog("[WARN][%s.%s] Unknow param location: %s, Possible values are `query`, `header`, `path`, `formData` or `body`.\n", controllerName, funcName, p[1])
} }
para.In = p[1] para.In = p[1]
pp := strings.Split(p[2], ".") pp := strings.Split(p[2], ".")
@ -459,15 +446,32 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat
modelsList[pkgpath+controllerName][typ] = mod modelsList[pkgpath+controllerName][typ] = mod
appendModels(cmpath, pkgpath, controllerName, realTypes) appendModels(cmpath, pkgpath, controllerName, realTypes)
} else { } else {
isArray := false
paraType := ""
paraFormat := ""
if strings.HasPrefix(typ, "[]") {
typ = typ[2:]
isArray = true
}
if typ == "string" || typ == "number" || typ == "integer" || typ == "boolean" || if typ == "string" || typ == "number" || typ == "integer" || typ == "boolean" ||
typ == "array" || typ == "file" { typ == "array" || typ == "file" {
para.Type = typ paraType = typ
} else if sType, ok := basicTypes[typ]; ok { } else if sType, ok := basicTypes[typ]; ok {
typeFormat := strings.Split(sType, ":") typeFormat := strings.Split(sType, ":")
para.Type = typeFormat[0] paraType = typeFormat[0]
para.Format = typeFormat[1] paraFormat = typeFormat[1]
} else { } else {
fmt.Fprintf(os.Stderr, "[%s.%s] Unknow param type: %s\n", controllerName, funcName, typ) ColorLog("[WARN][%s.%s] Unknow param type: %s\n", controllerName, funcName, typ)
}
if isArray {
para.Type = "array"
para.Items = &swagger.ParameterItems{
Type: paraType,
Format: paraFormat,
}
} else {
para.Type = paraType
para.Format = paraFormat
} }
} }
if len(p) > 4 { if len(p) > 4 {
@ -608,7 +612,7 @@ func getModel(str string) (pkgpath, objectname string, m swagger.Schema, realTyp
} }
ts, ok := d.Decl.(*ast.TypeSpec) ts, ok := d.Decl.(*ast.TypeSpec)
if !ok { if !ok {
ColorLog("Unknown type without TypeSec: %v", d) ColorLog("Unknown type without TypeSec: %v\n", d)
os.Exit(1) os.Exit(1)
} }
st, ok := ts.Type.(*ast.StructType) st, ok := ts.Type.(*ast.StructType)
@ -631,7 +635,6 @@ func getModel(str string) (pkgpath, objectname string, m swagger.Schema, realTyp
Type: typeFormat[0], Type: typeFormat[0],
Format: typeFormat[1], Format: typeFormat[1],
} }
} else { } else {
mp.Items = &swagger.Propertie{ mp.Items = &swagger.Propertie{
Ref: "#/definitions/" + realType, Ref: "#/definitions/" + realType,
@ -701,8 +704,8 @@ func getModel(str string) (pkgpath, objectname string, m swagger.Schema, realTyp
} }
} }
if m.Title == "" { if m.Title == "" {
ColorLog("can't find the object: %s", str) ColorLog("[ERRO]can't find the object: %s\n", str)
os.Exit(1) //os.Exit(1)
} }
if len(rootapi.Definitions) == 0 { if len(rootapi.Definitions) == 0 {
rootapi.Definitions = make(map[string]swagger.Schema) rootapi.Definitions = make(map[string]swagger.Schema)