fix inner type generate error (#377)

* fix point type bug

* optimized

* fix inner type error
This commit is contained in:
kingxt 2021-01-13 11:54:53 +08:00 committed by GitHub
parent cf3a1020b0
commit 9cd2015661
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 92 additions and 54 deletions

View File

@ -122,15 +122,6 @@ func (c *componentsContext) createComponent(dir, packetName string, ty spec.Type
return err 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) propertiesString, err := c.buildProperties(defineStruct)
if err != nil { if err != nil {
return err return err
@ -160,6 +151,15 @@ func (c *componentsContext) createComponent(dir, packetName string, ty spec.Type
return err 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) buffer := new(bytes.Buffer)
t := template.Must(template.New("componentType").Parse(componentTemplate)) t := template.Must(template.New("componentType").Parse(componentTemplate))
err = t.Execute(buffer, map[string]interface{}{ 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) { func (c *componentsContext) buildGetterSetter(defineStruct spec.DefineStruct) (string, error) {
var builder strings.Builder 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") 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 return nil
} }
func (c *componentsContext) writeMembers(writer io.Writer, defineStruct spec.DefineStruct, indent int) error { func (c *componentsContext) writeMembers(writer io.Writer, tp spec.Type, indent int) error {
for _, member := range defineStruct.Members { 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 { if member.IsInline {
defineStruct, ok := member.Type.(spec.DefineStruct) err := c.writeMembers(writer, member.Type, indent)
if ok { if err != nil {
err := c.writeMembers(writer, defineStruct, indent) return err
if err != nil {
return err
}
continue
} }
return errors.New("unsupported inline type %s" + member.Type.Name()) continue
} }
if member.IsBodyMember() || member.IsFormMember() { if member.IsBodyMember() || member.IsFormMember() {
@ -263,9 +268,8 @@ func (c *componentsContext) buildConstructor() (string, string, error) {
return params.String(), constructorSetter.String(), nil return params.String(), constructorSetter.String(), nil
} }
func (c *componentsContext) genGetSet(writer io.Writer, defineStruct spec.DefineStruct, indent int) error { func (c *componentsContext) genGetSet(writer io.Writer, indent int) error {
var members = defineStruct.GetBodyMembers() var members = c.members
members = append(members, defineStruct.GetFormMembers()...)
for _, member := range members { for _, member := range members {
javaType, err := specTypeToJava(member.Type) javaType, err := specTypeToJava(member.Type)
if err != nil { if err != nil {

View File

@ -1,10 +1,8 @@
package javagen package javagen
import ( import (
"bufio"
"bytes" "bytes"
"fmt" "fmt"
"os"
"strings" "strings"
"text/template" "text/template"
@ -20,6 +18,7 @@ import com.xhb.core.packet.HttpPacket;
import com.xhb.core.network.HttpRequestClient; import com.xhb.core.network.HttpRequestClient;
{{.imports}} {{.imports}}
{{.doc}}
public class {{.packetName}} extends HttpPacket<{{.responseType}}> { public class {{.packetName}} extends HttpPacket<{{.responseType}}> {
{{.paramsDeclaration}} {{.paramsDeclaration}}
@ -101,14 +100,28 @@ func createWith(dir string, api *spec.ApiSpec, route spec.Route, packetName stri
"requestType": util.Title(route.RequestTypeName()), "requestType": util.Title(route.RequestTypeName()),
"HasRequestBody": hasRequestBody, "HasRequestBody": hasRequestBody,
"imports": imports, "imports": imports,
"doc": doc(route),
}) })
if err != nil { if err != nil {
return err return err
} }
formatFile(&tmplBytes, fp)
_, err = fp.WriteString(formatSource(tmplBytes.String()))
return nil 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 { func getImports(api *spec.ApiSpec, packetName string) string {
var builder strings.Builder var builder strings.Builder
allTypes := api.Types allTypes := api.Types
@ -118,24 +131,6 @@ func getImports(api *spec.ApiSpec, packetName string) string {
return builder.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 { func paramsSet(route spec.Route) string {
path := route.Path path := route.Path
cops := strings.Split(path, "/") cops := strings.Split(path, "/")

View File

@ -11,6 +11,10 @@ import (
) )
func writeProperty(writer io.Writer, member spec.Member, indent int) error { 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) writeIndent(writer, indent)
ty, err := specTypeToJava(member.Type) ty, err := specTypeToJava(member.Type)
ty = strings.Replace(ty, "*", "", 1) ty = strings.Replace(ty, "*", "", 1)

View File

@ -104,9 +104,11 @@ func (p parser) fillTypes() error {
} }
} }
var types []spec.Type
for _, item := range p.spec.Types { for _, item := range p.spec.Types {
switch v := (item).(type) { switch v := (item).(type) {
case spec.DefineStruct: case spec.DefineStruct:
var members []spec.Member
for _, member := range v.Members { for _, member := range v.Members {
switch v := member.Type.(type) { switch v := member.Type.(type) {
case spec.DefineStruct: case spec.DefineStruct:
@ -117,11 +119,16 @@ func (p parser) fillTypes() error {
member.Type = *tp member.Type = *tp
} }
} }
members = append(members, member)
} }
v.Members = members
types = append(types, v)
default: default:
return errors.New(fmt.Sprintf("unknown type %+v", v)) return errors.New(fmt.Sprintf("unknown type %+v", v))
} }
} }
p.spec.Types = types
return nil return nil
} }
@ -243,6 +250,16 @@ func (p parser) fillService() error {
if astRoute.Route.Reply != nil { if astRoute.Route.Reply != nil {
route.ResponseType = p.astTypeToSpec(astRoute.Route.Reply.Name) 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) err := p.fillRouteType(&route)
if err != nil { if err != nil {

View File

@ -8,8 +8,11 @@ import (
"github.com/tal-tech/go-zero/tools/goctl/util" "github.com/tal-tech/go-zero/tools/goctl/util"
) )
const bodyTagKey = "json" const (
const formTagKey = "form" bodyTagKey = "json"
formTagKey = "form"
defaultSummaryKey = "summary"
)
var definedKeys = []string{bodyTagKey, formTagKey, "path"} var definedKeys = []string{bodyTagKey, formTagKey, "path"}
@ -155,7 +158,12 @@ func (t DefineStruct) GetNonBodyMembers() []Member {
} }
func (r Route) JoinedDoc() string { 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 { func (r Route) GetAnnotation(key string) string {

View File

@ -61,6 +61,7 @@ type (
ResponseType Type ResponseType Type
Docs Doc Docs Doc
Handler string Handler string
AtDoc AtDoc
} }
Service struct { Service struct {
@ -109,4 +110,9 @@ type (
RawName string RawName string
Type Type Type Type
} }
AtDoc struct {
Properties map[string]string
Text string
}
) )

View File

@ -46,10 +46,11 @@ func genHandler(dir, webApi, caller string, api *spec.ApiSpec, unwrapApi bool) e
if len(api.Types) != 0 { if len(api.Types) != 0 {
if len(imports) > 0 { if len(imports) > 0 {
imports += "\n" imports += util.NL
} }
outputFile := apiutil.ComponentName(api) outputFile := apiutil.ComponentName(api)
imports += fmt.Sprintf(`import * as components from "%s"`, "./"+outputFile) imports += fmt.Sprintf(`import * as components from "%s"`, "./"+outputFile)
imports += fmt.Sprintf(`%sexport * from "%s"`, util.NL, "./"+outputFile)
} }
apis, err := genApi(api, caller) 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)) t := template.Must(template.New("handlerTemplate").Parse(handlerTemplate))
return t.Execute(fp, map[string]string{ return t.Execute(fp, map[string]string{
"webApi": webApi,
"imports": imports, "imports": imports,
"apis": strings.TrimSpace(apis), "apis": strings.TrimSpace(apis),
}) })

View File

@ -111,7 +111,7 @@ func primitiveType(tp string) (string, bool) {
func writeType(writer io.Writer, tp spec.Type) error { func writeType(writer io.Writer, tp spec.Type) error {
fmt.Fprintf(writer, "export interface %s {\n", util.Title(tp.Name())) 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 return err
} }
@ -131,7 +131,7 @@ func genParamsTypesIfNeed(writer io.Writer, tp spec.Type) error {
} }
fmt.Fprintf(writer, "\n") fmt.Fprintf(writer, "\n")
fmt.Fprintf(writer, "export interface %sParams {\n", util.Title(tp.Name())) 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 return err
} }
@ -139,10 +139,14 @@ func genParamsTypesIfNeed(writer io.Writer, tp spec.Type) error {
return nil 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) definedType, ok := tp.(spec.DefineStruct)
if !ok { 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() members := definedType.GetBodyMembers()
@ -151,7 +155,7 @@ func genMembers(writer io.Writer, tp spec.Type, isParam bool) error {
} }
for _, member := range members { for _, member := range members {
if member.IsInline { if member.IsInline {
if err := genMembers(writer, member.Type, isParam); err != nil { if err := writeMembers(writer, member.Type, isParam); err != nil {
return err return err
} }
continue continue