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:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user