diff --git a/operationv3.go b/operationv3.go index f54c59e2a..4737694e1 100644 --- a/operationv3.go +++ b/operationv3.go @@ -388,27 +388,29 @@ func (o *OperationV3) ParseParamComment(commentLine string, astFile *ast.File) e continue } + itemParam := param // Avoid shadowed variable which could cause side effects to o.Operation.Parameters + switch { case prop.Type[0] == ARRAY && prop.Items.Schema != nil && len(prop.Items.Schema.Spec.Type) > 0 && IsSimplePrimitiveType(prop.Items.Schema.Spec.Type[0]): - param = createParameterV3(paramType, prop.Description, name, prop.Type[0], prop.Items.Schema.Spec.Type[0], findInSlice(schema.Spec.Required, name), enums, o.parser.collectionFormatInQuery) + itemParam = createParameterV3(paramType, prop.Description, name, prop.Type[0], prop.Items.Schema.Spec.Type[0], findInSlice(schema.Spec.Required, name), enums, o.parser.collectionFormatInQuery) case IsSimplePrimitiveType(prop.Type[0]): - param = createParameterV3(paramType, prop.Description, name, PRIMITIVE, prop.Type[0], findInSlice(schema.Spec.Required, name), enums, o.parser.collectionFormatInQuery) + itemParam = createParameterV3(paramType, prop.Description, name, PRIMITIVE, prop.Type[0], findInSlice(schema.Spec.Required, name), enums, o.parser.collectionFormatInQuery) default: o.parser.debug.Printf("skip field [%s] in %s is not supported type for %s", name, refType, paramType) continue } - param.Schema.Spec = prop + itemParam.Schema.Spec = prop listItem := &spec.RefOrSpec[spec.Extendable[spec.Parameter]]{ Spec: &spec.Extendable[spec.Parameter]{ - Spec: ¶m, + Spec: &itemParam, }, } @@ -710,7 +712,7 @@ func (o *OperationV3) parseAPIObjectSchema(commentLine, schemaType, refType stri result := spec.NewSchemaSpec() result.Spec.Type = spec.NewSingleOrArray("array") - result.Spec.Items = spec.NewBoolOrSchema(false, schema) //TODO: allowed? + result.Spec.Items = spec.NewBoolOrSchema(false, schema) // TODO: allowed? return result, nil default: diff --git a/operationv3_test.go b/operationv3_test.go index 6d79ca4cf..8408aa34f 100644 --- a/operationv3_test.go +++ b/operationv3_test.go @@ -1,6 +1,7 @@ package swag import ( + "go/ast" goparser "go/parser" "go/token" "testing" @@ -852,6 +853,95 @@ func TestOperation_ParseParamCommentV3(t *testing.T) { } }) + t.Run("struct queries", func(t *testing.T) { + t.Parallel() + parser := New() + parser.packages.uniqueDefinitions["main.Object"] = &TypeSpecDef{ + File: &ast.File{Name: &ast.Ident{Name: "test"}}, + TypeSpec: &ast.TypeSpec{ + Name: &ast.Ident{Name: "Field"}, + TypeParams: &ast.FieldList{List: []*ast.Field{{Names: []*ast.Ident{{Name: "T"}}}}}, + Type: &ast.StructType{ + Struct: 100, + Fields: &ast.FieldList{ + List: []*ast.Field{ + { + Names: []*ast.Ident{ + {Name: "T"}, + }, + Type: ast.NewIdent("string"), + }, + { + Names: []*ast.Ident{ + {Name: "T2"}, + }, + Type: ast.NewIdent("string"), + }, + }, + }, + }, + }, + } + o := NewOperationV3(parser) + err := o.ParseComment(`@Param some_object query main.Object true "Some Object"`, + nil) + + assert.NoError(t, err) + + expectedT := &spec.RefOrSpec[spec.Extendable[spec.Parameter]]{ + Spec: &spec.Extendable[spec.Parameter]{ + Spec: &spec.Parameter{ + Name: "t", + In: "query", + Schema: &spec.RefOrSpec[spec.Schema]{ + Spec: &spec.Schema{ + JsonSchema: spec.JsonSchema{ + JsonSchemaCore: spec.JsonSchemaCore{ + Type: typeString, + }, + }, + }, + }, + }, + }, + } + expectedT2 := &spec.RefOrSpec[spec.Extendable[spec.Parameter]]{ + Spec: &spec.Extendable[spec.Parameter]{ + Spec: &spec.Parameter{ + Name: "t2", + In: "query", + Schema: &spec.RefOrSpec[spec.Schema]{ + Spec: &spec.Schema{ + JsonSchema: spec.JsonSchema{ + JsonSchemaCore: spec.JsonSchemaCore{ + Type: typeString, + }, + }, + }, + }, + }, + }, + } + + assert.Len(t, o.Parameters, 2) + tFound := false + t2Found := false + for _, param := range o.Parameters { + switch param.Spec.Spec.Name { + case "t": + assert.EqualValues(t, expectedT, param) + tFound = true + case "t2": + assert.EqualValues(t, expectedT2, param) + t2Found = true + default: + assert.Fail(t, "unexpected result") + } + } + + assert.True(t, tFound, "results should contain t") + assert.True(t, t2Found, "results should contain t2") + }) } // Test ParseParamComment Query Params