Fixed generation of swagger docs (#29)
This commit is contained in:
1
vendor/github.com/swaggo/swag/.gitignore
generated
vendored
1
vendor/github.com/swaggo/swag/.gitignore
generated
vendored
@ -1,4 +1,3 @@
|
||||
swag
|
||||
testdata/simple/docs
|
||||
cover.out
|
||||
|
||||
|
34
vendor/github.com/swaggo/swag/README.md
generated
vendored
34
vendor/github.com/swaggo/swag/README.md
generated
vendored
@ -22,7 +22,7 @@
|
||||
- [Getting started](#getting-started)
|
||||
- [Go web frameworks](#supported-web-frameworks)
|
||||
- [Supported Web Frameworks](#supported-web-frameworks)
|
||||
- [How to use it with `gin`?](#how-to-use-it-with-`gin`?)
|
||||
- [How to use it with Gin](#how-to-use-it-with-gin)
|
||||
- [Implementation Status](#implementation-status)
|
||||
- [swag cli](#swag-cli)
|
||||
- [General API Info](#general-api-info)
|
||||
@ -72,7 +72,7 @@ $ swag init
|
||||
- [echo](http://github.com/swaggo/echo-swagger)
|
||||
- [net/http](https://github.com/swaggo/http-swagger)
|
||||
|
||||
## How to use it with `gin`?
|
||||
## How to use it with Gin
|
||||
|
||||
Find the example source code [here](https://github.com/swaggo/swag/tree/master/example/celler).
|
||||
|
||||
@ -307,19 +307,23 @@ OPTIONS:
|
||||
**Example**
|
||||
[celler/main.go](https://github.com/swaggo/swag/blob/master/example/celler/main.go)
|
||||
|
||||
| annotation | description | example |
|
||||
|--------------------|-------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
|
||||
| title | **Required.** The title of the application. | // @title Swagger Example API |
|
||||
| version | **Required.** Provides the version of the application API. | // @version 1.0 |
|
||||
| description | A short description of the application. | // @description This is a sample server celler server. |
|
||||
| termsOfService | The Terms of Service for the API. | // @termsOfService http://swagger.io/terms/ |
|
||||
| contact.name | The contact information for the exposed API. | // @contact.name API Support |
|
||||
| contact.url | The URL pointing to the contact information. MUST be in the format of a URL. | // @contact.url http://www.swagger.io/support |
|
||||
| contact.email | The email address of the contact person/organization. MUST be in the format of an email address.| // @contact.email support@swagger.io |
|
||||
| license.name | **Required.** The license name used for the API. | // @license.name Apache 2.0 |
|
||||
| license.url | A URL to the license used for the API. MUST be in the format of a URL. | // @license.url http://www.apache.org/licenses/LICENSE-2.0.html |
|
||||
| host | The host (name or ip) serving the API. | // @host localhost:8080 |
|
||||
| BasePath | The base path on which the API is served. | // @BasePath /api/v1 |
|
||||
| annotation | description | example |
|
||||
|-----------------------|-------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
|
||||
| title | **Required.** The title of the application. | // @title Swagger Example API |
|
||||
| version | **Required.** Provides the version of the application API. | // @version 1.0 |
|
||||
| description | A short description of the application. | // @description This is a sample server celler server. |
|
||||
| tag.name | Name of a tag. | // @tag.name This is the name of the tag |
|
||||
| tag.description | Description of the tag | // @tag.description Cool Description |
|
||||
| tag.docs.url | Url of the external Documentation of the tag | // @tag.docs.url https://example.com |
|
||||
| tag.docs.descripiton | Description of the external Documentation of the tag | // @tag.docs.descirption Best example documentation |
|
||||
| termsOfService | The Terms of Service for the API. | // @termsOfService http://swagger.io/terms/ |
|
||||
| contact.name | The contact information for the exposed API. | // @contact.name API Support |
|
||||
| contact.url | The URL pointing to the contact information. MUST be in the format of a URL. | // @contact.url http://www.swagger.io/support |
|
||||
| contact.email | The email address of the contact person/organization. MUST be in the format of an email address.| // @contact.email support@swagger.io |
|
||||
| license.name | **Required.** The license name used for the API. | // @license.name Apache 2.0 |
|
||||
| license.url | A URL to the license used for the API. MUST be in the format of a URL. | // @license.url http://www.apache.org/licenses/LICENSE-2.0.html |
|
||||
| host | The host (name or ip) serving the API. | // @host localhost:8080 |
|
||||
| BasePath | The base path on which the API is served. | // @BasePath /api/v1 |
|
||||
|
||||
## Security
|
||||
|
||||
|
65
vendor/github.com/swaggo/swag/cmd/swag/main.go
generated
vendored
Normal file
65
vendor/github.com/swaggo/swag/cmd/swag/main.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/swaggo/swag"
|
||||
"github.com/swaggo/swag/gen"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
app.Version = swag.Version
|
||||
app.Usage = "Automatically generate RESTful API documentation with Swagger 2.0 for Go."
|
||||
app.Commands = []cli.Command{
|
||||
{
|
||||
Name: "init",
|
||||
Aliases: []string{"i"},
|
||||
Usage: "Create docs.go",
|
||||
Action: func(c *cli.Context) error {
|
||||
dir := c.String("dir")
|
||||
mainAPIFile := c.String("generalInfo")
|
||||
swaggerConfDir := c.String("swagger")
|
||||
strategy := c.String("propertyStrategy")
|
||||
switch strategy {
|
||||
case swag.CamelCase, swag.SnakeCase, swag.PascalCase:
|
||||
default:
|
||||
return errors.Errorf("not supported %s propertyStrategy", strategy)
|
||||
}
|
||||
|
||||
gen.New().Build(dir, mainAPIFile, swaggerConfDir, strategy)
|
||||
return nil
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "generalInfo, g",
|
||||
Value: "main.go",
|
||||
Usage: "Go file path in which 'swagger general API Info' is written",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "dir, d",
|
||||
Value: "./",
|
||||
Usage: "Directory you want to parse",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "swagger, s",
|
||||
Value: "./docs/swagger",
|
||||
Usage: "Output the swagger conf for json and yaml",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "propertyStrategy, p",
|
||||
Value: "camelcase",
|
||||
Usage: "Property Naming Strategy like snakecase,camelcase,pascalcase",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
270
vendor/github.com/swaggo/swag/parser.go
generated
vendored
270
vendor/github.com/swaggo/swag/parser.go
generated
vendored
@ -50,6 +50,9 @@ type Parser struct {
|
||||
registerTypes map[string]*ast.TypeSpec
|
||||
|
||||
PropNamingStrategy string
|
||||
|
||||
// structStack stores full names of the structures that were already parsed or are being parsed now
|
||||
structStack []string
|
||||
}
|
||||
|
||||
// New creates a new Parser with default properties.
|
||||
@ -146,6 +149,34 @@ func (parser *Parser) ParseGeneralAPIInfo(mainAPIFile string) error {
|
||||
parser.swagger.BasePath = strings.TrimSpace(commentLine[len(attribute):])
|
||||
case "@schemes":
|
||||
parser.swagger.Schemes = GetSchemes(commentLine)
|
||||
case "@tag.name":
|
||||
commentInfo := strings.TrimSpace(commentLine[len(attribute):])
|
||||
parser.swagger.Tags = append(parser.swagger.Tags, spec.Tag{
|
||||
TagProps: spec.TagProps{
|
||||
Name: strings.TrimSpace(commentInfo),
|
||||
},
|
||||
})
|
||||
case "@tag.description":
|
||||
commentInfo := strings.TrimSpace(commentLine[len(attribute):])
|
||||
tag := parser.swagger.Tags[len(parser.swagger.Tags)-1]
|
||||
tag.TagProps.Description = commentInfo
|
||||
replaceLastTag(parser.swagger.Tags, tag)
|
||||
case "@tag.docs.url":
|
||||
commentInfo := strings.TrimSpace(commentLine[len(attribute):])
|
||||
tag := parser.swagger.Tags[len(parser.swagger.Tags)-1]
|
||||
tag.TagProps.ExternalDocs = &spec.ExternalDocumentation{
|
||||
URL: commentInfo,
|
||||
}
|
||||
replaceLastTag(parser.swagger.Tags, tag)
|
||||
|
||||
case "@tag.docs.description":
|
||||
commentInfo := strings.TrimSpace(commentLine[len(attribute):])
|
||||
tag := parser.swagger.Tags[len(parser.swagger.Tags)-1]
|
||||
if tag.TagProps.ExternalDocs == nil {
|
||||
log.Panic("@tag.docs.description needs to come after a @tags.docs.url")
|
||||
}
|
||||
tag.TagProps.ExternalDocs.Description = commentInfo
|
||||
replaceLastTag(parser.swagger.Tags, tag)
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,47 +396,46 @@ func (parser *Parser) ParseType(astFile *ast.File) {
|
||||
}
|
||||
}
|
||||
|
||||
func (parser *Parser) isInStructStack(refTypeName string) bool {
|
||||
for _, structName := range parser.structStack {
|
||||
if refTypeName == structName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ParseDefinitions parses Swagger Api definitions.
|
||||
func (parser *Parser) ParseDefinitions() {
|
||||
for refTypeName, typeSpec := range parser.registerTypes {
|
||||
ss := strings.Split(refTypeName, ".")
|
||||
pkgName := ss[0]
|
||||
parser.ParseDefinition(pkgName, typeSpec, typeSpec.Name.Name)
|
||||
parser.structStack = nil
|
||||
parser.ParseDefinition(pkgName, typeSpec.Name.Name, typeSpec)
|
||||
}
|
||||
}
|
||||
|
||||
var structStacks []string
|
||||
|
||||
// isNotRecurringNestStruct check if a structure that is not a not repeating
|
||||
func isNotRecurringNestStruct(refTypeName string, structStacks []string) bool {
|
||||
for _, v := range structStacks {
|
||||
if refTypeName == v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ParseDefinition TODO: NEEDS COMMENT INFO
|
||||
func (parser *Parser) ParseDefinition(pkgName string, typeSpec *ast.TypeSpec, typeName string) {
|
||||
var refTypeName string
|
||||
if len(pkgName) > 0 {
|
||||
refTypeName = pkgName + "." + typeName
|
||||
} else {
|
||||
refTypeName = typeName
|
||||
}
|
||||
if _, already := parser.swagger.Definitions[refTypeName]; already {
|
||||
log.Println("Skipping '" + refTypeName + "', already present.")
|
||||
// ParseDefinition parses given type spec that corresponds to the type under
|
||||
// given name and package, and populates swagger schema definitions registry
|
||||
// with a schema for the given type
|
||||
func (parser *Parser) ParseDefinition(pkgName, typeName string, typeSpec *ast.TypeSpec) {
|
||||
refTypeName := fullTypeName(pkgName, typeName)
|
||||
if _, isParsed := parser.swagger.Definitions[refTypeName]; isParsed {
|
||||
log.Println("Skipping '" + refTypeName + "', already parsed.")
|
||||
return
|
||||
}
|
||||
properties := make(map[string]spec.Schema)
|
||||
// stop repetitive structural parsing
|
||||
if isNotRecurringNestStruct(refTypeName, structStacks) {
|
||||
structStacks = append(structStacks, refTypeName)
|
||||
parser.parseTypeSpec(pkgName, typeSpec, properties)
|
||||
}
|
||||
structStacks = []string{}
|
||||
|
||||
if parser.isInStructStack(refTypeName) {
|
||||
log.Println("Skipping '" + refTypeName + "', recursion detected.")
|
||||
return
|
||||
}
|
||||
parser.structStack = append(parser.structStack, refTypeName)
|
||||
|
||||
log.Println("Generating " + refTypeName)
|
||||
parser.swagger.Definitions[refTypeName] = parser.parseTypeExpr(pkgName, typeName, typeSpec.Type)
|
||||
}
|
||||
|
||||
func (parser *Parser) collectRequiredFields(pkgName string, properties map[string]spec.Schema) (requiredFields []string) {
|
||||
// created sorted list of properties keys so when we iterate over them it's deterministic
|
||||
ks := make([]string, 0, len(properties))
|
||||
for k := range properties {
|
||||
@ -413,7 +443,7 @@ func (parser *Parser) ParseDefinition(pkgName string, typeSpec *ast.TypeSpec, ty
|
||||
}
|
||||
sort.Strings(ks)
|
||||
|
||||
requiredFields := make([]string, 0)
|
||||
requiredFields = make([]string, 0)
|
||||
|
||||
// iterate over keys list instead of map to avoid the random shuffle of the order that go does for maps
|
||||
for _, k := range ks {
|
||||
@ -423,7 +453,7 @@ func (parser *Parser) ParseDefinition(pkgName string, typeSpec *ast.TypeSpec, ty
|
||||
tname := prop.SchemaProps.Type[0]
|
||||
if _, ok := parser.TypeDefinitions[pkgName][tname]; ok {
|
||||
tspec := parser.TypeDefinitions[pkgName][tname]
|
||||
parser.ParseDefinition(pkgName, tspec, tname)
|
||||
parser.ParseDefinition(pkgName, tname, tspec)
|
||||
}
|
||||
if tname != "object" {
|
||||
requiredFields = append(requiredFields, prop.SchemaProps.Required...)
|
||||
@ -431,39 +461,98 @@ func (parser *Parser) ParseDefinition(pkgName string, typeSpec *ast.TypeSpec, ty
|
||||
}
|
||||
properties[k] = prop
|
||||
}
|
||||
log.Println("Generating " + refTypeName)
|
||||
parser.swagger.Definitions[refTypeName] = spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: properties,
|
||||
Required: requiredFields,
|
||||
},
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (parser *Parser) parseTypeSpec(pkgName string, typeSpec *ast.TypeSpec, properties map[string]spec.Schema) {
|
||||
switch typeSpec.Type.(type) {
|
||||
case *ast.StructType:
|
||||
structDecl := typeSpec.Type.(*ast.StructType)
|
||||
fields := structDecl.Fields.List
|
||||
func fullTypeName(pkgName, typeName string) string {
|
||||
if pkgName != "" {
|
||||
return pkgName + "." + typeName
|
||||
}
|
||||
return typeName
|
||||
}
|
||||
|
||||
for _, field := range fields {
|
||||
if field.Names == nil { //anonymous field
|
||||
parser.parseAnonymousField(pkgName, field, properties)
|
||||
// parseTypeExpr parses given type expression that corresponds to the type under
|
||||
// given name and package, and returns swagger schema for it.
|
||||
func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr) spec.Schema {
|
||||
switch expr := typeExpr.(type) {
|
||||
// type Foo struct {...}
|
||||
case *ast.StructType:
|
||||
refTypeName := fullTypeName(pkgName, typeName)
|
||||
if schema, isParsed := parser.swagger.Definitions[refTypeName]; isParsed {
|
||||
return schema
|
||||
}
|
||||
|
||||
properties := make(map[string]spec.Schema)
|
||||
for _, field := range expr.Fields.List {
|
||||
var fieldProps map[string]spec.Schema
|
||||
if field.Names == nil {
|
||||
fieldProps = parser.parseAnonymousField(pkgName, field)
|
||||
} else {
|
||||
props := parser.parseStruct(pkgName, field)
|
||||
for k, v := range props {
|
||||
properties[k] = v
|
||||
}
|
||||
fieldProps = parser.parseStruct(pkgName, field)
|
||||
}
|
||||
|
||||
for k, v := range fieldProps {
|
||||
properties[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: properties,
|
||||
Required: parser.collectRequiredFields(pkgName, properties),
|
||||
},
|
||||
}
|
||||
|
||||
// type Foo Baz
|
||||
case *ast.Ident:
|
||||
refTypeName := fullTypeName(pkgName, expr.Name)
|
||||
if _, isParsed := parser.swagger.Definitions[refTypeName]; !isParsed {
|
||||
typedef := parser.TypeDefinitions[pkgName][expr.Name]
|
||||
parser.ParseDefinition(pkgName, expr.Name, typedef)
|
||||
}
|
||||
return parser.swagger.Definitions[refTypeName]
|
||||
|
||||
// type Foo *Baz
|
||||
case *ast.StarExpr:
|
||||
return parser.parseTypeExpr(pkgName, typeName, expr.X)
|
||||
|
||||
// type Foo []Baz
|
||||
case *ast.ArrayType:
|
||||
log.Println("ParseDefinitions not supported 'Array' yet.")
|
||||
case *ast.InterfaceType:
|
||||
log.Println("ParseDefinitions not supported 'Interface' yet.")
|
||||
case *ast.MapType:
|
||||
log.Println("ParseDefinitions not supported 'Map' yet.")
|
||||
itemSchema := parser.parseTypeExpr(pkgName, "", expr.Elt)
|
||||
return spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &itemSchema,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// type Foo pkg.Bar
|
||||
case *ast.SelectorExpr:
|
||||
if xIdent, ok := expr.X.(*ast.Ident); ok {
|
||||
pkgName = xIdent.Name
|
||||
typeName = expr.Sel.Name
|
||||
refTypeName := fullTypeName(pkgName, typeName)
|
||||
if _, isParsed := parser.swagger.Definitions[refTypeName]; !isParsed {
|
||||
typedef := parser.TypeDefinitions[pkgName][typeName]
|
||||
parser.ParseDefinition(pkgName, typeName, typedef)
|
||||
}
|
||||
return parser.swagger.Definitions[refTypeName]
|
||||
}
|
||||
|
||||
// type Foo map[string]Bar
|
||||
// ...
|
||||
default:
|
||||
log.Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
|
||||
}
|
||||
|
||||
return spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,7 +589,8 @@ func (parser *Parser) parseStruct(pkgName string, field *ast.Field) (properties
|
||||
}
|
||||
if _, ok := parser.TypeDefinitions[pkgName][structField.schemaType]; ok { // user type field
|
||||
// write definition if not yet present
|
||||
parser.ParseDefinition(pkgName, parser.TypeDefinitions[pkgName][structField.schemaType], structField.schemaType)
|
||||
parser.ParseDefinition(pkgName, structField.schemaType,
|
||||
parser.TypeDefinitions[pkgName][structField.schemaType])
|
||||
properties[structField.name] = spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"}, // to avoid swagger validation error
|
||||
@ -513,7 +603,8 @@ func (parser *Parser) parseStruct(pkgName string, field *ast.Field) (properties
|
||||
} else if structField.schemaType == "array" { // array field type
|
||||
// if defined -- ref it
|
||||
if _, ok := parser.TypeDefinitions[pkgName][structField.arrayType]; ok { // user type in array
|
||||
parser.ParseDefinition(pkgName, parser.TypeDefinitions[pkgName][structField.arrayType], structField.arrayType)
|
||||
parser.ParseDefinition(pkgName, structField.arrayType,
|
||||
parser.TypeDefinitions[pkgName][structField.arrayType])
|
||||
properties[structField.name] = spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{structField.schemaType},
|
||||
@ -620,30 +711,48 @@ func (parser *Parser) parseStruct(pkgName string, field *ast.Field) (properties
|
||||
return
|
||||
}
|
||||
|
||||
func (parser *Parser) parseAnonymousField(pkgName string, field *ast.Field, properties map[string]spec.Schema) {
|
||||
// check if ast Field is Ident type
|
||||
astTypeIdent, okTypeIdent := field.Type.(*ast.Ident)
|
||||
func (parser *Parser) parseAnonymousField(pkgName string, field *ast.Field) map[string]spec.Schema {
|
||||
properties := make(map[string]spec.Schema)
|
||||
|
||||
// if ast Field is not Ident type we check if it's StarExpr
|
||||
// because it might be a pointer to an Ident
|
||||
if !okTypeIdent {
|
||||
if astTypeStar, okTypeStar := field.Type.(*ast.StarExpr); okTypeStar {
|
||||
astTypeIdent, okTypeIdent = astTypeStar.X.(*ast.Ident)
|
||||
fullTypeName := ""
|
||||
switch ftype := field.Type.(type) {
|
||||
case *ast.Ident:
|
||||
fullTypeName = ftype.Name
|
||||
case *ast.StarExpr:
|
||||
if ftypeX, ok := ftype.X.(*ast.Ident); ok {
|
||||
fullTypeName = ftypeX.Name
|
||||
}
|
||||
default:
|
||||
log.Printf("Field type of '%T' is unsupported. Skipping", ftype)
|
||||
return properties
|
||||
}
|
||||
|
||||
if okTypeIdent {
|
||||
findPgkName := pkgName
|
||||
findBaseTypeName := astTypeIdent.Name
|
||||
ss := strings.Split(astTypeIdent.Name, ".")
|
||||
if len(ss) > 1 {
|
||||
findPgkName = ss[0]
|
||||
findBaseTypeName = ss[1]
|
||||
}
|
||||
|
||||
baseTypeSpec := parser.TypeDefinitions[findPgkName][findBaseTypeName]
|
||||
parser.parseTypeSpec(findPgkName, baseTypeSpec, properties)
|
||||
typeName := fullTypeName
|
||||
if splits := strings.Split(fullTypeName, "."); len(splits) > 1 {
|
||||
pkgName = splits[0]
|
||||
typeName = splits[1]
|
||||
}
|
||||
|
||||
typeSpec := parser.TypeDefinitions[pkgName][typeName]
|
||||
schema := parser.parseTypeExpr(pkgName, typeName, typeSpec.Type)
|
||||
|
||||
schemaType := "unknown"
|
||||
if len(schema.SchemaProps.Type) > 0 {
|
||||
schemaType = schema.SchemaProps.Type[0]
|
||||
}
|
||||
|
||||
switch schemaType {
|
||||
case "object":
|
||||
for k, v := range schema.SchemaProps.Properties {
|
||||
properties[k] = v
|
||||
}
|
||||
case "array":
|
||||
properties[typeName] = schema
|
||||
default:
|
||||
log.Printf("Can't extract properties from a schema of type '%s'", schemaType)
|
||||
}
|
||||
|
||||
return properties
|
||||
}
|
||||
|
||||
func (parser *Parser) parseField(field *ast.Field) *structField {
|
||||
@ -755,6 +864,11 @@ func (parser *Parser) parseField(field *ast.Field) *structField {
|
||||
return structField
|
||||
}
|
||||
|
||||
func replaceLastTag(slice []spec.Tag, element spec.Tag) {
|
||||
slice = slice[:len(slice)-1]
|
||||
slice = append(slice, element)
|
||||
}
|
||||
|
||||
func getFloatTag(structTag reflect.StructTag, tagName string) *float64 {
|
||||
strValue := structTag.Get(tagName)
|
||||
if strValue == "" {
|
||||
|
16
vendor/github.com/swaggo/swag/property.go
generated
vendored
16
vendor/github.com/swaggo/swag/property.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -52,7 +53,7 @@ func parseFieldSelectorExpr(astTypeSelectorExpr *ast.SelectorExpr, parser *Parse
|
||||
|
||||
if pkgName, ok := astTypeSelectorExpr.X.(*ast.Ident); ok {
|
||||
if typeDefinitions, ok := parser.TypeDefinitions[pkgName.Name][astTypeSelectorExpr.Sel.Name]; ok {
|
||||
parser.ParseDefinition(pkgName.Name, typeDefinitions, astTypeSelectorExpr.Sel.Name)
|
||||
parser.ParseDefinition(pkgName.Name, astTypeSelectorExpr.Sel.Name, typeDefinitions)
|
||||
return propertyNewFunc(astTypeSelectorExpr.Sel.Name, pkgName.Name)
|
||||
}
|
||||
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[astTypeSelectorExpr.Sel.Name]; isCustomType {
|
||||
@ -60,7 +61,7 @@ func parseFieldSelectorExpr(astTypeSelectorExpr *ast.SelectorExpr, parser *Parse
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("%s is not supported. but it will be set with string temporary. Please report any problems.", astTypeSelectorExpr.Sel.Name)
|
||||
log.Printf("%s is not supported. but it will be set with string temporary. Please report any problems.\n", astTypeSelectorExpr.Sel.Name)
|
||||
return propertyName{SchemaType: "string", ArrayType: "string"}
|
||||
}
|
||||
|
||||
@ -86,6 +87,14 @@ func getPropertyName(field *ast.Field, parser *Parser) propertyName {
|
||||
if astTypeSelectorExpr, ok := ptr.X.(*ast.SelectorExpr); ok {
|
||||
return parseFieldSelectorExpr(astTypeSelectorExpr, parser, newProperty)
|
||||
}
|
||||
// TODO support custom pointer type?
|
||||
if _, ok := ptr.X.(*ast.MapType); ok { // if map
|
||||
//TODO support map
|
||||
return propertyName{SchemaType: "object", ArrayType: "object"}
|
||||
}
|
||||
if _, ok := ptr.X.(*ast.StructType); ok { // if struct
|
||||
return propertyName{SchemaType: "object", ArrayType: "object"}
|
||||
}
|
||||
if astTypeIdent, ok := ptr.X.(*ast.Ident); ok {
|
||||
name := astTypeIdent.Name
|
||||
schemeType := TransToValidSchemeType(name)
|
||||
@ -106,6 +115,9 @@ func getPropertyName(field *ast.Field, parser *Parser) propertyName {
|
||||
return parseFieldSelectorExpr(astTypeArrayExpr, parser, newArrayProperty)
|
||||
}
|
||||
if astTypeArrayExpr, ok := astTypeArray.Elt.(*ast.StarExpr); ok {
|
||||
if astTypeArraySel, ok := astTypeArrayExpr.X.(*ast.SelectorExpr); ok {
|
||||
return parseFieldSelectorExpr(astTypeArraySel, parser, newArrayProperty)
|
||||
}
|
||||
if astTypeArrayIdent, ok := astTypeArrayExpr.X.(*ast.Ident); ok {
|
||||
name := TransToValidSchemeType(astTypeArrayIdent.Name)
|
||||
return propertyName{SchemaType: "array", ArrayType: name}
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -108,7 +108,7 @@ github.com/stretchr/testify/assert
|
||||
github.com/swaggo/echo-swagger
|
||||
# github.com/swaggo/files v0.0.0-20180215091130-49c8a91ea3fa
|
||||
github.com/swaggo/files
|
||||
# github.com/swaggo/swag v1.3.3-0.20181109030545-8f09470d62b2
|
||||
# github.com/swaggo/swag v1.4.1-0.20181129020348-1c8533a91397
|
||||
github.com/swaggo/swag/cmd/swag
|
||||
github.com/swaggo/swag
|
||||
github.com/swaggo/swag/gen
|
||||
|
Reference in New Issue
Block a user