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