OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library inferrer_visitor; | 5 library inferrer_visitor; |
6 | 6 |
7 import '../dart2jslib.dart' hide Selector, TypedSelector; | 7 import '../dart2jslib.dart' hide Selector, TypedSelector; |
8 import '../dart_types.dart'; | 8 import '../dart_types.dart'; |
9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
10 import '../tree/tree.dart'; | 10 import '../tree/tree.dart'; |
11 import '../universe/universe.dart'; | 11 import '../universe/universe.dart'; |
12 import '../util/util.dart'; | 12 import '../util/util.dart'; |
| 13 import '../types/types.dart' show TypeMask; |
13 | 14 |
14 /** | 15 /** |
15 * The interface [InferrerVisitor] will use when working on types. | 16 * The interface [InferrerVisitor] will use when working on types. |
16 */ | 17 */ |
17 abstract class TypeSystem<T> { | 18 abstract class TypeSystem<T> { |
18 T get dynamicType; | 19 T get dynamicType; |
19 T get nullType; | 20 T get nullType; |
20 T get intType; | 21 T get intType; |
| 22 T get uint31Type; |
| 23 T get uint32Type; |
21 T get doubleType; | 24 T get doubleType; |
22 T get numType; | 25 T get numType; |
23 T get boolType; | 26 T get boolType; |
24 T get functionType; | 27 T get functionType; |
25 T get listType; | 28 T get listType; |
26 T get constListType; | 29 T get constListType; |
27 T get fixedListType; | 30 T get fixedListType; |
28 T get growableListType; | 31 T get growableListType; |
29 T get mapType; | 32 T get mapType; |
30 T get constMapType; | 33 T get constMapType; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 /** | 81 /** |
79 * Adds [newType] as an input of [phiType]. | 82 * Adds [newType] as an input of [phiType]. |
80 */ | 83 */ |
81 T addPhiInput(Element element, T phiType, T newType); | 84 T addPhiInput(Element element, T phiType, T newType); |
82 | 85 |
83 /** | 86 /** |
84 * Returns a new receiver type for this [selector] applied to | 87 * Returns a new receiver type for this [selector] applied to |
85 * [receiverType]. | 88 * [receiverType]. |
86 */ | 89 */ |
87 T refineReceiver(Selector selector, T receiverType); | 90 T refineReceiver(Selector selector, T receiverType); |
| 91 |
| 92 /** |
| 93 * Returns the internal inferrer representation for [mask]. |
| 94 */ |
| 95 T getConcreteTypeFor(TypeMask mask); |
88 } | 96 } |
89 | 97 |
90 /** | 98 /** |
91 * A variable scope holds types for variables. It has a link to a | 99 * A variable scope holds types for variables. It has a link to a |
92 * parent scope, but never changes the types in that parent. Instead, | 100 * parent scope, but never changes the types in that parent. Instead, |
93 * updates to locals of a parent scope are put in the current scope. | 101 * updates to locals of a parent scope are put in the current scope. |
94 * The inferrer makes sure updates get merged into the parent scope, | 102 * The inferrer makes sure updates get merged into the parent scope, |
95 * once the control flow block has been visited. | 103 * once the control flow block has been visited. |
96 */ | 104 */ |
97 class VariableScope<T> { | 105 class VariableScope<T> { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 named.forEach((name, type) { | 249 named.forEach((name, type) { |
242 if (other.named[name] != type) return false; | 250 if (other.named[name] != type) return false; |
243 }); | 251 }); |
244 return true; | 252 return true; |
245 } | 253 } |
246 | 254 |
247 int get hashCode => throw new UnsupportedError('ArgumentsTypes.hashCode'); | 255 int get hashCode => throw new UnsupportedError('ArgumentsTypes.hashCode'); |
248 | 256 |
249 bool hasNoArguments() => positional.isEmpty && named.isEmpty; | 257 bool hasNoArguments() => positional.isEmpty && named.isEmpty; |
250 | 258 |
251 bool hasOnePositionalArgumentWithType(T type) { | 259 bool hasOnePositionalArgumentThatMatches(bool f(T type)) { |
252 return named.isEmpty && positional.length == 1 && positional[0] == type; | 260 return named.isEmpty && positional.length == 1 && f(positional[0]); |
253 } | 261 } |
254 | 262 |
255 void forEach(void f(T type)) { | 263 void forEach(void f(T type)) { |
256 positional.forEach(f); | 264 positional.forEach(f); |
257 named.values.forEach(f); | 265 named.values.forEach(f); |
258 } | 266 } |
259 | 267 |
260 bool every(bool f(T type)) { | 268 bool every(bool f(T type)) { |
261 return positional.every(f) && named.values.every(f); | 269 return positional.every(f) && named.values.every(f); |
262 } | 270 } |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 node.visitChildren(this); | 653 node.visitChildren(this); |
646 return types.stringType; | 654 return types.stringType; |
647 } | 655 } |
648 | 656 |
649 T visitLiteralBool(LiteralBool node) { | 657 T visitLiteralBool(LiteralBool node) { |
650 return types.boolType; | 658 return types.boolType; |
651 } | 659 } |
652 | 660 |
653 T visitLiteralDouble(LiteralDouble node) { | 661 T visitLiteralDouble(LiteralDouble node) { |
654 ConstantSystem constantSystem = compiler.backend.constantSystem; | 662 ConstantSystem constantSystem = compiler.backend.constantSystem; |
655 Constant constant = constantSystem.createDouble(node.value); | |
656 // The JavaScript backend may turn this literal into an integer at | 663 // The JavaScript backend may turn this literal into an integer at |
657 // runtime. | 664 // runtime. |
658 return constantSystem.isDouble(constant) | 665 return types.getConcreteTypeFor( |
659 ? types.doubleType | 666 constantSystem.createDouble(node.value).computeMask(compiler)); |
660 : types.intType; | |
661 } | 667 } |
662 | 668 |
663 T visitLiteralInt(LiteralInt node) { | 669 T visitLiteralInt(LiteralInt node) { |
664 ConstantSystem constantSystem = compiler.backend.constantSystem; | 670 ConstantSystem constantSystem = compiler.backend.constantSystem; |
665 Constant constant = constantSystem.createInt(node.value); | |
666 // The JavaScript backend may turn this literal into a double at | 671 // The JavaScript backend may turn this literal into a double at |
667 // runtime. | 672 // runtime. |
668 return constantSystem.isDouble(constant) | 673 return types.getConcreteTypeFor( |
669 ? types.doubleType | 674 constantSystem.createInt(node.value).computeMask(compiler)); |
670 : types.intType; | |
671 } | 675 } |
672 | 676 |
673 T visitLiteralList(LiteralList node) { | 677 T visitLiteralList(LiteralList node) { |
674 node.visitChildren(this); | 678 node.visitChildren(this); |
675 return node.isConst() ? types.constListType : types.growableListType; | 679 return node.isConst() ? types.constListType : types.growableListType; |
676 } | 680 } |
677 | 681 |
678 T visitLiteralMap(LiteralMap node) { | 682 T visitLiteralMap(LiteralMap node) { |
679 node.visitChildren(this); | 683 node.visitChildren(this); |
680 return node.isConst() ? types.constMapType : types.mapType; | 684 return node.isConst() ? types.constMapType : types.mapType; |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 return type; | 1148 return type; |
1145 } | 1149 } |
1146 | 1150 |
1147 T visitCascade(Cascade node) { | 1151 T visitCascade(Cascade node) { |
1148 // Ignore the result of the cascade send and return the type of the cascade | 1152 // Ignore the result of the cascade send and return the type of the cascade |
1149 // receiver. | 1153 // receiver. |
1150 visit(node.expression); | 1154 visit(node.expression); |
1151 return cascadeReceiverStack.removeLast(); | 1155 return cascadeReceiverStack.removeLast(); |
1152 } | 1156 } |
1153 } | 1157 } |
OLD | NEW |