| Index: sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart (revision 22031)
|
| +++ sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart (working copy)
|
| @@ -96,28 +96,6 @@
|
| bool get isDone => constructorsToVisitCount == 0;
|
| }
|
|
|
| -/**
|
| - * A sentinel type mask class used by the inferrer for the give up
|
| - * type, and the dynamic type.
|
| - */
|
| -class SentinelTypeMask extends TypeMask {
|
| - final String name;
|
| -
|
| - SentinelTypeMask(this.name) : super(null, 0, false);
|
| -
|
| - bool operator==(other) {
|
| - return identical(this, other);
|
| - }
|
| -
|
| - TypeMask nullable() {
|
| - throw 'Unsupported operation';
|
| - }
|
| -
|
| - bool get isNullable => true;
|
| -
|
| - String toString() => '$name sentinel type mask';
|
| -}
|
| -
|
| final OPTIMISTIC = 0;
|
| final RETRY = 1;
|
| final PESSIMISTIC = 2;
|
| @@ -261,8 +239,8 @@
|
| * Sentinel used by the inferrer to notify that it does not know
|
| * the type of a specific element.
|
| */
|
| - final TypeMask dynamicType = new SentinelTypeMask('dynamic');
|
| - bool isDynamicType(TypeMask type) => identical(type, dynamicType);
|
| + TypeMask dynamicType;
|
| + bool isDynamicType(TypeMask type) => type == dynamicType;
|
|
|
| TypeMask nullType;
|
| TypeMask intType;
|
| @@ -543,6 +521,9 @@
|
| rawTypeOf(backend.functionImplementation));
|
| typeType = new TypeMask.nonNullExact(
|
| rawTypeOf(backend.typeImplementation));
|
| +
|
| + dynamicType = new TypeMask.subclass(
|
| + rawTypeOf(compiler.objectClass));
|
| }
|
|
|
| dump() {
|
| @@ -1187,7 +1168,6 @@
|
| * [secondType].
|
| */
|
| TypeMask computeLUB(TypeMask firstType, TypeMask secondType) {
|
| - assert(secondType != null);
|
| if (firstType == null) {
|
| return secondType;
|
| } else if (isDynamicType(secondType)) {
|
| @@ -1590,6 +1570,7 @@
|
| inferrer.recordType(variable, locals.locals[variable]);
|
| });
|
|
|
| + locals.update(elements[node], inferrer.functionType);
|
| return inferrer.functionType;
|
| }
|
|
|
| @@ -2078,6 +2059,19 @@
|
| : new TypedSelector(receiver, selector);
|
| updateSelectorInTree(node, selector);
|
| }
|
| +
|
| + // If the receiver of the call is a local, we may know more about
|
| + // its type by refining it with the potential targets of the
|
| + // calls.
|
| + if (node.asSend() != null
|
| + && node.asSend().receiver != null
|
| + && Elements.isLocal(elements[node.asSend().receiver])) {
|
| + Element element = elements[node.asSend().receiver];
|
| + TypeMask refinedMask = new TypeMask.refineWith(
|
| + locals.use(element), selector, compiler);
|
| + locals.update(element, refinedMask);
|
| + }
|
| +
|
| return inferrer.registerCalledSelector(
|
| node, selector, receiver, outermostElement, arguments,
|
| constraint, inLoop);
|
|
|