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