Skip to content
This repository has been archived by the owner on Jun 27, 2023. It is now read-only.

fix parse array with the external const correctly #569

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions mockgen/internal/tests/const_array_length/input.go
@@ -1,10 +1,13 @@
package const_length

import "math"

//go:generate mockgen -package const_length -destination mock.go -source input.go

const C = 2

type I interface {
Foo() [C]int
Bar() [2]int
Baz() [math.MaxInt8]int
}
14 changes: 14 additions & 0 deletions mockgen/internal/tests/const_array_length/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion mockgen/parse.go
Expand Up @@ -22,8 +22,10 @@ import (
"fmt"
"go/ast"
"go/build"
"go/importer"
"go/parser"
"go/token"
"go/types"
"io/ioutil"
"log"
"path"
Expand Down Expand Up @@ -409,8 +411,16 @@ func (p *fileParser) parseType(pkg string, typ ast.Expr) (model.Type, error) {
case (*ast.BasicLit):
value = val.Value
case (*ast.Ident):
// when the length is a const
// when the length is a const defined locally
value = val.Obj.Decl.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value
case (*ast.SelectorExpr):
// when the length is a const defined in an external package
usedPkg, err := importer.Default().Import(fmt.Sprintf("%s", val.X))
codyoss marked this conversation as resolved.
Show resolved Hide resolved
ev, err := types.Eval(token.NewFileSet(), usedPkg, token.NoPos, val.Sel.String())
codyoss marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, p.errorf(v.Len.Pos(), "unknown constant in array length: %v", err)
}
value = ev.Value.String()
}

x, err := strconv.Atoi(value)
Expand Down
19 changes: 13 additions & 6 deletions mockgen/parse_test.go
Expand Up @@ -116,24 +116,31 @@ func Benchmark_parseFile(b *testing.B) {

func TestParseArrayWithConstLength(t *testing.T) {
fs := token.NewFileSet()
srcDir := "internal/tests/const_array_length/input.go"

file, err := parser.ParseFile(fs, "internal/tests/const_array_length/input.go", nil, 0)
file, err := parser.ParseFile(fs, srcDir, nil, 0)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

p := fileParser{
fileSet: fs,
fileSet: fs,
imports: make(map[string]importedPackage),
importedInterfaces: make(map[string]map[string]*ast.InterfaceType),
auxInterfaces: make(map[string]map[string]*ast.InterfaceType),
srcDir: srcDir,
}

pkg, err := p.parseFile("", file)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

expect := "[2]int"
got := pkg.Interfaces[0].Methods[0].Out[0].Type.String(nil, "")
if got != expect {
t.Fatalf("got %v; expected %v", got, expect)
expects := []string{"[2]int", "[2]int", "[127]int"}
for i, e := range expects {
got := pkg.Interfaces[0].Methods[i].Out[0].Type.String(nil, "")
if got != e {
t.Fatalf("got %v; expected %v", got, e)
}
}
}