Ver Fonte

optimize: fix experimental api (#3604)

kesonan há 1 ano atrás
pai
commit
02c95108b9

+ 2 - 5
tools/goctl/api/parser/parser.go

@@ -178,12 +178,9 @@ func (p parser) fieldToMember(field *ast.TypeField) spec.Member {
 	tag := ""
 	if !field.IsAnonymous {
 		name = field.Name.Text()
-		if field.Tag == nil {
-			panic(fmt.Sprintf("error: line %d:%d field %s has no tag",
-				field.Name.Line(), field.Name.Column(), field.Name.Text()))
+		if field.Tag != nil {
+			tag = field.Tag.Text()
 		}
-
-		tag = field.Tag.Text()
 	}
 	return spec.Member{
 		Name:     name,

+ 20 - 1
tools/goctl/pkg/parser/api/parser/analyzer.go

@@ -2,6 +2,7 @@ package parser
 
 import (
 	"fmt"
+	"sort"
 	"strings"
 
 	"github.com/zeromicro/go-zero/tools/goctl/api/spec"
@@ -101,7 +102,25 @@ func (a *Analyzer) convert2Spec() error {
 		return err
 	}
 
-	return a.fillService()
+	if err := a.fillService(); err != nil {
+		return err
+	}
+	sort.SliceStable(a.spec.Types, func(i, j int) bool {
+		return a.spec.Types[i].Name() < a.spec.Types[j].Name()
+	})
+
+	groups := make([]spec.Group, 0, len(a.spec.Service.Groups))
+	for _, v := range a.spec.Service.Groups {
+		sort.SliceStable(v.Routes, func(i, j int) bool {
+			return v.Routes[i].Path < v.Routes[j].Path
+		})
+		groups = append(groups, v)
+	}
+	sort.SliceStable(groups, func(i, j int) bool {
+		return groups[i].Annotation.Properties["group"] < groups[j].Annotation.Properties["group"]
+	})
+	a.spec.Service.Groups = groups
+	return nil
 }
 
 func (a *Analyzer) convertAtDoc(atDoc ast.AtDocStmt) spec.AtDoc {

+ 27 - 5
tools/goctl/pkg/parser/api/parser/api.go

@@ -31,18 +31,40 @@ func convert2API(a *ast.AST, importManager map[string]placeholder.Type) (*API, e
 	one := a.Stmts[0]
 	syntax, ok := one.(*ast.SyntaxStmt)
 	if !ok {
-		return nil, ast.SyntaxError(one.Pos(), "expected syntax statement, got <%T>", one)
+		syntax = &ast.SyntaxStmt{
+			Syntax: ast.NewTokenNode(token.Token{
+				Type: token.IDENT,
+				Text: token.Syntax,
+			}),
+			Assign: ast.NewTokenNode(token.Token{
+				Type: token.ASSIGN,
+				Text: "=",
+			}),
+			Value: ast.NewTokenNode(token.Token{
+				Type: token.STRING,
+				Text: `"v1"`,
+			}),
+		}
 	}
-	api.Syntax = syntax
 
-	for i := 1; i < len(a.Stmts); i++ {
+	api.Syntax = syntax
+	var hasSyntax, hasInfo bool
+	for i := 0; i < len(a.Stmts); i++ {
 		one := a.Stmts[i]
 		switch val := one.(type) {
 		case *ast.SyntaxStmt:
-			return nil, ast.DuplicateStmtError(val.Pos(), "duplicate syntax statement")
+			if hasSyntax {
+				return nil, ast.DuplicateStmtError(val.Pos(), "duplicate syntax statement")
+			} else {
+				hasSyntax = true
+			}
 		case *ast.InfoStmt:
 			if api.info != nil {
-				return nil, ast.DuplicateStmtError(val.Pos(), "duplicate info statement")
+				if hasInfo {
+					return nil, ast.DuplicateStmtError(val.Pos(), "duplicate info statement")
+				}
+			} else {
+				hasInfo = true
 			}
 			api.info = val
 		case ast.ImportStmt:

+ 0 - 4
tools/goctl/pkg/parser/api/parser/testdata/invalid.api

@@ -1,7 +1,3 @@
-// test case: expected syntax statement
-info ()
-
------
 // test case: duplicate syntax statement
 syntax = "v1"
 syntax = "v1"