mirror of
https://github.com/zeromicro/go-zero.git
synced 2025-01-23 09:00:20 +08:00
(goctl): support nested struct (#4211)
This commit is contained in:
parent
4ec9cac82b
commit
a012a9138f
@ -1,6 +1,7 @@
|
|||||||
package dartgen
|
package dartgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
@ -8,8 +9,8 @@ import (
|
|||||||
"github.com/zeromicro/go-zero/tools/goctl/api/spec"
|
"github.com/zeromicro/go-zero/tools/goctl/api/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
const dataTemplate = `// --{{with .Info}}{{.Title}}{{end}}--
|
const dataTemplate = `// --{{with .APISpec.Info}}{{.Title}}{{end}}--
|
||||||
{{ range .Types}}
|
{{ range .APISpec.Types}}
|
||||||
class {{.Name}}{
|
class {{.Name}}{
|
||||||
{{range .Members}}
|
{{range .Members}}
|
||||||
/// {{.Comment}}
|
/// {{.Comment}}
|
||||||
@ -28,12 +29,16 @@ class {{.Name}}{
|
|||||||
'{{getPropertyFromMember .}}': {{if isDirectType .Type.Name}}{{lowCamelCase .Name}}{{else if isClassListType .Type.Name}}{{lowCamelCase .Name}}.map((i) => i.toJson()){{else}}{{lowCamelCase .Name}}.toJson(){{end}},{{end}}
|
'{{getPropertyFromMember .}}': {{if isDirectType .Type.Name}}{{lowCamelCase .Name}}{{else if isClassListType .Type.Name}}{{lowCamelCase .Name}}.map((i) => i.toJson()){{else}}{{lowCamelCase .Name}}.toJson(){{end}},{{end}}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{{ range $.InnerClassList}}
|
||||||
|
{{.}}
|
||||||
|
{{end}}
|
||||||
}
|
}
|
||||||
{{end}}
|
{{end}}
|
||||||
`
|
`
|
||||||
|
|
||||||
const dataTemplateV2 = `// --{{with .Info}}{{.Title}}{{end}}--
|
const dataTemplateV2 = `// --{{with .APISpec.Info}}{{.Title}}{{end}}--
|
||||||
{{ range .Types}}
|
{{ range .APISpec.Types}}
|
||||||
class {{.Name}} {
|
class {{.Name}} {
|
||||||
{{range .Members}}
|
{{range .Members}}
|
||||||
{{if .Comment}}{{.Comment}}{{end}}
|
{{if .Comment}}{{.Comment}}{{end}}
|
||||||
@ -73,9 +78,18 @@ class {{.Name}} {
|
|||||||
,{{end}}
|
,{{end}}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{{ range $.InnerClassList}}
|
||||||
|
{{.}}
|
||||||
|
{{end}}
|
||||||
}
|
}
|
||||||
{{end}}`
|
{{end}}`
|
||||||
|
|
||||||
|
type DartSpec struct {
|
||||||
|
APISpec *spec.ApiSpec
|
||||||
|
InnerClassList []string
|
||||||
|
}
|
||||||
|
|
||||||
func genData(dir string, api *spec.ApiSpec, isLegacy bool) error {
|
func genData(dir string, api *spec.ApiSpec, isLegacy bool) error {
|
||||||
err := os.MkdirAll(dir, 0o755)
|
err := os.MkdirAll(dir, 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,12 +118,12 @@ func genData(dir string, api *spec.ApiSpec, isLegacy bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = convertDataType(api)
|
err, dartSpec := convertDataType(api, isLegacy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.Execute(file, api)
|
return t.Execute(file, dartSpec)
|
||||||
}
|
}
|
||||||
|
|
||||||
func genTokens(dir string, isLeagcy bool) error {
|
func genTokens(dir string, isLeagcy bool) error {
|
||||||
@ -132,24 +146,61 @@ func genTokens(dir string, isLeagcy bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertDataType(api *spec.ApiSpec) error {
|
func convertDataType(api *spec.ApiSpec, isLegacy bool) (error, *DartSpec) {
|
||||||
|
var result DartSpec
|
||||||
types := api.Types
|
types := api.Types
|
||||||
if len(types) == 0 {
|
if len(types) == 0 {
|
||||||
return nil
|
return nil, &result
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ty := range types {
|
for _, ty := range types {
|
||||||
defineStruct, ok := ty.(spec.DefineStruct)
|
defineStruct, ok := ty.(spec.DefineStruct)
|
||||||
if ok {
|
if ok {
|
||||||
for index, member := range defineStruct.Members {
|
for index, member := range defineStruct.Members {
|
||||||
|
structMember, ok := member.Type.(spec.DefineStruct)
|
||||||
|
if ok && structMember.IsNestedStruct() {
|
||||||
|
defineStruct.Members[index].Type = spec.PrimitiveType{RawName: member.Name}
|
||||||
|
t := template.New("dataTemplate")
|
||||||
|
t = t.Funcs(funcMap)
|
||||||
|
tpl := dataTemplateV2
|
||||||
|
if isLegacy {
|
||||||
|
tpl = dataTemplate
|
||||||
|
}
|
||||||
|
t, err := t.Parse(tpl)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var innerClassSpec = &spec.ApiSpec{
|
||||||
|
Types: []spec.Type{
|
||||||
|
spec.DefineStruct{
|
||||||
|
RawName: member.Name,
|
||||||
|
Members: structMember.Members,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err, dartSpec := convertDataType(innerClassSpec, isLegacy)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
writer := bytes.NewBuffer(nil)
|
||||||
|
err = t.Execute(writer, dartSpec)
|
||||||
|
if err != nil {
|
||||||
|
return err, nil
|
||||||
|
}
|
||||||
|
result.InnerClassList = append(result.InnerClassList, writer.String())
|
||||||
|
} else {
|
||||||
tp, err := specTypeToDart(member.Type)
|
tp, err := specTypeToDart(member.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err, nil
|
||||||
}
|
}
|
||||||
defineStruct.Members[index].Type = buildSpecType(member.Type, tp)
|
defineStruct.Members[index].Type = buildSpecType(member.Type, tp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
result.APISpec = api
|
||||||
|
|
||||||
|
return nil, &result
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,8 @@ var (
|
|||||||
importTwiceApi string
|
importTwiceApi string
|
||||||
//go:embed testdata/another_import_api.api
|
//go:embed testdata/another_import_api.api
|
||||||
anotherImportApi string
|
anotherImportApi string
|
||||||
|
//go:embed testdata/example.api
|
||||||
|
exampleApi string
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParser(t *testing.T) {
|
func TestParser(t *testing.T) {
|
||||||
@ -316,15 +318,32 @@ func TestCamelStyle(t *testing.T) {
|
|||||||
validateWithCamel(t, filename, "GoZero")
|
validateWithCamel(t, filename, "GoZero")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExampleGen(t *testing.T) {
|
||||||
|
env.Set(t, env.GoctlExperimental, env.ExperimentalOn)
|
||||||
|
filename := "greet.api"
|
||||||
|
err := os.WriteFile(filename, []byte(exampleApi), os.ModePerm)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
_ = os.Remove(filename)
|
||||||
|
})
|
||||||
|
|
||||||
|
spec, err := parser.Parse(filename)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, len(spec.Types), 10)
|
||||||
|
|
||||||
|
validate(t, filename)
|
||||||
|
}
|
||||||
|
|
||||||
func validate(t *testing.T, api string) {
|
func validate(t *testing.T, api string) {
|
||||||
validateWithCamel(t, api, "gozero")
|
validateWithCamel(t, api, "gozero")
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateWithCamel(t *testing.T, api, camel string) {
|
func validateWithCamel(t *testing.T, api, camel string) {
|
||||||
dir := "workspace"
|
dir := "workspace"
|
||||||
defer func() {
|
t.Cleanup(func() {
|
||||||
os.RemoveAll(dir)
|
_ = os.RemoveAll(dir)
|
||||||
}()
|
})
|
||||||
|
|
||||||
err := pathx.MkdirIfNotExist(dir)
|
err := pathx.MkdirIfNotExist(dir)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
err = initMod(dir)
|
err = initMod(dir)
|
||||||
|
@ -74,8 +74,21 @@ func writeType(writer io.Writer, tp spec.Type) error {
|
|||||||
return fmt.Errorf("unspport struct type: %s", tp.Name())
|
return fmt.Errorf("unspport struct type: %s", tp.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(writer, "type %s struct {\n", util.Title(tp.Name()))
|
_, err := fmt.Fprintf(writer, "type %s struct {\n", util.Title(tp.Name()))
|
||||||
for _, member := range structType.Members {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeMember(writer, structType.Members); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprintf(writer, "}")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeMember(writer io.Writer, members []spec.Member) error {
|
||||||
|
for _, member := range members {
|
||||||
if member.IsInline {
|
if member.IsInline {
|
||||||
if _, err := fmt.Fprintf(writer, "%s\n", strings.Title(member.Type.Name())); err != nil {
|
if _, err := fmt.Fprintf(writer, "%s\n", strings.Title(member.Type.Name())); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -88,6 +101,5 @@ func writeType(writer io.Writer, tp spec.Type) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(writer, "}")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
99
tools/goctl/api/gogen/testdata/example.api
vendored
Normal file
99
tools/goctl/api/gogen/testdata/example.api
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
info(
|
||||||
|
title: "demo title"
|
||||||
|
desc: "demo desc"
|
||||||
|
author: "keson.an"
|
||||||
|
date: "2024-06-25"
|
||||||
|
version: "v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// empty structure
|
||||||
|
type Foo {
|
||||||
|
}
|
||||||
|
|
||||||
|
// type lit
|
||||||
|
type Bar {
|
||||||
|
Foo int `json:"foo"`
|
||||||
|
Bar bool `json:"bar"`
|
||||||
|
Baz []string `json:"baz"`
|
||||||
|
Qux map[string]string `json:"qux"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Baz {
|
||||||
|
Foo `json:"foo"`
|
||||||
|
// array type
|
||||||
|
Arr [2]int `json:"arr"`
|
||||||
|
// nested type
|
||||||
|
Bar {
|
||||||
|
Foo string `json:"foo"`
|
||||||
|
Bar bool `json:"bar"`
|
||||||
|
Baz {
|
||||||
|
Foo string `json:"foo"`
|
||||||
|
Bar bool `json:"bar"`
|
||||||
|
}
|
||||||
|
Qux {
|
||||||
|
Foo string `json:"foo"`
|
||||||
|
Bar bool `json:"bar"`
|
||||||
|
} `json:"qux"`
|
||||||
|
} `json:"bar"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type UpdateReq {
|
||||||
|
Arg1 string `json:"arg1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListItem {
|
||||||
|
Value1 string `json:"value1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginReq {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginResp {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FormExampleReq {
|
||||||
|
Name string `form:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PathExampleReq {
|
||||||
|
ID string `path:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PathExampleResp {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
@server(
|
||||||
|
jwt: Auth
|
||||||
|
prefix: /v1
|
||||||
|
group: g1
|
||||||
|
timeout: 3s
|
||||||
|
middleware: AuthInterceptor
|
||||||
|
maxBytes: 1048576
|
||||||
|
)
|
||||||
|
service Foo {
|
||||||
|
@handler ping
|
||||||
|
get /ping
|
||||||
|
|
||||||
|
@handler update
|
||||||
|
post /update (UpdateReq)
|
||||||
|
|
||||||
|
@handler list
|
||||||
|
get /list returns ([]ListItem)
|
||||||
|
|
||||||
|
@handler login
|
||||||
|
post /login (LoginReq) returns (LoginResp)
|
||||||
|
|
||||||
|
@handler formExample
|
||||||
|
post /form/example (FormExampleReq)
|
||||||
|
|
||||||
|
@handler pathExample
|
||||||
|
get /path/example/:id (PathExampleReq) returns (PathExampleResp)
|
||||||
|
}
|
||||||
|
|
@ -59,18 +59,61 @@ func genFile(c fileGenConfig) error {
|
|||||||
|
|
||||||
func writeProperty(writer io.Writer, name, tag, comment string, tp spec.Type, indent int) error {
|
func writeProperty(writer io.Writer, name, tag, comment string, tp spec.Type, indent int) error {
|
||||||
util.WriteIndent(writer, indent)
|
util.WriteIndent(writer, indent)
|
||||||
var err error
|
var (
|
||||||
|
err error
|
||||||
|
isNestedStruct bool
|
||||||
|
)
|
||||||
|
structType, ok := tp.(spec.DefineStruct)
|
||||||
|
if ok && structType.IsNestedStruct() {
|
||||||
|
isNestedStruct = true
|
||||||
|
}
|
||||||
if len(comment) > 0 {
|
if len(comment) > 0 {
|
||||||
comment = strings.TrimPrefix(comment, "//")
|
comment = strings.TrimPrefix(comment, "//")
|
||||||
comment = "//" + comment
|
comment = "//" + comment
|
||||||
_, err = fmt.Fprintf(writer, "%s %s %s %s\n", strings.Title(name), tp.Name(), tag, comment)
|
|
||||||
} else {
|
|
||||||
_, err = fmt.Fprintf(writer, "%s %s %s\n", strings.Title(name), tp.Name(), tag)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isNestedStruct {
|
||||||
|
_, err = fmt.Fprintf(writer, "%s struct {\n", strings.Title(name))
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := writeMember(writer, structType.Members); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := fmt.Fprintf(writer, "} %s", tag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(comment) > 0 {
|
||||||
|
_, err = fmt.Fprintf(writer, " %s", comment)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprint(writer, "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(comment) > 0 {
|
||||||
|
_, err = fmt.Fprintf(writer, "%s %s %s %s\n", strings.Title(name), tp.Name(), tag, comment)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, err = fmt.Fprintf(writer, "%s %s %s\n", strings.Title(name), tp.Name(), tag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func getAuths(api *spec.ApiSpec) []string {
|
func getAuths(api *spec.ApiSpec) []string {
|
||||||
authNames := collection.NewSet()
|
authNames := collection.NewSet()
|
||||||
for _, g := range api.Service.Groups {
|
for _, g := range api.Service.Groups {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import "github.com/zeromicro/go-zero/tools/goctl/api/parser/g4/gen/api"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/api/parser/g4/gen/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ImportExpr defines import syntax for api
|
// ImportExpr defines import syntax for api
|
||||||
type ImportExpr struct {
|
type ImportExpr struct {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import "github.com/zeromicro/go-zero/tools/goctl/api/parser/g4/gen/api"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/api/parser/g4/gen/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InfoExpr defines info syntax for api
|
// InfoExpr defines info syntax for api
|
||||||
type InfoExpr struct {
|
type InfoExpr struct {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import "github.com/zeromicro/go-zero/tools/goctl/api/parser/g4/gen/api"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/api/parser/g4/gen/api"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SyntaxExpr describes syntax for api
|
// SyntaxExpr describes syntax for api
|
||||||
type SyntaxExpr struct {
|
type SyntaxExpr struct {
|
||||||
|
@ -30,6 +30,11 @@ func (t DefineStruct) Documents() []string {
|
|||||||
return t.Docs
|
return t.Docs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsNestedStruct returns whether the structure is nested.
|
||||||
|
func (t DefineStruct) IsNestedStruct() bool {
|
||||||
|
return len(t.Members) > 0
|
||||||
|
}
|
||||||
|
|
||||||
// Name returns a map string, such as map[string]int
|
// Name returns a map string, such as map[string]int
|
||||||
func (t MapType) Name() string {
|
func (t MapType) Name() string {
|
||||||
return t.RawName
|
return t.RawName
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package tsgen
|
package tsgen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -19,7 +20,7 @@ const (
|
|||||||
|
|
||||||
func writeProperty(writer io.Writer, member spec.Member, indent int) error {
|
func writeProperty(writer io.Writer, member spec.Member, indent int) error {
|
||||||
writeIndent(writer, indent)
|
writeIndent(writer, indent)
|
||||||
ty, err := genTsType(member)
|
ty, err := genTsType(member, indent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -40,7 +41,7 @@ func writeProperty(writer io.Writer, member spec.Member, indent int) error {
|
|||||||
}
|
}
|
||||||
if len(member.Docs) > 0 {
|
if len(member.Docs) > 0 {
|
||||||
fmt.Fprintf(writer, "%s\n", strings.Join(member.Docs, ""))
|
fmt.Fprintf(writer, "%s\n", strings.Join(member.Docs, ""))
|
||||||
writeIndent(writer, 1)
|
writeIndent(writer, indent)
|
||||||
}
|
}
|
||||||
_, err = fmt.Fprintf(writer, "%s%s: %s%s\n", name, optionalTag, ty, comment)
|
_, err = fmt.Fprintf(writer, "%s%s: %s%s\n", name, optionalTag, ty, comment)
|
||||||
return err
|
return err
|
||||||
@ -52,7 +53,27 @@ func writeIndent(writer io.Writer, indent int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genTsType(m spec.Member) (ty string, err error) {
|
func genTsType(m spec.Member, indent int) (ty string, err error) {
|
||||||
|
v, ok := m.Type.(spec.DefineStruct)
|
||||||
|
if ok && v.IsNestedStruct() {
|
||||||
|
writer := bytes.NewBuffer(nil)
|
||||||
|
_, err := fmt.Fprintf(writer, "{\n")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeMembers(writer, v, false, indent+1); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
writeIndent(writer, indent)
|
||||||
|
_, err = fmt.Fprintf(writer, "}")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return writer.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
ty, err = goTypeToTs(m.Type, false)
|
ty, err = goTypeToTs(m.Type, false)
|
||||||
if enums := m.GetEnumOptions(); enums != nil {
|
if enums := m.GetEnumOptions(); enums != nil {
|
||||||
if ty == "string" {
|
if ty == "string" {
|
||||||
@ -130,7 +151,7 @@ func primitiveType(tp string) (string, bool) {
|
|||||||
|
|
||||||
func writeType(writer io.Writer, tp spec.Type) error {
|
func writeType(writer io.Writer, tp spec.Type) error {
|
||||||
fmt.Fprintf(writer, "export interface %s {\n", util.Title(tp.Name()))
|
fmt.Fprintf(writer, "export interface %s {\n", util.Title(tp.Name()))
|
||||||
if err := writeMembers(writer, tp, false); err != nil {
|
if err := writeMembers(writer, tp, false, 1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,12 +187,12 @@ func genParamsTypesIfNeed(writer io.Writer, tp spec.Type) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeMembers(writer io.Writer, tp spec.Type, isParam bool) error {
|
func writeMembers(writer io.Writer, tp spec.Type, isParam bool, indent int) error {
|
||||||
definedType, ok := tp.(spec.DefineStruct)
|
definedType, ok := tp.(spec.DefineStruct)
|
||||||
if !ok {
|
if !ok {
|
||||||
pointType, ok := tp.(spec.PointerType)
|
pointType, ok := tp.(spec.PointerType)
|
||||||
if ok {
|
if ok {
|
||||||
return writeMembers(writer, pointType.Type, isParam)
|
return writeMembers(writer, pointType.Type, isParam, indent)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("type %s not supported", tp.Name())
|
return fmt.Errorf("type %s not supported", tp.Name())
|
||||||
@ -183,13 +204,13 @@ func writeMembers(writer io.Writer, tp spec.Type, isParam bool) error {
|
|||||||
}
|
}
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
if member.IsInline {
|
if member.IsInline {
|
||||||
if err := writeMembers(writer, member.Type, isParam); err != nil {
|
if err := writeMembers(writer, member.Type, isParam, indent); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := writeProperty(writer, member, 1); err != nil {
|
if err := writeProperty(writer, member, indent); err != nil {
|
||||||
return apiutil.WrapErr(err, " type "+tp.Name())
|
return apiutil.WrapErr(err, " type "+tp.Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,14 @@ func TestGenTsType(t *testing.T) {
|
|||||||
Docs: nil,
|
Docs: nil,
|
||||||
IsInline: false,
|
IsInline: false,
|
||||||
}
|
}
|
||||||
ty, err := genTsType(member)
|
ty, err := genTsType(member, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
assert.Equal(t, `'foo' | 'bar' | 'options' | '123'`, ty)
|
assert.Equal(t, `'foo' | 'bar' | 'options' | '123'`, ty)
|
||||||
|
|
||||||
member.IsInline = true
|
member.IsInline = true
|
||||||
ty, err = genTsType(member)
|
ty, err = genTsType(member, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ func TestGenTsType(t *testing.T) {
|
|||||||
|
|
||||||
member.Type = spec.PrimitiveType{RawName: "int"}
|
member.Type = spec.PrimitiveType{RawName: "int"}
|
||||||
member.Tag = `json:"foo,options=1|3|4|123"`
|
member.Tag = `json:"foo,options=1|3|4|123"`
|
||||||
ty, err = genTsType(member)
|
ty, err = genTsType(member, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
@ -4,13 +4,12 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/core/service"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/config"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/config"
|
||||||
greetServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/server/greet"
|
greetServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/server/greet"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/svc"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/svc"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/conf"
|
|
||||||
"github.com/zeromicro/go-zero/core/service"
|
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/reflection"
|
"google.golang.org/grpc/reflection"
|
||||||
|
@ -3,10 +3,9 @@ package greetlogic
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/svc"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/internal/svc"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hello/pb/hello"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SayHelloLogic struct {
|
type SayHelloLogic struct {
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
@ -4,14 +4,13 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/core/service"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/config"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/config"
|
||||||
eventServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/server/event"
|
eventServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/server/event"
|
||||||
greetServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/server/greet"
|
greetServer "github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/server/greet"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/conf"
|
|
||||||
"github.com/zeromicro/go-zero/core/service"
|
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/reflection"
|
"google.golang.org/grpc/reflection"
|
||||||
|
@ -3,10 +3,9 @@ package eventlogic
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type AskQuestionLogic struct {
|
type AskQuestionLogic struct {
|
||||||
|
@ -3,10 +3,9 @@ package greetlogic
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SayHelloLogic struct {
|
type SayHelloLogic struct {
|
||||||
|
@ -3,10 +3,9 @@ package greetlogic
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/internal/svc"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
"github.com/zeromicro/go-zero/tools/goctl/example/rpc/hi/pb/hi"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SayHiLogic struct {
|
type SayHiLogic struct {
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// BuildVersion is the version of goctl.
|
// BuildVersion is the version of goctl.
|
||||||
const BuildVersion = "1.6.6"
|
const BuildVersion = "1.6.7-beta"
|
||||||
|
|
||||||
var tag = map[string]int{"pre-alpha": 0, "alpha": 1, "pre-bata": 2, "beta": 3, "released": 4, "": 5}
|
var tag = map[string]int{"pre-alpha": 0, "alpha": 1, "pre-bata": 2, "beta": 3, "released": 4, "": 5}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package builderx
|
package builderx
|
||||||
|
|
||||||
import (
|
import "github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: Use github.com/zeromicro/go-zero/core/stores/builder.RawFieldNames instead.
|
// Deprecated: Use github.com/zeromicro/go-zero/core/stores/builder.RawFieldNames instead.
|
||||||
func FieldNames(in any) []string {
|
func FieldNames(in any) []string {
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/collection"
|
"github.com/zeromicro/go-zero/core/collection"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/core/stores/postgres"
|
"github.com/zeromicro/go-zero/core/stores/postgres"
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/config"
|
"github.com/zeromicro/go-zero/tools/goctl/config"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/model/sql/gen"
|
"github.com/zeromicro/go-zero/tools/goctl/model/sql/gen"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
"github.com/zeromicro/go-zero/core/stringx"
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/model/sql/model"
|
"github.com/zeromicro/go-zero/tools/goctl/model/sql/model"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/model/sql/util"
|
"github.com/zeromicro/go-zero/tools/goctl/model/sql/util"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
||||||
|
@ -42,7 +42,18 @@ func (a *Analyzer) astTypeToSpec(in ast.DataType) (spec.Type, error) {
|
|||||||
case *ast.AnyDataType:
|
case *ast.AnyDataType:
|
||||||
return nil, ast.SyntaxError(v.Pos(), "unsupported any type")
|
return nil, ast.SyntaxError(v.Pos(), "unsupported any type")
|
||||||
case *ast.StructDataType:
|
case *ast.StructDataType:
|
||||||
// TODO(keson) feature: can be extended
|
var members []spec.Member
|
||||||
|
for _, item := range v.Elements {
|
||||||
|
m, err := a.fieldToMember(item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
members = append(members, m)
|
||||||
|
}
|
||||||
|
return spec.DefineStruct{
|
||||||
|
RawName: v.RawText(),
|
||||||
|
Members: members,
|
||||||
|
}, nil
|
||||||
case *ast.InterfaceDataType:
|
case *ast.InterfaceDataType:
|
||||||
return spec.InterfaceType{RawName: v.RawText()}, nil
|
return spec.InterfaceType{RawName: v.RawText()}, nil
|
||||||
case *ast.MapDataType:
|
case *ast.MapDataType:
|
||||||
@ -323,6 +334,7 @@ func (a *Analyzer) fillTypes() error {
|
|||||||
for _, member := range v.Members {
|
for _, member := range v.Members {
|
||||||
switch v := member.Type.(type) {
|
switch v := member.Type.(type) {
|
||||||
case spec.DefineStruct:
|
case spec.DefineStruct:
|
||||||
|
if !v.IsNestedStruct() {
|
||||||
tp, err := a.findDefinedType(v.RawName)
|
tp, err := a.findDefinedType(v.RawName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -330,6 +342,7 @@ func (a *Analyzer) fillTypes() error {
|
|||||||
|
|
||||||
member.Type = tp
|
member.Type = tp
|
||||||
}
|
}
|
||||||
|
}
|
||||||
members = append(members, member)
|
members = append(members, member)
|
||||||
}
|
}
|
||||||
v.Members = members
|
v.Members = members
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package generator
|
package generator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/util/format"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
conf "github.com/zeromicro/go-zero/tools/goctl/config"
|
conf "github.com/zeromicro/go-zero/tools/goctl/config"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/rpc/parser"
|
"github.com/zeromicro/go-zero/tools/goctl/rpc/parser"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/util/ctx"
|
"github.com/zeromicro/go-zero/tools/goctl/util/ctx"
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/util/format"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/util/stringx"
|
"github.com/zeromicro/go-zero/tools/goctl/util/stringx"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user