@@ -36,14 +36,16 @@ Iterable<String> nameGenerator() sync* {
36
36
class BenchMaker implements DartTypeVisitor1 <void , StringBuffer > {
37
37
final List <Object > checks = < Object > [];
38
38
39
- final Map <Class , String > classNames = < Class , String > {};
39
+ final Map <TreeNode , String > nodeNames = < TreeNode , String > {};
40
40
41
41
final Set <String > usedNames = new Set <String >();
42
42
43
43
final Iterator <String > names = nameGenerator ().iterator..moveNext ();
44
44
45
45
final List <String > classes = < String > [];
46
46
47
+ final List <TypeParameter > usedTypeParameters = < TypeParameter > [];
48
+
47
49
String serializeTypeChecks (List <Object > typeChecks) {
48
50
for (List <Object > list in typeChecks) {
49
51
writeTypeCheck (list[0 ], list[1 ], list[2 ]);
@@ -53,24 +55,66 @@ class BenchMaker implements DartTypeVisitor1<void, StringBuffer> {
53
55
}
54
56
55
57
void writeTypeCheck (DartType s, DartType t, bool expected) {
56
- List <String > arguments = new List <String >(2 );
57
- Map <String , dynamic > typeCheck = < String , dynamic > {
58
- "kind" : expected ? "isSubtype" : "isNotSubtype" ,
59
- "arguments" : arguments,
60
- };
58
+ assert (usedTypeParameters.isEmpty);
59
+ usedTypeParameters.clear ();
61
60
StringBuffer sb = new StringBuffer ();
62
61
s.accept1 (this , sb);
63
- arguments[ 0 ] = "$sb " ;
62
+ String sString = "$sb " ;
64
63
sb.clear ();
65
64
t.accept1 (this , sb);
66
- arguments[1 ] = "$sb " ;
67
- checks.add (typeCheck);
65
+ String tString = "$sb " ;
66
+ List <Object > arguments = < Object > [sString, tString];
67
+ Set <TypeParameter > seenTypeParameters = new Set <TypeParameter >();
68
+ List <String > parameterStrings = < String > [];
69
+ while (usedTypeParameters.isNotEmpty) {
70
+ List <TypeParameter > typeParameters = usedTypeParameters.toList ();
71
+ usedTypeParameters.clear ();
72
+ for (TypeParameter parameter in typeParameters) {
73
+ if (seenTypeParameters.add (parameter)) {
74
+ sb.clear ();
75
+ writeTypeParameter (parameter, sb);
76
+ parameterStrings.add ("$sb " );
77
+ }
78
+ }
79
+ }
80
+ if (parameterStrings.isNotEmpty) {
81
+ arguments.add (parameterStrings);
82
+ }
83
+ checks.add (< String , dynamic > {
84
+ "kind" : expected ? "isSubtype" : "isNotSubtype" ,
85
+ "arguments" : arguments,
86
+ });
87
+ }
88
+
89
+ void writeTypeParameter (TypeParameter parameter, StringBuffer sb) {
90
+ sb.write (computeName (parameter));
91
+ if (parameter.defaultType is ! DynamicType ||
92
+ parameter.bound is DynamicType ) {
93
+ sb.write (" extends " );
94
+ parameter.bound.accept1 (this , sb);
95
+ }
96
+ }
97
+
98
+ void writeTypeParameters (
99
+ List <TypeParameter > typeParameters, StringBuffer sb) {
100
+ if (typeParameters.isNotEmpty) {
101
+ sb.write ("<" );
102
+ bool first = true ;
103
+ for (TypeParameter p in typeParameters) {
104
+ if (! first) sb.write (", " );
105
+ writeTypeParameter (p, sb);
106
+ first = false ;
107
+ }
108
+ sb.write (">" );
109
+ }
68
110
}
69
111
70
112
void writeClasses () {
71
113
Set <Class > writtenClasses = new Set <Class >();
72
- for (Class cls in classNames.keys.toList ()) {
73
- writeClass (cls, writtenClasses);
114
+ for (TreeNode node in nodeNames.keys.toList ()) {
115
+ if (node is Class ) {
116
+ writeClass (node, writtenClasses);
117
+ }
74
118
}
75
119
}
76
120
@@ -86,6 +130,7 @@ class BenchMaker implements DartTypeVisitor1<void, StringBuffer> {
86
130
StringBuffer sb = new StringBuffer ();
87
131
sb.write ("class " );
88
132
sb.write (computeName (cls));
133
+ writeTypeParameters (cls.typeParameters, sb);
89
134
if (supertype != null ) {
90
135
sb.write (" extends " );
91
136
supertype.asInterfaceType.accept1 (this , sb);
@@ -120,23 +165,23 @@ class BenchMaker implements DartTypeVisitor1<void, StringBuffer> {
120
165
classes.add ("$sb " );
121
166
}
122
167
123
- String computeName (Class cls ) {
124
- String name = classNames[cls ];
168
+ String computeName (TreeNode node ) {
169
+ String name = nodeNames[node ];
125
170
if (name != null ) return name;
126
- Library library = cls.enclosingLibrary;
127
- if ("${library .importUri }" == "dart:core" ) {
128
- if (! usedNames.add (cls.name)) {
129
- throw "Class name conflict for $cls " ;
130
- }
131
- return classNames[cls] = cls.name;
132
- } else {
133
- String name;
134
- while (! usedNames.add (name = names.current)) {
135
- names.moveNext ();
171
+ if (node is Class ) {
172
+ Library library = node.enclosingLibrary;
173
+ if ("${library ?.importUri }" == "dart:core" ) {
174
+ if (! usedNames.add (node.name)) {
175
+ throw "Class name conflict for $node " ;
176
+ }
177
+ return nodeNames[node] = node.name;
136
178
}
179
+ }
180
+ while (! usedNames.add (name = names.current)) {
137
181
names.moveNext ();
138
- return classNames[cls] = name;
139
182
}
183
+ names.moveNext ();
184
+ return nodeNames[node] = name;
140
185
}
141
186
142
187
@override
@@ -185,18 +230,7 @@ class BenchMaker implements DartTypeVisitor1<void, StringBuffer> {
185
230
186
231
@override
187
232
void visitFunctionType (FunctionType node, StringBuffer sb) {
188
- if (node.typeParameters.isNotEmpty) {
189
- sb.write ("<" );
190
- bool first = true ;
191
- for (TypeParameter p in node.typeParameters) {
192
- if (! first) sb.write (", " );
193
- sb.write (p.name);
194
- sb.write (" extends " );
195
- p.bound.accept1 (this , sb);
196
- first = false ;
197
- }
198
- sb.write (">" );
199
- }
233
+ writeTypeParameters (node.typeParameters, sb);
200
234
sb.write ("(" );
201
235
bool first = true ;
202
236
for (int i = 0 ; i < node.requiredParameterCount; i++ ) {
@@ -238,10 +272,13 @@ class BenchMaker implements DartTypeVisitor1<void, StringBuffer> {
238
272
239
273
@override
240
274
void visitTypeParameterType (TypeParameterType node, StringBuffer sb) {
241
- // TODO(ahe): We need to collect used type parameters. See
242
- // pkg/front_end/test/fasta/types/shared_type_tests.dart for how they can
243
- // be used in testing subtype checks.
244
- sb.write (node.parameter.name);
275
+ String name = computeName (node.parameter);
276
+ usedTypeParameters.add (node.parameter);
277
+ sb.write (name);
278
+ if (node.promotedBound != null ) {
279
+ sb.write (" & " );
280
+ node.promotedBound.accept1 (this , sb);
281
+ }
245
282
}
246
283
247
284
@override
0 commit comments