Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/github.com/golang/mock/mockgen/model/model.go
2893 views
1
// Copyright 2012 Google Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
// Package model contains the data model necessary for generating mock implementations.
16
package model
17
18
import (
19
"encoding/gob"
20
"fmt"
21
"io"
22
"reflect"
23
"strings"
24
)
25
26
// pkgPath is the importable path for package model
27
const pkgPath = "github.com/golang/mock/mockgen/model"
28
29
// Package is a Go package. It may be a subset.
30
type Package struct {
31
Name string
32
PkgPath string
33
Interfaces []*Interface
34
DotImports []string
35
}
36
37
// Print writes the package name and its exported interfaces.
38
func (pkg *Package) Print(w io.Writer) {
39
_, _ = fmt.Fprintf(w, "package %s\n", pkg.Name)
40
for _, intf := range pkg.Interfaces {
41
intf.Print(w)
42
}
43
}
44
45
// Imports returns the imports needed by the Package as a set of import paths.
46
func (pkg *Package) Imports() map[string]bool {
47
im := make(map[string]bool)
48
for _, intf := range pkg.Interfaces {
49
intf.addImports(im)
50
}
51
return im
52
}
53
54
// Interface is a Go interface.
55
type Interface struct {
56
Name string
57
Methods []*Method
58
}
59
60
// Print writes the interface name and its methods.
61
func (intf *Interface) Print(w io.Writer) {
62
_, _ = fmt.Fprintf(w, "interface %s\n", intf.Name)
63
for _, m := range intf.Methods {
64
m.Print(w)
65
}
66
}
67
68
func (intf *Interface) addImports(im map[string]bool) {
69
for _, m := range intf.Methods {
70
m.addImports(im)
71
}
72
}
73
74
// AddMethod adds a new method, de-duplicating by method name.
75
func (intf *Interface) AddMethod(m *Method) {
76
for _, me := range intf.Methods {
77
if me.Name == m.Name {
78
return
79
}
80
}
81
intf.Methods = append(intf.Methods, m)
82
}
83
84
// Method is a single method of an interface.
85
type Method struct {
86
Name string
87
In, Out []*Parameter
88
Variadic *Parameter // may be nil
89
}
90
91
// Print writes the method name and its signature.
92
func (m *Method) Print(w io.Writer) {
93
_, _ = fmt.Fprintf(w, " - method %s\n", m.Name)
94
if len(m.In) > 0 {
95
_, _ = fmt.Fprintf(w, " in:\n")
96
for _, p := range m.In {
97
p.Print(w)
98
}
99
}
100
if m.Variadic != nil {
101
_, _ = fmt.Fprintf(w, " ...:\n")
102
m.Variadic.Print(w)
103
}
104
if len(m.Out) > 0 {
105
_, _ = fmt.Fprintf(w, " out:\n")
106
for _, p := range m.Out {
107
p.Print(w)
108
}
109
}
110
}
111
112
func (m *Method) addImports(im map[string]bool) {
113
for _, p := range m.In {
114
p.Type.addImports(im)
115
}
116
if m.Variadic != nil {
117
m.Variadic.Type.addImports(im)
118
}
119
for _, p := range m.Out {
120
p.Type.addImports(im)
121
}
122
}
123
124
// Parameter is an argument or return parameter of a method.
125
type Parameter struct {
126
Name string // may be empty
127
Type Type
128
}
129
130
// Print writes a method parameter.
131
func (p *Parameter) Print(w io.Writer) {
132
n := p.Name
133
if n == "" {
134
n = `""`
135
}
136
_, _ = fmt.Fprintf(w, " - %v: %v\n", n, p.Type.String(nil, ""))
137
}
138
139
// Type is a Go type.
140
type Type interface {
141
String(pm map[string]string, pkgOverride string) string
142
addImports(im map[string]bool)
143
}
144
145
func init() {
146
gob.Register(&ArrayType{})
147
gob.Register(&ChanType{})
148
gob.Register(&FuncType{})
149
gob.Register(&MapType{})
150
gob.Register(&NamedType{})
151
gob.Register(&PointerType{})
152
153
// Call gob.RegisterName to make sure it has the consistent name registered
154
// for both gob decoder and encoder.
155
//
156
// For a non-pointer type, gob.Register will try to get package full path by
157
// calling rt.PkgPath() for a name to register. If your project has vendor
158
// directory, it is possible that PkgPath will get a path like this:
159
// ../../../vendor/github.com/golang/mock/mockgen/model
160
gob.RegisterName(pkgPath+".PredeclaredType", PredeclaredType(""))
161
}
162
163
// ArrayType is an array or slice type.
164
type ArrayType struct {
165
Len int // -1 for slices, >= 0 for arrays
166
Type Type
167
}
168
169
func (at *ArrayType) String(pm map[string]string, pkgOverride string) string {
170
s := "[]"
171
if at.Len > -1 {
172
s = fmt.Sprintf("[%d]", at.Len)
173
}
174
return s + at.Type.String(pm, pkgOverride)
175
}
176
177
func (at *ArrayType) addImports(im map[string]bool) { at.Type.addImports(im) }
178
179
// ChanType is a channel type.
180
type ChanType struct {
181
Dir ChanDir // 0, 1 or 2
182
Type Type
183
}
184
185
func (ct *ChanType) String(pm map[string]string, pkgOverride string) string {
186
s := ct.Type.String(pm, pkgOverride)
187
if ct.Dir == RecvDir {
188
return "<-chan " + s
189
}
190
if ct.Dir == SendDir {
191
return "chan<- " + s
192
}
193
return "chan " + s
194
}
195
196
func (ct *ChanType) addImports(im map[string]bool) { ct.Type.addImports(im) }
197
198
// ChanDir is a channel direction.
199
type ChanDir int
200
201
// Constants for channel directions.
202
const (
203
RecvDir ChanDir = 1
204
SendDir ChanDir = 2
205
)
206
207
// FuncType is a function type.
208
type FuncType struct {
209
In, Out []*Parameter
210
Variadic *Parameter // may be nil
211
}
212
213
func (ft *FuncType) String(pm map[string]string, pkgOverride string) string {
214
args := make([]string, len(ft.In))
215
for i, p := range ft.In {
216
args[i] = p.Type.String(pm, pkgOverride)
217
}
218
if ft.Variadic != nil {
219
args = append(args, "..."+ft.Variadic.Type.String(pm, pkgOverride))
220
}
221
rets := make([]string, len(ft.Out))
222
for i, p := range ft.Out {
223
rets[i] = p.Type.String(pm, pkgOverride)
224
}
225
retString := strings.Join(rets, ", ")
226
if nOut := len(ft.Out); nOut == 1 {
227
retString = " " + retString
228
} else if nOut > 1 {
229
retString = " (" + retString + ")"
230
}
231
return "func(" + strings.Join(args, ", ") + ")" + retString
232
}
233
234
func (ft *FuncType) addImports(im map[string]bool) {
235
for _, p := range ft.In {
236
p.Type.addImports(im)
237
}
238
if ft.Variadic != nil {
239
ft.Variadic.Type.addImports(im)
240
}
241
for _, p := range ft.Out {
242
p.Type.addImports(im)
243
}
244
}
245
246
// MapType is a map type.
247
type MapType struct {
248
Key, Value Type
249
}
250
251
func (mt *MapType) String(pm map[string]string, pkgOverride string) string {
252
return "map[" + mt.Key.String(pm, pkgOverride) + "]" + mt.Value.String(pm, pkgOverride)
253
}
254
255
func (mt *MapType) addImports(im map[string]bool) {
256
mt.Key.addImports(im)
257
mt.Value.addImports(im)
258
}
259
260
// NamedType is an exported type in a package.
261
type NamedType struct {
262
Package string // may be empty
263
Type string
264
}
265
266
func (nt *NamedType) String(pm map[string]string, pkgOverride string) string {
267
if pkgOverride == nt.Package {
268
return nt.Type
269
}
270
prefix := pm[nt.Package]
271
if prefix != "" {
272
return prefix + "." + nt.Type
273
}
274
275
return nt.Type
276
}
277
278
func (nt *NamedType) addImports(im map[string]bool) {
279
if nt.Package != "" {
280
im[nt.Package] = true
281
}
282
}
283
284
// PointerType is a pointer to another type.
285
type PointerType struct {
286
Type Type
287
}
288
289
func (pt *PointerType) String(pm map[string]string, pkgOverride string) string {
290
return "*" + pt.Type.String(pm, pkgOverride)
291
}
292
func (pt *PointerType) addImports(im map[string]bool) { pt.Type.addImports(im) }
293
294
// PredeclaredType is a predeclared type such as "int".
295
type PredeclaredType string
296
297
func (pt PredeclaredType) String(map[string]string, string) string { return string(pt) }
298
func (pt PredeclaredType) addImports(map[string]bool) {}
299
300
// The following code is intended to be called by the program generated by ../reflect.go.
301
302
// InterfaceFromInterfaceType returns a pointer to an interface for the
303
// given reflection interface type.
304
func InterfaceFromInterfaceType(it reflect.Type) (*Interface, error) {
305
if it.Kind() != reflect.Interface {
306
return nil, fmt.Errorf("%v is not an interface", it)
307
}
308
intf := &Interface{}
309
310
for i := 0; i < it.NumMethod(); i++ {
311
mt := it.Method(i)
312
// TODO: need to skip unexported methods? or just raise an error?
313
m := &Method{
314
Name: mt.Name,
315
}
316
317
var err error
318
m.In, m.Variadic, m.Out, err = funcArgsFromType(mt.Type)
319
if err != nil {
320
return nil, err
321
}
322
323
intf.AddMethod(m)
324
}
325
326
return intf, nil
327
}
328
329
// t's Kind must be a reflect.Func.
330
func funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) {
331
nin := t.NumIn()
332
if t.IsVariadic() {
333
nin--
334
}
335
var p *Parameter
336
for i := 0; i < nin; i++ {
337
p, err = parameterFromType(t.In(i))
338
if err != nil {
339
return
340
}
341
in = append(in, p)
342
}
343
if t.IsVariadic() {
344
p, err = parameterFromType(t.In(nin).Elem())
345
if err != nil {
346
return
347
}
348
variadic = p
349
}
350
for i := 0; i < t.NumOut(); i++ {
351
p, err = parameterFromType(t.Out(i))
352
if err != nil {
353
return
354
}
355
out = append(out, p)
356
}
357
return
358
}
359
360
func parameterFromType(t reflect.Type) (*Parameter, error) {
361
tt, err := typeFromType(t)
362
if err != nil {
363
return nil, err
364
}
365
return &Parameter{Type: tt}, nil
366
}
367
368
var errorType = reflect.TypeOf((*error)(nil)).Elem()
369
370
var byteType = reflect.TypeOf(byte(0))
371
372
func typeFromType(t reflect.Type) (Type, error) {
373
// Hack workaround for https://golang.org/issue/3853.
374
// This explicit check should not be necessary.
375
if t == byteType {
376
return PredeclaredType("byte"), nil
377
}
378
379
if imp := t.PkgPath(); imp != "" {
380
return &NamedType{
381
Package: impPath(imp),
382
Type: t.Name(),
383
}, nil
384
}
385
386
// only unnamed or predeclared types after here
387
388
// Lots of types have element types. Let's do the parsing and error checking for all of them.
389
var elemType Type
390
switch t.Kind() {
391
case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:
392
var err error
393
elemType, err = typeFromType(t.Elem())
394
if err != nil {
395
return nil, err
396
}
397
}
398
399
switch t.Kind() {
400
case reflect.Array:
401
return &ArrayType{
402
Len: t.Len(),
403
Type: elemType,
404
}, nil
405
case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
406
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
407
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String:
408
return PredeclaredType(t.Kind().String()), nil
409
case reflect.Chan:
410
var dir ChanDir
411
switch t.ChanDir() {
412
case reflect.RecvDir:
413
dir = RecvDir
414
case reflect.SendDir:
415
dir = SendDir
416
}
417
return &ChanType{
418
Dir: dir,
419
Type: elemType,
420
}, nil
421
case reflect.Func:
422
in, variadic, out, err := funcArgsFromType(t)
423
if err != nil {
424
return nil, err
425
}
426
return &FuncType{
427
In: in,
428
Out: out,
429
Variadic: variadic,
430
}, nil
431
case reflect.Interface:
432
// Two special interfaces.
433
if t.NumMethod() == 0 {
434
return PredeclaredType("interface{}"), nil
435
}
436
if t == errorType {
437
return PredeclaredType("error"), nil
438
}
439
case reflect.Map:
440
kt, err := typeFromType(t.Key())
441
if err != nil {
442
return nil, err
443
}
444
return &MapType{
445
Key: kt,
446
Value: elemType,
447
}, nil
448
case reflect.Ptr:
449
return &PointerType{
450
Type: elemType,
451
}, nil
452
case reflect.Slice:
453
return &ArrayType{
454
Len: -1,
455
Type: elemType,
456
}, nil
457
case reflect.Struct:
458
if t.NumField() == 0 {
459
return PredeclaredType("struct{}"), nil
460
}
461
}
462
463
// TODO: Struct, UnsafePointer
464
return nil, fmt.Errorf("can't yet turn %v (%v) into a model.Type", t, t.Kind())
465
}
466
467
// impPath sanitizes the package path returned by `PkgPath` method of a reflect Type so that
468
// it is importable. PkgPath might return a path that includes "vendor". These paths do not
469
// compile, so we need to remove everything up to and including "/vendor/".
470
// See https://github.com/golang/go/issues/12019.
471
func impPath(imp string) string {
472
if strings.HasPrefix(imp, "vendor/") {
473
imp = "/" + imp
474
}
475
if i := strings.LastIndex(imp, "/vendor/"); i != -1 {
476
imp = imp[i+len("/vendor/"):]
477
}
478
return imp
479
}
480
481
// ErrorInterface represent built-in error interface.
482
var ErrorInterface = Interface{
483
Name: "error",
484
Methods: []*Method{
485
{
486
Name: "Error",
487
Out: []*Parameter{
488
{
489
Name: "",
490
Type: PredeclaredType("string"),
491
},
492
},
493
},
494
},
495
}
496
497