1
2
3
4
5 package types2_test
6
7 import (
8 "fmt"
9 "internal/testenv"
10 "strings"
11 "testing"
12
13 . "cmd/compile/internal/types2"
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 src := "package p; " + test.src
117 conf := Config{Error: func(error) {}, Importer: defaultImporter(), EnableAlias: test.alias}
118 pkg, err := typecheck(src, &conf, nil)
119 if err != nil {
120 t.Fatalf("%s: %s", src, err)
121 }
122
123 names := strings.Split(test.obj, ".")
124 if len(names) != 1 && len(names) != 2 {
125 t.Fatalf("%s: invalid object path %s", test.src, test.obj)
126 }
127 _, obj := pkg.Scope().LookupParent(names[0], nopos)
128 if obj == nil {
129 t.Fatalf("%s: %s not found", test.src, names[0])
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.Fatalf("%s: %s not found", test.src, test.obj)
136 }
137 } else {
138 t.Fatalf("%s: %s has no type parameters", test.src, names[0])
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
149 func lookupTypeParamObj(list *TypeParamList, name string) Object {
150 for i := 0; i < list.Len(); i++ {
151 tpar := list.At(i)
152 if tpar.Obj().Name() == name {
153 return tpar.Obj()
154 }
155 }
156 return nil
157 }
158
View as plain text