@@ -16,21 +16,27 @@ import (
16
16
"golang.org/x/tools/go/packages"
17
17
)
18
18
19
- type parserEntry struct {
19
+ type fileEntry struct {
20
20
fileName string
21
21
pkg * packages.Package
22
22
syntax * ast.File
23
23
interfaces []string
24
24
}
25
25
26
+ func (f * fileEntry ) ParseInterfaces (ctx context.Context ) {
27
+ nv := NewNodeVisitor (ctx )
28
+ ast .Walk (nv , f .syntax )
29
+ f .interfaces = nv .DeclaredInterfaces ()
30
+ }
31
+
26
32
type packageLoadEntry struct {
27
33
pkgs []* packages.Package
28
34
err error
29
35
}
30
36
31
37
type Parser struct {
32
- entries []* parserEntry
33
- entriesByFileName map [string ]* parserEntry
38
+ files []* fileEntry
39
+ entriesByFileName map [string ]* fileEntry
34
40
parserPackages []* types.Package
35
41
conf packages.Config
36
42
packageLoadCache map [string ]packageLoadEntry
@@ -52,7 +58,7 @@ func NewParser(buildTags []string) *Parser {
52
58
}
53
59
return & Parser {
54
60
parserPackages : make ([]* types.Package , 0 ),
55
- entriesByFileName : map [string ]* parserEntry {},
61
+ entriesByFileName : map [string ]* fileEntry {},
56
62
conf : conf ,
57
63
packageLoadCache : map [string ]packageLoadEntry {},
58
64
}
@@ -86,18 +92,21 @@ func (p *Parser) ParsePackages(ctx context.Context, packageNames []string) error
86
92
Str ("package" , pkg .PkgPath ).
87
93
Str ("file" , file ).
88
94
Msgf ("found file" )
89
- entry := parserEntry {
95
+ entry := fileEntry {
90
96
fileName : file ,
91
97
pkg : pkg ,
92
98
syntax : pkg .Syntax [fileIdx ],
93
99
}
94
- p .entries = append (p .entries , & entry )
100
+ entry .ParseInterfaces (ctx )
101
+ p .files = append (p .files , & entry )
95
102
p .entriesByFileName [file ] = & entry
96
103
}
97
104
}
98
105
return nil
99
106
}
100
107
108
+ // DEPRECATED: Parse is part of the deprecated, legacy mockery behavior. This is not
109
+ // used when the packages feature is enabled.
101
110
func (p * Parser ) Parse (ctx context.Context , path string ) error {
102
111
// To support relative paths to mock targets w/ vendor deps, we need to provide eventual
103
112
// calls to build.Context.Import with an absolute path. It needs to be absolute because
@@ -164,30 +173,28 @@ func (p *Parser) Parse(ctx context.Context, path string) error {
164
173
if _ , ok := p .entriesByFileName [f ]; ok {
165
174
continue
166
175
}
167
- entry := parserEntry {
176
+ entry := fileEntry {
168
177
fileName : f ,
169
178
pkg : pkg ,
170
179
syntax : pkg .Syntax [idx ],
171
180
}
172
- p .entries = append (p .entries , & entry )
181
+ p .files = append (p .files , & entry )
173
182
p .entriesByFileName [f ] = & entry
174
183
}
175
184
}
176
185
177
186
return nil
178
187
}
179
188
180
- func (p * Parser ) Load () error {
181
- for _ , entry := range p .entries {
182
- nv := NewNodeVisitor ()
183
- ast .Walk (nv , entry .syntax )
184
- entry .interfaces = nv .DeclaredInterfaces ()
189
+ func (p * Parser ) Load (ctx context.Context ) error {
190
+ for _ , entry := range p .files {
191
+ entry .ParseInterfaces (ctx )
185
192
}
186
193
return nil
187
194
}
188
195
189
196
func (p * Parser ) Find (name string ) (* Interface , error ) {
190
- for _ , entry := range p .entries {
197
+ for _ , entry := range p .files {
191
198
for _ , iface := range entry .interfaces {
192
199
if iface == name {
193
200
list := p .packageInterfaces (entry .pkg .Types , entry .fileName , []string {name }, nil )
@@ -202,7 +209,7 @@ func (p *Parser) Find(name string) (*Interface, error) {
202
209
203
210
func (p * Parser ) Interfaces () []* Interface {
204
211
ifaces := make (sortableIFaceList , 0 )
205
- for _ , entry := range p .entries {
212
+ for _ , entry := range p .files {
206
213
declaredIfaces := entry .interfaces
207
214
ifaces = p .packageInterfaces (entry .pkg .Types , entry .fileName , declaredIfaces , ifaces )
208
215
}
@@ -314,12 +321,15 @@ func (s sortableIFaceList) Less(i, j int) bool {
314
321
}
315
322
316
323
type NodeVisitor struct {
317
- declaredInterfaces []string
324
+ declaredInterfaces []string
325
+ genericInstantiationInterface map [string ]any
326
+ ctx context.Context
318
327
}
319
328
320
- func NewNodeVisitor () * NodeVisitor {
329
+ func NewNodeVisitor (ctx context. Context ) * NodeVisitor {
321
330
return & NodeVisitor {
322
331
declaredInterfaces : make ([]string , 0 ),
332
+ ctx : ctx ,
323
333
}
324
334
}
325
335
@@ -328,11 +338,23 @@ func (nv *NodeVisitor) DeclaredInterfaces() []string {
328
338
}
329
339
330
340
func (nv * NodeVisitor ) Visit (node ast.Node ) ast.Visitor {
341
+ log := zerolog .Ctx (nv .ctx )
342
+
331
343
switch n := node .(type ) {
332
344
case * ast.TypeSpec :
345
+ log := log .With ().
346
+ Str ("node-name" , n .Name .Name ).
347
+ Str ("node-type" , fmt .Sprintf ("%T" , n .Type )).
348
+ Logger ()
349
+
333
350
switch n .Type .(type ) {
334
- case * ast.InterfaceType , * ast.FuncType :
351
+ case * ast.InterfaceType , * ast.FuncType , * ast.IndexExpr :
352
+ log .Debug ().
353
+ Str ("node-type" , fmt .Sprintf ("%T" , n .Type )).
354
+ Msg ("found node with acceptable type for mocking" )
335
355
nv .declaredInterfaces = append (nv .declaredInterfaces , n .Name .Name )
356
+ default :
357
+ log .Debug ().Msg ("Found node with unacceptable type for mocking. Rejecting." )
336
358
}
337
359
}
338
360
return nv
0 commit comments