// gotTypeRefExt computes the type reference for a type in a different package. func goTypeRefExt(t design.DataType, tabs int, pkg string) string { ref := codegen.GoTypeRef(t, nil, tabs, false) if strings.HasPrefix(ref, "*") { return fmt.Sprintf("%s.%s", pkg, ref[1:]) } return fmt.Sprintf("%s.%s", pkg, ref) }
func okResp(a *design.ActionDefinition) map[string]interface{} { var ok *design.ResponseDefinition for _, resp := range a.Responses { if resp.Status == 200 { ok = resp break } } if ok == nil { return nil } var mt *design.MediaTypeDefinition var ok2 bool if mt, ok2 = design.Design.MediaTypes[design.CanonicalIdentifier(ok.MediaType)]; !ok2 { return nil } name := codegen.GoTypeRef(mt, mt.AllRequired(), 1, false) var pointer string if strings.HasPrefix(name, "*") { name = name[1:] pointer = "*" } typeref := fmt.Sprintf("%s%s.%s", pointer, TargetPackage, name) if strings.HasPrefix(typeref, "*") { typeref = "&" + typeref[1:] } return map[string]interface{}{ "Name": ok.Name, "GoType": codegen.GoNativeType(mt), "TypeRef": typeref, } }
// decodeGoTypeRef handles the case where the type being decoded is a error response media type. func decodeGoTypeRef(t design.DataType, required []string, tabs int, private bool) string { mt, ok := t.(*design.MediaTypeDefinition) if ok && mt.IsError() { return "*goa.ErrorResponse" } return codegen.GoTypeRef(t, required, tabs, private) }
func attToObject(name string, parent, att *design.AttributeDefinition) *ObjectType { obj := &ObjectType{} obj.Label = name obj.Name = codegen.Goify(name, false) obj.Type = codegen.GoTypeRef(att.Type, nil, 0, false) if att.Type.IsPrimitive() && parent.IsPrimitivePointer(name) { obj.Pointer = "*" } return obj }
func (g *Generator) okResp(a *design.ActionDefinition) map[string]interface{} { var ok *design.ResponseDefinition for _, resp := range a.Responses { if resp.Status == 200 { ok = resp break } } if ok == nil { return nil } var mt *design.MediaTypeDefinition var ok2 bool if mt, ok2 = design.Design.MediaTypes[design.CanonicalIdentifier(ok.MediaType)]; !ok2 { return nil } view := ok.ViewName if view == "" { view = design.DefaultView } pmt, _, err := mt.Project(view) if err != nil { return nil } var typeref string if pmt.IsError() { typeref = `goa.ErrInternal("not implemented")` } else { name := codegen.GoTypeRef(pmt, pmt.AllRequired(), 1, false) var pointer string if strings.HasPrefix(name, "*") { name = name[1:] pointer = "*" } typeref = fmt.Sprintf("%s%s.%s", pointer, g.Target, name) if strings.HasPrefix(typeref, "*") { typeref = "&" + typeref[1:] } typeref += "{}" } var nameSuffix string if view != "default" { nameSuffix = codegen.Goify(view, true) } return map[string]interface{}{ "Name": ok.Name + nameSuffix, "GoType": codegen.GoNativeType(pmt), "TypeRef": typeref, } }
func okResp(a *design.ActionDefinition) map[string]interface{} { var ok *design.ResponseDefinition for _, resp := range a.Responses { if resp.Status == 200 { ok = resp break } } if ok == nil { return nil } var mt *design.MediaTypeDefinition var ok2 bool if mt, ok2 = design.Design.MediaTypes[design.CanonicalIdentifier(ok.MediaType)]; !ok2 { return nil } view := "default" if _, ok := mt.Views["default"]; !ok { for v := range mt.Views { view = v break } } pmt, _, err := mt.Project(view) if err != nil { return nil } name := codegen.GoTypeRef(pmt, pmt.AllRequired(), 1, false) var pointer string if strings.HasPrefix(name, "*") { name = name[1:] pointer = "*" } typeref := fmt.Sprintf("%s%s.%s", pointer, TargetPackage, name) if strings.HasPrefix(typeref, "*") { typeref = "&" + typeref[1:] } var nameSuffix string if view != "default" { nameSuffix = codegen.Goify(view, true) } return map[string]interface{}{ "Name": ok.Name + nameSuffix, "GoType": codegen.GoNativeType(pmt), "TypeRef": typeref, } }
func paramFromNames(action *design.ActionDefinition, names []string) (params []*ObjectType) { for _, paramName := range names { for name, att := range action.Params.Type.ToObject() { if name == paramName { param := &ObjectType{} param.Label = name param.Name = codegen.Goify(name, false) param.Type = codegen.GoTypeRef(att.Type, nil, 0, false) if att.Type.IsPrimitive() && action.Params.IsPrimitivePointer(name) { param.Pointer = "*" } params = append(params, param) } } } return }
func createTestMethod(resource *design.ResourceDefinition, action *design.ActionDefinition, response *design.ResponseDefinition, route *design.RouteDefinition, routeIndex int, mediaType *design.MediaTypeDefinition, view *design.ViewDefinition) TestMethod { routeNameQualifier := suffixRoute(action.Routes, routeIndex) viewNameQualifier := func() string { if view != nil && view.Name != "default" { return view.Name } return "" }() method := TestMethod{} method.Name = fmt.Sprintf("%s%s%s%s%s", codegen.Goify(action.Name, true), codegen.Goify(resource.Name, true), codegen.Goify(response.Name, true), routeNameQualifier, codegen.Goify(viewNameQualifier, true)) method.ActionName = codegen.Goify(action.Name, true) method.ResourceName = codegen.Goify(resource.Name, true) method.Comment = fmt.Sprintf("test setup") method.ControllerName = fmt.Sprintf("%s.%sController", TargetPackage, codegen.Goify(resource.Name, true)) method.ContextVarName = fmt.Sprintf("%sCtx", codegen.Goify(action.Name, false)) method.ContextType = fmt.Sprintf("%s.New%s%sContext", TargetPackage, codegen.Goify(action.Name, true), codegen.Goify(resource.Name, true)) method.RouteVerb = route.Verb method.Status = response.Status method.FullPath = goPathFormat(route.FullPath()) if view != nil && mediaType != nil { p, _, err := mediaType.Project(view.Name) if err != nil { panic(err) } tmp := codegen.GoTypeName(p, nil, 0, false) if !p.IsBuiltIn() { tmp = fmt.Sprintf("%s.%s", TargetPackage, tmp) } validate := codegen.RecursiveChecker(p.AttributeDefinition, false, false, false, "payload", "raw", 1, true) returnType := ObjectType{} returnType.Type = tmp returnType.Pointer = "*" returnType.Validatable = validate != "" method.ReturnType = &returnType } if len(route.Params()) > 0 { var params = []ObjectType{} for _, paramName := range route.Params() { for name, att := range action.Params.Type.ToObject() { if name == paramName { param := ObjectType{} param.Name = codegen.Goify(name, false) param.Type = codegen.GoTypeRef(att.Type, nil, 0, false) if att.Type.IsPrimitive() && action.Params.IsPrimitivePointer(name) { param.Pointer = "*" } params = append(params, param) } } } method.Params = params } if action.Payload != nil { payload := ObjectType{} payload.Name = "payload" payload.Type = fmt.Sprintf("%s.%s", TargetPackage, codegen.Goify(action.Payload.TypeName, true)) if !action.Payload.IsPrimitive() && !action.Payload.IsArray() && !action.Payload.IsHash() { payload.Pointer = "*" } validate := codegen.RecursiveChecker(action.Payload.AttributeDefinition, false, false, false, "payload", "raw", 1, true) if validate != "" { payload.Validatable = true } method.Payload = &payload } return method }
}) Context("unmarshaler code", func() { BeforeEach(func() { unmarshaler = codegen.TypeUnmarshaler(o, false, "", context, source, target) data := map[string]interface{}{ "raw": `interface{}(map[string]interface{}{ "baz": map[string]interface{}{ "foo": 345.0, "bar":[]interface{}{[]interface{}{1.0,2.0,3.0}}, }, "faz": 2.0, })`, "source": unmarshaler, "target": target, "targetType": codegen.GoTypeRef(o, nil, 1), } err := tmpl.Execute(tmpFile, data) Ω(err).ShouldNot(HaveOccurred()) }) It("compiles", func() { Ω(string(out)).Should(BeEmpty()) bin := "codegen" if runtime.GOOS == "windows" { bin += ".exe" } cmd := exec.Command(filepath.FromSlash(fmt.Sprintf("./%s", bin))) cmd.Env = []string{fmt.Sprintf("PATH=%s", filepath.Join(gopath, "bin"))} cmd.Dir = srcDir code, err := cmd.CombinedOutput()
func (g *Generator) generateActionClient(action *design.ActionDefinition, file *codegen.SourceFile, funcs template.FuncMap) error { var ( params []string names []string queryParams []*paramData headers []*paramData signer string clientsTmpl = template.Must(template.New("clients").Funcs(funcs).Parse(clientsTmpl)) requestsTmpl = template.Must(template.New("requests").Funcs(funcs).Parse(requestsTmpl)) clientsWSTmpl = template.Must(template.New("clientsws").Funcs(funcs).Parse(clientsWSTmpl)) ) if action.Payload != nil { params = append(params, "payload "+codegen.GoTypeRef(action.Payload, action.Payload.AllRequired(), 1, false)) names = append(names, "payload") } initParams := func(att *design.AttributeDefinition) []*paramData { if att == nil { return nil } obj := att.Type.ToObject() var pdata []*paramData var optData []*paramData for n, q := range obj { varName := codegen.Goify(n, false) param := ¶mData{ Name: n, VarName: varName, Attribute: q, } if q.Type.IsPrimitive() { param.MustToString = q.Type.Kind() != design.StringKind if att.IsRequired(n) { param.ValueName = varName pdata = append(pdata, param) } else { param.ValueName = "*" + varName param.CheckNil = true optData = append(optData, param) } } else { if q.Type.IsArray() { param.IsArray = true param.ElemAttribute = q.Type.ToArray().ElemType } param.MustToString = true param.ValueName = varName param.CheckNil = true if att.IsRequired(n) { pdata = append(pdata, param) } else { optData = append(optData, param) } } } sort.Sort(byParamName(pdata)) sort.Sort(byParamName(optData)) // Update closure for _, p := range pdata { names = append(names, p.VarName) params = append(params, p.VarName+" "+cmdFieldType(p.Attribute.Type, false)) } for _, p := range optData { names = append(names, p.VarName) params = append(params, p.VarName+" "+cmdFieldType(p.Attribute.Type, p.Attribute.Type.IsPrimitive())) } return append(pdata, optData...) } queryParams = initParams(action.QueryParams) headers = initParams(action.Headers) if action.Security != nil { signer = codegen.Goify(action.Security.Scheme.SchemeName, true) } data := struct { Name string ResourceName string Description string Routes []*design.RouteDefinition HasPayload bool Params string ParamNames string CanonicalScheme string Signer string QueryParams []*paramData Headers []*paramData }{ Name: action.Name, ResourceName: action.Parent.Name, Description: action.Description, Routes: action.Routes, HasPayload: action.Payload != nil, Params: strings.Join(params, ", "), ParamNames: strings.Join(names, ", "), CanonicalScheme: action.CanonicalScheme(), Signer: signer, QueryParams: queryParams, Headers: headers, } if action.WebSocket() { return clientsWSTmpl.Execute(file, data) } if err := clientsTmpl.Execute(file, data); err != nil { return err } return requestsTmpl.Execute(file, data) }