OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 'package:expect/expect.dart'; | 5 import 'package:expect/expect.dart'; |
6 import "package:async_helper/async_helper.dart"; | 6 import "package:async_helper/async_helper.dart"; |
7 import 'memory_compiler.dart'; | 7 import 'memory_compiler.dart'; |
8 import 'compiler_helper.dart' show findElement; | 8 import 'compiler_helper.dart' show findElement; |
9 | 9 |
10 var SOURCES = const { | 10 var SOURCES = const { |
11 'testAddAll.dart': """ | 11 'AddAll.dart': """ |
12 var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5, | 12 var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5, |
13 'list': []}; | 13 'list': []}; |
14 var dictionaryB = {'string': "aString", 'int': 42, 'double': 21.5, | 14 var dictionaryB = {'string': "aString", 'int': 42, 'double': 21.5, |
15 'list': []}; | 15 'list': []}; |
16 var otherDict = {'stringTwo' : "anotherString", 'intTwo' : 84}; | 16 var otherDict = {'stringTwo' : "anotherString", 'intTwo' : 84}; |
17 var int = 0; | 17 var int = 0; |
18 var anotherInt = 0; | 18 var anotherInt = 0; |
19 var nullOrInt = 0; | 19 var nullOrInt = 0; |
20 var dynamic = 0; | 20 var dynamic = 0; |
21 | 21 |
22 main() { | 22 main() { |
23 dictionaryA.addAll(otherDict); | 23 dictionaryA.addAll(otherDict); |
24 dictionaryB.addAll({'stringTwo' : "anotherString", 'intTwo' : 84}); | 24 dictionaryB.addAll({'stringTwo' : "anotherString", 'intTwo' : 84}); |
25 int = dictionaryB['int']; | 25 int = dictionaryB['int']; |
26 anotherInt = otherDict['intTwo']; | 26 anotherInt = otherDict['intTwo']; |
27 dynamic = dictionaryA['int']; | 27 dynamic = dictionaryA['int']; |
28 nullOrInt = dictionaryB['intTwo']; | 28 nullOrInt = dictionaryB['intTwo']; |
29 } | 29 } |
30 """, | 30 """, |
31 'testUnion.dart': """ | 31 'Union.dart': """ |
32 var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5, | 32 var dictionaryA = {'string': "aString", 'int': 42, 'double': 21.5, |
33 'list': []}; | 33 'list': []}; |
34 var dictionaryB = {'string': "aString", 'intTwo': 42, 'list': []}; | 34 var dictionaryB = {'string': "aString", 'intTwo': 42, 'list': []}; |
35 var nullOrInt = 0; | 35 var nullOrInt = 0; |
36 var aString = ""; | 36 var aString = ""; |
37 var doubleOrNull = 22.2; | 37 var doubleOrNull = 22.2; |
38 var key = "string"; | 38 var key = "string"; |
39 | 39 |
40 main() { | 40 main() { |
41 var union = dictionaryA['foo'] ? dictionaryA : dictionaryB; | 41 var union = dictionaryA['foo'] ? dictionaryA : dictionaryB; |
42 nullOrInt = union['intTwo']; | 42 nullOrInt = union['intTwo']; |
43 aString = union['string']; | 43 aString = union['string']; |
44 doubleOrNull = union['double']; | 44 doubleOrNull = union['double']; |
45 } | 45 } |
46 """, | 46 """, |
47 'testValueType.dart': """ | 47 'ValueType.dart': """ |
48 var dictionary = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []}; | 48 var dictionary = {'string': "aString", 'int': 42, 'double': 21.5, 'list': []}; |
49 var keyD = 'double'; | 49 var keyD = 'double'; |
50 var keyI = 'int'; | 50 var keyI = 'int'; |
51 var keyN = 'notFoundInMap'; | 51 var keyN = 'notFoundInMap'; |
52 var knownDouble = 42.2; | 52 var knownDouble = 42.2; |
53 var intOrNull = dictionary[keyI]; | 53 var intOrNull = dictionary[keyI]; |
54 var justNull = dictionary[keyN]; | 54 var justNull = dictionary[keyN]; |
55 | 55 |
56 main() { | 56 main() { |
57 knownDouble = dictionary[keyD]; | 57 knownDouble = dictionary[keyD]; |
58 var x = [intOrNull, justNull]; | 58 var x = [intOrNull, justNull]; |
59 } | 59 } |
60 """, | 60 """, |
61 'testPropagation.dart': """ | 61 'Propagation.dart': """ |
62 class A { | 62 class A { |
63 A(); | 63 A(); |
64 foo(value) { | 64 foo(value) { |
65 return value['anInt']; | 65 return value['anInt']; |
66 } | 66 } |
67 } | 67 } |
68 | 68 |
69 class B { | 69 class B { |
70 B(); | 70 B(); |
71 foo(value) { | 71 foo(value) { |
72 return 0; | 72 return 0; |
73 } | 73 } |
74 } | 74 } |
75 | 75 |
76 main() { | 76 main() { |
77 var dictionary = {'anInt': 42, 'aString': "theString"}; | 77 var dictionary = {'anInt': 42, 'aString': "theString"}; |
78 var it; | 78 var it; |
79 if ([true, false][0]) { | 79 if ([true, false][0]) { |
80 it = new A(); | 80 it = new A(); |
81 } else { | 81 } else { |
82 it = new B(); | 82 it = new B(); |
83 } | 83 } |
84 print(it.foo(dictionary) + 2); | 84 print(it.foo(dictionary) + 2); |
85 } | 85 } |
| 86 """, |
| 87 'Bailout.dart': """ |
| 88 var dict = makeMap([1,2]); |
| 89 var notInt = 0; |
| 90 var alsoNotInt = 0; |
| 91 |
| 92 makeMap(values) { |
| 93 return {'moo': values[0], 'boo': values[1]}; |
| 94 } |
| 95 |
| 96 main () { |
| 97 dict['goo'] = 42; |
| 98 var closure = dictfun() => dict; |
| 99 notInt = closure()['boo']; |
| 100 alsoNotInt = dict['goo']; |
| 101 print("\$notInt and \$alsoNotInt."); |
| 102 } |
86 """}; | 103 """}; |
87 | 104 |
88 void main() { | 105 void main() { |
89 asyncTest(() => | 106 asyncTest(() => |
90 compileAndTest("testAddAll.dart", (types, getType, compiler) { | 107 compileAndTest("AddAll.dart", (types, getType, compiler) { |
91 Expect.equals(getType('int'), types.uint31Type); | 108 Expect.equals(getType('int'), types.uint31Type); |
92 Expect.equals(getType('anotherInt'), types.uint31Type); | 109 Expect.equals(getType('anotherInt'), types.uint31Type); |
93 Expect.equals(getType('dynamic'), types.dynamicType); | 110 Expect.equals(getType('dynamic'), types.dynamicType); |
94 Expect.equals(getType('nullOrInt'), types.uint31Type.nullable()); | 111 Expect.equals(getType('nullOrInt'), types.uint31Type.nullable()); |
95 }).then((_) => compileAndTest("testUnion.dart", (types, getType, compiler) { | 112 })); |
96 Expect.equals(getType('nullOrInt'), types.uint31Type.nullable()); | 113 asyncTest(() => compileAndTest("Union.dart", (types, getType, compiler) { |
97 Expect.isTrue(getType('aString').containsOnlyString(compiler)); | 114 Expect.equals(getType('nullOrInt'), types.uint31Type.nullable()); |
98 Expect.equals(getType('doubleOrNull'), types.doubleType.nullable()); | 115 Expect.isTrue(getType('aString').containsOnlyString(compiler)); |
99 })).then((_) => compileAndTest("testValueType.dart", | 116 Expect.equals(getType('doubleOrNull'), types.doubleType.nullable()); |
100 (types, getType, compiler) { | 117 })); |
| 118 asyncTest(() => |
| 119 compileAndTest("ValueType.dart", (types, getType, compiler) { |
101 Expect.equals(getType('knownDouble'), types.doubleType); | 120 Expect.equals(getType('knownDouble'), types.doubleType); |
102 Expect.equals(getType('intOrNull'), types.uint31Type.nullable()); | 121 Expect.equals(getType('intOrNull'), types.uint31Type.nullable()); |
103 Expect.equals(getType('justNull'), types.nullType); | 122 Expect.equals(getType('justNull'), types.nullType); |
104 })).then((_) => compileAndTest("testPropagation.dart", (code) { | 123 })); |
105 Expect.isFalse(code.contains("J.\$add\$ns")); | 124 asyncTest(() => compileAndTest("Propagation.dart", (code) { |
106 }, createCode: true)) | 125 Expect.isFalse(code.contains("J.\$add\$ns")); |
107 ); | 126 }, createCode: true)); |
| 127 asyncTest(() => compileAndTest("Bailout.dart", (types, getType, compiler) { |
| 128 Expect.equals(getType('notInt'), types.dynamicType); |
| 129 Expect.equals(getType('alsoNotInt'), types.dynamicType); |
| 130 Expect.isFalse(getType('dict').isDictionary); |
| 131 })); |
108 } | 132 } |
109 | 133 |
110 compileAndTest(source, checker, {createCode: false}) { | 134 compileAndTest(source, checker, {createCode: false}) { |
111 var compiler = compilerFor(SOURCES); | 135 var compiler = compilerFor(SOURCES); |
112 compiler.stopAfterTypeInference = !createCode; | 136 compiler.stopAfterTypeInference = !createCode; |
113 var uri = Uri.parse('memory:'+source); | 137 var uri = Uri.parse('memory:'+source); |
114 return compiler.runCompiler(uri).then((_) { | 138 return compiler.runCompiler(uri).then((_) { |
115 var typesTask = compiler.typesTask; | 139 var typesTask = compiler.typesTask; |
116 var typesInferrer = typesTask.typesInferrer; | 140 var typesInferrer = typesTask.typesInferrer; |
117 getType(String name) { | 141 getType(String name) { |
118 var element = findElement(compiler, name); | 142 var element = findElement(compiler, name); |
119 return typesInferrer.getTypeOfElement(element); | 143 return typesInferrer.getTypeOfElement(element); |
120 } | 144 } |
121 if (!createCode) { | 145 if (!createCode) { |
122 checker(typesTask, getType, compiler); | 146 checker(typesTask, getType, compiler); |
123 } else { | 147 } else { |
124 var element = compiler.mainApp.findExported('main'); | 148 var element = compiler.mainApp.findExported('main'); |
125 var code = compiler.backend.assembleCode(element); | 149 var code = compiler.backend.assembleCode(element); |
126 checker(code); | 150 checker(code); |
127 } | 151 } |
128 }); | 152 }); |
129 } | 153 } |
OLD | NEW |