| 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 |