Source file
src/go/types/methodset_test.go
1
2
3
4
5 package types_test
6
7 import (
8 "testing"
9
10 "go/internal/typeparams"
11 . "go/types"
12 )
13
14 func TestNewMethodSet(t *testing.T) {
15 type method struct {
16 name string
17 index []int
18 indirect bool
19 }
20
21
22
23 tests := map[string][]method{
24
25 "var a T; type T struct{}; func (T) f() {}": {{"f", []int{0}, false}},
26 "var a *T; type T struct{}; func (T) f() {}": {{"f", []int{0}, true}},
27 "var a T; type T struct{}; func (*T) f() {}": {},
28 "var a *T; type T struct{}; func (*T) f() {}": {{"f", []int{0}, true}},
29
30
31 "var a T; type T interface{ f() }": {{"f", []int{0}, true}},
32 "var a T1; type ( T1 T2; T2 interface{ f() } )": {{"f", []int{0}, true}},
33 "var a T1; type ( T1 interface{ T2 }; T2 interface{ f() } )": {{"f", []int{0}, true}},
34
35
36 "var a struct{ E }; type E interface{ f() }": {{"f", []int{0, 0}, true}},
37 "var a *struct{ E }; type E interface{ f() }": {{"f", []int{0, 0}, true}},
38 "var a struct{ E }; type E struct{}; func (E) f() {}": {{"f", []int{0, 0}, false}},
39 "var a struct{ *E }; type E struct{}; func (E) f() {}": {{"f", []int{0, 0}, true}},
40 "var a struct{ E }; type E struct{}; func (*E) f() {}": {},
41 "var a struct{ *E }; type E struct{}; func (*E) f() {}": {{"f", []int{0, 0}, true}},
42
43
44 "var a struct{ E1; *E2 }; type ( E1 interface{ f() }; E2 struct{ f int })": {},
45 "var a struct{ E1; *E2 }; type ( E1 struct{ f int }; E2 struct{} ); func (E2) f() {}": {},
46 }
47
48 genericTests := map[string][]method{
49
50 "type C interface{ f() }; func g[T C](a T){}": {{"f", []int{0}, true}},
51 "type C interface{ f() }; func g[T C]() { var a T; _ = a }": {{"f", []int{0}, true}},
52 "type C interface{ f() }; func g[T C]() { var a struct{T}; _ = a }": {{"f", []int{0, 0}, true}},
53
54
55 "type C interface{ f() }; func g[T C]() { type Y T; var a Y; _ = a }": {},
56 }
57
58 check := func(src string, methods []method, generic bool) {
59 pkgName := "p"
60 if generic {
61
62 pkgName = "generic_p"
63 }
64 pkg, err := pkgFor("test", "package "+pkgName+";"+src, nil)
65 if err != nil {
66 t.Errorf("%s: incorrect test case: %s", src, err)
67 return
68 }
69
70 scope := pkg.Scope()
71 if generic {
72 fn := pkg.Scope().Lookup("g").(*Func)
73 scope = fn.Scope()
74 }
75 obj := scope.Lookup("a")
76 if obj == nil {
77 t.Errorf("%s: incorrect test case - no object a", src)
78 return
79 }
80
81 ms := NewMethodSet(obj.Type())
82 if got, want := ms.Len(), len(methods); got != want {
83 t.Errorf("%s: got %d methods, want %d", src, got, want)
84 return
85 }
86 for i, m := range methods {
87 sel := ms.At(i)
88 if got, want := sel.Obj().Name(), m.name; got != want {
89 t.Errorf("%s [method %d]: got name = %q at, want %q", src, i, got, want)
90 }
91 if got, want := sel.Index(), m.index; !sameSlice(got, want) {
92 t.Errorf("%s [method %d]: got index = %v, want %v", src, i, got, want)
93 }
94 if got, want := sel.Indirect(), m.indirect; got != want {
95 t.Errorf("%s [method %d]: got indirect = %v, want %v", src, i, got, want)
96 }
97 }
98 }
99
100 for src, methods := range tests {
101 check(src, methods, false)
102 }
103
104 if typeparams.Enabled {
105 for src, methods := range genericTests {
106 check(src, methods, true)
107 }
108 }
109 }
110
View as plain text