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

Commit aba2ff9

Browse files
authored
fix parse array with the external const correctly (#569)
Fixes #561 - Panic on array parsing if length is externally defined It also fixes the following minor problems in TestParseArrayWithConstLength, a test function related to this feature. It doesn't check all outputs to be asserted. It doesn't initialize some of the fields in mockgen.fileParser, even though they are initialized in the production code. (Actually, it caused an unnecessary test error by test data I added)
1 parent bb196fc commit aba2ff9

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package const_length
22

3+
import "math"
4+
35
//go:generate mockgen -package const_length -destination mock.go -source input.go
46

57
const C = 2
68

79
type I interface {
810
Foo() [C]int
911
Bar() [2]int
12+
Baz() [math.MaxInt8]int
1013
}

mockgen/internal/tests/const_array_length/mock.go

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mockgen/parse.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import (
2222
"fmt"
2323
"go/ast"
2424
"go/build"
25+
"go/importer"
2526
"go/parser"
2627
"go/token"
28+
"go/types"
2729
"io/ioutil"
2830
"log"
2931
"path"
@@ -409,8 +411,19 @@ func (p *fileParser) parseType(pkg string, typ ast.Expr) (model.Type, error) {
409411
case (*ast.BasicLit):
410412
value = val.Value
411413
case (*ast.Ident):
412-
// when the length is a const
414+
// when the length is a const defined locally
413415
value = val.Obj.Decl.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value
416+
case (*ast.SelectorExpr):
417+
// when the length is a const defined in an external package
418+
usedPkg, err := importer.Default().Import(fmt.Sprintf("%s", val.X))
419+
if err != nil {
420+
return nil, p.errorf(v.Len.Pos(), "unknown package in array length: %v", err)
421+
}
422+
ev, err := types.Eval(token.NewFileSet(), usedPkg, token.NoPos, val.Sel.Name)
423+
if err != nil {
424+
return nil, p.errorf(v.Len.Pos(), "unknown constant in array length: %v", err)
425+
}
426+
value = ev.Value.String()
414427
}
415428

416429
x, err := strconv.Atoi(value)

mockgen/parse_test.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -116,24 +116,31 @@ func Benchmark_parseFile(b *testing.B) {
116116

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

120-
file, err := parser.ParseFile(fs, "internal/tests/const_array_length/input.go", nil, 0)
121+
file, err := parser.ParseFile(fs, srcDir, nil, 0)
121122
if err != nil {
122123
t.Fatalf("Unexpected error: %v", err)
123124
}
124125

125126
p := fileParser{
126-
fileSet: fs,
127+
fileSet: fs,
128+
imports: make(map[string]importedPackage),
129+
importedInterfaces: make(map[string]map[string]*ast.InterfaceType),
130+
auxInterfaces: make(map[string]map[string]*ast.InterfaceType),
131+
srcDir: srcDir,
127132
}
128133

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

134-
expect := "[2]int"
135-
got := pkg.Interfaces[0].Methods[0].Out[0].Type.String(nil, "")
136-
if got != expect {
137-
t.Fatalf("got %v; expected %v", got, expect)
139+
expects := []string{"[2]int", "[2]int", "[127]int"}
140+
for i, e := range expects {
141+
got := pkg.Interfaces[0].Methods[i].Out[0].Type.String(nil, "")
142+
if got != e {
143+
t.Fatalf("got %v; expected %v", got, e)
144+
}
138145
}
139146
}

0 commit comments

Comments
 (0)