type should not define nested (#212)

* nest type should not supported

* nest type should not supported

* nest type should not supported

* nest type should not supported

* new test

* new test
This commit is contained in:
kingxt
2020-11-17 18:08:55 +08:00
committed by GitHub
parent 9592639cb4
commit d6d8fc21d8
5 changed files with 88 additions and 29 deletions

View File

@@ -11,10 +11,18 @@ import (
"strings" "strings"
"github.com/tal-tech/go-zero/core/errorx" "github.com/tal-tech/go-zero/core/errorx"
"github.com/tal-tech/go-zero/tools/goctl/api/parser"
"github.com/tal-tech/go-zero/tools/goctl/api/util" "github.com/tal-tech/go-zero/tools/goctl/api/util"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
const (
leftParenthesis = "("
rightParenthesis = ")"
leftBrace = "{"
rightBrace = "}"
)
func GoFormatApi(c *cli.Context) error { func GoFormatApi(c *cli.Context) error {
useStdin := c.Bool("stdin") useStdin := c.Bool("stdin")
@@ -57,7 +65,10 @@ func ApiFormatByStdin() error {
return err return err
} }
result := apiFormat(string(data)) result, err := apiFormat(string(data))
if err != nil {
return err
}
_, err = fmt.Print(result) _, err = fmt.Print(result)
if err != nil { if err != nil {
@@ -72,28 +83,44 @@ func ApiFormatByPath(apiFilePath string) error {
return err return err
} }
result := apiFormat(string(data)) result, err := apiFormat(string(data))
if err != nil {
return err
}
if err := ioutil.WriteFile(apiFilePath, []byte(result), os.ModePerm); err != nil { if err := ioutil.WriteFile(apiFilePath, []byte(result), os.ModePerm); err != nil {
return err return err
} }
return nil return nil
} }
func apiFormat(data string) string { func apiFormat(data string) (string, error) {
_, err := parser.ParseApi(data)
if err != nil {
return "", err
}
var builder strings.Builder var builder strings.Builder
scanner := bufio.NewScanner(strings.NewReader(data)) s := bufio.NewScanner(strings.NewReader(data))
var tapCount = 0 var tapCount = 0
for scanner.Scan() { for s.Scan() {
line := strings.TrimSpace(scanner.Text()) line := strings.TrimSpace(s.Text())
noCommentLine := util.RemoveComment(line) noCommentLine := util.RemoveComment(line)
if noCommentLine == ")" || noCommentLine == "}" { if noCommentLine == rightParenthesis || noCommentLine == rightBrace {
tapCount -= 1 tapCount -= 1
} }
if tapCount < 0 {
line = strings.TrimSuffix(line, rightBrace)
line = strings.TrimSpace(line)
if strings.HasSuffix(line, leftBrace) {
tapCount += 1
}
}
util.WriteIndent(&builder, tapCount) util.WriteIndent(&builder, tapCount)
builder.WriteString(line + "\n") builder.WriteString(line + "\n")
if strings.HasSuffix(noCommentLine, "(") || strings.HasSuffix(noCommentLine, "{") { if strings.HasSuffix(noCommentLine, leftParenthesis) || strings.HasSuffix(noCommentLine, leftBrace) {
tapCount += 1 tapCount += 1
} }
} }
return strings.TrimSpace(builder.String()) return strings.TrimSpace(builder.String()), nil
} }

View File

@@ -41,6 +41,7 @@ service A-api {
) )
func TestInlineTypeNotExist(t *testing.T) { func TestInlineTypeNotExist(t *testing.T) {
r := apiFormat(notFormattedStr) r, err := apiFormat(notFormattedStr)
assert.Nil(t, err)
assert.Equal(t, r, formattedStr) assert.Equal(t, r, formattedStr)
} }

View File

@@ -288,13 +288,16 @@ type Request {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + ` Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
} }
type XXX { type XXX {}
}
type ( type (
Response { Response {
Message string ` + "`" + `json:"message"` + "`" + ` Message string ` + "`" + `json:"message"` + "`" + `
} }
A {}
B struct {}
) )
service A-api { service A-api {
@@ -303,6 +306,19 @@ service A-api {
} }
` `
const nestTypeApi = `
type Request {
Name string ` + "`" + `path:"name,options=you|me"` + "`" + `
XXX struct {
}
}
service A-api {
@handler GreetHandler
get /greet/from/:name(Request)
}
`
func TestParser(t *testing.T) { func TestParser(t *testing.T) {
filename := "greet.api" filename := "greet.api"
err := ioutil.WriteFile(filename, []byte(testApiTemplate), os.ModePerm) err := ioutil.WriteFile(filename, []byte(testApiTemplate), os.ModePerm)
@@ -532,11 +548,21 @@ func TestNoStructApi(t *testing.T) {
spec, err := parser.Parse() spec, err := parser.Parse()
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, len(spec.Types), 3) assert.Equal(t, len(spec.Types), 5)
validate(t, filename) validate(t, filename)
} }
func TestNestTypeApi(t *testing.T) {
filename := "greet.api"
err := ioutil.WriteFile(filename, []byte(nestTypeApi), os.ModePerm)
assert.Nil(t, err)
defer os.Remove(filename)
_, err = parser.NewParser(filename)
assert.NotNil(t, err)
}
func validate(t *testing.T, api string) { func validate(t *testing.T, api string) {
dir := "_go" dir := "_go"
os.RemoveAll(dir) os.RemoveAll(dir)

View File

@@ -154,6 +154,7 @@ func (s *apiImportState) process(api *ApiStruct, token string) (apiFileState, er
func (s *apiTypeState) process(api *ApiStruct, token string) (apiFileState, error) { func (s *apiTypeState) process(api *ApiStruct, token string) (apiFileState, error) {
var blockCount = 0 var blockCount = 0
var braceCount = 0
for { for {
line, err := s.readLine() line, err := s.readLine()
if err != nil { if err != nil {
@@ -161,7 +162,7 @@ func (s *apiTypeState) process(api *ApiStruct, token string) (apiFileState, erro
} }
line = token + line line = token + line
if blockCount <= 1 { if braceCount == 0 {
line = mayInsertStructKeyword(line) line = mayInsertStructKeyword(line)
} }
api.Type += newline + newline + line api.Type += newline + newline + line
@@ -171,17 +172,31 @@ func (s *apiTypeState) process(api *ApiStruct, token string) (apiFileState, erro
if strings.HasSuffix(line, leftBrace) { if strings.HasSuffix(line, leftBrace) {
blockCount++ blockCount++
braceCount++
} }
if strings.HasSuffix(line, string(leftParenthesis)) { if strings.HasSuffix(line, string(leftParenthesis)) {
blockCount++ blockCount++
} }
if strings.HasSuffix(line, string(rightBrace)) { if strings.HasSuffix(line, string(rightBrace)) {
blockCount-- blockCount--
braceCount--
} }
if strings.HasSuffix(line, string(rightParenthesis)) { if strings.HasSuffix(line, string(rightParenthesis)) {
blockCount-- blockCount--
} }
if braceCount >= 2 {
return nil, errors.New("nested type not supported: " + line)
}
if braceCount < 0 {
line = strings.TrimSuffix(line, string(rightBrace))
line = strings.TrimSpace(line)
if strings.HasSuffix(line, leftBrace) {
blockCount++
braceCount++
}
}
if blockCount == 0 { if blockCount == 0 {
return &apiRootState{s.baseState}, nil return &apiRootState{s.baseState}, nil
} }
@@ -223,12 +238,15 @@ func (s *apiServiceState) process(api *ApiStruct, token string) (apiFileState, e
func mayInsertStructKeyword(line string) string { func mayInsertStructKeyword(line string) string {
line = util.RemoveComment(line) line = util.RemoveComment(line)
if !strings.HasSuffix(line, leftBrace) { if !strings.HasSuffix(line, leftBrace) && !strings.HasSuffix(line, string(rightBrace)) {
return line return line
} }
fields := strings.Fields(line) fields := strings.Fields(line)
if stringx.Contains(fields, tokenStruct) || stringx.Contains(fields, tokenStruct+leftBrace) || len(fields) <= 1 { if stringx.Contains(fields, tokenStruct) ||
stringx.Contains(fields, tokenStruct+leftBrace) ||
stringx.Contains(fields, tokenStruct+leftBrace+string(rightBrace)) ||
len(fields) <= 1 {
return line return line
} }

View File

@@ -26,19 +26,6 @@ func MaybeCreateFile(dir, subdir, file string) (fp *os.File, created bool, err e
return return
} }
func ClearAndOpenFile(fpath string) (*os.File, error) {
f, err := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0600)
if err != nil {
return nil, err
}
_, err = f.WriteString("")
if err != nil {
return nil, err
}
return f, nil
}
func WrapErr(err error, message string) error { func WrapErr(err error, message string) error {
return errors.New(message + ", " + err.Error()) return errors.New(message + ", " + err.Error())
} }