Explorar o código

optimize route parse (#70)

* rebase upstream

* rebase

* trim no need line

* trim no need line

* trim no need line

* update doc

* remove update

* optimized route parser

Co-authored-by: kingxt <dream4kingxt@163.com>
kingxt %!s(int64=4) %!d(string=hai) anos
pai
achega
ee45b0a459
Modificáronse 2 ficheiros con 44 adicións e 21 borrados
  1. 41 21
      tools/goctl/api/parser/servicestate.go
  2. 3 0
      tools/goctl/api/parser/vars.go

+ 41 - 21
tools/goctl/api/parser/servicestate.go

@@ -1,7 +1,10 @@
 package parser
 
 import (
+	"bufio"
+	"bytes"
 	"fmt"
+	"io"
 	"strings"
 
 	"github.com/tal-tech/go-zero/tools/goctl/api/spec"
@@ -54,32 +57,49 @@ type serviceEntityParser struct {
 }
 
 func (p *serviceEntityParser) parseLine(line string, api *spec.ApiSpec, annos []spec.Annotation) error {
-	fields := strings.Fields(line)
-	if len(fields) < 2 {
-		return fmt.Errorf("wrong line %q", line)
-	}
+	line = strings.TrimSpace(line)
 
-	method := fields[0]
-	pathAndRequest := fields[1]
-	pos := strings.Index(pathAndRequest, "(")
-	if pos < 0 {
-		return fmt.Errorf("wrong line %q", line)
+	var buffer = new(bytes.Buffer)
+	buffer.WriteString(line)
+	reader := bufio.NewReader(buffer)
+	var builder strings.Builder
+	var fields []string
+	for {
+		ch, _, err := reader.ReadRune()
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return err
+		}
+
+		switch {
+		case isSpace(ch), ch == leftParenthesis, ch == rightParenthesis, ch == semicolon:
+			if builder.Len() == 0 {
+				continue
+			}
+			token := builder.String()
+			builder.Reset()
+			fields = append(fields, token)
+		default:
+			builder.WriteRune(ch)
+		}
 	}
-	path := strings.TrimSpace(pathAndRequest[:pos])
-	pathAndRequest = pathAndRequest[pos+1:]
-	pos = strings.Index(pathAndRequest, ")")
-	if pos < 0 {
-		return fmt.Errorf("wrong line %q", line)
+
+	if len(fields) < 3 {
+		return fmt.Errorf("wrong line %q, %q", line, routeSyntax)
 	}
-	req := pathAndRequest[:pos]
+
+	method := fields[0]
+	path := fields[1]
+	req := fields[2]
 	var returns string
-	if len(fields) > 2 {
-		returns = fields[2]
+	if len(fields) > 4 {
+		returns = fields[4]
+		if fields[3] != returnsTag {
+			return fmt.Errorf("wrong line %q, %q", line, routeSyntax)
+		}
 	}
-	returns = strings.ReplaceAll(returns, "returns", "")
-	returns = strings.ReplaceAll(returns, "(", "")
-	returns = strings.ReplaceAll(returns, ")", "")
-	returns = strings.TrimSpace(returns)
 
 	p.acceptRoute(spec.Route{
 		Annotations:  annos,

+ 3 - 0
tools/goctl/api/parser/vars.go

@@ -5,6 +5,8 @@ const (
 	serviceDirective  = "service"
 	typeDirective     = "type"
 	typeStruct        = "struct"
+	routeSyntax       = "route syntax: [get/post/delete] /path(request) returns[(response)]"
+	returnsTag        = "returns"
 	at                = '@'
 	colon             = ':'
 	leftParenthesis   = '('
@@ -13,4 +15,5 @@ const (
 	rightBrace        = '}'
 	multilineBeginTag = '>'
 	multilineEndTag   = '<'
+	semicolon         = ';'
 )