Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Generics not detected if name does not contain a pkg name #1328

Merged
merged 1 commit into from Sep 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 25 additions & 14 deletions packages.go
Expand Up @@ -389,25 +389,17 @@ func (pkgDefs *PackagesDefinitions) FindTypeSpec(typeName string, file *ast.File
}
}

if strings.Contains(typeName, "[") {
// joinedParts differs from typeName in that it does not contain any type parameters
joinedParts := strings.Join(parts, ".")
for tName, tSpec := range pkgDefs.uniqueDefinitions {
if !strings.Contains(tName, "[") {
continue
}

if strings.Contains(tName, joinedParts) {
if parametrized := pkgDefs.parametrizeStruct(file, tSpec, typeName, parseDependency); parametrized != nil {
return parametrized
}
}
}
if def := pkgDefs.findGenericTypeSpec(typeName, file, parseDependency); def != nil {
return def
}

return pkgDefs.findTypeSpec(pkgPath, parts[1])
}

if def := pkgDefs.findGenericTypeSpec(fullTypeName(file.Name.Name, typeName), file, parseDependency); def != nil {
return def
}

typeDef, ok := pkgDefs.uniqueDefinitions[fullTypeName(file.Name.Name, typeName)]
if ok {
return typeDef
Expand All @@ -429,3 +421,22 @@ func (pkgDefs *PackagesDefinitions) FindTypeSpec(typeName string, file *ast.File

return nil
}

func (pkgDefs *PackagesDefinitions) findGenericTypeSpec(typeName string, file *ast.File, parseDependency bool) *TypeSpecDef {
if strings.Contains(typeName, "[") {
// genericName differs from typeName in that it does not contain any type parameters
genericName := strings.SplitN(typeName, "[", 2)[0]
for tName, tSpec := range pkgDefs.uniqueDefinitions {
if !strings.Contains(tName, "[") {
continue
}

if strings.Contains(tName, genericName) {
if parametrized := pkgDefs.parametrizeStruct(file, tSpec, typeName, parseDependency); parametrized != nil {
return parametrized
}
}
}
}
return nil
}
13 changes: 13 additions & 0 deletions testdata/generics_basic/api/api.go
Expand Up @@ -7,6 +7,17 @@ import (
"github.com/swaggo/swag/testdata/generics_basic/web"
)

type Response[T any, X any] struct {
Data T
Meta X

Status string
}

type StringStruct struct {
Data string
}

// @Summary Add a new pet to the store
// @Description get string by ID
// @Accept json
Expand All @@ -16,6 +27,8 @@ import (
// @Success 201 {object} web.GenericResponse[types.Hello]
// @Success 202 {object} web.GenericResponse[types.Field[string]]
// @Success 203 {object} web.GenericResponse[types.Field[int]]
// @Success 204 {object} Response[string, types.Field[int]]
// @Success 205 {object} Response[StringStruct, types.Field[int]]
// @Success 222 {object} web.GenericResponseMulti[types.Post, types.Post]
// @Failure 400 {object} web.APIError "We need ID!!"
// @Failure 404 {object} web.APIError "Can not find ID"
Expand Down
48 changes: 48 additions & 0 deletions testdata/generics_basic/expected.json
Expand Up @@ -147,6 +147,18 @@
"$ref": "#/definitions/web.GenericResponse-types_Field_int"
}
},
"204": {
"description": "No Content",
"schema": {
"$ref": "#/definitions/api.Response-string-types_Field_int"
}
},
"205": {
"description": "Reset Content",
"schema": {
"$ref": "#/definitions/api.Response-api_StringStruct-types_Field_int"
}
},
"222": {
"description": "",
"schema": {
Expand All @@ -170,6 +182,42 @@
}
},
"definitions": {
"api.Response-api_StringStruct-types_Field_int": {
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/api.StringStruct"
},
"meta": {
"$ref": "#/definitions/types.Field-int"
},
"status": {
"type": "string"
}
}
},
"api.Response-string-types_Field_int": {
"type": "object",
"properties": {
"data": {
"type": "string"
},
"meta": {
"$ref": "#/definitions/types.Field-int"
},
"status": {
"type": "string"
}
}
},
"api.StringStruct": {
"type": "object",
"properties": {
"data": {
"type": "string"
}
}
},
"types.Field-int": {
"type": "object",
"properties": {
Expand Down