| Index: tests/compiler/dart2js/cpa_inference_test.dart
|
| diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
|
| index 912d349e5d7c1aedc611a3f083ca94cf5b3e2f17..159b8dea34f66e978293bd0a29e775374083b743 100644
|
| --- a/tests/compiler/dart2js/cpa_inference_test.dart
|
| +++ b/tests/compiler/dart2js/cpa_inference_test.dart
|
| @@ -111,6 +111,14 @@ class AnalysisResult {
|
| }
|
|
|
| /**
|
| + * Checks that the inferred type of the node corresponding to the last
|
| + * occurence of [: variable; :] in the program is the unknown concrete type.
|
| + */
|
| + void checkNodeHasUnknownType(String variable) {
|
| + return Expect.isTrue(inferrer.inferredTypes[findNode(variable)].isUnkown());
|
| + }
|
| +
|
| + /**
|
| * Checks that [: className#fieldName :]'s inferred type is the concrete type
|
| * made of [baseTypes].
|
| */
|
| @@ -120,6 +128,16 @@ class AnalysisResult {
|
| concreteFrom(baseTypes),
|
| inferrer.inferredFieldTypes[findField(className, fieldName)]);
|
| }
|
| +
|
| + /**
|
| + * Checks that [: className#fieldName :]'s inferred type is the unknown
|
| + * concrete type.
|
| + */
|
| + void checkFieldHasUknownType(String className, String fieldName) {
|
| + return Expect.isTrue(
|
| + inferrer.inferredFieldTypes[findField(className, fieldName)]
|
| + .isUnkown());
|
| + }
|
| }
|
|
|
| const String CORELIB = r'''
|
| @@ -144,10 +162,22 @@ AnalysisResult analyze(String code) {
|
| MockCompiler compiler = new MockCompiler(coreSource: CORELIB,
|
| enableConcreteTypeInference: true);
|
| compiler.sourceFiles[uri.toString()] = new SourceFile(uri.toString(), code);
|
| + compiler.typesTask.concreteTypesInferrer.testMode = true;
|
| compiler.runCompiler(uri);
|
| return new AnalysisResult(compiler);
|
| }
|
|
|
| +testDynamicBackDoor() {
|
| + final String source = r"""
|
| + main () {
|
| + var x = "__dynamic_for_test";
|
| + x;
|
| + }
|
| + """;
|
| + AnalysisResult result = analyze(source);
|
| + result.checkNodeHasUnknownType('x');
|
| +}
|
| +
|
| testLiterals() {
|
| final String source = r"""
|
| main() {
|
| @@ -267,6 +297,15 @@ testFor2() {
|
| result.checkNodeHasType('bar', [result.int]);
|
| }
|
|
|
| +testToplevelVariable() {
|
| + final String source = r"""
|
| + final top = 'abc';
|
| + main() { var foo = top; foo; }
|
| + """;
|
| + AnalysisResult result = analyze(source);
|
| + result.checkNodeHasType('foo', [result.string]);
|
| +}
|
| +
|
| testNonRecusiveFunction() {
|
| final String source = r"""
|
| f(x, y) => true ? x : y;
|
| @@ -298,6 +337,49 @@ testMutuallyRecusiveFunction() {
|
| result.checkNodeHasType('foo', [result.int, result.string]);
|
| }
|
|
|
| +testSimpleSend() {
|
| + final String source = r"""
|
| + class A {
|
| + f(x) => x;
|
| + }
|
| + class B {
|
| + f(x) => 'abc';
|
| + }
|
| + class C {
|
| + f(x) => 3.14;
|
| + }
|
| + class D {
|
| + var f; // we check that this field is ignored in calls to dynamic.f()
|
| + D(this.f);
|
| + }
|
| + main() {
|
| + new B(); new D(42); // we instantiate B and D but not C
|
| + var foo = new A().f(42);
|
| + var bar = "__dynamic_for_test".f(42);
|
| + foo; bar;
|
| + }
|
| + """;
|
| + AnalysisResult result = analyze(source);
|
| + result.checkNodeHasType('foo', [result.int]);
|
| + result.checkNodeHasType('bar', [result.int, result.string]);
|
| +}
|
| +
|
| +testSendToClosureField() {
|
| + final String source = r"""
|
| + f(x) => x;
|
| + class A {
|
| + var g;
|
| + A(this.g);
|
| + }
|
| + main() {
|
| + var foo = new A(f).g(42);
|
| + foo;
|
| + }
|
| + """;
|
| + AnalysisResult result = analyze(source);
|
| + result.checkNodeHasType('foo', [result.int]);
|
| +}
|
| +
|
| testSendToThis1() {
|
| final String source = r"""
|
| class A {
|
| @@ -356,13 +438,19 @@ testGetters() {
|
| get y => x;
|
| get z => y;
|
| }
|
| + class B {
|
| + var x;
|
| + B(this.x);
|
| + }
|
| main() {
|
| var a = new A(42);
|
| + var b = new B('abc');
|
| var foo = a.x;
|
| var bar = a.y;
|
| var baz = a.z;
|
| var qux = null.x;
|
| - foo; bar; baz; qux;
|
| + var quux = "__dynamic_for_test".x;
|
| + foo; bar; baz; qux; quux;
|
| }
|
| """;
|
| AnalysisResult result = analyze(source);
|
| @@ -370,6 +458,7 @@ testGetters() {
|
| result.checkNodeHasType('bar', [result.int]);
|
| result.checkNodeHasType('baz', [result.int]);
|
| result.checkNodeHasType('qux', []);
|
| + result.checkNodeHasType('quux', [result.int, result.string]);
|
| }
|
|
|
| testSetters() {
|
| @@ -381,16 +470,34 @@ testSetters() {
|
| set y(a) { x = a; z = a; }
|
| set z(a) { w = a; }
|
| }
|
| + class B {
|
| + var x;
|
| + B(this.x);
|
| + }
|
| main() {
|
| var a = new A(42, 42);
|
| + var b = new B(42);
|
| a.x = 'abc';
|
| a.y = true;
|
| null.x = 42; // should be ignored
|
| + "__dynamic_for_test".x = null;
|
| + "__dynamic_for_test".y = 3.14;
|
| }
|
| """;
|
| AnalysisResult result = analyze(source);
|
| - result.checkFieldHasType('A', 'x', [result.int, result.string, result.bool]);
|
| - result.checkFieldHasType('A', 'w', [result.int, result.bool]);
|
| + result.checkFieldHasType('B', 'x',
|
| + [result.int, // new B(42)
|
| + result.nullType]); // dynamic.x = null
|
| + result.checkFieldHasType('A', 'x',
|
| + [result.int, // new A(42, ...)
|
| + result.string, // a.x = 'abc'
|
| + result.bool, // a.y = true
|
| + result.nullType, // dynamic.x = null
|
| + result.double]); // dynamic.y = 3.14
|
| + result.checkFieldHasType('A', 'w',
|
| + [result.int, // new A(..., 42)
|
| + result.bool, // a.y = true
|
| + result.double]); // dynamic.y = double
|
| }
|
|
|
| testNamedParameters() {
|
| @@ -610,7 +717,24 @@ testSendWithWrongArity() {
|
| result.checkNodeHasType('w', []);
|
| }
|
|
|
| +testDynamicIsAbsorbing() {
|
| + final String source = r"""
|
| + main () {
|
| + var x = 1;
|
| + if (true) {
|
| + x = "__dynamic_for_test";
|
| + } else {
|
| + x = 42;
|
| + }
|
| + x;
|
| + }
|
| + """;
|
| + AnalysisResult result = analyze(source);
|
| + result.checkNodeHasUnknownType('x');
|
| +}
|
| +
|
| void main() {
|
| + testDynamicBackDoor();
|
| testLiterals();
|
| testRedefinition();
|
| testIfThenElse();
|
| @@ -618,9 +742,12 @@ void main() {
|
| testWhile();
|
| testFor1();
|
| testFor2();
|
| + // testToplevelVariable(); // toplevel variables are not yet supported
|
| testNonRecusiveFunction();
|
| testRecusiveFunction();
|
| testMutuallyRecusiveFunction();
|
| + testSimpleSend();
|
| + // testSendToClosureField(); // closures are not yet supported
|
| testSendToThis1();
|
| testSendToThis2();
|
| testConstructor();
|
| @@ -637,4 +764,5 @@ void main() {
|
| testCompoundOperators2();
|
| // testFieldInitialization(); // TODO(polux)
|
| testSendWithWrongArity();
|
| + testDynamicIsAbsorbing();
|
| }
|
|
|