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