Skip to content

Commit dfce6c8

Browse files
authored
parse self-nested generic struct (#1420)
1 parent 4519064 commit dfce6c8

File tree

6 files changed

+118
-56
lines changed

6 files changed

+118
-56
lines changed

generics.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,14 @@ func (pkgDefs *PackagesDefinitions) parametrizeGenericType(file *ast.File, origi
9595
NamePos: original.TypeSpec.Name.NamePos,
9696
Obj: original.TypeSpec.Name.Obj,
9797
},
98-
Type: pkgDefs.resolveGenericType(original.File, original.TypeSpec.Type, genericParamTypeDefs),
9998
Doc: original.TypeSpec.Doc,
10099
Assign: original.TypeSpec.Assign,
101100
},
102101
}
103102
pkgDefs.uniqueDefinitions[name] = parametrizedTypeSpec
104103

104+
parametrizedTypeSpec.TypeSpec.Type = pkgDefs.resolveGenericType(original.File, original.TypeSpec.Type, genericParamTypeDefs)
105+
105106
return parametrizedTypeSpec
106107
}
107108

@@ -184,7 +185,7 @@ func (pkgDefs *PackagesDefinitions) resolveGenericType(file *ast.File, expr ast.
184185
fullGenericName, _ := getGenericFieldType(file, expr, genericParamTypeDefs)
185186
typeDef := pkgDefs.FindTypeSpec(fullGenericName, file)
186187
if typeDef != nil {
187-
return typeDef.TypeSpec.Type
188+
return typeDef.TypeSpec.Name
188189
}
189190
case *ast.StructType:
190191
newStructTypeDef := &ast.StructType{

generics_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"encoding/json"
88
"fmt"
99
"go/ast"
10+
"io/fs"
1011
"os"
1112
"path/filepath"
1213
"testing"
@@ -84,6 +85,7 @@ func TestParseGenericsProperty(t *testing.T) {
8485
err = p.ParseAPI(searchDir, mainAPIFile, defaultParseDepth)
8586
assert.NoError(t, err)
8687
b, err := json.MarshalIndent(p.swagger, "", " ")
88+
os.WriteFile(searchDir+"/expected.json", b, fs.ModePerm)
8789
assert.NoError(t, err)
8890
assert.Equal(t, string(expected), string(b))
8991
}

testdata/generics_nested/api/api.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,13 @@ func GetPosts(w http.ResponseWriter, r *http.Request) {
3838
func GetPostArray(w http.ResponseWriter, r *http.Request) {
3939
_ = web.GenericNestedResponse[types.Post]{}
4040
}
41+
42+
// @Summary List Posts
43+
// @Description Get All of the Posts
44+
// @Accept json
45+
// @Produce json
46+
// @Success 200 {object} web.GenericNodeThree[string]
47+
// @Router /posts-self-nested-struct/ [get]
48+
func GetPostSelfNestStruct(w http.ResponseWriter, r *http.Request) {
49+
50+
}

testdata/generics_nested/expected.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,26 @@
130130
}
131131
}
132132
}
133+
},
134+
"/posts-self-nested-struct/": {
135+
"get": {
136+
"description": "Get All of the Posts",
137+
"consumes": [
138+
"application/json"
139+
],
140+
"produces": [
141+
"application/json"
142+
],
143+
"summary": "List Posts",
144+
"responses": {
145+
"200": {
146+
"description": "OK",
147+
"schema": {
148+
"$ref": "#/definitions/web.GenericNodeThree-string"
149+
}
150+
}
151+
}
152+
}
133153
}
134154
},
135155
"definitions": {
@@ -580,6 +600,23 @@
580600
"type": "string"
581601
}
582602
}
603+
},
604+
"web.GenericNodeThree-string": {
605+
"type": "object",
606+
"properties": {
607+
"current": {
608+
"type": "array",
609+
"items": {
610+
"type": "string"
611+
}
612+
},
613+
"next": {
614+
"type": "array",
615+
"items": {
616+
"$ref": "#/definitions/web.GenericNodeThree-string"
617+
}
618+
}
619+
}
583620
}
584621
}
585622
}

testdata/generics_nested/web/handler.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,8 @@ type APIError struct {
6262
ErrorCtx string // Error `context` tick comment
6363
CreatedAt time.Time // Error time
6464
}
65+
66+
type GenericNodeThree[T any] struct {
67+
CurrentData []T `json:"current"`
68+
Next []*GenericNodeThree[T] `json:"next"`
69+
}

