Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: tests/compiler/dart2js/world_test.dart

Issue 1627333002: Optimize subclass/subtype queries (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Cleanup Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library world_test; 5 library world_test;
6 6
7 import 'package:expect/expect.dart'; 7 import 'package:expect/expect.dart';
8 import 'package:async_helper/async_helper.dart'; 8 import 'package:async_helper/async_helper.dart';
9 import 'type_test_helper.dart'; 9 import 'type_test_helper.dart';
10 import 'package:compiler/src/common.dart';
10 import 'package:compiler/src/elements/elements.dart' 11 import 'package:compiler/src/elements/elements.dart'
11 show Element, ClassElement; 12 show Element, ClassElement;
13 import 'package:compiler/src/universe/class_set.dart';
12 import 'package:compiler/src/world.dart' show ClassWorld; 14 import 'package:compiler/src/world.dart' show ClassWorld;
13 15
14 void main() { 16 void main() {
15 asyncTest(() => TypeEnvironment.create(r""" 17 asyncTest(() async {
18 await testClassSets();
19 await testProperties();
20 });
21 }
22
23 testClassSets() async {
24 var env = await TypeEnvironment.create(r"""
16 class A {} 25 class A {}
17 class B {} 26 class B {}
18 class C_Super extends A {} 27 class C_Super extends A {}
19 class C extends C_Super {} 28 class C extends C_Super {}
20 class D implements A {} 29 class D implements A {}
21 class E extends B implements A {} 30 class E extends B implements A {}
22 class F extends Object with A implements B {} 31 class F extends Object with A implements B {}
23 class G extends Object with A, B {} 32 class G extends Object with A, B {}
24 """, 33 """,
25 mainSource: r""" 34 mainSource: r"""
26 main() { 35 main() {
27 new A(); 36 new A();
28 new B(); 37 new B();
29 new C(); 38 new C();
30 new D(); 39 new D();
31 new E(); 40 new E();
32 new F(); 41 new F();
33 new G(); 42 new G();
34 } 43 }
35 """, 44 """,
36 useMockCompiler: false).then((env) { 45 useMockCompiler: false);
37 ClassWorld classWorld = env.compiler.world; 46 ClassWorld classWorld = env.compiler.world;
38 47
39 ClassElement Object_ = env.getElement("Object"); 48 ClassElement Object_ = env.getElement("Object");
40 ClassElement A = env.getElement("A"); 49 ClassElement A = env.getElement("A");
41 ClassElement B = env.getElement("B"); 50 ClassElement B = env.getElement("B");
42 ClassElement C = env.getElement("C"); 51 ClassElement C = env.getElement("C");
43 ClassElement D = env.getElement("D"); 52 ClassElement D = env.getElement("D");
44 ClassElement E = env.getElement("E"); 53 ClassElement E = env.getElement("E");
45 ClassElement F = env.getElement("F"); 54 ClassElement F = env.getElement("F");
46 ClassElement G = env.getElement("G"); 55 ClassElement G = env.getElement("G");
47 56
48 void check( 57 void checkClasses(
49 String property, 58 String property,
50 ClassElement cls, 59 ClassElement cls,
51 Iterable<ClassElement> foundClasses, 60 Iterable<ClassElement> foundClasses,
52 List<ClassElement> expectedClasses, 61 List<ClassElement> expectedClasses,
53 {bool exact: true}) { 62 {bool exact: true}) {
54 for (ClassElement expectedClass in expectedClasses) { 63
55 Expect.isTrue(foundClasses.contains(expectedClass), 64 for (ClassElement expectedClass in expectedClasses) {
56 "Expect $expectedClass in '$property' on $cls. " 65 Expect.isTrue(foundClasses.contains(expectedClass),
57 "Found:\n ${foundClasses.join('\n ')}"); 66 "Expect $expectedClass in '$property' on $cls. "
67 "Found:\n ${foundClasses.join('\n ')}");
68 }
69 if (exact) {
70 Expect.equals(expectedClasses.length, foundClasses.length,
71 "Unexpected classes "
72 "${foundClasses.where((c) => !expectedClasses.contains(c))} "
73 "in '$property' on $cls.");
74 }
75 }
76
77 void check(
78 String property,
79 ClassElement cls,
80 Iterable<ClassElement> foundClasses,
81 List<ClassElement> expectedClasses,
82 {bool exact: true,
83 void forEach(ClassElement cls, ForEachFunction f),
84 int getCount(ClassElement cls)}) {
85 checkClasses(property, cls, foundClasses, expectedClasses, exact: exact);
86
87 if (forEach != null) {
88 List<ClassElement> visited = <ClassElement>[];
89 forEach(cls, (ClassElement c) {
90 visited.add(c);
91 });
92 checkClasses(
93 'forEach($property)', cls, visited, expectedClasses, exact: exact);
94 }
95
96 if (getCount != null && exact) {
97 int count = getCount(cls);
98 Expect.equals(expectedClasses.length, count,
99 "Unexpected class count in '$property' on $cls.");
100 }
101
102 }
103
104 void testSubclasses(
105 ClassElement cls,
106 List<ClassElement> expectedClasses,
107 {bool exact: true}) {
108 check(
109 'subclassesOf',
110 cls,
111 classWorld.subclassesOf(cls),
112 expectedClasses,
113 exact: exact);
114 }
115
116 void testStrictSubclasses(
117 ClassElement cls,
118 List<ClassElement> expectedClasses,
119 {bool exact: true}) {
120 check(
121 'strictSubclassesOf',
122 cls,
123 classWorld.strictSubclassesOf(cls),
124 expectedClasses,
125 exact: exact,
126 forEach: classWorld.forEachStrictSubclassOf,
127 getCount: classWorld.strictSubclassCount);
128 }
129
130 void testStrictSubtypes(
131 ClassElement cls,
132 List<ClassElement> expectedClasses,
133 {bool exact: true}) {
134 check(
135 'strictSubtypesOf',
136 cls,
137 classWorld.strictSubtypesOf(cls),
138 expectedClasses,
139 exact: exact,
140 forEach: classWorld.forEachStrictSubtypeOf,
141 getCount: classWorld.strictSubtypeCount);
142 }
143
144 void testMixinUses(
145 ClassElement cls,
146 List<ClassElement> expectedClasses,
147 {bool exact: true}) {
148 check(
149 'mixinUsesOf',
150 cls,
151 classWorld.mixinUsesOf(cls),
152 expectedClasses,
153 exact: exact);
154 }
155
156 testSubclasses(Object_, [A, B, C, D, E, F, G], exact: false);
157 testSubclasses(A, [A, C]);
158 testSubclasses(B, [B, E]);
159 testSubclasses(C, [C]);
160 testSubclasses(D, [D]);
161 testSubclasses(E, [E]);
162 testSubclasses(F, [F]);
163 testSubclasses(G, [G]);
164
165 testStrictSubclasses(Object_, [A, B, C, D, E, F, G], exact: false);
166 testStrictSubclasses(A, [C]);
167 testStrictSubclasses(B, [E]);
168 testStrictSubclasses(C, []);
169 testStrictSubclasses(D, []);
170 testStrictSubclasses(E, []);
171 testStrictSubclasses(F, []);
172 testStrictSubclasses(G, []);
173
174 testStrictSubtypes(Object_, [A, B, C, D, E, F, G], exact: false);
175 testStrictSubtypes(A, [C, D, E, F, G]);
176 testStrictSubtypes(B, [E, F, G]);
177 testStrictSubtypes(C, []);
178 testStrictSubtypes(D, []);
179 testStrictSubtypes(E, []);
180 testStrictSubtypes(F, []);
181 testStrictSubtypes(G, []);
182
183 testMixinUses(Object_, []);
184 testMixinUses(A, [F.superclass, G.superclass.superclass]);
185 testMixinUses(B, [G.superclass]);
186 testMixinUses(C, []);
187 testMixinUses(D, []);
188 testMixinUses(E, []);
189 testMixinUses(F, []);
190 testMixinUses(G, []);
191 }
192
193 testProperties() async {
194 var env = await TypeEnvironment.create(r"""
195 class A {}
196 class A1 extends A {}
197 class A2 implements A {}
198 class A3 extends Object with A {}
199
200 class B {}
201 class B1 extends B {}
202 class B2 implements B {}
203 class B3 extends Object with B {}
204
205 class C {}
206 class C1 extends C {}
207 class C2 implements C {}
208 class C3 extends Object with C {}
209
210 class D {}
211 class D1 extends D {}
212 class D2 implements D {}
213 class D3 extends Object with D {}
214
215 class E {}
216 class E1 extends E {}
217 class E2 implements E {}
218 class E3 extends Object with E {}
219
220 class F {}
221 class F1 extends F {}
222 class F2 implements F {}
223 class F3 extends Object with F {}
224
225 class G {}
226 class G1 extends G {}
227 class G2 extends G1 {}
228 class G3 extends G2 implements G {}
229 class G4 extends G2 with G {}
230
231 class H {}
232 class H1 extends H {}
233 class H2 extends H1 {}
234 class H3 extends H2 implements H {}
235 class H4 extends H2 with H {}
236 """,
237 mainSource: r"""
238 main() {
239 new B();
240 new C1();
241 new D2();
242 new E3();
243 new F1();
244 new F2();
245 new G2();
246 new G3();
247 new H4();
58 } 248 }
59 if (exact) { 249 """,
60 Expect.equals(expectedClasses.length, foundClasses.length, 250 useMockCompiler: false);
61 "Unexpected classes " 251 ClassWorld classWorld = env.compiler.world;
62 "${foundClasses.where((c) => !expectedClasses.contains(c))} " 252
63 "in '$property' on $cls."); 253 check(String name,
64 } 254 {bool hasStrictSubtype,
65 } 255 bool hasOnlySubclasses}) {
66 256 ClassElement cls = env.getElement(name);
67 void testSubclasses( 257 Expect.equals(hasStrictSubtype, classWorld.hasAnyStrictSubtype(cls),
68 ClassElement cls, 258 "Unexpected hasAnyStrictSubtype property on $cls.");
69 List<ClassElement> expectedClasses, 259 Expect.equals(hasOnlySubclasses, classWorld.hasOnlySubclasses(cls),
70 {bool exact: true}) { 260 "Unexpected hasOnlySubclasses property on $cls.");
71 check( 261 }
72 'subclassesOf', 262
73 cls, 263 check("Object", hasStrictSubtype: true, hasOnlySubclasses: true);
74 classWorld.subclassesOf(cls), 264
75 expectedClasses, 265 // No instantiated Ax classes.
76 exact: exact); 266 check("A", hasStrictSubtype: false, hasOnlySubclasses: true);
77 } 267 check("A1", hasStrictSubtype: false, hasOnlySubclasses: true);
78 268 check("A2", hasStrictSubtype: false, hasOnlySubclasses: true);
79 void testStrictSubclasses( 269 check("A3", hasStrictSubtype: false, hasOnlySubclasses: true);
80 ClassElement cls, 270
81 List<ClassElement> expectedClasses, 271 // class B instantiated
82 {bool exact: true}) { 272 check("B", hasStrictSubtype: false, hasOnlySubclasses: true);
83 check( 273 check("B1", hasStrictSubtype: false, hasOnlySubclasses: true);
84 'strictSubclassesOf', 274 check("B2", hasStrictSubtype: false, hasOnlySubclasses: true);
85 cls, 275 check("B3", hasStrictSubtype: false, hasOnlySubclasses: true);
86 classWorld.strictSubclassesOf(cls), 276
87 expectedClasses, 277 // class C1 extends C instantiated
88 exact: exact); 278 check("C", hasStrictSubtype: true, hasOnlySubclasses: true);
89 } 279 check("C1", hasStrictSubtype: false, hasOnlySubclasses: true);
90 280 check("C2", hasStrictSubtype: false, hasOnlySubclasses: true);
91 void testStrictSubtypes( 281 check("C3", hasStrictSubtype: false, hasOnlySubclasses: true);
92 ClassElement cls, 282
93 List<ClassElement> expectedClasses, 283 // class D2 implements D instantiated
94 {bool exact: true}) { 284 check("D", hasStrictSubtype: true, hasOnlySubclasses: false);
95 check( 285 check("D1", hasStrictSubtype: false, hasOnlySubclasses: true);
96 'strictSubtypesOf', 286 check("D2", hasStrictSubtype: false, hasOnlySubclasses: true);
97 cls, 287 check("D3", hasStrictSubtype: false, hasOnlySubclasses: true);
98 classWorld.strictSubtypesOf(cls), 288
99 expectedClasses, 289 // class E2 extends Object with E instantiated
100 exact: exact); 290 check("E", hasStrictSubtype: true, hasOnlySubclasses: false);
101 } 291 check("E1", hasStrictSubtype: false, hasOnlySubclasses: true);
102 292 check("E2", hasStrictSubtype: false, hasOnlySubclasses: true);
103 void testMixinUses( 293 check("E3", hasStrictSubtype: false, hasOnlySubclasses: true);
104 ClassElement cls, 294
105 List<ClassElement> expectedClasses, 295 // class F1 extends F instantiated
106 {bool exact: true}) { 296 // class F2 implements F instantiated
107 check( 297 check("F", hasStrictSubtype: true, hasOnlySubclasses: false);
108 'mixinUsesOf', 298 check("F1", hasStrictSubtype: false, hasOnlySubclasses: true);
109 cls, 299 check("F2", hasStrictSubtype: false, hasOnlySubclasses: true);
110 classWorld.mixinUsesOf(cls), 300 check("F3", hasStrictSubtype: false, hasOnlySubclasses: true);
111 expectedClasses, 301
112 exact: exact); 302 // class G2 extends G1 extends G instantiated
113 } 303 // class G3 extends G2 extends G1 extends G instantiated
114 304 check("G", hasStrictSubtype: true, hasOnlySubclasses: true);
115 testSubclasses(Object_, [A, B, C, D, E, F, G], exact: false); 305 check("G1", hasStrictSubtype: true, hasOnlySubclasses: true);
116 testSubclasses(A, [A, C]); 306 check("G2", hasStrictSubtype: true, hasOnlySubclasses: true);
117 testSubclasses(B, [B, E]); 307 check("G3", hasStrictSubtype: false, hasOnlySubclasses: true);
118 testSubclasses(C, [C]); 308 check("G4", hasStrictSubtype: false, hasOnlySubclasses: true);
119 testSubclasses(D, [D]); 309
120 testSubclasses(E, [E]); 310 // class H4 extends H2 with H extends H1 extends H instantiated
121 testSubclasses(F, [F]); 311 check("H", hasStrictSubtype: true, hasOnlySubclasses: true);
122 testSubclasses(G, [G]); 312 check("H1", hasStrictSubtype: true, hasOnlySubclasses: true);
123 313 check("H2", hasStrictSubtype: true, hasOnlySubclasses: true);
124 testStrictSubclasses(Object_, [A, B, C, D, E, F, G], exact: false); 314 check("H3", hasStrictSubtype: false, hasOnlySubclasses: true);
125 testStrictSubclasses(A, [C]); 315 check("H4", hasStrictSubtype: false, hasOnlySubclasses: true);
126 testStrictSubclasses(B, [E]);
127 testStrictSubclasses(C, []);
128 testStrictSubclasses(D, []);
129 testStrictSubclasses(E, []);
130 testStrictSubclasses(F, []);
131 testStrictSubclasses(G, []);
132
133 testStrictSubtypes(Object_, [A, B, C, D, E, F, G], exact: false);
134 testStrictSubtypes(A, [C, D, E, F, G]);
135 testStrictSubtypes(B, [E, F, G]);
136 testStrictSubtypes(C, []);
137 testStrictSubtypes(D, []);
138 testStrictSubtypes(E, []);
139 testStrictSubtypes(F, []);
140 testStrictSubtypes(G, []);
141
142 testMixinUses(Object_, []);
143 testMixinUses(A, [F.superclass, G.superclass.superclass]);
144 testMixinUses(B, [G.superclass]);
145 testMixinUses(C, []);
146 testMixinUses(D, []);
147 testMixinUses(E, []);
148 testMixinUses(F, []);
149 testMixinUses(G, []);
150
151 }));
152 } 316 }
OLDNEW
« pkg/compiler/lib/src/universe/class_set.dart ('K') | « tests/compiler/dart2js/class_set_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698