Source file
src/go/types/object_test.go
1
2
3
4
5
6
7 package types_test
8
9 import (
10 "internal/testenv"
11 "strings"
12 "testing"
13
14 . "go/types"
15 )
16
17 func TestIsAlias(t *testing.T) {
18 check := func(obj *TypeName, want bool) {
19 if got := obj.IsAlias(); got != want {
20 t.Errorf("%v: got IsAlias = %v; want %v", obj, got, want)
21 }
22 }
23
24
25 check(Unsafe.Scope().Lookup("Pointer").(*TypeName), false)
26 for _, name := range Universe.Names() {
27 if obj, _ := Universe.Lookup(name).(*TypeName); obj != nil {
28 check(obj, name == "any" || name == "byte" || name == "rune")
29 }
30 }
31
32
33 pkg := NewPackage("p", "p")
34 t1 := NewTypeName(nopos, pkg, "t1", nil)
35 n1 := NewNamed(t1, new(Struct), nil)
36 t5 := NewTypeName(nopos, pkg, "t5", nil)
37 NewTypeParam(t5, nil)
38 for _, test := range []struct {
39 name *TypeName
40 alias bool
41 }{
42 {NewTypeName(nopos, nil, "t0", nil), false},
43 {NewTypeName(nopos, pkg, "t0", nil), false},
44 {t1, false},
45 {NewTypeName(nopos, nil, "t2", NewInterfaceType(nil, nil)), true},
46 {NewTypeName(nopos, pkg, "t3", n1), true},
47 {NewTypeName(nopos, nil, "t4", Typ[Int32]), true},
48 {NewTypeName(nopos, nil, "int32", Typ[Int32]), false},
49 {NewTypeName(nopos, pkg, "int32", Typ[Int32]), true},
50 {NewTypeName(nopos, nil, "rune", Typ[Rune]), true},
51 {t5, false},
52 } {
53 check(test.name, test.alias)
54 }
55 }
56
57
58
59 func TestEmbeddedMethod(t *testing.T) {
60 const src = `package p; type I interface { error }`
61 pkg := mustTypecheck(src, nil, nil)
62
63
64 eface := Universe.Lookup("error")
65 orig, _, _ := LookupFieldOrMethod(eface.Type(), false, nil, "Error")
66 if orig == nil {
67 t.Fatalf("original error.Error not found")
68 }
69
70
71 iface := pkg.Scope().Lookup("I")
72 embed, _, _ := LookupFieldOrMethod(iface.Type(), false, nil, "Error")
73 if embed == nil {
74 t.Fatalf("embedded error.Error not found")
75 }
76
77
78 if orig != embed {
79 t.Fatalf("%s (%p) != %s (%p)", orig, orig, embed, embed)
80 }
81 }
82
83 var testObjects = []struct {
84 src string
85 obj string
86 want string
87 }{
88 {"import \"io\"; var r io.Reader", "r", "var p.r io.Reader"},
89
90 {"const c = 1.2", "c", "const p.c untyped float"},
91 {"const c float64 = 3.14", "c", "const p.c float64"},
92
93 {"type t struct{f int}", "t", "type p.t struct{f int}"},
94 {"type t func(int)", "t", "type p.t func(int)"},
95 {"type t[P any] struct{f P}", "t", "type p.t[P any] struct{f P}"},
96 {"type t[P any] struct{f P}", "t.P", "type parameter P any"},
97 {"type C interface{m()}; type t[P C] struct{}", "t.P", "type parameter P p.C"},
98
99 {"type t = struct{f int}", "t", "type p.t = struct{f int}"},
100 {"type t = func(int)", "t", "type p.t = func(int)"},
101
102 {"var v int", "v", "var p.v int"},
103
104 {"func f(int) string", "f", "func p.f(int) string"},
105 {"func g[P any](x P){}", "g", "func p.g[P any](x P)"},
106 {"func g[P interface{~int}](x P){}", "g.P", "type parameter P interface{~int}"},
107 {"", "any", "type any = interface{}"},
108 }
109
110 func TestObjectString(t *testing.T) {
111 testenv.MustHaveGoBuild(t)
112
113 for _, test := range testObjects {
114 src := "package p; " + test.src
115 pkg, err := typecheck(src, nil, nil)
116 if err != nil {
117 t.Errorf("%s: %s", src, err)
118 continue
119 }
120
121 names := strings.Split(test.obj, ".")
122 if len(names) != 1 && len(names) != 2 {
123 t.Errorf("%s: invalid object path %s", test.src, test.obj)
124 continue
125 }
126 _, obj := pkg.Scope().LookupParent(names[0], nopos)
127 if obj == nil {
128 t.Errorf("%s: %s not found", test.src, names[0])
129 continue
130 }
131 if len(names) == 2 {
132 if typ, ok := obj.Type().(interface{ TypeParams() *TypeParamList }); ok {
133 obj = lookupTypeParamObj(typ.TypeParams(), names[1])
134 if obj == nil {
135 t.Errorf("%s: %s not found", test.src, test.obj)
136 continue
137 }
138 } else {
139 t.Errorf("%s: %s has no type parameters", test.src, names[0])
140 continue
141 }
142 }
143
144 if got := obj.String(); got != test.want {
145 t.Errorf("%s: got %s, want %s", test.src, got, test.want)
146 }
147 }
148 }
149
150 func lookupTypeParamObj(list *TypeParamList, name string) Object {
151 for i := 0; i < list.Len(); i++ {
152 tpar := list.At(i)
153 if tpar.Obj().Name() == name {
154 return tpar.Obj()
155 }
156 }
157 return nil
158 }
159
View as plain text