@@ -19,6 +19,7 @@ import (
19
19
"testing"
20
20
21
21
"golang.org/x/tools/go/ast/astutil"
22
+ "golang.org/x/tools/internal/typeparams"
22
23
)
23
24
24
25
// pathToString returns a string containing the concrete types of the
@@ -59,7 +60,10 @@ func findInterval(t *testing.T, fset *token.FileSet, input, substr string) (f *a
59
60
}
60
61
61
62
// Common input for following tests.
62
- const input = `
63
+ var input = makeInput ()
64
+
65
+ func makeInput () string {
66
+ src := `
63
67
// Hello.
64
68
package main
65
69
import "fmt"
@@ -70,52 +74,88 @@ func main() {
70
74
}
71
75
`
72
76
77
+ if typeparams .Enabled {
78
+ src += `
79
+ func g[A any, P interface{ctype1| ~ctype2}](a1 A, p1 P) {}
80
+
81
+ type PT[T constraint] struct{ t T }
82
+
83
+ var v GT[targ1]
84
+
85
+ var h = g[ targ2, targ3]
86
+ `
87
+ }
88
+ return src
89
+ }
90
+
73
91
func TestPathEnclosingInterval_Exact (t * testing.T ) {
74
- // For the exact tests, we check that a substring is mapped to
75
- // the canonical string for the node it denotes.
76
- tests := []struct {
92
+ type testCase struct {
77
93
substr string // first occurrence of this string indicates interval
78
94
node string // complete text of expected containing node
79
- }{
95
+ }
96
+
97
+ dup := func (s string ) testCase { return testCase {s , s } }
98
+ // For the exact tests, we check that a substring is mapped to
99
+ // the canonical string for the node it denotes.
100
+ tests := []testCase {
80
101
{"package" ,
81
102
input [11 : len (input )- 1 ]},
82
103
{"\n pack" ,
83
104
input [11 : len (input )- 1 ]},
84
- {"main" ,
85
- "main" },
105
+ dup ("main" ),
86
106
{"import" ,
87
107
"import \" fmt\" " },
88
- {"\" fmt\" " ,
89
- "\" fmt\" " },
108
+ dup ("\" fmt\" " ),
90
109
{"\n func f() {}\n " ,
91
110
"func f() {}" },
92
111
{"x " ,
93
112
"x" },
94
113
{" y" ,
95
114
"y" },
96
- {"z" ,
97
- "z" },
115
+ dup ("z" ),
98
116
{" + " ,
99
117
"x + y" },
100
118
{" :=" ,
101
119
"z := (x + y)" },
102
- {"x + y" ,
103
- "x + y" },
104
- {"(x + y)" ,
105
- "(x + y)" },
120
+ dup ("x + y" ),
121
+ dup ("(x + y)" ),
106
122
{" (x + y) " ,
107
123
"(x + y)" },
108
124
{" (x + y) // add" ,
109
125
"(x + y)" },
110
126
{"func" ,
111
127
"func f() {}" },
112
- {"func f() {}" ,
113
- "func f() {}" },
128
+ dup ("func f() {}" ),
114
129
{"\n fun" ,
115
130
"func f() {}" },
116
131
{" f" ,
117
132
"f" },
118
133
}
134
+ if typeparams .Enabled {
135
+ tests = append (tests , []testCase {
136
+ dup ("[A any, P interface{ctype1| ~ctype2}]" ),
137
+ {"[" , "[A any, P interface{ctype1| ~ctype2}]" },
138
+ dup ("A" ),
139
+ {" any" , "any" },
140
+ dup ("ctype1" ),
141
+ {"|" , "ctype1| ~ctype2" },
142
+ dup ("ctype2" ),
143
+ {"~" , "~ctype2" },
144
+ dup ("~ctype2" ),
145
+ {" ~ctype2" , "~ctype2" },
146
+ {"]" , "[A any, P interface{ctype1| ~ctype2}]" },
147
+ dup ("a1" ),
148
+ dup ("a1 A" ),
149
+ dup ("(a1 A, p1 P)" ),
150
+ dup ("type PT[T constraint] struct{ t T }" ),
151
+ dup ("PT" ),
152
+ dup ("[T constraint]" ),
153
+ dup ("constraint" ),
154
+ dup ("targ1" ),
155
+ {" targ2" , "targ2" },
156
+ dup ("g[ targ2, targ3]" ),
157
+ }... )
158
+ }
119
159
for _ , test := range tests {
120
160
f , start , end := findInterval (t , new (token.FileSet ), input , test .substr )
121
161
if f == nil {
@@ -145,13 +185,14 @@ func TestPathEnclosingInterval_Exact(t *testing.T) {
145
185
}
146
186
147
187
func TestPathEnclosingInterval_Paths (t * testing.T ) {
188
+ type testCase struct {
189
+ substr string // first occurrence of this string indicates interval
190
+ path string // the pathToString(),exact of the expected path
191
+ }
148
192
// For these tests, we check only the path of the enclosing
149
193
// node, but not its complete text because it's often quite
150
194
// large when !exact.
151
- tests := []struct {
152
- substr string // first occurrence of this string indicates interval
153
- path string // the pathToString(),exact of the expected path
154
- }{
195
+ tests := []testCase {
155
196
{"// add" ,
156
197
"[BlockStmt FuncDecl File],false" },
157
198
{"(x + y" ,
@@ -179,6 +220,18 @@ func TestPathEnclosingInterval_Paths(t *testing.T) {
179
220
{"f() // NB" ,
180
221
"[CallExpr ExprStmt BlockStmt FuncDecl File],true" },
181
222
}
223
+ if typeparams .Enabled {
224
+ tests = append (tests , []testCase {
225
+ {" any" , "[Ident Field FieldList FuncDecl File],true" },
226
+ {"|" , "[BinaryExpr Field FieldList InterfaceType Field FieldList FuncDecl File],true" },
227
+ {"ctype2" ,
228
+ "[Ident UnaryExpr BinaryExpr Field FieldList InterfaceType Field FieldList FuncDecl File],true" },
229
+ {"a1" , "[Ident Field FieldList FuncDecl File],true" },
230
+ {"PT[T constraint]" , "[TypeSpec GenDecl File],false" },
231
+ {"[T constraint]" , "[FieldList TypeSpec GenDecl File],true" },
232
+ {"targ2" , "[Ident IndexListExpr ValueSpec GenDecl File],true" },
233
+ }... )
234
+ }
182
235
for _ , test := range tests {
183
236
f , start , end := findInterval (t , new (token.FileSet ), input , test .substr )
184
237
if f == nil {
0 commit comments