瀏覽代碼

Java (#327)

* add g4 file

* new define api by g4

* reactor parser to g4gen

* add syntax parser & test

* add syntax parser & test

* add syntax parser & test

* update g4 file

* add import parse & test

* ractor AT lexer

* panic with error

* revert AT

* update g4 file

* update g4 file

* update g4 file

* optimize parser

* update g4 file

* parse info

* optimized java generator

* revert

* optimize java generator

* update java generator

* update java generator

* update java generator

* update java generator

Co-authored-by: anqiansong <anqiansong@xiaoheiban.cn>
kingxt 4 年之前
父節點
當前提交
25cab2f273
共有 3 個文件被更改,包括 89 次插入31 次删除
  1. 52 11
      tools/goctl/api/javagen/gencomponents.go
  2. 24 14
      tools/goctl/api/javagen/genpacket.go
  3. 13 6
      tools/goctl/api/javagen/util.go

+ 52 - 11
tools/goctl/api/javagen/gencomponents.go

@@ -1,6 +1,7 @@
 package javagen
 
 import (
+	"errors"
 	"fmt"
 	"io"
 	"path"
@@ -17,6 +18,8 @@ const (
 package com.xhb.logic.http.packet.{{.packet}}.model;
 
 import com.xhb.logic.http.DeProguardable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 {{.componentType}}
 `
@@ -28,7 +31,7 @@ func genComponents(dir, packetName string, api *spec.ApiSpec) error {
 		return nil
 	}
 	for _, ty := range types {
-		if err := createComponent(dir, packetName, ty); err != nil {
+		if err := createComponent(dir, packetName, ty, api.Types); err != nil {
 			return err
 		}
 	}
@@ -36,7 +39,7 @@ func genComponents(dir, packetName string, api *spec.ApiSpec) error {
 	return nil
 }
 
-func createComponent(dir, packetName string, ty spec.Type) error {
+func createComponent(dir, packetName string, ty spec.Type, types []spec.Type) error {
 	modelFile := util.Title(ty.Name) + ".java"
 	filename := path.Join(dir, modelDir, modelFile)
 	if err := util.RemoveOrQuit(filename); err != nil {
@@ -52,7 +55,7 @@ func createComponent(dir, packetName string, ty spec.Type) error {
 	}
 	defer fp.Close()
 
-	tys, err := buildType(ty)
+	tys, err := buildType(ty, types)
 	if err != nil {
 		return err
 	}
@@ -64,22 +67,60 @@ func createComponent(dir, packetName string, ty spec.Type) error {
 	})
 }
 
-func buildType(ty spec.Type) (string, error) {
+func buildType(ty spec.Type, types []spec.Type) (string, error) {
 	var builder strings.Builder
-	if err := writeType(&builder, ty); err != nil {
+	if err := writeType(&builder, ty, types); err != nil {
 		return "", apiutil.WrapErr(err, "Type "+ty.Name+" generate error")
 	}
 	return builder.String(), nil
 }
 
-func writeType(writer io.Writer, tp spec.Type) error {
+func writeType(writer io.Writer, tp spec.Type, types []spec.Type) error {
 	fmt.Fprintf(writer, "public class %s implements DeProguardable {\n", util.Title(tp.Name))
-	for _, member := range tp.Members {
-		if err := writeProperty(writer, member, 1); err != nil {
-			return err
+	var members []spec.Member
+	err := writeMembers(writer, types, tp.Members, &members, 1)
+	if err != nil {
+		return err
+	}
+
+	genGetSet(writer, members, 1)
+	fmt.Fprintf(writer, "}")
+	return nil
+}
+
+func writeMembers(writer io.Writer, types []spec.Type, members []spec.Member, allMembers *[]spec.Member, indent int) error {
+	for _, member := range members {
+		if !member.IsBodyMember() {
+			continue
+		}
+
+		for _, item := range *allMembers {
+			if item.Name == member.Name {
+				continue
+			}
+		}
+
+		if member.IsInline {
+			hasInline := false
+			for _, ty := range types {
+				if strings.ToLower(ty.Name) == strings.ToLower(member.Name) {
+					err := writeMembers(writer, types, ty.Members, allMembers, indent)
+					if err != nil {
+						return err
+					}
+					hasInline = true
+					break
+				}
+			}
+			if !hasInline {
+				return errors.New("inline type " + member.Name + " not exist, please correct api file")
+			}
+		} else {
+			if err := writeProperty(writer, member, indent); err != nil {
+				return err
+			}
+			*allMembers = append(*allMembers, member)
 		}
 	}
-	genGetSet(writer, tp, 1)
-	fmt.Fprintf(writer, "}\n")
 	return nil
 }

+ 24 - 14
tools/goctl/api/javagen/genpacket.go

@@ -19,23 +19,27 @@ const packetTemplate = `package com.xhb.logic.http.packet.{{.packet}};
 
 import com.google.gson.Gson;
 import com.xhb.commons.JSON;
-import com.xhb.commons.JsonParser;
+import com.xhb.commons.JsonMarshal;
 import com.xhb.core.network.HttpRequestClient;
 import com.xhb.core.packet.HttpRequestPacket;
 import com.xhb.core.response.HttpResponseData;
 import com.xhb.logic.http.DeProguardable;
+{{if not .HasRequestBody}}
+import com.xhb.logic.http.request.EmptyRequest;
+{{end}}
 {{.import}}
 
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.json.JSONObject;
 
 public class {{.packetName}} extends HttpRequestPacket<{{.packetName}}.{{.packetName}}Response> {
 
 	{{.paramsDeclaration}}
 
-	public {{.packetName}}({{.params}}{{.requestType}} request) {
-        super(request);
-		this.request = request;{{.paramsSet}}
+	public {{.packetName}}({{.params}}{{if .HasRequestBody}}, {{.requestType}} request{{end}}) {
+		{{if .HasRequestBody}}super(request);{{else}}super(EmptyRequest.instance);{{end}}
+		{{if .HasRequestBody}}this.request = request;{{end}}{{.paramsSet}}
     }
 
 	@Override
@@ -113,7 +117,8 @@ func createWith(dir string, api *spec.ApiSpec, route spec.Route, packetName stri
 		} else {
 			fmt.Fprintln(&builder)
 		}
-		if err := genType(&builder, tp); err != nil {
+
+		if err := genType(&builder, tp, api.Types); err != nil {
 			return err
 		}
 	}
@@ -126,7 +131,7 @@ func createWith(dir string, api *spec.ApiSpec, route spec.Route, packetName stri
 
 	t := template.Must(template.New("packetTemplate").Parse(packetTemplate))
 	var tmplBytes bytes.Buffer
-	err = t.Execute(&tmplBytes, map[string]string{
+	err = t.Execute(&tmplBytes, map[string]interface{}{
 		"packetName":        packet,
 		"method":            strings.ToUpper(route.Method),
 		"uri":               processUri(route),
@@ -137,6 +142,7 @@ func createWith(dir string, api *spec.ApiSpec, route spec.Route, packetName stri
 		"paramsSet":         paramsSet,
 		"packet":            packetName,
 		"requestType":       util.Title(route.RequestType.Name),
+		"HasRequestBody":    len(route.RequestType.GetBodyMembers()) > 0,
 		"import":            getImports(api, route, packetName),
 	})
 	if err != nil {
@@ -209,7 +215,7 @@ func paramsForRoute(route spec.Route) string {
 			builder.WriteString(fmt.Sprintf("String %s, ", cop[1:]))
 		}
 	}
-	return builder.String()
+	return strings.TrimSuffix(builder.String(), ", ")
 }
 
 func declarationForRoute(route spec.Route) string {
@@ -260,18 +266,22 @@ func processUri(route spec.Route) string {
 	return result
 }
 
-func genType(writer io.Writer, tp spec.Type) error {
+func genType(writer io.Writer, tp spec.Type, types []spec.Type) error {
+	if len(tp.GetBodyMembers()) == 0 {
+		return nil
+	}
+
 	writeIndent(writer, 1)
 	fmt.Fprintf(writer, "static class %s implements DeProguardable {\n", util.Title(tp.Name))
-	for _, member := range tp.Members {
-		if err := writeProperty(writer, member, 2); err != nil {
-			return err
-		}
+	var members []spec.Member
+	err := writeMembers(writer, types, tp.Members, &members, 2)
+	if err != nil {
+		return err
 	}
 
-	writeBreakline(writer)
+	writeNewline(writer)
 	writeIndent(writer, 1)
-	genGetSet(writer, tp, 2)
+	genGetSet(writer, members, 2)
 	writeIndent(writer, 1)
 	fmt.Fprintln(writer, "}")
 

+ 13 - 6
tools/goctl/api/javagen/util.go

@@ -67,8 +67,8 @@ func indentString(indent int) string {
 	return result
 }
 
-func writeBreakline(writer io.Writer) {
-	fmt.Fprint(writer, "\n")
+func writeNewline(writer io.Writer) {
+	fmt.Fprint(writer, util.NL)
 }
 
 func isPrimitiveType(tp string) bool {
@@ -87,6 +87,7 @@ func goTypeToJava(tp string) (string, error) {
 	if len(tp) == 0 {
 		return "", errors.New("property type empty")
 	}
+
 	if strings.HasPrefix(tp, "*") {
 		tp = tp[1:]
 	}
@@ -107,39 +108,44 @@ func goTypeToJava(tp string) (string, error) {
 		if err != nil {
 			return "", err
 		}
+
 		if len(tys) == 0 {
 			return "", fmt.Errorf("%s tp parse error", tp)
 		}
+
 		return fmt.Sprintf("java.util.ArrayList<%s>", util.Title(tys[0])), nil
 	} else if strings.HasPrefix(tp, "map") {
 		tys, err := apiutil.DecomposeType(tp)
 		if err != nil {
 			return "", err
 		}
+
 		if len(tys) == 2 {
 			return "", fmt.Errorf("%s tp parse error", tp)
 		}
+
 		return fmt.Sprintf("java.util.HashMap<String, %s>", util.Title(tys[1])), nil
 	}
 	return util.Title(tp), nil
 }
 
-func genGetSet(writer io.Writer, tp spec.Type, indent int) error {
+func genGetSet(writer io.Writer, members []spec.Member, indent int) error {
 	t := template.Must(template.New("getSetTemplate").Parse(getSetTemplate))
-	for _, member := range tp.Members {
+	for _, member := range members {
 		var tmplBytes bytes.Buffer
 
 		oty, err := goTypeToJava(member.Type)
 		if err != nil {
 			return err
 		}
+
 		tyString := oty
 		decorator := ""
 		if !isPrimitiveType(member.Type) {
 			if member.IsOptional() {
-				decorator = "@org.jetbrains.annotations.Nullable "
+				decorator = "@Nullable "
 			} else {
-				decorator = "@org.jetbrains.annotations.NotNull "
+				decorator = "@NotNull "
 			}
 			tyString = decorator + tyString
 		}
@@ -155,6 +161,7 @@ func genGetSet(writer io.Writer, tp spec.Type, indent int) error {
 		if err != nil {
 			return err
 		}
+
 		r := tmplBytes.String()
 		r = strings.Replace(r, " boolean get", " boolean is", 1)
 		writer.Write([]byte(r))