(goctl): fix unresolved type if linked api imported (#3881)

master
kesonan 10 months ago committed by GitHub
parent f54c2e384f
commit 3331954a78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -403,6 +403,9 @@ func Parse(filename string, src interface{}) (*spec.ApiSpec, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := api.SelfCheck(); err != nil {
return nil, err
}
var result = new(spec.ApiSpec) var result = new(spec.ApiSpec)
analyzer := Analyzer{ analyzer := Analyzer{

@ -42,4 +42,8 @@ func Test_Parse(t *testing.T) {
_, err := Parse("./testdata/base.api", nil) _, err := Parse("./testdata/base.api", nil)
assertx.Error(t, err) assertx.Error(t, err)
}) })
t.Run("link_import", func(t *testing.T) {
_, err := Parse("./testdata/link_import.api", nil)
assert.Nil(t, err)
})
} }

@ -85,15 +85,12 @@ func convert2API(a *ast.AST, importSet map[string]lang.PlaceholderType, is *impo
} }
} }
if err := api.SelfCheck(); err != nil {
return nil, err
}
return api, nil return api, nil
} }
func (api *API) checkImportStmt() error { func (api *API) checkImportStmt() error {
f := newFilter() f := newFilter()
b := f.addCheckItem("import value expression") b := f.addCheckItem(api.Filename, "import value expression")
for _, v := range api.importStmt { for _, v := range api.importStmt {
switch val := v.(type) { switch val := v.(type) {
case *ast.ImportLiteralStmt: case *ast.ImportLiteralStmt:
@ -110,7 +107,7 @@ func (api *API) checkInfoStmt() error {
return nil return nil
} }
f := newFilter() f := newFilter()
b := f.addCheckItem("info key expression") b := f.addCheckItem(api.Filename, "info key expression")
for _, v := range api.info.Values { for _, v := range api.info.Values {
b.check(v.Key) b.check(v.Key)
} }
@ -119,9 +116,9 @@ func (api *API) checkInfoStmt() error {
func (api *API) checkServiceStmt() error { func (api *API) checkServiceStmt() error {
f := newFilter() f := newFilter()
serviceNameChecker := f.addCheckItem("service name expression") serviceNameChecker := f.addCheckItem(api.Filename, "service name expression")
handlerChecker := f.addCheckItem("handler expression") handlerChecker := f.addCheckItem(api.Filename, "handler expression")
pathChecker := f.addCheckItem("path expression") pathChecker := f.addCheckItem(api.Filename, "path expression")
var serviceName = map[string]string{} var serviceName = map[string]string{}
for _, v := range api.ServiceStmts { for _, v := range api.ServiceStmts {
name := strings.TrimSuffix(v.Name.Format(""), "-api") name := strings.TrimSuffix(v.Name.Format(""), "-api")
@ -150,7 +147,7 @@ func (api *API) checkServiceStmt() error {
func (api *API) checkTypeStmt() error { func (api *API) checkTypeStmt() error {
f := newFilter() f := newFilter()
b := f.addCheckItem("type expression") b := f.addCheckItem(api.Filename, "type expression")
for _, v := range api.TypeStmt { for _, v := range api.TypeStmt {
switch val := v.(type) { switch val := v.(type) {
case *ast.TypeLiteralStmt: case *ast.TypeLiteralStmt:

@ -8,6 +8,7 @@ import (
) )
type filterBuilder struct { type filterBuilder struct {
filename string
m map[string]placeholder.Type m map[string]placeholder.Type
checkExprName string checkExprName string
errorManager *errorManager errorManager *errorManager
@ -15,10 +16,11 @@ type filterBuilder struct {
func (b *filterBuilder) check(nodes ...*ast.TokenNode) { func (b *filterBuilder) check(nodes ...*ast.TokenNode) {
for _, node := range nodes { for _, node := range nodes {
if _, ok := b.m[node.Token.Text]; ok { fileNodeText := fmt.Sprintf("%s/%s", b.filename, node.Token.Text)
if _, ok := b.m[fileNodeText]; ok {
b.errorManager.add(ast.DuplicateStmtError(node.Pos(), "duplicate "+b.checkExprName)) b.errorManager.add(ast.DuplicateStmtError(node.Pos(), "duplicate "+b.checkExprName))
} else { } else {
b.m[node.Token.Text] = placeholder.PlaceHolder b.m[fileNodeText] = placeholder.PlaceHolder
} }
} }
} }
@ -46,8 +48,9 @@ func newFilter() *filter {
return &filter{} return &filter{}
} }
func (f *filter) addCheckItem(checkExprName string) *filterBuilder { func (f *filter) addCheckItem(filename, checkExprName string) *filterBuilder {
b := &filterBuilder{ b := &filterBuilder{
filename: filename,
m: make(map[string]placeholder.Type), m: make(map[string]placeholder.Type),
checkExprName: checkExprName, checkExprName: checkExprName,
errorManager: newErrorManager(), errorManager: newErrorManager(),

@ -0,0 +1,6 @@
syntax = "v1"
type Baz {
Foo string `json:"foo"`
Baz bool `json:"bar"`
}

@ -0,0 +1,10 @@
syntax = "v1"
import "request.api"
type Bar {
Foo int `json:"foo"`
Bar bool `json:"bar"`
Baz
Qux map[string]string `json:"qux"`
}

@ -0,0 +1,12 @@
syntax = "v1"
import "base/request.api"
import "base/response.api"
type Foo {}
service demo {
@handler handlerName
get /users/id/:userId (Baz) returns (Bar)
}
Loading…
Cancel
Save