Java optimized (#376)

* optiimzed java gen

* optiimzed java gen

* fix
master
kingxt 4 years ago committed by GitHub
parent ee19fb736b
commit cf3a1020b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,8 @@
package javagen package javagen
import ( import (
"bufio"
"bytes"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -22,9 +24,43 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
{{.imports}} {{.imports}}
{{.componentType}} public class {{.className}} extends {{.superClassName}} {
{{.properties}}
{{if .HasProperty}}
public {{.className}}() {
}
public {{.className}}({{.params}}) {
{{.constructorSetter}}
}
{{end}}
{{.getSet}}
}
`
getSetTemplate = `
{{.indent}}{{.decorator}}
{{.indent}}public {{.returnType}} get{{.property}}() {
{{.indent}} return this.{{.tagValue}};
{{.indent}}}
{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) {
{{.indent}} this.{{.tagValue}} = {{.propertyValue}};
{{.indent}}}
` `
boolTemplate = `
{{.indent}}{{.decorator}}
{{.indent}}public {{.returnType}} is{{.property}}() {
{{.indent}} return this.{{.tagValue}};
{{.indent}}}
{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) {
{{.indent}} this.{{.tagValue}} = {{.propertyValue}};
{{.indent}}}
`
httpResponseData = "import com.xhb.core.response.HttpResponseData;" httpResponseData = "import com.xhb.core.response.HttpResponseData;"
httpData = "import com.xhb.core.packet.HttpData;" httpData = "import com.xhb.core.packet.HttpData;"
) )
@ -34,6 +70,7 @@ type componentsContext struct {
requestTypes []spec.Type requestTypes []spec.Type
responseTypes []spec.Type responseTypes []spec.Type
imports []string imports []string
members []spec.Member
} }
func genComponents(dir, packetName string, api *spec.ApiSpec) error { func genComponents(dir, packetName string, api *spec.ApiSpec) error {
@ -94,56 +131,86 @@ func (c *componentsContext) createComponent(dir, packetName string, ty spec.Type
} }
defer fp.Close() defer fp.Close()
tyString, err := c.buildType(defineStruct) propertiesString, err := c.buildProperties(defineStruct)
if err != nil { if err != nil {
return err return err
} }
t := template.Must(template.New("componentType").Parse(componentTemplate)) getSetString, err := c.buildGetterSetter(defineStruct)
return t.Execute(fp, map[string]string{ if err != nil {
"componentType": tyString, return err
"packet": packetName,
"imports": strings.Join(c.imports, "\n"),
})
}
func (c *componentsContext) buildType(ty spec.DefineStruct) (string, error) {
var builder strings.Builder
if err := c.writeType(&builder, ty); err != nil {
return "", apiutil.WrapErr(err, "Type "+ty.Name()+" generate error")
} }
return builder.String(), nil superClassName := "HttpData"
}
func (c *componentsContext) writeType(writer io.Writer, defineStruct spec.DefineStruct) error {
responseData := "HttpData"
for _, item := range c.responseTypes { for _, item := range c.responseTypes {
if item.Name() == defineStruct.Name() { if item.Name() == defineStruct.Name() {
responseData = "HttpResponseData" superClassName = "HttpResponseData"
if !stringx.Contains(c.imports, httpResponseData) { if !stringx.Contains(c.imports, httpResponseData) {
c.imports = append(c.imports, httpResponseData) c.imports = append(c.imports, httpResponseData)
} }
break break
} }
} }
if responseData == "HttpData" && !stringx.Contains(c.imports, httpData) { if superClassName == "HttpData" && !stringx.Contains(c.imports, httpData) {
c.imports = append(c.imports, httpData) c.imports = append(c.imports, httpData)
} }
fmt.Fprintf(writer, "public class %s extends %s {\n", util.Title(defineStruct.Name()), responseData) params, constructorSetter, err := c.buildConstructor()
if err != nil {
return err
}
buffer := new(bytes.Buffer)
t := template.Must(template.New("componentType").Parse(componentTemplate))
err = t.Execute(buffer, map[string]interface{}{
"properties": propertiesString,
"params": params,
"constructorSetter": constructorSetter,
"getSet": getSetString,
"packet": packetName,
"imports": strings.Join(c.imports, "\n"),
"className": util.Title(defineStruct.Name()),
"superClassName": superClassName,
"HasProperty": len(strings.TrimSpace(propertiesString)) > 0,
})
if err != nil {
return err
}
_, err = fp.WriteString(formatSource(buffer.String()))
return err
}
func (c *componentsContext) buildProperties(defineStruct spec.DefineStruct) (string, error) {
var builder strings.Builder
if err := c.writeType(&builder, defineStruct); err != nil {
return "", apiutil.WrapErr(err, "Type "+defineStruct.Name()+" generate error")
}
return builder.String(), nil
}
func (c *componentsContext) buildGetterSetter(defineStruct spec.DefineStruct) (string, error) {
var builder strings.Builder
if err := c.genGetSet(&builder, defineStruct, 1); err != nil {
return "", apiutil.WrapErr(err, "Type "+defineStruct.Name()+" get or set generate error")
}
return builder.String(), nil
}
func (c *componentsContext) writeType(writer io.Writer, defineStruct spec.DefineStruct) error {
c.members = make([]spec.Member, 0)
err := c.writeMembers(writer, defineStruct, 1) err := c.writeMembers(writer, defineStruct, 1)
if err != nil { if err != nil {
return err return err
} }
genGetSet(writer, defineStruct, 1)
fmt.Fprintf(writer, "}")
return nil return nil
} }
func (c *componentsContext) writeMembers(writer io.Writer, ty spec.DefineStruct, indent int) error { func (c *componentsContext) writeMembers(writer io.Writer, defineStruct spec.DefineStruct, indent int) error {
for _, member := range ty.Members { for _, member := range defineStruct.Members {
if member.IsInline { if member.IsInline {
defineStruct, ok := member.Type.(spec.DefineStruct) defineStruct, ok := member.Type.(spec.DefineStruct)
if ok { if ok {
@ -160,7 +227,113 @@ func (c *componentsContext) writeMembers(writer io.Writer, ty spec.DefineStruct,
if err := writeProperty(writer, member, indent); err != nil { if err := writeProperty(writer, member, indent); err != nil {
return err return err
} }
c.members = append(c.members, member)
} }
} }
return nil return nil
} }
func (c *componentsContext) buildConstructor() (string, string, error) {
var params strings.Builder
var constructorSetter strings.Builder
for index, member := range c.members {
tp, err := specTypeToJava(member.Type)
if err != nil {
return "", "", err
}
params.WriteString(fmt.Sprintf("%s %s", tp, util.Untitle(member.Name)))
pn, err := member.GetPropertyName()
if err != nil {
return "", "", err
}
if index != len(c.members)-1 {
params.WriteString(", ")
}
writeIndent(&constructorSetter, 2)
constructorSetter.WriteString(fmt.Sprintf("this.%s = %s;", pn, util.Untitle(member.Name)))
if index != len(c.members)-1 {
constructorSetter.WriteString(util.NL)
}
}
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()...)
for _, member := range members {
javaType, err := specTypeToJava(member.Type)
if err != nil {
return nil
}
var property = util.Title(member.Name)
var templateStr = getSetTemplate
if javaType == "boolean" {
templateStr = boolTemplate
property = strings.TrimPrefix(property, "Is")
property = strings.TrimPrefix(property, "is")
}
t := template.Must(template.New(templateStr).Parse(getSetTemplate))
var tmplBytes bytes.Buffer
tyString := javaType
decorator := ""
javaPrimitiveType := []string{"int", "long", "boolean", "float", "double", "short"}
if !stringx.Contains(javaPrimitiveType, javaType) {
if member.IsOptional() || member.IsOmitEmpty() {
decorator = "@Nullable "
} else {
decorator = "@NotNull "
}
tyString = decorator + tyString
}
tagName, err := member.GetPropertyName()
if err != nil {
return err
}
err = t.Execute(&tmplBytes, map[string]string{
"property": property,
"propertyValue": util.Untitle(member.Name),
"tagValue": tagName,
"type": tyString,
"decorator": decorator,
"returnType": javaType,
"indent": indentString(indent),
})
if err != nil {
return err
}
r := tmplBytes.String()
r = strings.Replace(r, " boolean get", " boolean is", 1)
writer.Write([]byte(r))
}
return nil
}
func formatSource(source string) string {
var builder strings.Builder
scanner := bufio.NewScanner(strings.NewReader(source))
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)
}
return builder.String()
}

