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

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

Issue 2857943002: Implement KernelNoSuchMethodResolver. (Closed)
Patch Set: Created 3 years, 7 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 import 'dart:async'; 5 import 'dart:async';
6 import 'package:async_helper/async_helper.dart';
7 import 'package:compiler/src/common_elements.dart';
8 import 'package:compiler/src/compiler.dart';
9 import 'package:compiler/src/elements/entities.dart';
10 import 'package:compiler/src/js_backend/no_such_method_registry.dart';
6 import 'package:expect/expect.dart'; 11 import 'package:expect/expect.dart';
7 import 'package:async_helper/async_helper.dart'; 12 import 'kernel/compiler_helper.dart';
8 import 'compiler_helper.dart'; 13 import 'compiler_helper.dart';
9 14
10 Future dummyImplTest() async { 15 class NoSuchMethodInfo {
11 String source = """ 16 final String className;
17 final String superClassName;
18 final bool hasThrowingSyntax;
19 final bool hasForwardingSyntax;
20 final bool isThrowing;
21 final bool isDefault;
22 final bool isOther;
23 final bool isNotApplicable;
24 final bool isComplexNoReturn;
25 final bool isComplexReturn;
26
27 const NoSuchMethodInfo(this.className,
28 {this.superClassName,
29 this.hasThrowingSyntax: false,
30 this.hasForwardingSyntax: false,
31 this.isThrowing: false,
32 this.isDefault: false,
33 this.isOther: false,
34 this.isNotApplicable: false,
35 this.isComplexNoReturn: false,
36 this.isComplexReturn: false});
37 }
38
39 class NoSuchMethodTest {
40 final String code;
41 final List<NoSuchMethodInfo> methods;
42 final bool isNoSuchMethodUsed;
43
44 const NoSuchMethodTest(this.code, this.methods,
45 {this.isNoSuchMethodUsed: false});
46 }
47
48 const List<NoSuchMethodTest> TESTS = const <NoSuchMethodTest>[
49 const NoSuchMethodTest(
50 """
12 class A { 51 class A {
13 foo() => 3; 52 foo() => 3;
14 noSuchMethod(x) => super.noSuchMethod(x); 53 noSuchMethod(x) => super.noSuchMethod(x);
15 } 54 }
16 main() { 55 main() {
17 print(new A().foo()); 56 print(new A().foo());
18 } 57 }
19 """; 58 """,
20 Uri uri = new Uri(scheme: 'source'); 59 const <NoSuchMethodInfo>[
21 var compiler = compilerFor(source, uri); 60 const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
22 await compiler.run(uri); 61 ]),
23 Expect.isFalse(compiler.backend.backendUsage.isNoSuchMethodUsed); 62 const NoSuchMethodTest(
24 ClassElement clsA = findElement(compiler, 'A'); 63 """
25 Expect.isTrue(compiler.backend.noSuchMethodRegistry.defaultImpls
26 .contains(clsA.lookupMember('noSuchMethod')));
27 }
28
29 Future dummyImplTest2() async {
30 String source = """
31 class A extends B { 64 class A extends B {
32 foo() => 3; 65 foo() => 3;
33 noSuchMethod(x) => super.noSuchMethod(x); 66 noSuchMethod(x) => super.noSuchMethod(x);
34 } 67 }
35 class B {} 68 class B {}
36 main() { 69 main() {
37 print(new A().foo()); 70 print(new A().foo());
38 } 71 }
39 """; 72 """,
40 Uri uri = new Uri(scheme: 'source'); 73 const <NoSuchMethodInfo>[
41 var compiler = compilerFor(source, uri); 74 const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
42 await compiler.run(uri); 75 ]),
43 Expect.isFalse(compiler.backend.backendUsage.isNoSuchMethodUsed); 76 const NoSuchMethodTest(
44 ClassElement clsA = findElement(compiler, 'A'); 77 """
45 Expect.isTrue(compiler.backend.noSuchMethodRegistry.defaultImpls
46 .contains(clsA.lookupMember('noSuchMethod')));
47 }
48
49 Future dummyImplTest3() async {
50 String source = """
51 class A extends B { 78 class A extends B {
52 foo() => 3; 79 foo() => 3;
53 noSuchMethod(x) { 80 noSuchMethod(x) {
54 return super.noSuchMethod(x); 81 return super.noSuchMethod(x);
55 } 82 }
56 } 83 }
57 class B {} 84 class B {}
58 main() { 85 main() {
59 print(new A().foo()); 86 print(new A().foo());
60 } 87 }
61 """; 88 """,
62 Uri uri = new Uri(scheme: 'source'); 89 const <NoSuchMethodInfo>[
63 var compiler = compilerFor(source, uri); 90 const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
64 await compiler.run(uri); 91 ]),
65 Expect.isFalse(compiler.backend.backendUsage.isNoSuchMethodUsed); 92 const NoSuchMethodTest(
66 ClassElement clsA = findElement(compiler, 'A'); 93 """
67 Expect.isTrue(compiler.backend.noSuchMethodRegistry.defaultImpls
68 .contains(clsA.lookupMember('noSuchMethod')));
69 }
70
71 Future dummyImplTest4() async {
72 String source = """
73 class A extends B { 94 class A extends B {
74 foo() => 3; 95 foo() => 3;
75 noSuchMethod(x) => super.noSuchMethod(x); 96 noSuchMethod(x) => super.noSuchMethod(x);
76 } 97 }
77 class B { 98 class B {
78 noSuchMethod(x) => super.noSuchMethod(x); 99 noSuchMethod(x) => super.noSuchMethod(x);
79 } 100 }
80 main() { 101 main() {
81 print(new A().foo()); 102 print(new A().foo());
82 } 103 }
83 """; 104 """,
84 Uri uri = new Uri(scheme: 'source'); 105 const <NoSuchMethodInfo>[
85 var compiler = compilerFor(source, uri); 106 const NoSuchMethodInfo('A',
86 await compiler.run(uri); 107 superClassName: 'B', hasForwardingSyntax: true, isDefault: true),
87 Expect.isFalse(compiler.backend.backendUsage.isNoSuchMethodUsed); 108 const NoSuchMethodInfo('B', hasForwardingSyntax: true, isDefault: true),
88 ClassElement clsA = findElement(compiler, 'A'); 109 ]),
89 Expect.isTrue(compiler.backend.noSuchMethodRegistry.defaultImpls 110 const NoSuchMethodTest(
90 .contains(clsA.lookupMember('noSuchMethod'))); 111 """
91 ClassElement clsB = findElement(compiler, 'B');
92 Expect.isTrue(compiler.backend.noSuchMethodRegistry.defaultImpls
93 .contains(clsB.lookupMember('noSuchMethod')));
94 }
95
96 Future dummyImplTest5() async {
97 String source = """
98 class A extends B { 112 class A extends B {
99 foo() => 3; 113 foo() => 3;
100 noSuchMethod(x) => super.noSuchMethod(x); 114 noSuchMethod(x) => super.noSuchMethod(x);
101 } 115 }
102 class B { 116 class B {
103 noSuchMethod(x) => throw 'foo'; 117 noSuchMethod(x) => throw 'foo';
104 } 118 }
105 main() { 119 main() {
106 print(new A().foo()); 120 print(new A().foo());
107 } 121 }
108 """; 122 """,
109 Uri uri = new Uri(scheme: 'source'); 123 const <NoSuchMethodInfo>[
110 var compiler = compilerFor(source, uri); 124 const NoSuchMethodInfo('A',
111 await compiler.run(uri); 125 superClassName: 'B', hasForwardingSyntax: true, isThrowing: true),
112 Expect.isTrue(compiler.backend.backendUsage.isNoSuchMethodUsed); 126 const NoSuchMethodInfo('B', hasThrowingSyntax: true, isThrowing: true),
113 ClassElement clsA = findElement(compiler, 'A'); 127 ],
114 Expect.isTrue(compiler.backend.noSuchMethodRegistry.throwingImpls 128 isNoSuchMethodUsed: true),
115 .contains(clsA.lookupMember('noSuchMethod'))); 129 const NoSuchMethodTest(
116 ClassElement clsB = findElement(compiler, 'B'); 130 """
117 Expect.isTrue(compiler.backend.noSuchMethodRegistry.throwingImpls
118 .contains(clsB.lookupMember('noSuchMethod')));
119 }
120
121 Future dummyImplTest6() async {
122 String source = """
123 class A { 131 class A {
124 noSuchMethod(x) => 3; 132 noSuchMethod(x) => 3;
125 } 133 }
126 main() { 134 main() {
127 print(new A().foo()); 135 print(new A().foo());
128 } 136 }
129 """; 137 """,
130 Uri uri = new Uri(scheme: 'source'); 138 const <NoSuchMethodInfo>[
131 var compiler = compilerFor(source, uri); 139 const NoSuchMethodInfo('A', isOther: true, isComplexReturn: true),
132 await compiler.run(uri); 140 ],
133 Expect.isTrue(compiler.backend.backendUsage.isNoSuchMethodUsed); 141 isNoSuchMethodUsed: true),
134 ClassElement clsA = findElement(compiler, 'A'); 142 const NoSuchMethodTest(
135 Expect.isTrue(compiler.backend.noSuchMethodRegistry.otherImpls 143 """
136 .contains(clsA.lookupMember('noSuchMethod')));
137 }
138
139 Future dummyImplTest7() async {
140 String source = """
141 class A { 144 class A {
142 noSuchMethod(x, [y]) => super.noSuchMethod(x); 145 noSuchMethod(x, [y]) => super.noSuchMethod(x);
143 } 146 }
144 main() { 147 main() {
145 print(new A().foo()); 148 print(new A().foo());
146 } 149 }
147 """; 150 """,
148 Uri uri = new Uri(scheme: 'source'); 151 const <NoSuchMethodInfo>[
149 var compiler = compilerFor(source, uri); 152 const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
150 await compiler.run(uri); 153 ]),
151 Expect.isFalse(compiler.backend.backendUsage.isNoSuchMethodUsed); 154 const NoSuchMethodTest(
152 ClassElement clsA = findElement(compiler, 'A'); 155 """
153 Expect.isTrue(compiler.backend.noSuchMethodRegistry.defaultImpls
154 .contains(clsA.lookupMember('noSuchMethod')));
155 }
156
157 Future dummyImplTest8() async {
158 String source = """
159 class A { 156 class A {
160 noSuchMethod(x, [y]) => super.noSuchMethod(x, y); 157 noSuchMethod(x, [y]) => super.noSuchMethod(x, y);
161 } 158 }
162 main() { 159 main() {
163 print(new A().foo()); 160 print(new A().foo());
164 } 161 }
165 """; 162 """,
166 Uri uri = new Uri(scheme: 'source'); 163 const <NoSuchMethodInfo>[
167 var compiler = compilerFor(source, uri); 164 const NoSuchMethodInfo('A', isOther: true, isComplexNoReturn: true),
168 await compiler.run(uri); 165 ],
169 Expect.isTrue(compiler.backend.backendUsage.isNoSuchMethodUsed); 166 isNoSuchMethodUsed: true),
170 ClassElement clsA = findElement(compiler, 'A'); 167 const NoSuchMethodTest(
171 Expect.isTrue(compiler.backend.noSuchMethodRegistry.otherImpls 168 """
172 .contains(clsA.lookupMember('noSuchMethod')));
173 }
174
175 Future dummyImplTest9() async {
176 String source = """
177 class A { 169 class A {
178 noSuchMethod(x, y) => super.noSuchMethod(x); 170 noSuchMethod(x, y) => super.noSuchMethod(x);
179 } 171 }
180 main() { 172 main() {
181 print(new A().foo()); 173 print(new A().foo());
182 } 174 }
183 """; 175 """,
184 Uri uri = new Uri(scheme: 'source'); 176 const <NoSuchMethodInfo>[
185 var compiler = compilerFor(source, uri); 177 const NoSuchMethodInfo('A',
186 await compiler.run(uri); 178 hasForwardingSyntax: true, isNotApplicable: true),
187 Expect.isFalse(compiler.backend.backendUsage.isNoSuchMethodUsed); 179 ]),
188 ClassElement clsA = findElement(compiler, 'A'); 180 const NoSuchMethodTest(
189 Expect.isTrue(compiler.backend.noSuchMethodRegistry.notApplicableImpls 181 """
190 .contains(clsA.lookupMember('noSuchMethod')));
191 }
192
193 Future dummyImplTest10() async {
194 String source = """
195 class A { 182 class A {
196 noSuchMethod(Invocation x) { 183 noSuchMethod(Invocation x) {
197 throw new UnsupportedException(); 184 throw new UnsupportedException();
198 } 185 }
199 } 186 }
200 main() { 187 main() {
201 print(new A().foo()); 188 print(new A().foo());
202 } 189 }
203 """; 190 """,
204 Uri uri = new Uri(scheme: 'source'); 191 const <NoSuchMethodInfo>[
205 var compiler = compilerFor(source, uri); 192 const NoSuchMethodInfo('A', hasThrowingSyntax: true, isThrowing: true),
206 await compiler.run(uri); 193 ],
207 Expect.isTrue(compiler.backend.backendUsage.isNoSuchMethodUsed); 194 isNoSuchMethodUsed: true),
208 ClassElement clsA = findElement(compiler, 'A'); 195 const NoSuchMethodTest(
209 Expect.isTrue(compiler.backend.noSuchMethodRegistry.throwingImpls 196 """
210 .contains(clsA.lookupMember('noSuchMethod')));
211 }
212
213 Future dummyImplTest11() async {
214 String source = """
215 class A { 197 class A {
216 noSuchMethod(Invocation x) { 198 noSuchMethod(Invocation x) {
217 print('foo'); 199 print('foo');
218 throw 'foo'; 200 throw 'foo';
219 } 201 }
220 } 202 }
221 main() { 203 main() {
222 print(new A().foo()); 204 print(new A().foo());
223 } 205 }
224 """; 206 """,
225 Uri uri = new Uri(scheme: 'source'); 207 const <NoSuchMethodInfo>[
226 var compiler = compilerFor(source, uri); 208 const NoSuchMethodInfo('A', isOther: true, isComplexNoReturn: true),
227 await compiler.run(uri); 209 ],
228 Expect.isTrue(compiler.backend.backendUsage.isNoSuchMethodUsed); 210 isNoSuchMethodUsed: true),
229 ClassElement clsA = findElement(compiler, 'A'); 211 const NoSuchMethodTest(
230 Expect.isTrue(compiler.backend.noSuchMethodRegistry.otherImpls 212 """
231 .contains(clsA.lookupMember('noSuchMethod')));
232 Expect.isTrue(compiler.backend.noSuchMethodRegistry.complexNoReturnImpls
233 .contains(clsA.lookupMember('noSuchMethod')));
234 }
235
236 Future dummyImplTest12() async {
237 String source = """
238 class A { 213 class A {
239 noSuchMethod(Invocation x) { 214 noSuchMethod(Invocation x) {
240 return toString(); 215 return toString();
241 } 216 }
242 } 217 }
243 main() { 218 main() {
244 print(new A().foo()); 219 print(new A().foo());
245 } 220 }
246 """; 221 """,
247 Uri uri = new Uri(scheme: 'source'); 222 const <NoSuchMethodInfo>[
248 var compiler = compilerFor(source, uri); 223 const NoSuchMethodInfo('A', isOther: true, isComplexReturn: true),
249 await compiler.run(uri); 224 ],
250 Expect.isTrue(compiler.backend.backendUsage.isNoSuchMethodUsed); 225 isNoSuchMethodUsed: true),
251 ClassElement clsA = findElement(compiler, 'A'); 226 const NoSuchMethodTest(
252 Expect.isTrue(compiler.backend.noSuchMethodRegistry.otherImpls 227 """
253 .contains(clsA.lookupMember('noSuchMethod')));
254 Expect.isTrue(compiler.backend.noSuchMethodRegistry.complexReturningImpls
255 .contains(clsA.lookupMember('noSuchMethod')));
256 }
257
258 Future dummyImplTest13() async {
259 String source = """
260 class A { 228 class A {
261 noSuchMethod(x) => super.noSuchMethod(x) as dynamic; 229 noSuchMethod(x) => super.noSuchMethod(x) as dynamic;
262 } 230 }
263 main() { 231 main() {
264 print(new A().foo()); 232 print(new A().foo());
265 } 233 }
266 """; 234 """,
267 Uri uri = new Uri(scheme: 'source'); 235 const <NoSuchMethodInfo>[
268 var compiler = compilerFor(source, uri); 236 const NoSuchMethodInfo('A', hasForwardingSyntax: true, isDefault: true),
269 await compiler.run(uri); 237 ]),
270 Expect.isFalse(compiler.backend.backendUsage.isNoSuchMethodUsed); 238 ];
271 ClassElement clsA = findElement(compiler, 'A');
272 Expect.isTrue(compiler.backend.noSuchMethodRegistry.defaultImpls
273 .contains(clsA.lookupMember('noSuchMethod')));
274 }
275 239
276 main() { 240 main() {
277 asyncTest(() async { 241 asyncTest(() async {
278 await dummyImplTest(); 242 for (NoSuchMethodTest test in TESTS) {
279 await dummyImplTest2(); 243 print('---- testing -------------------------------------------------');
280 await dummyImplTest3(); 244 print(test.code);
281 await dummyImplTest4(); 245 Uri uri = new Uri(scheme: 'source');
282 await dummyImplTest5(); 246 Compiler compiler = compilerFor(test.code, uri);
283 await dummyImplTest6(); 247 await compiler.run(uri);
284 await dummyImplTest7(); 248 checkTest(compiler, test, testComplexReturns: true);
285 await dummyImplTest8(); 249 }
286 await dummyImplTest9(); 250
287 await dummyImplTest10(); 251 List<String> sources = <String>[];
288 await dummyImplTest11(); 252 for (NoSuchMethodTest test in TESTS) {
289 await dummyImplTest12(); 253 sources.add(test.code);
290 await dummyImplTest13(); 254 }
255
256 print('---- preparing for kernel tests ----------------------------------');
257 List<CompileFunction> results = await compileMultiple(sources);
258 for (int index = 0; index < results.length; index++) {
259 print('---- testing with kernel --------------------------------------');
260 print(sources[index]);
261 Compiler compiler = await results[index]();
262 // Complex returns are computed during inference.
263 checkTest(compiler, TESTS[index], testComplexReturns: false);
264 }
291 }); 265 });
292 } 266 }
267
268 checkTest(Compiler compiler, NoSuchMethodTest test, {bool testComplexReturns}) {
269 ElementEnvironment elementEnvironment = compiler.elementEnvironment;
270 NoSuchMethodRegistry registry = compiler.backend.noSuchMethodRegistry;
271 NoSuchMethodResolver resolver = registry.resolver;
Siggi Cherem (dart-lang) 2017/05/03 17:29:49 nit: rather than making the resolver public, I'd k
Johnni Winther 2017/05/04 09:13:36 Done.
272 FunctionEntity noSuchMethodObject = elementEnvironment.lookupClassMember(
Siggi Cherem (dart-lang) 2017/05/03 17:29:49 nit: noSuchMethodInObject or ObjectNSM or defaultN
Johnni Winther 2017/05/04 09:13:36 Done.
273 compiler.commonElements.objectClass, 'noSuchMethod');
274
275 // Test [NoSuchMethodResolver] results for each method.
276 for (NoSuchMethodInfo info in test.methods) {
277 ClassEntity cls =
278 elementEnvironment.lookupClass(compiler.mainApp, info.className);
279 Expect.isNotNull(cls, "Class ${info.className} not found.");
280 FunctionEntity noSuchMethod =
281 elementEnvironment.lookupClassMember(cls, 'noSuchMethod');
282 Expect.isNotNull(noSuchMethod, "noSuchMethod not found in $cls.");
283
284 if (info.superClassName == null) {
285 Expect.equals(
286 noSuchMethodObject, resolver.getSuperNoSuchMethod(noSuchMethod));
287 } else {
288 ClassEntity superclass =
289 elementEnvironment.lookupClass(compiler.mainApp, info.superClassName);
290 Expect.isNotNull(
291 superclass, "Superclass ${info.superClassName} not found.");
292 FunctionEntity superNoSuchMethod =
293 elementEnvironment.lookupClassMember(superclass, 'noSuchMethod');
294 Expect.isNotNull(
295 superNoSuchMethod, "noSuchMethod not found in $superclass.");
296 Expect.equals(
297 superNoSuchMethod,
298 resolver.getSuperNoSuchMethod(noSuchMethod),
299 "Unexpected super noSuchMethod for $noSuchMethod.");
300 }
301
302 Expect.equals(
303 info.hasForwardingSyntax,
304 resolver.hasForwardingSyntax(noSuchMethod),
305 "Unexpected hasForwardSyntax result on $noSuchMethod.");
306 Expect.equals(
307 info.hasThrowingSyntax,
308 resolver.hasThrowingSyntax(noSuchMethod),
309 "Unexpected hasThrowingSyntax result on $noSuchMethod.");
310 }
311
312 // Test [NoSuchMethodRegistry] results for each method. These are based on
313 // the [NoSuchMethodResolver] results which are therefore tested for all
314 // methods first.
315 for (NoSuchMethodInfo info in test.methods) {
316 ClassEntity cls =
317 elementEnvironment.lookupClass(compiler.mainApp, info.className);
318 Expect.isNotNull(cls, "Class ${info.className} not found.");
319 FunctionEntity noSuchMethod =
320 elementEnvironment.lookupClassMember(cls, 'noSuchMethod');
321 Expect.isNotNull(noSuchMethod, "noSuchMethod not found in $cls.");
322
323 Expect.equals(info.isDefault, registry.defaultImpls.contains(noSuchMethod),
324 "Unexpected isDefault result on $noSuchMethod.");
325 Expect.equals(
326 info.isThrowing,
327 registry.throwingImpls.contains(noSuchMethod),
328 "Unexpected isThrowing result on $noSuchMethod.");
329 Expect.equals(info.isOther, registry.otherImpls.contains(noSuchMethod),
330 "Unexpected isOther result on $noSuchMethod.");
331 Expect.equals(
332 info.isNotApplicable,
333 registry.notApplicableImpls.contains(noSuchMethod),
334 "Unexpected isNotApplicable result on $noSuchMethod.");
335 if (testComplexReturns) {
336 Expect.equals(
337 info.isComplexNoReturn,
338 registry.complexNoReturnImpls.contains(noSuchMethod),
339 "Unexpected isComplexNoReturn result on $noSuchMethod.");
340 Expect.equals(
341 info.isComplexReturn,
342 registry.complexReturningImpls.contains(noSuchMethod),
343 "Unexpected isComplexReturn result on $noSuchMethod.");
344 }
345 }
346
347 Expect.equals(
348 test.isNoSuchMethodUsed,
349 compiler.backend.backendUsage.isNoSuchMethodUsed,
350 "Unexpected isNoSuchMethodUsed result.");
351 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698