Skip to content

Commit

Permalink
fix(goctl): multi imports the api cause redeclared error
Browse files Browse the repository at this point in the history
  • Loading branch information
wjiec committed Mar 12, 2024
1 parent 94fa125 commit 93ef7e4
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 10 deletions.
69 changes: 69 additions & 0 deletions tools/goctl/api/gogen/gen_test.go
Expand Up @@ -2,7 +2,12 @@ package gogen

import (
_ "embed"
"go/ast"
goformat "go/format"
"go/importer"
goparser "go/parser"
"go/token"
"go/types"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -48,6 +53,10 @@ var (
noStructTagApi string
//go:embed testdata/nest_type_api.api
nestTypeApi string
//go:embed testdata/import_twice.api
importTwiceApi string
//go:embed testdata/another_import_api.api
anotherImportApi string
)

func TestParser(t *testing.T) {
Expand Down Expand Up @@ -232,6 +241,46 @@ func TestHasImportApi(t *testing.T) {
validate(t, filename)
}

func TestImportTwiceOnExperimental(t *testing.T) {
defaultExperimental := env.Get(env.GoctlExperimental)
env.Set(t, env.GoctlExperimental, "on")
defer env.Set(t, env.GoctlExperimental, defaultExperimental)

filename := "greet.api"
err := os.WriteFile(filename, []byte(importTwiceApi), os.ModePerm)
assert.Nil(t, err)
defer os.Remove(filename)

importApiName := "importApi.api"
err = os.WriteFile(importApiName, []byte(importApi), os.ModePerm)
assert.Nil(t, err)
defer os.Remove(importApiName)

hasImportApiName := "hasImportApi.api"
err = os.WriteFile(hasImportApiName, []byte(hasImportApi), os.ModePerm)
assert.Nil(t, err)
defer os.Remove(hasImportApiName)

anotherImportApiName := "anotherImportApi.api"
err = os.WriteFile(anotherImportApiName, []byte(anotherImportApi), os.ModePerm)
assert.Nil(t, err)
defer os.Remove(anotherImportApiName)

api, err := parser.Parse(filename)
assert.Nil(t, err)

var hasInline bool
for _, ty := range api.Types {
if ty.Name() == "ImportData" {
hasInline = true
break
}
}
assert.True(t, hasInline)

validate(t, filename)
}

func TestNoStructApi(t *testing.T) {
filename := "greet.api"
err := os.WriteFile(filename, []byte(noStructTagApi), os.ModePerm)
Expand Down Expand Up @@ -287,6 +336,9 @@ func validateWithCamel(t *testing.T, api, camel string) {
code, err := os.ReadFile(path)
assert.Nil(t, err)
assert.Nil(t, validateCode(string(code)))
if strings.HasSuffix(path, "types.go") {
assert.Nil(t, checkRedeclaredType(string(code)))
}
}
return nil
})
Expand All @@ -301,3 +353,20 @@ func validateCode(code string) error {
_, err := goformat.Source([]byte(code))
return err
}

func checkRedeclaredType(code string) error {
fset := token.NewFileSet()
f, err := goparser.ParseFile(fset, "", code, goparser.ParseComments)
if err != nil {
return err
}

conf := types.Config{
Error: func(err error) {},
Importer: importer.Default(),
}

info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
_, err = conf.Check(f.Name.Name, fset, []*ast.File{f}, &info)
return err
}
17 changes: 17 additions & 0 deletions tools/goctl/api/gogen/testdata/another_import_api.api
@@ -0,0 +1,17 @@
import "importApi.api"

type AnotherRequest {
Name string `path:"name,options=you|me"`
}

type AnotherResponse {
Message string `json:"message"` // message
}

@server(
group: greet
)
service A-api {
@handler AnotherImportHandler
get /greet/from/another/:name(AnotherRequest) returns (AnotherResponse)
}
11 changes: 6 additions & 5 deletions tools/goctl/api/gogen/testdata/has_import_api.api
@@ -1,16 +1,17 @@
import "importApi.api"

type Request struct {
type Request {
Name string `path:"name,options=you|me"`
}

type Response struct {
type Response {
Message string `json:"message"` // message
}

@server(
group: greet
)
service A-api {
@server(
handler: GreetHandler
)
@handler GreetHandler
get /greet/from/:name(Request) returns (Response)
}
2 changes: 1 addition & 1 deletion tools/goctl/api/gogen/testdata/import_api.api
@@ -1,3 +1,3 @@
type ImportData struct {
type ImportData {
Name string `path:"name,options=you|me"`
}
2 changes: 2 additions & 0 deletions tools/goctl/api/gogen/testdata/import_twice.api
@@ -0,0 +1,2 @@
import "hasImportApi.api"
import "anotherImportApi.api"
5 changes: 1 addition & 4 deletions tools/goctl/pkg/parser/api/parser/api.go
Expand Up @@ -32,11 +32,8 @@ type API struct {
func convert2API(a *ast.AST, importSet map[string]lang.PlaceholderType, is *importstack.ImportStack) (*API, error) {
var api = new(API)
api.importManager = is
api.importSet = make(map[string]lang.PlaceholderType)
api.importSet = importSet
api.Filename = a.Filename
for k, v := range importSet {
api.importSet[k] = v
}
one := a.Stmts[0]
syntax, ok := one.(*ast.SyntaxStmt)
if !ok {
Expand Down

0 comments on commit 93ef7e4

Please sign in to comment.