@ -1,43 +1,18 @@
package javagen package javagen
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"strings" "strings"
"text/template"
"github.com/tal-tech/go-zero/core/stringx"
"github.com/tal-tech/go-zero/tools/goctl/api/spec" "github.com/tal-tech/go-zero/tools/goctl/api/spec"
"github.com/tal-tech/go-zero/tools/goctl/util" "github.com/tal-tech/go-zero/tools/goctl/util"
) )
const getSetTemplate = `
{{.indent}}{{.decorator}}
{{.indent}}public {{.returnType}} get{{.property}}() {
{{.indent}} return this.{{.tagValue}};
{{.indent}}}
{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) {
{{.indent}} this.{{.tagValue}} = {{.propertyValue}};
{{.indent}}}
`
const boolTemplate = `
{{.indent}}{{.decorator}}
{{.indent}}public {{.returnType}} is{{.property}}() {
{{.indent}} return this.{{.tagValue}};
{{.indent}}}
{{.indent}}public void set{{.property}}({{.type}} {{.propertyValue}}) {
{{.indent}} this.{{.tagValue}} = {{.propertyValue}};
{{.indent}}}
`
func writeProperty(writer io.Writer, member spec.Member, indent int) error { func writeProperty(writer io.Writer, member spec.Member, indent int) error {
writeIndent(writer, indent) writeIndent(writer, indent)
ty, err := goTypeToJava(member.Type) ty, err := specTypeToJava(member.Type)
ty = strings.Replace(ty, "*", "", 1) ty = strings.Replace(ty, "*", "", 1)
if err != nil { if err != nil {
return err return err
@ -53,13 +28,17 @@ func writeProperty(writer io.Writer, member spec.Member, indent int) error {
return err return err
} }
writeDefaultValue(writer, member) err = writeDefaultValue(writer, member)
if err != nil {
return err
}
fmt.Fprint(writer, ";\n") fmt.Fprint(writer, ";\n")
return err return err
} }
func writeDefaultValue(writer io.Writer, member spec.Member) error { func writeDefaultValue(writer io.Writer, member spec.Member) error {
javaType, err := goTypeToJava(member.Type) javaType, err := specTypeToJava(member.Type)
if err != nil { if err != nil {
return err return err
} }
@ -85,7 +64,7 @@ func indentString(indent int) string {
return result return result
} }
func goTypeToJava(tp spec.Type) (string, error) { func specTypeToJava(tp spec.Type) (string, error) {
switch v := tp.(type) { switch v := tp.(type) {
case spec.DefineStruct: case spec.DefineStruct:
return util.Title(tp.Name()), nil return util.Title(tp.Name()), nil
@ -96,7 +75,7 @@ func goTypeToJava(tp spec.Type) (string, error) {
} }
return r, nil return r, nil
case spec.MapType: case spec.MapType:
valueType, err := goTypeToJava(v.Value) valueType, err := specTypeToJava(v.Value)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -107,16 +86,29 @@ func goTypeToJava(tp spec.Type) (string, error) {
return "byte[]", nil return "byte[]", nil
} }
valueType, err := goTypeToJava(v.Value) valueType, err := specTypeToJava(v.Value)
if err != nil { if err != nil {
return "", err return "", err
} }
switch valueType {
case "int":
return "Integer[]", nil
case "long":
return "Long[]", nil
case "float":
return "Float[]", nil
case "double":
return "Double[]", nil
case "boolean":
return "Boolean[]", nil
}
return fmt.Sprintf("java.util.ArrayList<%s>", util.Title(valueType)), nil return fmt.Sprintf("java.util.ArrayList<%s>", util.Title(valueType)), nil
case spec.InterfaceType: case spec.InterfaceType:
return "Object", nil return "Object", nil
case spec.PointerType: case spec.PointerType:
return goTypeToJava(v.Type) return specTypeToJava(v.Type)
} }
return "", errors.New("unsupported primitive type " + tp.Name()) return "", errors.New("unsupported primitive type " + tp.Name())
@ -130,7 +122,9 @@ func primitiveType(tp string) (string, bool) {
return "long", true return "long", true
case "int", "int8", "int32", "uint", "uint8", "uint16", "uint32": case "int", "int8", "int32", "uint", "uint8", "uint16", "uint32":
return "int", true return "int", true
case "float", "float32", "float64": case "float", "float32":
return "float", true
case "float64":
return "double", true return "double", true
case "bool": case "bool":
return "boolean", true return "boolean", true
@ -138,59 +132,3 @@ func primitiveType(tp string) (string, bool) {
return "", false return "", false
} }
func genGetSet(writer io.Writer, defineStruct spec.DefineStruct, indent int) error {
var members = defineStruct.GetBodyMembers()
members = append(members, defineStruct.GetFormMembers()...)
for _, member := range members {
javaType, err := goTypeToJava(member.Type)
if err != nil {
return nil
}
var property = util.Title(member.Name)
var templateStr = getSetTemplate
if javaType == "boolean" {
templateStr = boolTemplate
property = strings.TrimPrefix(property, "Is")
property = strings.TrimPrefix(property, "is")
}
t := template.Must(template.New(templateStr).Parse(getSetTemplate))
var tmplBytes bytes.Buffer
tyString := javaType
decorator := ""
javaPrimitiveType := []string{"int", "long", "boolean", "float", "double", "short"}
if !stringx.Contains(javaPrimitiveType, javaType) {
if member.IsOptional() || member.IsOmitEmpty() {
decorator = "@Nullable "
} else {
decorator = "@NotNull "
}
tyString = decorator + tyString
}
tagName, err := member.GetPropertyName()
if err != nil {
return err
}
err = t.Execute(&tmplBytes, map[string]string{
"property": property,
"propertyValue": util.Untitle(member.Name),
"tagValue": tagName,
"type": tyString,
"decorator": decorator,
"returnType": javaType,
"indent": indentString(indent),
})
if err != nil {
return err
}
r := tmplBytes.String()
r = strings.Replace(r, " boolean get", " boolean is", 1)
writer.Write([]byte(r))
}
return nil
}

@ -1,7 +0,0 @@
package parser
import (
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
)
var emptyType spec.Type
Loading…
Cancel
Save