From 9cd20156617bb8c27ffcf3e21fe3a21881467745 Mon Sep 17 00:00:00 2001 From: kingxt Date: Wed, 13 Jan 2021 11:54:53 +0800 Subject: [PATCH] fix inner type generate error (#377) * fix point type bug * optimized * fix inner type error --- tools/goctl/api/javagen/gencomponents.go | 50 +++++++++++++----------- tools/goctl/api/javagen/genpacket.go | 37 ++++++++---------- tools/goctl/api/javagen/util.go | 4 ++ tools/goctl/api/parser/parser.go | 17 ++++++++ tools/goctl/api/spec/fn.go | 14 +++++-- tools/goctl/api/spec/spec.go | 6 +++ tools/goctl/api/tsgen/genpacket.go | 4 +- tools/goctl/api/tsgen/util.go | 14 ++++--- 8 files changed, 92 insertions(+), 54 deletions(-) diff --git a/tools/goctl/api/javagen/gencomponents.go b/tools/goctl/api/javagen/gencomponents.go index 25a52171..a619d0d8 100644 --- a/tools/goctl/api/javagen/gencomponents.go +++ b/tools/goctl/api/javagen/gencomponents.go @@ -122,15 +122,6 @@ func (c *componentsContext) createComponent(dir, packetName string, ty spec.Type return err } - fp, created, err := apiutil.MaybeCreateFile(dir, modelDir, modelFile) - if err != nil { - return err - } - if !created { - return nil - } - defer fp.Close() - propertiesString, err := c.buildProperties(defineStruct) if err != nil { return err @@ -160,6 +151,15 @@ func (c *componentsContext) createComponent(dir, packetName string, ty spec.Type return err } + fp, created, err := apiutil.MaybeCreateFile(dir, modelDir, modelFile) + if err != nil { + return err + } + if !created { + return nil + } + defer fp.Close() + buffer := new(bytes.Buffer) t := template.Must(template.New("componentType").Parse(componentTemplate)) err = t.Execute(buffer, map[string]interface{}{ @@ -192,7 +192,7 @@ func (c *componentsContext) buildProperties(defineStruct spec.DefineStruct) (str func (c *componentsContext) buildGetterSetter(defineStruct spec.DefineStruct) (string, error) { var builder strings.Builder - if err := c.genGetSet(&builder, defineStruct, 1); err != nil { + if err := c.genGetSet(&builder, 1); err != nil { return "", apiutil.WrapErr(err, "Type "+defineStruct.Name()+" get or set generate error") } @@ -209,18 +209,23 @@ func (c *componentsContext) writeType(writer io.Writer, defineStruct spec.Define return nil } -func (c *componentsContext) writeMembers(writer io.Writer, defineStruct spec.DefineStruct, indent int) error { - for _, member := range defineStruct.Members { +func (c *componentsContext) writeMembers(writer io.Writer, tp spec.Type, indent int) error { + definedType, ok := tp.(spec.DefineStruct) + if !ok { + pointType, ok := tp.(spec.PointerType) + if ok { + return c.writeMembers(writer, pointType.Type, indent) + } + return errors.New(fmt.Sprintf("type %s not supported", tp.Name())) + } + + for _, member := range definedType.Members { if member.IsInline { - defineStruct, ok := member.Type.(spec.DefineStruct) - if ok { - err := c.writeMembers(writer, defineStruct, indent) - if err != nil { - return err - } - continue + err := c.writeMembers(writer, member.Type, indent) + if err != nil { + return err } - return errors.New("unsupported inline type %s" + member.Type.Name()) + continue } if member.IsBodyMember() || member.IsFormMember() { @@ -263,9 +268,8 @@ func (c *componentsContext) buildConstructor() (string, string, error) { return params.String(), constructorSetter.String(), nil } -func (c *componentsContext) genGetSet(writer io.Writer, defineStruct spec.DefineStruct, indent int) error { - var members = defineStruct.GetBodyMembers() - members = append(members, defineStruct.GetFormMembers()...) +func (c *componentsContext) genGetSet(writer io.Writer, indent int) error { + var members = c.members for _, member := range members { javaType, err := specTypeToJava(member.Type) if err != nil { diff --git a/tools/goctl/api/javagen/genpacket.go b/tools/goctl/api/javagen/genpacket.go index 07aed720..2f37d1f1 100644 --- a/tools/goctl/api/javagen/genpacket.go +++ b/tools/goctl/api/javagen/genpacket.go @@ -1,10 +1,8 @@ package javagen import ( - "bufio" "bytes" "fmt" - "os" "strings" "text/template" @@ -20,6 +18,7 @@ import com.xhb.core.packet.HttpPacket; import com.xhb.core.network.HttpRequestClient; {{.imports}} +{{.doc}} public class {{.packetName}} extends HttpPacket<{{.responseType}}> { {{.paramsDeclaration}} @@ -101,14 +100,28 @@ func createWith(dir string, api *spec.ApiSpec, route spec.Route, packetName stri "requestType": util.Title(route.RequestTypeName()), "HasRequestBody": hasRequestBody, "imports": imports, + "doc": doc(route), }) if err != nil { return err } - formatFile(&tmplBytes, fp) + + _, err = fp.WriteString(formatSource(tmplBytes.String())) return nil } +func doc(route spec.Route) string { + comment := route.JoinedDoc() + if len(comment) > 0 { + formatter := ` +/* + %s +*/` + return fmt.Sprintf(formatter, comment) + } + return "" +} + func getImports(api *spec.ApiSpec, packetName string) string { var builder strings.Builder allTypes := api.Types @@ -118,24 +131,6 @@ func getImports(api *spec.ApiSpec, packetName string) string { return builder.String() } -func formatFile(tmplBytes *bytes.Buffer, file *os.File) { - scanner := bufio.NewScanner(tmplBytes) - builder := bufio.NewWriter(file) - defer builder.Flush() - preIsBreakLine := false - for scanner.Scan() { - text := strings.TrimSpace(scanner.Text()) - if text == "" && preIsBreakLine { - continue - } - preIsBreakLine = text == "" - builder.WriteString(scanner.Text() + "\n") - } - if err := scanner.Err(); err != nil { - fmt.Println(err) - } -} - func paramsSet(route spec.Route) string { path := route.Path cops := strings.Split(path, "/") diff --git a/tools/goctl/api/javagen/util.go b/tools/goctl/api/javagen/util.go index 06d7742b..fd55a68a 100644 --- a/tools/goctl/api/javagen/util.go +++ b/tools/goctl/api/javagen/util.go @@ -11,6 +11,10 @@ import ( ) func writeProperty(writer io.Writer, member spec.Member, indent int) error { + if len(member.Comment) > 0 { + writeIndent(writer, indent) + fmt.Fprint(writer, member.Comment+util.NL) + } writeIndent(writer, indent) ty, err := specTypeToJava(member.Type) ty = strings.Replace(ty, "*", "", 1) diff --git a/tools/goctl/api/parser/parser.go b/tools/goctl/api/parser/parser.go index 96e92ddb..b42295db 100644 --- a/tools/goctl/api/parser/parser.go +++ b/tools/goctl/api/parser/parser.go @@ -104,9 +104,11 @@ func (p parser) fillTypes() error { } } + var types []spec.Type for _, item := range p.spec.Types { switch v := (item).(type) { case spec.DefineStruct: + var members []spec.Member for _, member := range v.Members { switch v := member.Type.(type) { case spec.DefineStruct: @@ -117,11 +119,16 @@ func (p parser) fillTypes() error { member.Type = *tp } } + members = append(members, member) } + v.Members = members + types = append(types, v) default: return errors.New(fmt.Sprintf("unknown type %+v", v)) } } + p.spec.Types = types + return nil } @@ -243,6 +250,16 @@ func (p parser) fillService() error { if astRoute.Route.Reply != nil { route.ResponseType = p.astTypeToSpec(astRoute.Route.Reply.Name) } + if astRoute.AtDoc != nil { + var properties = make(map[string]string, 0) + for _, kv := range astRoute.AtDoc.Kv { + properties[kv.Key.Text()] = kv.Value.Text() + } + route.AtDoc.Properties = properties + if astRoute.AtDoc.LineDoc != nil { + route.AtDoc.Text = astRoute.AtDoc.LineDoc.Text() + } + } err := p.fillRouteType(&route) if err != nil { diff --git a/tools/goctl/api/spec/fn.go b/tools/goctl/api/spec/fn.go index 7d044615..41c9ad79 100644 --- a/tools/goctl/api/spec/fn.go +++ b/tools/goctl/api/spec/fn.go @@ -8,8 +8,11 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/util" ) -const bodyTagKey = "json" -const formTagKey = "form" +const ( + bodyTagKey = "json" + formTagKey = "form" + defaultSummaryKey = "summary" +) var definedKeys = []string{bodyTagKey, formTagKey, "path"} @@ -155,7 +158,12 @@ func (t DefineStruct) GetNonBodyMembers() []Member { } func (r Route) JoinedDoc() string { - return strings.Join(r.Docs, " ") + doc := r.AtDoc.Text + if r.AtDoc.Properties != nil { + doc += r.AtDoc.Properties[defaultSummaryKey] + } + doc += strings.Join(r.Docs, " ") + return strings.TrimSpace(doc) } func (r Route) GetAnnotation(key string) string { diff --git a/tools/goctl/api/spec/spec.go b/tools/goctl/api/spec/spec.go index 72d4a0ec..3c93db0d 100644 --- a/tools/goctl/api/spec/spec.go +++ b/tools/goctl/api/spec/spec.go @@ -61,6 +61,7 @@ type ( ResponseType Type Docs Doc Handler string + AtDoc AtDoc } Service struct { @@ -109,4 +110,9 @@ type ( RawName string Type Type } + + AtDoc struct { + Properties map[string]string + Text string + } ) diff --git a/tools/goctl/api/tsgen/genpacket.go b/tools/goctl/api/tsgen/genpacket.go index 4d81bdfd..31830e2d 100644 --- a/tools/goctl/api/tsgen/genpacket.go +++ b/tools/goctl/api/tsgen/genpacket.go @@ -46,10 +46,11 @@ func genHandler(dir, webApi, caller string, api *spec.ApiSpec, unwrapApi bool) e if len(api.Types) != 0 { if len(imports) > 0 { - imports += "\n" + imports += util.NL } outputFile := apiutil.ComponentName(api) imports += fmt.Sprintf(`import * as components from "%s"`, "./"+outputFile) + imports += fmt.Sprintf(`%sexport * from "%s"`, util.NL, "./"+outputFile) } apis, err := genApi(api, caller) @@ -59,7 +60,6 @@ func genHandler(dir, webApi, caller string, api *spec.ApiSpec, unwrapApi bool) e t := template.Must(template.New("handlerTemplate").Parse(handlerTemplate)) return t.Execute(fp, map[string]string{ - "webApi": webApi, "imports": imports, "apis": strings.TrimSpace(apis), }) diff --git a/tools/goctl/api/tsgen/util.go b/tools/goctl/api/tsgen/util.go index 9f664151..799a8a1d 100644 --- a/tools/goctl/api/tsgen/util.go +++ b/tools/goctl/api/tsgen/util.go @@ -111,7 +111,7 @@ func primitiveType(tp string) (string, bool) { func writeType(writer io.Writer, tp spec.Type) error { fmt.Fprintf(writer, "export interface %s {\n", util.Title(tp.Name())) - if err := genMembers(writer, tp, false); err != nil { + if err := writeMembers(writer, tp, false); err != nil { return err } @@ -131,7 +131,7 @@ func genParamsTypesIfNeed(writer io.Writer, tp spec.Type) error { } fmt.Fprintf(writer, "\n") fmt.Fprintf(writer, "export interface %sParams {\n", util.Title(tp.Name())) - if err := genMembers(writer, tp, true); err != nil { + if err := writeMembers(writer, tp, true); err != nil { return err } @@ -139,10 +139,14 @@ func genParamsTypesIfNeed(writer io.Writer, tp spec.Type) error { return nil } -func genMembers(writer io.Writer, tp spec.Type, isParam bool) error { +func writeMembers(writer io.Writer, tp spec.Type, isParam bool) error { definedType, ok := tp.(spec.DefineStruct) if !ok { - return errors.New("no members of type " + tp.Name()) + pointType, ok := tp.(spec.PointerType) + if ok { + return writeMembers(writer, pointType.Type, isParam) + } + return errors.New(fmt.Sprintf("type %s not supported", tp.Name())) } members := definedType.GetBodyMembers() @@ -151,7 +155,7 @@ func genMembers(writer io.Writer, tp spec.Type, isParam bool) error { } for _, member := range members { if member.IsInline { - if err := genMembers(writer, member.Type, isParam); err != nil { + if err := writeMembers(writer, member.Type, isParam); err != nil { return err } continue