From 487b789bee77b1c72bb029a1c04b39894986b4fe Mon Sep 17 00:00:00 2001 From: "deepsource-autofix[bot]" <62050782+deepsource-autofix[bot]@users.noreply.github.com> Date: Sun, 28 Jul 2024 06:51:40 +0000 Subject: [PATCH] refactor: autofix issues in 1 file Resolved issues in http/codegen/service_data.go with DeepSource Autofix --- http/codegen/service_data.go | 730 +++++++++++++++-------------------- 1 file changed, 301 insertions(+), 429 deletions(-) diff --git a/http/codegen/service_data.go b/http/codegen/service_data.go index ab5537d8a7..eae87f9041 100644 --- a/http/codegen/service_data.go +++ b/http/codegen/service_data.go @@ -736,36 +736,33 @@ func (ServicesData) analyze(httpSvc *expr.HTTPServiceExpr) *ServiceData { qsch service.SchemesData basch *service.SchemeData ) - { - for _, req := range httpEndpoint.Requirements { - var rs service.SchemesData - for _, sch := range req.Schemes { - s := service.BuildSchemeData(sch, httpEndpoint.MethodExpr) - rs = rs.Append(s) - switch s.Type { - case "Basic": - basch = s + for _, req := range httpEndpoint.Requirements { + var rs service.SchemesData + for _, sch := range req.Schemes { + s := service.BuildSchemeData(sch, httpEndpoint.MethodExpr) + rs = rs.Append(s) + switch s.Type { + case "Basic": + basch = s + default: + switch s.In { + case "query": + qsch = qsch.Append(s) + case "header": + hsch = hsch.Append(s) default: - switch s.In { - case "query": - qsch = qsch.Append(s) - case "header": - hsch = hsch.Append(s) - default: - bosch = bosch.Append(s) - } + bosch = bosch.Append(s) } } - reqs = append(reqs, &service.RequirementData{Schemes: rs, Scopes: req.Scopes}) } + reqs = append(reqs, &service.RequirementData{Schemes: rs, Scopes: req.Scopes}) } var requestEncoder string - { - if payload.Request.ClientBody != nil || len(payload.Request.Headers) > 0 || len(payload.Request.QueryParams) > 0 || len(payload.Request.Cookies) > 0 || basch != nil { - requestEncoder = fmt.Sprintf("Encode%sRequest", method.VarName) - } + + if payload.Request.ClientBody != nil || len(payload.Request.Headers) > 0 || len(payload.Request.QueryParams) > 0 || len(payload.Request.Cookies) > 0 || basch != nil { + requestEncoder = fmt.Sprintf("Encode%sRequest", method.VarName) } var requestInit *InitData @@ -1010,89 +1007,67 @@ func buildPayloadData(e *expr.HTTPEndpointExpr, sd *ServiceData) *PayloadData { mustValidate bool mustHaveBody = true ) - { - if e.MapQueryParams != nil { - var ( - fieldName string - name = "query" - required = true - pAtt = payload - ) - if n := *e.MapQueryParams; n != "" { - pAtt = expr.AsObject(payload.Type).Attribute(n) - required = payload.IsRequired(n) - name = n - fieldName = codegen.Goify(name, true) - } - varn := codegen.Goify(name, false) - mapQueryParam = &ParamData{ - MapQueryParams: e.MapQueryParams, - Map: expr.AsMap(payload.Type) != nil, - Element: &Element{ - HTTPName: name, - AttributeData: &AttributeData{ - Name: name, - VarName: varn, - FieldName: fieldName, - FieldType: pAtt.Type, - Required: required, - Type: pAtt.Type, - TypeName: sd.Scope.GoTypeName(pAtt), - TypeRef: sd.Scope.GoTypeRef(pAtt), - Validate: codegen.AttributeValidationCode(pAtt, nil, httpsvrctx, required, expr.IsAlias(pAtt.Type), varn, name), - DefaultValue: pAtt.DefaultValue, - Example: pAtt.Example(expr.Root.API.ExampleGenerator), - }, - }, - } - queryData = append(queryData, mapQueryParam) - } - if serverBodyData != nil { - sd.ServerTypeNames[serverBodyData.Name] = false - sd.ClientTypeNames[serverBodyData.Name] = false + + if e.MapQueryParams != nil { + var ( + fieldName string + name = "query" + required = true + pAtt = payload + ) + if n := *e.MapQueryParams; n != "" { + pAtt = expr.AsObject(payload.Type).Attribute(n) + required = payload.IsRequired(n) + name = n + fieldName = codegen.Goify(name, true) + } + varn := codegen.Goify(name, false) + mapQueryParam = &ParamData{MapQueryParams: e.MapQueryParams, Map: expr.AsMap(payload.Type) != nil, Element: &Element{HTTPName: name, AttributeData: &AttributeData{Name: name, VarName: varn, FieldName: fieldName, FieldType: pAtt.Type, Required: required, Type: pAtt.Type, TypeName: sd.Scope.GoTypeName(pAtt), TypeRef: sd.Scope.GoTypeRef(pAtt), Validate: codegen.AttributeValidationCode(pAtt, nil, httpsvrctx, required, expr.IsAlias(pAtt.Type), varn, name), DefaultValue: pAtt.DefaultValue, Example: pAtt.Example(expr.Root.API.ExampleGenerator)}}} + queryData = append(queryData, mapQueryParam) + } + if serverBodyData != nil { + sd.ServerTypeNames[serverBodyData.Name] = false + sd.ClientTypeNames[serverBodyData.Name] = false + } + for _, p := range cookiesData { + if p.Required || p.Validate != "" || needConversion(p.Type) { + mustValidate = true + break } - for _, p := range cookiesData { - if p.Required || p.Validate != "" || needConversion(p.Type) { + } + if !mustValidate { + for _, p := range paramsData { + if p.Validate != "" || needConversion(p.Type) { mustValidate = true break } } - if !mustValidate { - for _, p := range paramsData { - if p.Validate != "" || needConversion(p.Type) { - mustValidate = true - break - } - } - } - if !mustValidate { - for _, q := range queryData { - if q.Map || q.Validate != "" || q.Required || needConversion(q.Type) { - mustValidate = true - break - } + } + if !mustValidate { + for _, q := range queryData { + if q.Map || q.Validate != "" || q.Required || needConversion(q.Type) { + mustValidate = true + break } } - if !mustValidate { - for _, h := range headersData { - if h.Validate != "" || h.Required || needConversion(h.Type) { - mustValidate = true - break - } + } + if !mustValidate { + for _, h := range headersData { + if h.Validate != "" || h.Required || needConversion(h.Type) { + mustValidate = true + break } } - if e.Body.Type != expr.Empty { - // If design uses Body("name") syntax we need to use the - // corresponding attribute in the result type for body - // transformation. - if o, ok := e.Body.Meta["origin:attribute"]; ok { - origin = o[0] - if !payload.IsRequired(o[0]) { - mustHaveBody = false - } + } + if e.Body.Type != expr.Empty { + if o, ok := e.Body.Meta["origin:attribute"]; ok { + origin = o[0] + if !payload.IsRequired(o[0]) { + mustHaveBody = false } } } + request = &RequestData{ PathParams: paramsData, QueryParams: queryData, @@ -1389,21 +1364,20 @@ func buildPayloadData(e *expr.HTTPEndpointExpr, sd *ServiceData) *PayloadData { name string ref string ) - { - if payload.Type != expr.Empty { - name = svc.Scope.GoFullTypeName(payload, pkg) - ref = svc.Scope.GoFullTypeRef(payload, pkg) - } - if init == nil { - if o := expr.AsObject(e.Params.Type); o != nil && len(*o) > 0 { - returnValue = codegen.Goify((*o)[0].Name, false) - } else if o := expr.AsObject(e.Headers.Type); o != nil && len(*o) > 0 { - returnValue = codegen.Goify((*o)[0].Name, false) - } else if o := expr.AsObject(e.Cookies.Type); o != nil && len(*o) > 0 { - returnValue = codegen.Goify((*o)[0].Name, false) - } else if e.MapQueryParams != nil && *e.MapQueryParams == "" { - returnValue = mapQueryParam.VarName - } + + if payload.Type != expr.Empty { + name = svc.Scope.GoFullTypeName(payload, pkg) + ref = svc.Scope.GoFullTypeRef(payload, pkg) + } + if init == nil { + if o := expr.AsObject(e.Params.Type); o != nil && len(*o) > 0 { + returnValue = codegen.Goify((*o)[0].Name, false) + } else if o := expr.AsObject(e.Headers.Type); o != nil && len(*o) > 0 { + returnValue = codegen.Goify((*o)[0].Name, false) + } else if o := expr.AsObject(e.Cookies.Type); o != nil && len(*o) > 0 { + returnValue = codegen.Goify((*o)[0].Name, false) + } else if e.MapQueryParams != nil && *e.MapQueryParams == "" { + returnValue = mapQueryParam.VarName } } @@ -1427,15 +1401,14 @@ func buildResultData(e *expr.HTTPEndpointExpr, sd *ServiceData) *ResultData { ref string view string ) - { - view = expr.DefaultView - if v, ok := result.Meta.Last(expr.ViewMetaKey); ok { - view = v - } - if result.Type != expr.Empty { - name = svc.Scope.GoFullTypeName(result, pkg) - ref = svc.Scope.GoFullTypeRef(result, pkg) - } + + view = expr.DefaultView + if v, ok := result.Meta.Last(expr.ViewMetaKey); ok { + view = v + } + if result.Type != expr.Empty { + name = svc.Scope.GoFullTypeName(result, pkg) + ref = svc.Scope.GoFullTypeRef(result, pkg) } var ( @@ -1710,13 +1683,13 @@ func buildResponses(e *expr.HTTPEndpointExpr, result *expr.AttributeExpr, viewed tagVal string tagPtr bool ) - { - if resp.Tag[0] != "" { - tagName = codegen.Goify(resp.Tag[0], true) - tagVal = resp.Tag[1] - tagPtr = viewed || result.IsPrimitivePointer(resp.Tag[0], true) - } + + if resp.Tag[0] != "" { + tagName = codegen.Goify(resp.Tag[0], true) + tagVal = resp.Tag[1] + tagPtr = viewed || result.IsPrimitivePointer(resp.Tag[0], true) } + responses = append(responses, &ResponseData{ StatusCode: statusCodeToHTTPConst(resp.StatusCode), Description: resp.Description, @@ -1772,53 +1745,22 @@ func buildErrorsData(e *expr.HTTPEndpointExpr, sd *ServiceData) []*ErrorGroupDat isObject bool args []*InitArgData ) - { - name = fmt.Sprintf("New%s%s", codegen.Goify(ep.Name, true), codegen.Goify(v.ErrorExpr.Name, true)) - desc = fmt.Sprintf("%s builds a %s service %s endpoint %s error.", - name, svc.Name, e.Name(), v.ErrorExpr.Name) - if body != expr.Empty { - isObject = expr.IsObject(body) - ref := "body" - if isObject { - ref = "&body" - } - args = []*InitArgData{{ - Ref: ref, - AttributeData: &AttributeData{Name: "body", VarName: "body", TypeRef: sd.Scope.GoTypeRef(v.Response.Body)}, - }} - } - for _, h := range extractHeaders(v.Response.Headers, v.ErrorExpr.AttributeExpr, errctx, sd.Scope) { - args = append(args, &InitArgData{ - Ref: h.VarName, - AttributeData: &AttributeData{ - Name: h.Name, - VarName: h.VarName, - FieldName: h.FieldName, - FieldPointer: false, - FieldType: h.FieldType, - TypeRef: h.TypeRef, - Type: h.Type, - Validate: h.Validate, - Example: h.Example, - }, - }) - } - for _, c := range extractCookies(v.Response.Cookies, v.ErrorExpr.AttributeExpr, errctx, sd.Scope) { - args = append(args, &InitArgData{ - Ref: c.VarName, - AttributeData: &AttributeData{ - Name: c.Name, - VarName: c.VarName, - FieldName: c.FieldName, - FieldPointer: false, - FieldType: c.FieldType, - TypeRef: c.TypeRef, - Type: c.Type, - Validate: c.Validate, - Example: c.Example, - }, - }) + + name = fmt.Sprintf("New%s%s", codegen.Goify(ep.Name, true), codegen.Goify(v.ErrorExpr.Name, true)) + desc = fmt.Sprintf("%s builds a %s service %s endpoint %s error.", name, svc.Name, e.Name(), v.ErrorExpr.Name) + if body != expr.Empty { + isObject = expr.IsObject(body) + ref := "body" + if isObject { + ref = "&body" } + args = []*InitArgData{{Ref: ref, AttributeData: &AttributeData{Name: "body", VarName: "body", TypeRef: sd.Scope.GoTypeRef(v.Response.Body)}}} + } + for _, h := range extractHeaders(v.Response.Headers, v.ErrorExpr.AttributeExpr, errctx, sd.Scope) { + args = append(args, &InitArgData{Ref: h.VarName, AttributeData: &AttributeData{Name: h.Name, VarName: h.VarName, FieldName: h.FieldName, FieldPointer: false, FieldType: h.FieldType, TypeRef: h.TypeRef, Type: h.Type, Validate: h.Validate, Example: h.Example}}) + } + for _, c := range extractCookies(v.Response.Cookies, v.ErrorExpr.AttributeExpr, errctx, sd.Scope) { + args = append(args, &InitArgData{Ref: c.VarName, AttributeData: &AttributeData{Name: c.Name, VarName: c.VarName, FieldName: c.FieldName, FieldPointer: false, FieldType: c.FieldType, TypeRef: c.TypeRef, Type: c.Type, Validate: c.Validate, Example: c.Example}}) } var ( @@ -1826,34 +1768,30 @@ func buildErrorsData(e *expr.HTTPEndpointExpr, sd *ServiceData) []*ErrorGroupDat origin string err error ) - { - if body != expr.Empty { - eAtt := v.ErrorExpr.AttributeExpr - // If design uses Body("name") syntax then need to use payload - // attribute to transform. - if o, ok := v.Response.Body.Meta["origin:attribute"]; ok { - origin = o[0] - eAtt = expr.AsObject(v.ErrorExpr.Type).Attribute(origin) - } + if body != expr.Empty { + eAtt := v.ErrorExpr.AttributeExpr + if o, ok := v.Response.Body.Meta["origin:attribute"]; ok { + origin = o[0] + eAtt = expr.AsObject(v.ErrorExpr.Type).Attribute(origin) + } + var helpers []*codegen.TransformFunctionData + code, helpers, err = unmarshal(v.Response.Body, eAtt, "body", "v", httpclictx, errctx) + if err == nil { + sd.ClientTransformHelpers = codegen.AppendHelpers(sd.ClientTransformHelpers, helpers) + } + } else if expr.IsArray(v.ErrorExpr.Type) || expr.IsMap(v.ErrorExpr.Type) { + if params := expr.AsObject(e.QueryParams().Type); len(*params) > 0 { var helpers []*codegen.TransformFunctionData - code, helpers, err = unmarshal(v.Response.Body, eAtt, "body", "v", httpclictx, errctx) + code, helpers, err = unmarshal((*params)[0].Attribute, v.ErrorExpr.AttributeExpr, codegen.Goify((*params)[0].Name, false), "v", httpclictx, errctx) if err == nil { sd.ClientTransformHelpers = codegen.AppendHelpers(sd.ClientTransformHelpers, helpers) } - } else if expr.IsArray(v.ErrorExpr.Type) || expr.IsMap(v.ErrorExpr.Type) { - if params := expr.AsObject(e.QueryParams().Type); len(*params) > 0 { - var helpers []*codegen.TransformFunctionData - code, helpers, err = unmarshal((*params)[0].Attribute, v.ErrorExpr.AttributeExpr, codegen.Goify((*params)[0].Name, false), "v", httpclictx, errctx) - if err == nil { - sd.ClientTransformHelpers = codegen.AppendHelpers(sd.ClientTransformHelpers, helpers) - } - } - } - if err != nil { - fmt.Println(err.Error()) // TBD validate DSL so errors are not possible } } + if err != nil { + fmt.Println(err.Error()) + } init = &InitData{ Name: name, @@ -1894,20 +1832,20 @@ func buildErrorsData(e *expr.HTTPEndpointExpr, sd *ServiceData) []*ErrorGroupDat headers := extractHeaders(v.Response.Headers, v.ErrorExpr.AttributeExpr, errctx, sd.Scope) cookies := extractCookies(v.Response.Cookies, v.ErrorExpr.AttributeExpr, errctx, sd.Scope) var mustValidate bool - { - for _, h := range headers { - if h.Validate != "" || h.Required || needConversion(h.Type) { - mustValidate = true - break - } + + for _, h := range headers { + if h.Validate != "" || h.Required || needConversion(h.Type) { + mustValidate = true + break } - for _, c := range cookies { - if c.Validate != "" || c.Required || needConversion(c.Type) { - mustValidate = true - break - } + } + for _, c := range cookies { + if c.Validate != "" || c.Required || needConversion(c.Type) { + mustValidate = true + break } } + var contentType string if v.Response.ContentType != expr.ErrorResultIdentifier { contentType = v.Response.ContentType @@ -1995,93 +1933,64 @@ func buildRequestBodyType(body, att *expr.AttributeExpr, e *expr.HTTPEndpointExp pkg = pkgWithDefault(ep.PayloadLoc, sd.Service.PkgName) svcctx = serviceContext(pkg, sd.Service.Scope) ) - { - name = body.Type.Name() - ref = sd.Scope.GoTypeRef(body) - - AddMarshalTags(body, make(map[string]struct{})) - - if ut, ok := body.Type.(expr.UserType); ok { - varname = codegen.Goify(ut.Name(), true) - def = goTypeDef(sd.Scope, ut.Attribute(), svr, !svr) - desc = fmt.Sprintf("%s is the type of the %q service %q endpoint HTTP request body.", - varname, svc.Name, e.Name()) - if svr { - // generate validation code for unmarshaled type (server-side). - validateDef = codegen.ValidationCode(ut.Attribute(), ut, httpctx, true, expr.IsAlias(ut), false, "body") - if validateDef != "" { - validateRef = fmt.Sprintf("err = Validate%s(&body)", varname) - } - } - } else { - if svr && expr.IsObject(body.Type) { - // Body is an explicit object described in the design and in - // this case the GoTypeRef is an inline struct definition. We - // want to force all attributes to be pointers because we are - // generating the server body type pre-validation. - body.Validation = nil + + name = body.Type.Name() + ref = sd.Scope.GoTypeRef(body) + AddMarshalTags(body, make(map[string]struct{})) + if ut, ok := body.Type.(expr.UserType); ok { + varname = codegen.Goify(ut.Name(), true) + def = goTypeDef(sd.Scope, ut.Attribute(), svr, !svr) + desc = fmt.Sprintf("%s is the type of the %q service %q endpoint HTTP request body.", varname, svc.Name, e.Name()) + if svr { + validateDef = codegen.ValidationCode(ut.Attribute(), ut, httpctx, true, expr.IsAlias(ut), false, "body") + if validateDef != "" { + validateRef = fmt.Sprintf("err = Validate%s(&body)", varname) } - varname = sd.Scope.GoTypeRef(body) - ctx := codegen.NewAttributeContext(false, false, !svr, "", sd.Scope) - validateRef = codegen.ValidationCode(body, nil, ctx, true, expr.IsAlias(body.Type), false, "body") - desc = body.Description } + } else { + if svr && expr.IsObject(body.Type) { + body.Validation = nil + } + varname = sd.Scope.GoTypeRef(body) + ctx := codegen.NewAttributeContext(false, false, !svr, "", sd.Scope) + validateRef = codegen.ValidationCode(body, nil, ctx, true, expr.IsAlias(body.Type), false, "body") + desc = body.Description } + var init *InitData - { - if !svr && att.Type != expr.Empty && needInit(body.Type) { - var ( - name string - desc string - code string - origin string - err error - helpers []*codegen.TransformFunctionData - sourceVar = "p" - svc = sd.Service - ) - { - name = fmt.Sprintf("New%s", codegen.Goify(sd.Scope.GoTypeName(body), true)) - desc = fmt.Sprintf("%s builds the HTTP request body from the payload of the %q endpoint of the %q service.", - name, e.Name(), svc.Name) - src := sourceVar - srcAtt := att - // If design uses Body("name") syntax then need to use payload attribute - // to transform. - if o, ok := body.Meta["origin:attribute"]; ok { - srcObj := expr.AsObject(att.Type) - origin = o[0] - srcAtt = srcObj.Attribute(origin) - src += "." + codegen.Goify(origin, true) - } - code, helpers, err = marshal(srcAtt, body, src, "body", svcctx, httpctx) - if err != nil { - fmt.Println(err.Error()) // TBD validate DSL so errors are not possible - } - sd.ClientTransformHelpers = codegen.AppendHelpers(sd.ClientTransformHelpers, helpers) - } - arg := InitArgData{ - Ref: sourceVar, - AttributeData: &AttributeData{ - Name: "payload", - VarName: sourceVar, - TypeRef: svc.Scope.GoFullTypeRef(att, pkg), - Type: att.Type, - Validate: validateDef, - Example: att.Example(expr.Root.API.ExampleGenerator), - }, + if !svr && att.Type != expr.Empty && needInit(body.Type) { + var ( + name string + desc string + code string + origin string + err error + helpers []*codegen.TransformFunctionData + sourceVar = "p" + svc = sd.Service + ) + { + name = fmt.Sprintf("New%s", codegen.Goify(sd.Scope.GoTypeName(body), true)) + desc = fmt.Sprintf("%s builds the HTTP request body from the payload of the %q endpoint of the %q service.", name, e.Name(), svc.Name) + src := sourceVar + srcAtt := att + if o, ok := body.Meta["origin:attribute"]; ok { + srcObj := expr.AsObject(att.Type) + origin = o[0] + srcAtt = srcObj.Attribute(origin) + src += "." + codegen.Goify(origin, true) } - init = &InitData{ - Name: name, - Description: desc, - ReturnTypeRef: sd.Scope.GoTypeRef(body), - ReturnTypeAttribute: codegen.Goify(origin, true), - ClientCode: code, - ClientArgs: []*InitArgData{&arg}, + code, helpers, err = marshal(srcAtt, body, src, "body", svcctx, httpctx) + if err != nil { + fmt.Println(err.Error()) } + sd.ClientTransformHelpers = codegen.AppendHelpers(sd.ClientTransformHelpers, helpers) } + arg := InitArgData{Ref: sourceVar, AttributeData: &AttributeData{Name: "payload", VarName: sourceVar, TypeRef: svc.Scope.GoFullTypeRef(att, pkg), Type: att.Type, Validate: validateDef, Example: att.Example(expr.Root.API.ExampleGenerator)}} + init = &InitData{Name: name, Description: desc, ReturnTypeRef: sd.Scope.GoTypeRef(body), ReturnTypeAttribute: codegen.Goify(origin, true), ClientCode: code, ClientArgs: []*InitArgData{&arg}} } + return &TypeData{ Name: name, VarName: varname, @@ -2126,65 +2035,51 @@ func buildResponseBodyType(body, att *expr.AttributeExpr, loc *codegen.Location, pkg = pkgWithDefault(loc, sd.Service.PkgName) svcctx = serviceContext(pkg, sd.Service.Scope) ) - { - // For server code, we project the response body type if the type is a result - // type and generate a type for each view in the result type. This makes it - // possible to return only the attributes in the view in the server response. - if svr && view != nil && *view != "" { - viewName = *view - body = expr.DupAtt(body) - if rt, ok := body.Type.(*expr.ResultTypeExpr); ok { - var err error - rt, err = expr.Project(rt, *view) - if err != nil { - panic(err) - } - body.Type = rt - sd.ServerTypeNames[rt.Name()] = false - } - } - name = body.Type.Name() - ref = sd.Scope.GoTypeRef(body) - mustInit = att.Type != expr.Empty && needInit(body.Type) - - AddMarshalTags(body, make(map[string]struct{})) - - if ut, ok := body.Type.(expr.UserType); ok { - // response body is a user type. - varname = codegen.Goify(ut.Name(), true) - def = goTypeDef(sd.Scope, ut.Attribute(), !svr, svr) - desc = fmt.Sprintf("%s is the type of the %q service %q endpoint HTTP response body.", - varname, svc.Name, e.Name()) - if !svr && view == nil { - // generate validation code for unmarshaled type (client-side). - validateDef = codegen.ValidationCode(body, ut, httpctx, true, expr.IsAlias(body.Type), false, "body") - if validateDef != "" { - target := "&body" - if expr.IsArray(ut) { - // result type collection - target = "body" - } - validateRef = fmt.Sprintf("err = Validate%s(%s)", varname, target) + if svr && view != nil && *view != "" { + viewName = *view + body = expr.DupAtt(body) + if rt, ok := body.Type.(*expr.ResultTypeExpr); ok { + var err error + rt, err = expr.Project(rt, *view) + if err != nil { + panic(err) + } + body.Type = rt + sd.ServerTypeNames[rt.Name()] = false + } + } + name = body.Type.Name() + ref = sd.Scope.GoTypeRef(body) + mustInit = att.Type != expr.Empty && needInit(body.Type) + AddMarshalTags(body, make(map[string]struct{})) + if ut, ok := body.Type.(expr.UserType); ok { + varname = codegen.Goify(ut.Name(), true) + def = goTypeDef(sd.Scope, ut.Attribute(), !svr, svr) + desc = fmt.Sprintf("%s is the type of the %q service %q endpoint HTTP response body.", varname, svc.Name, e.Name()) + if !svr && view == nil { + validateDef = codegen.ValidationCode(body, ut, httpctx, true, expr.IsAlias(body.Type), false, "body") + if validateDef != "" { + target := "&body" + if expr.IsArray(ut) { + target = "body" } + validateRef = fmt.Sprintf("err = Validate%s(%s)", varname, target) } - } else if !expr.IsPrimitive(body.Type) && mustInit { - // response body is an array or map type. - name = codegen.Goify(e.Name(), true) + "ResponseBody" - varname = name - desc = fmt.Sprintf("%s is the type of the %q service %q endpoint HTTP response body.", - varname, svc.Name, e.Name()) - def = goTypeDef(sd.Scope, body, !svr, svr) - validateRef = codegen.ValidationCode(body, nil, httpctx, true, expr.IsAlias(body.Type), false, "body") - } else { - // response body is a primitive type. They are used as non-pointers when - // encoding/decoding responses. - httpctx = httpContext("", sd.Scope, false, true) - validateRef = codegen.ValidationCode(body, nil, httpctx, true, expr.IsAlias(body.Type), false, "body") - varname = sd.Scope.GoTypeRef(body) - desc = body.Description } + } else if !expr.IsPrimitive(body.Type) && mustInit { + name = codegen.Goify(e.Name(), true) + "ResponseBody" + varname = name + desc = fmt.Sprintf("%s is the type of the %q service %q endpoint HTTP response body.", varname, svc.Name, e.Name()) + def = goTypeDef(sd.Scope, body, !svr, svr) + validateRef = codegen.ValidationCode(body, nil, httpctx, true, expr.IsAlias(body.Type), false, "body") + } else { + httpctx = httpContext("", sd.Scope, false, true) + validateRef = codegen.ValidationCode(body, nil, httpctx, true, expr.IsAlias(body.Type), false, "body") + varname = sd.Scope.GoTypeRef(body) + desc = body.Description } + if svr { sd.ServerTypeNames[name] = false // We collect the server body types need to generate a response body type @@ -2201,80 +2096,59 @@ func buildResponseBodyType(body, att *expr.AttributeExpr, loc *codegen.Location, } var init *InitData - { - if svr && mustInit { - var ( - name string - desc string - rtref string - code string - origin string - err error - helpers []*codegen.TransformFunctionData - sourceVar = "res" - svc = sd.Service - ) - { - var rtname string - if _, ok := body.Type.(expr.UserType); !ok && !expr.IsPrimitive(body.Type) { - rtname = codegen.Goify(e.Name(), true) + "ResponseBody" - rtref = rtname - } else { - rtname = codegen.Goify(sd.Scope.GoTypeName(body), true) - rtref = sd.Scope.GoTypeRef(body) - } - name = fmt.Sprintf("New%s", rtname) - desc = fmt.Sprintf("%s builds the HTTP response body from the result of the %q endpoint of the %q service.", - name, e.Name(), svc.Name) - if view != nil { - svcctx = viewContext(sd.Service.ViewsPkg, sd.Service.ViewScope) - } - src := sourceVar - srcAtt := att - // If design uses Body("name") syntax then need to use result attribute - // to transform. - if o, ok := body.Meta["origin:attribute"]; ok { - srcObj := expr.AsObject(att.Type) - origin = o[0] - srcAtt = srcObj.Attribute(origin) - src += "." + codegen.Goify(origin, true) - } - code, helpers, err = marshal(srcAtt, body, src, "body", svcctx, httpctx) - if err != nil { - panic(err) // bug - } - sd.ServerTransformHelpers = codegen.AppendHelpers(sd.ServerTransformHelpers, helpers) - } - ref := sourceVar - if view != nil { - ref += ".Projected" + if svr && mustInit { + var ( + name string + desc string + rtref string + code string + origin string + err error + helpers []*codegen.TransformFunctionData + sourceVar = "res" + svc = sd.Service + ) + { + var rtname string + if _, ok := body.Type.(expr.UserType); !ok && !expr.IsPrimitive(body.Type) { + rtname = codegen.Goify(e.Name(), true) + "ResponseBody" + rtref = rtname + } else { + rtname = codegen.Goify(sd.Scope.GoTypeName(body), true) + rtref = sd.Scope.GoTypeRef(body) } - tref := svc.Scope.GoFullTypeRef(att, pkg) + name = fmt.Sprintf("New%s", rtname) + desc = fmt.Sprintf("%s builds the HTTP response body from the result of the %q endpoint of the %q service.", name, e.Name(), svc.Name) if view != nil { - tref = svc.ViewScope.GoFullTypeRef(att, svc.ViewsPkg) + svcctx = viewContext(sd.Service.ViewsPkg, sd.Service.ViewScope) } - arg := InitArgData{ - Ref: ref, - AttributeData: &AttributeData{ - Name: "result", - VarName: sourceVar, - TypeRef: tref, - Type: att.Type, - Validate: validateDef, - Example: att.Example(expr.Root.API.ExampleGenerator), - }, + src := sourceVar + srcAtt := att + if o, ok := body.Meta["origin:attribute"]; ok { + srcObj := expr.AsObject(att.Type) + origin = o[0] + srcAtt = srcObj.Attribute(origin) + src += "." + codegen.Goify(origin, true) } - init = &InitData{ - Name: name, - Description: desc, - ReturnTypeRef: rtref, - ReturnTypeAttribute: codegen.Goify(origin, true), - ServerCode: code, - ServerArgs: []*InitArgData{&arg}, + code, helpers, err = marshal(srcAtt, body, src, "body", svcctx, httpctx) + if err != nil { + panic(err) } + sd.ServerTransformHelpers = codegen.AppendHelpers(sd.ServerTransformHelpers, helpers) } + ref := sourceVar + if view != nil { + ref += ".Projected" + } + tref := svc.Scope.GoFullTypeRef(att, pkg) + if view != nil { + tref = svc.ViewScope.GoFullTypeRef(att, svc.ViewsPkg) + } + arg := InitArgData{Ref: ref, AttributeData: &AttributeData{Name: "result", VarName: sourceVar, TypeRef: tref, Type: att.Type, Validate: validateDef, Example: att.Example(expr.Root.API.ExampleGenerator)}} + init = &InitData{Name: name, Description: desc, ReturnTypeRef: rtref, ReturnTypeAttribute: codegen.Goify(origin, true), ServerCode: code, ServerArgs: []*InitArgData{&arg}} } + return &TypeData{ Name: name, VarName: varname, @@ -2422,14 +2296,12 @@ func extractHeaders(a *expr.MappedAttributeExpr, svcAtt *expr.AttributeExpr, svc } var hattr *expr.AttributeExpr var stringSlice bool - { - // The StringSlice field of ParamData must be false for aliased primitive types - if arr := expr.AsArray(attr.Type); arr != nil { - stringSlice = arr.ElemType.Type.Kind() == expr.StringKind - } - hattr = makeHTTPType(attr) + if arr := expr.AsArray(attr.Type); arr != nil { + stringSlice = arr.ElemType.Type.Kind() == expr.StringKind } + hattr = makeHTTPType(attr) + var ( varn = scope.Name(codegen.Goify(name, false)) arr = expr.AsArray(hattr.Type) @@ -2440,16 +2312,16 @@ func extractHeaders(a *expr.MappedAttributeExpr, svcAtt *expr.AttributeExpr, svc pointer bool fptr bool ) - { - pointer = a.IsPrimitivePointer(name, true) - if expr.IsObject(svcAtt.Type) { - fieldName = codegen.GoifyAtt(attr, name, true) - fptr = svcCtx.IsPrimitivePointer(name, svcAtt) - } - if pointer { - typeRef = "*" + typeRef - } + + pointer = a.IsPrimitivePointer(name, true) + if expr.IsObject(svcAtt.Type) { + fieldName = codegen.GoifyAtt(attr, name, true) + fptr = svcCtx.IsPrimitivePointer(name, svcAtt) } + if pointer { + typeRef = "*" + typeRef + } + headers = append(headers, &HeaderData{ CanonicalName: http.CanonicalHeaderKey(elem), Element: &Element{ @@ -2484,12 +2356,12 @@ func extractCookies(a *expr.MappedAttributeExpr, svcAtt *expr.AttributeExpr, svc var cookies []*CookieData codegen.WalkMappedAttr(a, func(name, elem string, required bool, _ *expr.AttributeExpr) error { // nolint: errcheck var hattr *expr.AttributeExpr - { - if hattr = svcAtt.Find(name); hattr == nil { - hattr = svcAtt - } - hattr = makeHTTPType(hattr) + + if hattr = svcAtt.Find(name); hattr == nil { + hattr = svcAtt } + hattr = makeHTTPType(hattr) + var ( varn = scope.Name(codegen.Goify(name, false)) typeRef = scope.GoTypeRef(hattr) @@ -2499,17 +2371,17 @@ func extractCookies(a *expr.MappedAttributeExpr, svcAtt *expr.AttributeExpr, svc pointer bool fptr bool ) - { - pointer = a.IsPrimitivePointer(name, true) - if expr.IsObject(svcAtt.Type) { - fieldName = codegen.GoifyAtt(hattr, name, true) - fptr = svcCtx.IsPrimitivePointer(name, svcAtt) - ft = svcAtt.Find(name).Type - } - if pointer { - typeRef = "*" + typeRef - } + + pointer = a.IsPrimitivePointer(name, true) + if expr.IsObject(svcAtt.Type) { + fieldName = codegen.GoifyAtt(hattr, name, true) + fptr = svcCtx.IsPrimitivePointer(name, svcAtt) + ft = svcAtt.Find(name).Type } + if pointer { + typeRef = "*" + typeRef + } + c := &CookieData{ Element: &Element{ HTTPName: elem,