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

Side by Side Diff: test/checker/inferred_type_test.dart

Issue 1011933002: Handle type-inference on fields, consts, and inferable overrides (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 9 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
« lib/src/checker/resolver.dart ('K') | « lib/src/testing.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /// Tests for type inference. 5 /// Tests for type inference.
6 library dev_compiler.test.inferred_type_test; 6 library dev_compiler.test.inferred_type_test;
7 7
8 import 'package:unittest/compact_vm_config.dart'; 8 import 'package:unittest/compact_vm_config.dart';
9 import 'package:unittest/unittest.dart'; 9 import 'package:unittest/unittest.dart';
10 10
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 static var x = 2; 154 static var x = 2;
155 static var y = A.x; 155 static var y = A.x;
156 } 156 }
157 157
158 test1() { 158 test1() {
159 A.x = /*severe:StaticTypeError*/"hi"; 159 A.x = /*severe:StaticTypeError*/"hi";
160 A.y = "hi"; 160 A.y = "hi";
161 } 161 }
162 ''' 162 '''
163 }); 163 });
164
165 // Allowed with special flag. Note, while the flag is generally not stable,
166 // we can use it in this test because it is stable within a library (order
167 // matches program order).
168 testChecker({
169 '/main.dart': '''
170 var x = 2;
171 var y = x;
172
173 test1() {
174 x = /*severe:StaticTypeError*/"hi";
175 y = /*severe:StaticTypeError*/"hi";
176 }
177 '''
178 }, inferInNonStableOrder: true);
179
180 testChecker({
181 '/main.dart': '''
182 class A {
183 static var x = 2;
184 static var y = A.x;
185 }
186
187 test1() {
188 A.x = /*severe:StaticTypeError*/"hi";
189 A.y = /*severe:StaticTypeError*/"hi";
190 }
191 '''
192 }, inferInNonStableOrder: true);
193 }); 164 });
194 165
195 test('not ok to infer from variables in non-cycle libs', () { 166 test('not ok to infer from variables in non-cycle libs', () {
196 testChecker({ 167 testChecker({
197 '/a.dart': ''' 168 '/a.dart': '''
198 var x = 2; 169 var x = 2;
199 ''', 170 ''',
200 '/main.dart': ''' 171 '/main.dart': '''
201 import 'a.dart'; 172 import 'a.dart';
202 var y = x; 173 var y = x;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 B.y = /*severe:StaticTypeError*/"hi"; 224 B.y = /*severe:StaticTypeError*/"hi";
254 } 225 }
255 ''' 226 '''
256 }, inferStaticsFromIdentifiers: true); 227 }, inferStaticsFromIdentifiers: true);
257 }); 228 });
258 229
259 test('do not infer from variables in cycle libs', () { 230 test('do not infer from variables in cycle libs', () {
260 testChecker({ 231 testChecker({
261 '/a.dart': ''' 232 '/a.dart': '''
262 import 'main.dart'; 233 import 'main.dart';
263 var x = 2; 234 var x = 2; // ok to infer
264 ''', 235 ''',
265 '/main.dart': ''' 236 '/main.dart': '''
266 import 'a.dart'; 237 import 'a.dart';
267 var y = x; 238 var y = x; // not ok to infer yet
268 239
269 test1() { 240 test1() {
270 int t = 3; 241 int t = 3;
271 t = /*info:DownCast*/x; 242 t = x;
272 t = /*info:DownCast*/y; 243 t = /*info:DownCast*/y;
273 } 244 }
274 ''' 245 '''
275 }, inferStaticsFromIdentifiers: true); 246 }, inferStaticsFromIdentifiers: true);
276 247
277 testChecker({ 248 testChecker({
278 '/a.dart': ''' 249 '/a.dart': '''
279 import 'main.dart'; 250 import 'main.dart';
280 class A { static var x = 2; } 251 class A { static var x = 2; }
281 ''', 252 ''',
282 '/main.dart': ''' 253 '/main.dart': '''
283 import 'a.dart'; 254 import 'a.dart';
284 class B { static var y = A.x; } 255 class B { static var y = A.x; }
285 256
286 test1() { 257 test1() {
287 int t = 3; 258 int t = 3;
288 t = /*info:DownCast*/A.x; 259 t = A.x;
289 t = /*info:DownCast*/A.y; 260 t = /*info:DownCast*/A.y;
290 } 261 }
291 ''' 262 '''
292 }, inferStaticsFromIdentifiers: true); 263 }, inferStaticsFromIdentifiers: true);
293 }); 264 });
294 265
295 test('do not infer from static and instance fields', () { 266 test('do not infer from static and instance fields', () {
296 testChecker({ 267 testChecker({
297 '/a.dart': ''' 268 '/a.dart': '''
298 import 'b.dart'; 269 import 'b.dart';
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 test1() { 312 test1() {
342 int x = 0; 313 int x = 0;
343 // inference in A now works. 314 // inference in A now works.
344 x = A.a1; 315 x = A.a1;
345 x = new A().a2; 316 x = new A().a2;
346 } 317 }
347 ''' 318 '''
348 }, inferStaticsFromIdentifiers: true); 319 }, inferStaticsFromIdentifiers: true);
349 }); 320 });
350 321
351 test('don\'t infer on cycles', () { 322 test('inference uses declared types', () {
323 testChecker({
324 '/main.dart': '''
325 int w = 0;
326 var x = 0;
327
328 var y = w; // y can be inferred because w is typed int.
329 var z = x; // z cannot, because x would be inferred.
330
331 test1() {
332 int a;
333 a = w;
334 a = x;
335 a = y;
336 a = /*info:DownCast*/z;
337 }
338 '''
339 }, inferStaticsFromIdentifiers: true);
340 });
341
342 test('inference in cycles is deterministic', () {
352 testChecker({ 343 testChecker({
353 '/a.dart': ''' 344 '/a.dart': '''
354 import 'b.dart'; 345 import 'b.dart';
355 class A { 346 class A {
356 static final a1 = B.b1; 347 static final a1 = B.b1;
357 final a2 = new B().b2; 348 final a2 = new B().b2;
358 } 349 }
359 ''', 350 ''',
360 '/b.dart': ''' 351 '/b.dart': '''
361 class B { 352 class B {
362 static final b1 = 1; 353 static final b1 = 1;
363 final b2 = 1; 354 final b2 = 1;
364 } 355 }
365 ''', 356 ''',
366 '/c.dart': ''' 357 '/c.dart': '''
367 import "main.dart"; // creates a cycle 358 import "main.dart"; // creates a cycle
368 359
369 class C { 360 class C {
370 static final c1 = 1; 361 static final c1 = 1;
371 final c2 = 1; 362 final c2 = 1;
372 } 363 }
373 ''', 364 ''',
374 '/e.dart': ''' 365 '/e.dart': '''
375 part "e2.dart"; 366 import 'a.dart';
367 part 'e2.dart';
376 368
377 class E { 369 class E {
378 static final e1 = 1; 370 static final e1 = 1;
379 final e2 = 1; 371 static final e2 = F.f1;
372 static final e3 = A.a1;
373 final e4 = 1;
374 final e5 = new F().f2;
375 final e6 = new A().a2;
380 } 376 }
381 ''', 377 ''',
382 '/f.dart': ''' 378 '/f.dart': '''
383 part "f2.dart"; 379 part 'f2.dart';
384 ''', 380 ''',
385 '/e2.dart': ''' 381 '/e2.dart': '''
386 class F { 382 class F {
387 static final f1 = 1; 383 static final f1 = 1;
388 final f2 = 1; 384 final f2 = 1;
389 } 385 }
390 ''', 386 ''',
391 '/main.dart': ''' 387 '/main.dart': '''
392 import "a.dart"; 388 import "a.dart";
393 import "c.dart"; 389 import "c.dart";
394 import "e.dart"; 390 import "e.dart";
395 391
396 class D { 392 class D {
397 static final d1 = A.a1 + 1; 393 static final d1 = A.a1 + 1;
398 static final d2 = C.c1 + 1; 394 static final d2 = C.c1 + 1;
399 final d3 = new A().a2; 395 final d3 = new A().a2;
400 final d4 = new C().c2; 396 final d4 = new C().c2;
401 } 397 }
402 398
403 test1() { 399 test1() {
404 int x = 0; 400 int x = 0;
405 // inference in A works, it's not in a cycle 401 // inference in A works, it's not in a cycle
406 x = A.a1; 402 x = A.a1;
407 x = new A().a2; 403 x = new A().a2;
408 404
409 // inference here or in c.dart is disabled because of the cycle 405 // Within a cycle we allow inference when the RHS is well known, but
410 x = /*info:DownCast*/C.c1; 406 // not when it depends on other fields within the cycle
411 x = /*info:DownCast*/D.d1; 407 x = C.c1;
408 x = D.d1;
412 x = /*info:DownCast*/D.d2; 409 x = /*info:DownCast*/D.d2;
413 x = /*info:DownCast*/new C().c2; 410 x = new C().c2;
414 x = /*info:DownCast*/new D().d3; 411 x = new D().d3;
415 x = /*info:DownCast*/new D().d4; 412 x = /*info:DownCast*/new D().d4;
416 413
417 414
418 // inference in e.dart and f.dart is disabled because they contains 415 // Similarly if the library contains parts.
419 // parts 416 x = E.e1;
420 x = /*info:DownCast*/E.e1; 417 x = /*info:DownCast*/E.e2;
421 x = /*info:DownCast*/new E().e2; 418 x = E.e3;
422 x = /*info:DownCast*/F.f1; 419 x = new E().e4;
423 x = /*info:DownCast*/new F().f2; 420 x = /*info:DownCast*/new E().e5;
421 x = new E().e6;
422 x = F.f1;
423 x = new F().f2;
424 } 424 }
425 ''' 425 '''
426 }, inferStaticsFromIdentifiers: true); 426 }, inferStaticsFromIdentifiers: true);
427 }); 427 });
428 428
429 test('infer from complex expressions if the outer-most value is precise', () { 429 test('infer from complex expressions if the outer-most value is precise', () {
430 testChecker({ 430 testChecker({
431 '/main.dart': ''' 431 '/main.dart': '''
432 class A { int x; B operator+(other) {} } 432 class A { int x; B operator+(other) {} }
433 class B extends A { B(ignore); } 433 class B extends A { B(ignore); }
434 var a = new A(); 434 var a = new A();
435 // Note: it doesn't matter that some of these refer to 'x'. 435 // Note: it doesn't matter that some of these refer to 'x'.
436 var b = new B(x); // allocations 436 var b = new B(x); // allocations
437 var c1 = [x]; // list literals 437 var c1 = [x]; // list literals
438 var c2 = const []; 438 var c2 = const [];
439 var d = {'a': 'b'}; // map literals 439 var d = {'a': 'b'}; // map literals
440 var e = new A()..x = 3; // cascades 440 var e = new A()..x = 3; // cascades
441 var f = 2 + 3; // binary expressions are OK if the left operand 441 var f = 2 + 3; // binary expressions are OK if the left operand
442 // is from a library in a different strongest 442 // is from a library in a different strongest
443 // conected component. 443 // conected component.
444 var g = -3; 444 var g = -3;
445 var h = new A() + 3; 445 var h = new A() + 3;
446 var i = - new A(); 446 var i = - new A();
447 var j = null as B;
447 448
448 test1() { 449 test1() {
449 a = /*severe:StaticTypeError*/"hi"; 450 a = /*severe:StaticTypeError*/"hi";
450 a = new B(3); 451 a = new B(3);
451 b = /*severe:StaticTypeError*/"hi"; 452 b = /*severe:StaticTypeError*/"hi";
452 b = new B(3); 453 b = new B(3);
453 c1 = []; 454 c1 = [];
454 c1 = /*severe:StaticTypeError*/{}; 455 c1 = /*severe:StaticTypeError*/{};
455 c2 = []; 456 c2 = [];
456 c2 = /*severe:StaticTypeError*/{}; 457 c2 = /*severe:StaticTypeError*/{};
457 d = {}; 458 d = {};
458 d = /*severe:StaticTypeError*/3; 459 d = /*severe:StaticTypeError*/3;
459 e = new A(); 460 e = new A();
460 e = /*severe:StaticTypeError*/{}; 461 e = /*severe:StaticTypeError*/{};
461 f = 3; 462 f = 3;
462 f = /*severe:StaticTypeError*/false; 463 f = /*severe:StaticTypeError*/false;
463 g = 1; 464 g = 1;
464 g = /*severe:StaticTypeError*/false; 465 g = /*severe:StaticTypeError*/false;
465 h = /*severe:StaticTypeError*/false; 466 h = /*severe:StaticTypeError*/false;
466 h = new B(); 467 h = new B();
467 i = false; 468 i = false;
469 j = new B();
470 j = /*severe:StaticTypeError*/false;
471 j = /*severe:StaticTypeError*/[];
468 } 472 }
469 ''' 473 '''
470 }); 474 });
471 }); 475 });
472 476
473 test('do not infer if complex expressions read possibly inferred field', () { 477 test('do not infer if complex expressions read possibly inferred field', () {
474 testChecker({ 478 testChecker({
475 '/a.dart': ''' 479 '/a.dart': '''
476 class A { 480 class A {
477 var x = 3; 481 var x = 3;
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 } 809 }
806 810
807 foo () { 811 foo () {
808 int y = /*severe:StaticTypeError*/new B().m(null, null); 812 int y = /*severe:StaticTypeError*/new B().m(null, null);
809 String z = new B().m(null, null); 813 String z = new B().m(null, null);
810 } 814 }
811 ''' 815 '''
812 }, inferFromOverrides: true); 816 }, inferFromOverrides: true);
813 }); 817 });
814 818
815 // TODO(sigmund): enable this test, it's currently flaky (see issue #48). 819 test('infer type regardless of declaration order or cycles', () {
816 skip_test('infer types on generic instantiations in library cycle', () { 820 testChecker({
821 '/b.dart': '''
822 import 'main.dart';
823
824 class B extends A { }
825 ''',
826 '/main.dart': '''
827 import 'b.dart';
828 class C extends B {
829 get x;
830 }
831 class A {
832 int get x;
833 }
834 foo () {
835 int y = new C().x;
836 String y = /*severe:StaticTypeError*/new C().x;
837 }
838 '''
839 }, inferFromOverrides: true);
840 });
841
842 // Note: this is a regression test for a non-deterministic behavior we used to
843 // have with inference in library cycles. If you see this test flake out,
844 // change `test` to `skip_test` and reopen bug #48.
845 test('infer types on generic instantiations in library cycle', () {
817 testChecker({ 846 testChecker({
818 '/a.dart': ''' 847 '/a.dart': '''
819 import 'main.dart'; 848 import 'main.dart';
820 abstract class I<E> { 849 abstract class I<E> {
821 A<E> m(a, String f(v, T e)); 850 A<E> m(a, String f(v, T e));
822 } 851 }
823 ''', 852 ''',
824 '/main.dart': ''' 853 '/main.dart': '''
825 import 'a.dart'; 854 import 'a.dart';
826 855
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 I3 get a => null; 954 I3 get a => null;
926 } 955 }
927 956
928 class C2 extends A implements B { 957 class C2 extends A implements B {
929 /*severe:InvalidMethodOverride*/get a => null; 958 /*severe:InvalidMethodOverride*/get a => null;
930 } 959 }
931 ''' 960 '''
932 }, inferFromOverrides: true); 961 }, inferFromOverrides: true);
933 }); 962 });
934 } 963 }
OLDNEW
« lib/src/checker/resolver.dart ('K') | « lib/src/testing.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698