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

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

Issue 11348067: Fix operator handling. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Handle []= properly Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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:uri"; 5 import "dart:uri";
6 import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dar t"; 6 import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dar t";
7 import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.da rt'; 7 import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.da rt';
8 import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart'; 8 import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart';
9 import '../../../sdk/lib/_internal/compiler/implementation/types/types.dart'; 9 import '../../../sdk/lib/_internal/compiler/implementation/types/types.dart';
10 import '../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart'; 10 import '../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart';
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 * occurence of [: variable; :] in the program is the concrete type 104 * occurence of [: variable; :] in the program is the concrete type
105 * made of [baseTypes]. 105 * made of [baseTypes].
106 */ 106 */
107 void checkNodeHasType(String variable, List<BaseType> baseTypes) { 107 void checkNodeHasType(String variable, List<BaseType> baseTypes) {
108 return Expect.equals( 108 return Expect.equals(
109 concreteFrom(baseTypes), 109 concreteFrom(baseTypes),
110 inferrer.inferredTypes[findNode(variable)]); 110 inferrer.inferredTypes[findNode(variable)]);
111 } 111 }
112 112
113 /** 113 /**
114 * Checks that the inferred type of the node corresponding to the last
115 * occurence of [: variable; :] in the program is the unknown concrete type.
116 */
117 void checkNodeHasUnknownType(String variable) {
118 return Expect.isTrue(inferrer.inferredTypes[findNode(variable)].isUnkown());
119 }
120
121 /**
114 * Checks that [: className#fieldName :]'s inferred type is the concrete type 122 * Checks that [: className#fieldName :]'s inferred type is the concrete type
115 * made of [baseTypes]. 123 * made of [baseTypes].
116 */ 124 */
117 void checkFieldHasType(String className, String fieldName, 125 void checkFieldHasType(String className, String fieldName,
118 List<BaseType> baseTypes) { 126 List<BaseType> baseTypes) {
119 return Expect.equals( 127 return Expect.equals(
120 concreteFrom(baseTypes), 128 concreteFrom(baseTypes),
121 inferrer.inferredFieldTypes[findField(className, fieldName)]); 129 inferrer.inferredFieldTypes[findField(className, fieldName)]);
122 } 130 }
131
132 /**
133 * Checks that [: className#fieldName :]'s inferred type is the unknown
134 * concrete type.
135 */
136 void checkFieldHasUknownType(String className, String fieldName) {
137 return Expect.isTrue(
138 inferrer.inferredFieldTypes[findField(className, fieldName)]
139 .isUnkown());
140 }
123 } 141 }
124 142
125 const String CORELIB = r''' 143 const String CORELIB = r'''
126 print(var obj) {} 144 print(var obj) {}
127 abstract class num { operator +(x); operator *(x); operator -(x); } 145 abstract class num {
146 operator +(x);
147 operator *(x);
148 operator -(x);
149 operator ==(x);
150 }
128 abstract class int extends num { } 151 abstract class int extends num { }
129 abstract class double extends num { } 152 abstract class double extends num { }
130 class bool {} 153 class bool {}
131 class String {} 154 class String {}
132 class Object {} 155 class Object {}
133 class Function {} 156 class Function {}
134 abstract class List {} 157 abstract class List {}
135 abstract class Map {} 158 abstract class Map {}
136 class Closure {} 159 class Closure {}
137 class Null {} 160 class Null {}
138 class Type {} 161 class Type {}
139 class Dynamic_ {} 162 class Dynamic_ {}
140 bool identical(Object a, Object b) {}'''; 163 bool identical(Object a, Object b) {}''';
141 164
142 AnalysisResult analyze(String code) { 165 AnalysisResult analyze(String code) {
143 Uri uri = new Uri.fromComponents(scheme: 'source'); 166 Uri uri = new Uri.fromComponents(scheme: 'source');
144 MockCompiler compiler = new MockCompiler(coreSource: CORELIB, 167 MockCompiler compiler = new MockCompiler(coreSource: CORELIB,
145 enableConcreteTypeInference: true); 168 enableConcreteTypeInference: true);
146 compiler.sourceFiles[uri.toString()] = new SourceFile(uri.toString(), code); 169 compiler.sourceFiles[uri.toString()] = new SourceFile(uri.toString(), code);
147 compiler.runCompiler(uri); 170 compiler.runCompiler(uri);
148 return new AnalysisResult(compiler); 171 return new AnalysisResult(compiler);
149 } 172 }
150 173
174 testDynamicBackDoor() {
175 final String source = r"""
176 main () {
177 var x = "__dynamic_for_test";
178 x;
179 }
180 """;
181 AnalysisResult result = analyze(source);
182 result.checkNodeHasUnknownType('x');
183 }
184
151 testLiterals() { 185 testLiterals() {
152 final String source = r""" 186 final String source = r"""
153 main() { 187 main() {
154 var v1 = 42; 188 var v1 = 42;
155 var v2 = 42.0; 189 var v2 = 42.0;
156 var v3 = 'abc'; 190 var v3 = 'abc';
157 var v4 = true; 191 var v4 = true;
158 var v5 = null; 192 var v5 = null;
159 v1; v2; v3; v4; v5; 193 v1; v2; v3; v4; v5;
160 } 194 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 294 }
261 foo; bar; 295 foo; bar;
262 } 296 }
263 """; 297 """;
264 AnalysisResult result = analyze(source); 298 AnalysisResult result = analyze(source);
265 result.checkNodeHasType('foo', [result.base('A'), result.base('B')]); 299 result.checkNodeHasType('foo', [result.base('A'), result.base('B')]);
266 // Check that the condition is evaluated. 300 // Check that the condition is evaluated.
267 result.checkNodeHasType('bar', [result.int]); 301 result.checkNodeHasType('bar', [result.int]);
268 } 302 }
269 303
304 testToplevelVariable() {
305 final String source = r"""
306 final top = 'abc';
307 main() { var foo = top; foo; }
308 """;
309 AnalysisResult result = analyze(source);
310 result.checkNodeHasType('foo', [result.string]);
311 }
312
270 testNonRecusiveFunction() { 313 testNonRecusiveFunction() {
271 final String source = r""" 314 final String source = r"""
272 f(x, y) => true ? x : y; 315 f(x, y) => true ? x : y;
273 main() { var foo = f(42, "abc"); foo; } 316 main() { var foo = f(42, "abc"); foo; }
274 """; 317 """;
275 AnalysisResult result = analyze(source); 318 AnalysisResult result = analyze(source);
276 result.checkNodeHasType('foo', [result.int, result.string]); 319 result.checkNodeHasType('foo', [result.int, result.string]);
277 } 320 }
278 321
279 testRecusiveFunction() { 322 testRecusiveFunction() {
(...skipping 11 matching lines...) Expand all
291 testMutuallyRecusiveFunction() { 334 testMutuallyRecusiveFunction() {
292 final String source = r""" 335 final String source = r"""
293 f() => true ? 42 : g(); 336 f() => true ? 42 : g();
294 g() => true ? "abc" : f(); 337 g() => true ? "abc" : f();
295 main() { var foo = f(); foo; } 338 main() { var foo = f(); foo; }
296 """; 339 """;
297 AnalysisResult result = analyze(source); 340 AnalysisResult result = analyze(source);
298 result.checkNodeHasType('foo', [result.int, result.string]); 341 result.checkNodeHasType('foo', [result.int, result.string]);
299 } 342 }
300 343
344 testSimpleSend() {
345 final String source = r"""
346 class A {
347 f(x) => x;
348 }
349 class B {
350 f(x) => 'abc';
351 }
352 class C {
353 f(x) => 3.14;
354 }
355 class D {
356 var f; // we check that this field is ignored in calls to dynamic.f()
357 D(this.f);
358 }
359 main() {
360 new B(); new D(42); // we instantiate B and D but not C
361 var foo = new A().f(42);
362 var bar = "__dynamic_for_test".f(42);
363 foo; bar;
364 }
365 """;
366 AnalysisResult result = analyze(source);
367 result.checkNodeHasType('foo', [result.int]);
368 result.checkNodeHasType('bar', [result.int, result.string]);
369 }
370
371 testSendToClosureField() {
372 final String source = r"""
373 f(x) => x;
374 class A {
375 var g;
376 A(this.g);
377 }
378 main() {
379 var foo = new A(f).g(42);
380 foo;
381 }
382 """;
383 AnalysisResult result = analyze(source);
384 result.checkNodeHasType('foo', [result.int]);
385 }
386
301 testSendToThis1() { 387 testSendToThis1() {
302 final String source = r""" 388 final String source = r"""
303 class A { 389 class A {
304 A(); 390 A();
305 f() => g(); 391 f() => g();
306 g() => 42; 392 g() => 42;
307 } 393 }
308 main() { 394 main() {
309 var foo = new A().f(); 395 var foo = new A().f();
310 foo; 396 foo;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 } 435 }
350 436
351 testGetters() { 437 testGetters() {
352 final String source = r""" 438 final String source = r"""
353 class A { 439 class A {
354 var x; 440 var x;
355 A(this.x); 441 A(this.x);
356 get y => x; 442 get y => x;
357 get z => y; 443 get z => y;
358 } 444 }
445 class B {
446 var x;
447 B(this.x);
448 }
359 main() { 449 main() {
360 var a = new A(42); 450 var a = new A(42);
451 var b = new B('abc');
361 var foo = a.x; 452 var foo = a.x;
362 var bar = a.y; 453 var bar = a.y;
363 var baz = a.z; 454 var baz = a.z;
364 foo; bar; baz; 455 var qux = "__dynamic_for_test".x;
456 foo; bar; baz; qux;
365 } 457 }
366 """; 458 """;
367 AnalysisResult result = analyze(source); 459 AnalysisResult result = analyze(source);
368 result.checkNodeHasType('foo', [result.int]); 460 result.checkNodeHasType('foo', [result.int]);
369 result.checkNodeHasType('bar', [result.int]); 461 result.checkNodeHasType('bar', [result.int]);
370 result.checkNodeHasType('baz', [result.int]); 462 result.checkNodeHasType('baz', [result.int]);
463 result.checkNodeHasType('qux', [result.int, result.string]);
371 } 464 }
372 465
373 testSetters() { 466 testSetters() {
374 final String source = r""" 467 final String source = r"""
375 class A { 468 class A {
376 var x; 469 var x;
377 var w; 470 var w;
378 A(this.x, this.w); 471 A(this.x, this.w);
379 set y(a) { x = a; z = a; } 472 set y(a) { x = a; z = a; }
380 set z(a) { w = a; } 473 set z(a) { w = a; }
381 } 474 }
475 class B {
476 var x;
477 B(this.x);
478 }
382 main() { 479 main() {
383 var a = new A(42, 42); 480 var a = new A(42, 42);
481 var b = new B(42);
384 a.x = 'abc'; 482 a.x = 'abc';
385 a.y = true; 483 a.y = true;
484 "__dynamic_for_test".x = null;
485 "__dynamic_for_test".y = 3.14;
386 } 486 }
387 """; 487 """;
388 AnalysisResult result = analyze(source); 488 AnalysisResult result = analyze(source);
389 result.checkFieldHasType('A', 'x', [result.int, result.string, result.bool]); 489 result.checkFieldHasType('B', 'x',
390 result.checkFieldHasType('A', 'w', [result.int, result.bool]); 490 [result.int, // new B(42)
491 result.nullType]); // dynamic.x = null
492 result.checkFieldHasType('A', 'x',
493 [result.int, // new A(42, ...)
494 result.string, // a.x = 'abc'
495 result.bool, // a.y = true
496 result.nullType, // dynamic.x = null
497 result.double]); // dynamic.y = 3.14
498 result.checkFieldHasType('A', 'w',
499 [result.int, // new A(..., 42)
500 result.bool, // a.y = true
501 result.double]); // dynamic.y = double
391 } 502 }
392 503
393 testNamedParameters() { 504 testNamedParameters() {
394 final String source = r""" 505 final String source = r"""
395 class A { 506 class A {
396 var x, y, z, w; 507 var x, y, z, w;
397 A(this.x, {this.y, this.z, this.w}); 508 A(this.x, {this.y, this.z, this.w});
398 } 509 }
399 main() { 510 main() {
400 new A(42); 511 new A(42);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 var x = new A() < "foo"; 631 var x = new A() < "foo";
521 var y = new A() << "foo"; 632 var y = new A() << "foo";
522 x; y; 633 x; y;
523 } 634 }
524 """; 635 """;
525 AnalysisResult result = analyze(source); 636 AnalysisResult result = analyze(source);
526 result.checkNodeHasType('x', [result.int]); 637 result.checkNodeHasType('x', [result.int]);
527 result.checkNodeHasType('y', [result.string]); 638 result.checkNodeHasType('y', [result.string]);
528 } 639 }
529 640
641 testSetIndexOperator() {
642 final String source = r"""
643 class A {
644 var witness1;
645 var witness2;
646 operator []=(i, x) { witness1 = i; witness2 = x; }
647 }
648 main() {
649 var x = new A()[42] = "abc";
650 x;
651 }
652 """;
653 AnalysisResult result = analyze(source);
654 result.checkNodeHasType('x', [result.string]);
655 // TODO(polux): the two following results should be {null, string}, see
656 // fieldInitialization().
karlklose 2012/11/28 08:24:07 fieldInitialization() -> testFieldInitialization?
polux 2012/11/29 14:18:39 Done.
657 result.checkFieldHasType('A', 'witness1', [result.int]);
658 result.checkFieldHasType('A', 'witness2', [result.string]);
659 }
660
530 testCompoundOperators1() { 661 testCompoundOperators1() {
531 final String source = r""" 662 final String source = r"""
532 class A { 663 class A {
533 operator +(x) => "foo"; 664 operator +(x) => "foo";
534 } 665 }
535 main() { 666 main() {
536 var x1 = 1; x1++; 667 var x1 = 1; x1++;
537 var x2 = 1; ++x2; 668 var x2 = 1; ++x2;
538 var x3 = new A(); x3++; 669 var x3 = 1; x3 += 42;
karlklose 2012/11/28 08:24:07 Perhaps these statements should all have their own
polux 2012/11/29 14:18:39 Done.
539 var x4 = new A(); ++x4; 670 var x4 = new A(); x4++;
671 var x5 = new A(); ++x5;
672 var x6 = new A(); x6 += true;
540 673
541 x1; x2; x3; x4; 674 x1; x2; x3; x4; x5; x6;
542 } 675 }
543 """; 676 """;
544 AnalysisResult result = analyze(source); 677 AnalysisResult result = analyze(source);
545 result.checkNodeHasType('x1', [result.int]); 678 result.checkNodeHasType('x1', [result.int]);
546 result.checkNodeHasType('x2', [result.int]); 679 result.checkNodeHasType('x2', [result.int]);
547 result.checkNodeHasType('x3', [result.string]); 680 result.checkNodeHasType('x3', [result.int]);
548 result.checkNodeHasType('x4', [result.string]); 681 result.checkNodeHasType('x4', [result.string]);
682 result.checkNodeHasType('x5', [result.string]);
683 result.checkNodeHasType('x6', [result.string]);
549 } 684 }
550 685
551 686
552 testCompoundOperators2() { 687 testCompoundOperators2() {
553 final String source = r""" 688 final String source = r"""
554 class A { 689 class A {
555 var xx; 690 var xx;
691 var yy;
556 var witness1; 692 var witness1;
557 var witness2; 693 var witness2;
694 var witness3;
695 var witness4;
558 696
559 A(this.xx); 697 A(this.xx, this.yy);
560 get x { witness1 = "foo"; return xx; } 698 get x { witness1 = "foo"; return xx; }
561 set x(y) { witness2 = "foo"; xx = y; } 699 set x(a) { witness2 = "foo"; xx = a; }
700 get y { witness3 = "foo"; return yy; }
701 set y(a) { witness4 = "foo"; yy = a; }
562 } 702 }
563 main () { 703 main () {
564 var a = new A(1); 704 var a = new A(1, 1);
565 a.x++; 705 a.x++;
706 a.y++;
566 } 707 }
567 """; 708 """;
568 AnalysisResult result = analyze(source); 709 AnalysisResult result = analyze(source);
569 result.checkFieldHasType('A', 'xx', [result.int]); 710 result.checkFieldHasType('A', 'xx', [result.int]);
570 // TODO(polux): the two following results should be {null, string}, see 711 result.checkFieldHasType('A', 'yy', [result.int]);
712 // TODO(polux): the four following results should be {null, string}, see
571 // fieldInitialization(). 713 // fieldInitialization().
572 result.checkFieldHasType('A', 'witness1', [result.string]); 714 result.checkFieldHasType('A', 'witness1', [result.string]);
573 result.checkFieldHasType('A', 'witness2', [result.string]); 715 result.checkFieldHasType('A', 'witness2', [result.string]);
716 result.checkFieldHasType('A', 'witness3', [result.string]);
717 result.checkFieldHasType('A', 'witness4', [result.string]);
718 }
719
720 testDisequality() {
karlklose 2012/11/28 08:24:07 'Disequality' -> 'Inequality'.
polux 2012/11/29 14:18:39 In automated theorem proving, disequalities are in
721 final String source = r"""
722 class A {
723 var witness;
724 operator ==(x) { witness = "foo"; return "abc"; }
725 }
726 class B {
727 operator ==(x) { throw "error"; }
728 }
729 main() {
730 var foo = 1 != 2;
731 var bar = new A() != 2;
732 var baz = new B() != 2;
733 foo; bar; baz;
734 }
735 """;
736 AnalysisResult result = analyze(source);
737 result.checkNodeHasType('foo', [result.bool]);
738 result.checkNodeHasType('bar', [result.bool]);
739 result.checkNodeHasType('baz', []);
740 // TODO(polux): the following result should be {null, string}, see
karlklose 2012/11/28 08:24:07 {null, string} -> [:[null, string]:]
polux 2012/11/29 14:18:39 Done. Is [: :] used in non dartdoc comments too?
741 // fieldInitialization().
742 result.checkFieldHasType('A', 'witness', [result.string]);
574 } 743 }
575 744
576 testFieldInitialization() { 745 testFieldInitialization() {
577 final String source = r""" 746 final String source = r"""
578 class A { 747 class A {
579 var x; 748 var x;
580 var y = 1; 749 var y = 1;
581 } 750 }
582 main () { 751 main () {
583 new A(); 752 new A();
584 } 753 }
585 """; 754 """;
586 AnalysisResult result = analyze(source); 755 AnalysisResult result = analyze(source);
587 result.checkFieldHasType('A', 'x', [result.nullType]); 756 result.checkFieldHasType('A', 'x', [result.nullType]);
588 result.checkFieldHasType('A', 'y', [result.int]); 757 result.checkFieldHasType('A', 'y', [result.int]);
589 } 758 }
590 759
760 testDynamicIsAbsorbing() {
761 final String source = r"""
762 main () {
763 var x = 1;
764 if (true) {
765 x = "__dynamic_for_test";
766 } else {
767 x = 42;
768 }
769 x;
770 }
771 """;
772 AnalysisResult result = analyze(source);
773 result.checkNodeHasUnknownType('x');
774 }
775
591 void main() { 776 void main() {
777 testDynamicBackDoor();
592 testLiterals(); 778 testLiterals();
593 testRedefinition(); 779 testRedefinition();
594 testIfThenElse(); 780 testIfThenElse();
595 testTernaryIf(); 781 testTernaryIf();
596 testWhile(); 782 testWhile();
597 testFor1(); 783 testFor1();
598 testFor2(); 784 testFor2();
785 // testToplevelVariable(); // toplevel variables are not yet supported
599 testNonRecusiveFunction(); 786 testNonRecusiveFunction();
600 testRecusiveFunction(); 787 testRecusiveFunction();
601 testMutuallyRecusiveFunction(); 788 testMutuallyRecusiveFunction();
789 testSimpleSend();
790 // testSendToClosureField(); // closures are not yet supported
602 testSendToThis1(); 791 testSendToThis1();
603 testSendToThis2(); 792 testSendToThis2();
604 testConstructor(); 793 testConstructor();
605 testGetters(); 794 testGetters();
606 testSetters(); 795 testSetters();
607 testNamedParameters(); 796 testNamedParameters();
608 testListLiterals(); 797 testListLiterals();
609 testMapLiterals(); 798 testMapLiterals();
610 testReturn(); 799 testReturn();
611 // testNoReturn(); // right now we infer the empty type instead of null 800 // testNoReturn(); // right now we infer the empty type instead of null
612 testArithmeticOperators(); 801 testArithmeticOperators();
613 testOperators(); 802 testOperators();
614 testCompoundOperators1(); 803 testCompoundOperators1();
615 testCompoundOperators2(); 804 testCompoundOperators2();
805 testSetIndexOperator();
806 testDisequality();
616 // testFieldInitialization(); // TODO(polux) 807 // testFieldInitialization(); // TODO(polux)
808 testDynamicIsAbsorbing();
617 } 809 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698