testdata/generics_property/expected.json

Lines changed: 61 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,7 @@
184184
}
185185
},
186186
"value4": {
187-
"type": "object",
188-
"properties": {
189-
"subValue1": {
190-
"$ref": "#/definitions/api.Person"
191-
},
192-
"subValue2": {
193-
"type": "string"
194-
}
195-
}
187+
"$ref": "#/definitions/types.SubField1-api_Person-string"
196188
}
197189
}
198190
},
@@ -221,15 +213,7 @@
221213
}
222214
},
223215
"value4": {
224-
"type": "object",
225-
"properties": {
226-
"subValue1": {
227-
"$ref": "#/definitions/api.Person"
228-
},
229-
"subValue2": {
230-
"type": "string"
231-
}
232-
}
216+
"$ref": "#/definitions/types.SubField1-api_Person-string"
233217
}
234218
}
235219
},
@@ -258,15 +242,7 @@
258242
}
259243
},
260244
"value4": {
261-
"type": "object",
262-
"properties": {
263-
"subValue1": {
264-
"$ref": "#/definitions/types.Post"
265-
},
266-
"subValue2": {
267-
"type": "string"
268-
}
269-
}
245+
"$ref": "#/definitions/types.SubField1-types_Post-string"
270246
}
271247
}
272248
},
@@ -286,15 +262,7 @@
286262
}
287263
},
288264
"value4": {
289-
"type": "object",
290-
"properties": {
291-
"subValue1": {
292-
"type": "string"
293-
},
294-
"subValue2": {
295-
"type": "string"
296-
}
297-
}
265+
"$ref": "#/definitions/types.SubField1-string-string"
298266
}
299267
}
300268
},
@@ -314,15 +282,7 @@
314282
}
315283
},
316284
"value4": {
317-
"type": "object",
318-
"properties": {
319-
"subValue1": {
320-
"$ref": "#/definitions/types.Field-api_Person"
321-
},
322-
"subValue2": {
323-
"type": "string"
324-
}
325-
}
285+
"$ref": "#/definitions/types.SubField1-types_Field-api_Person-string"
326286
}
327287
}
328288
},
@@ -342,15 +302,7 @@
342302
}
343303
},
344304
"value4": {
345-
"type": "object",
346-
"properties": {
347-
"subValue1": {
348-
"$ref": "#/definitions/types.Field-string"
349-
},
350-
"subValue2": {
351-
"type": "string"
352-
}
353-
}
305+
"$ref": "#/definitions/types.SubField1-types_Field-string-string"
354306
}
355307
}
356308
},
@@ -385,6 +337,61 @@
385337
}
386338
}
387339
},
340+
"types.SubField1-api_Person-string": {
341+
"type": "object",
342+
"properties": {
343+
"subValue1": {
344+
"$ref": "#/definitions/api.Person"
345+
},
346+
"subValue2": {
347+
"type": "string"
348+
}
349+
}
350+
},
351+
"types.SubField1-string-string": {
352+
"type": "object",
353+
"properties": {
354+
"subValue1": {
355+
"type": "string"
356+
},
357+
"subValue2": {
358+
"type": "string"
359+
}
360+
}
361+
},
362+
"types.SubField1-types_Field-api_Person-string": {
363+
"type": "object",
364+
"properties": {
365+
"subValue1": {
366+
"$ref": "#/definitions/types.Field-api_Person"
367+
},
368+
"subValue2": {
369+
"type": "string"
370+
}
371+
}
372+
},
373+
"types.SubField1-types_Field-string-string": {
374+
"type": "object",
375+
"properties": {
376+
"subValue1": {
377+
"$ref": "#/definitions/types.Field-string"
378+
},
379+
"subValue2": {
380+
"type": "string"
381+
}
382+
}
383+
},
384+
"types.SubField1-types_Post-string": {
385+
"type": "object",
386+
"properties": {
387+
"subValue1": {
388+
"$ref": "#/definitions/types.Post"
389+
},
390+
"subValue2": {
391+
"type": "string"
392+
}
393+
}
394+
},
388395
"web.PostResponse": {
389396
"type": "object",
390397
"properties": {

0 commit comments

Comments
 (0)