Use AbstractValue in inference results.

Change-Id: I2a932abd2d8d3236b560721c9d5ec010271d2b85
Reviewed-on: https://dart-review.googlesource.com/55362
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index ca4b7ce..07aa78b 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -17,6 +17,7 @@
 import '../js_emitter/sorter.dart';
 import '../native/behavior.dart' as native;
 import '../options.dart';
+import '../types/abstract_value_domain.dart';
 import '../types/constants.dart';
 import '../types/types.dart';
 import '../universe/call_structure.dart';
@@ -56,7 +57,8 @@
   ClosedWorld get closedWorld;
   ClosedWorldRefiner get closedWorldRefiner;
   DiagnosticReporter get reporter;
-  CommonMasks get commonMasks => closedWorld.abstractValueDomain;
+  AbstractValueDomain get abstractValueDomain =>
+      closedWorld.abstractValueDomain;
   CommonElements get commonElements => closedWorld.commonElements;
 
   // TODO(johnniwinther): This should be part of [ClosedWorld] or
@@ -438,7 +440,7 @@
 
     info.bailedOut = false;
     info.elementType.inferred = true;
-    TypeMask fixedListType = commonMasks.fixedListType;
+    TypeMask fixedListType = abstractValueDomain.fixedListType;
     if (info.originalType.forwardTo == fixedListType) {
       info.checksGrowable = tracer.callsGrowableMethod;
     }
diff --git a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
index 3b3754b..7b49435 100644
--- a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
@@ -18,6 +18,7 @@
 import '../js_model/locals.dart';
 import '../kernel/element_map.dart';
 import '../options.dart';
+import '../types/abstract_value_domain.dart';
 import '../types/types.dart';
 import '../world.dart';
 import 'builder_kernel.dart';
@@ -81,14 +82,13 @@
         // for closure elements.
         inferrer.inferrer.lookupDataOfMember(member),
         inferrer,
-        isJsInterop,
-        dynamicType);
+        isJsInterop);
   }
 
   GlobalTypeInferenceParameterResult<ir.Node> createParameterResult(
       TypeGraphInferrer<ir.Node> inferrer, Local parameter) {
     return new GlobalTypeInferenceParameterResultImpl<ir.Node>(
-        parameter, inferrer, dynamicType);
+        parameter, inferrer);
   }
 }
 
@@ -331,62 +331,65 @@
 class KernelGlobalTypeInferenceElementData
     extends GlobalTypeInferenceElementData<ir.Node> {
   // TODO(johnniwinther): Rename this together with [typeOfSend].
-  Map<ir.Node, TypeMask> _sendMap;
+  Map<ir.Node, AbstractValue> _sendMap;
 
-  Map<ir.ForInStatement, TypeMask> _iteratorMap;
-  Map<ir.ForInStatement, TypeMask> _currentMap;
-  Map<ir.ForInStatement, TypeMask> _moveNextMap;
+  Map<ir.ForInStatement, AbstractValue> _iteratorMap;
+  Map<ir.ForInStatement, AbstractValue> _currentMap;
+  Map<ir.ForInStatement, AbstractValue> _moveNextMap;
 
   @override
-  TypeMask typeOfSend(ir.Node node) {
+  AbstractValue typeOfSend(ir.Node node) {
     if (_sendMap == null) return null;
     return _sendMap[node];
   }
 
   @override
-  void setCurrentTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
-    _currentMap ??= <ir.ForInStatement, TypeMask>{};
+  void setCurrentTypeMask(
+      covariant ir.ForInStatement node, AbstractValue mask) {
+    _currentMap ??= <ir.ForInStatement, AbstractValue>{};
     _currentMap[node] = mask;
   }
 
   @override
-  void setMoveNextTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
-    _moveNextMap ??= <ir.ForInStatement, TypeMask>{};
+  void setMoveNextTypeMask(
+      covariant ir.ForInStatement node, AbstractValue mask) {
+    _moveNextMap ??= <ir.ForInStatement, AbstractValue>{};
     _moveNextMap[node] = mask;
   }
 
   @override
-  void setIteratorTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
-    _iteratorMap ??= <ir.ForInStatement, TypeMask>{};
+  void setIteratorTypeMask(
+      covariant ir.ForInStatement node, AbstractValue mask) {
+    _iteratorMap ??= <ir.ForInStatement, AbstractValue>{};
     _iteratorMap[node] = mask;
   }
 
   @override
-  TypeMask typeOfIteratorCurrent(covariant ir.ForInStatement node) {
+  AbstractValue typeOfIteratorCurrent(covariant ir.ForInStatement node) {
     if (_currentMap == null) return null;
     return _currentMap[node];
   }
 
   @override
-  TypeMask typeOfIteratorMoveNext(covariant ir.ForInStatement node) {
+  AbstractValue typeOfIteratorMoveNext(covariant ir.ForInStatement node) {
     if (_moveNextMap == null) return null;
     return _moveNextMap[node];
   }
 
   @override
-  TypeMask typeOfIterator(covariant ir.ForInStatement node) {
+  AbstractValue typeOfIterator(covariant ir.ForInStatement node) {
     if (_iteratorMap == null) return null;
     return _iteratorMap[node];
   }
 
   @override
-  void setTypeMask(ir.Node node, TypeMask mask) {
-    _sendMap ??= <ir.Node, TypeMask>{};
+  void setTypeMask(ir.Node node, AbstractValue mask) {
+    _sendMap ??= <ir.Node, AbstractValue>{};
     _sendMap[node] = mask;
   }
 
   @override
-  TypeMask typeOfGetter(ir.Node node) {
+  AbstractValue typeOfGetter(ir.Node node) {
     if (_sendMap == null) return null;
     return _sendMap[node];
   }
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 87f76a7..d6482a3 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -7,8 +7,7 @@
 import 'dart:collection' show Queue;
 
 import '../elements/entities.dart';
-import '../types/masks.dart'
-    show CommonMasks, ContainerTypeMask, MapTypeMask, TypeMask;
+import '../types/abstract_value_domain.dart';
 import '../types/types.dart';
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
@@ -58,9 +57,10 @@
 
   String get name => 'Graph inferrer';
 
-  CommonMasks get commonMasks => closedWorld.abstractValueDomain;
+  AbstractValueDomain get abstractValueDomain =>
+      closedWorld.abstractValueDomain;
 
-  TypeMask get _dynamicType => commonMasks.dynamicType;
+  AbstractValue get _dynamicType => abstractValueDomain.dynamicType;
 
   void analyzeMain(FunctionEntity main) {
     inferrer = createInferrerEngineFor(main);
@@ -70,34 +70,34 @@
 
   InferrerEngine<T> createInferrerEngineFor(FunctionEntity main);
 
-  TypeMask getReturnTypeOfMember(MemberEntity element) {
+  AbstractValue getReturnTypeOfMember(MemberEntity element) {
     if (_disableTypeInference) return _dynamicType;
     // Currently, closure calls return dynamic.
     if (element is! FunctionEntity) return _dynamicType;
     return inferrer.types.getInferredTypeOfMember(element).type;
   }
 
-  TypeMask getReturnTypeOfParameter(Local element) {
+  AbstractValue getReturnTypeOfParameter(Local element) {
     if (_disableTypeInference) return _dynamicType;
     return _dynamicType;
   }
 
-  TypeMask getTypeOfMember(MemberEntity element) {
+  AbstractValue getTypeOfMember(MemberEntity element) {
     if (_disableTypeInference) return _dynamicType;
     // The inferrer stores the return type for a function, so we have to
     // be careful to not return it here.
-    if (element is FunctionEntity) return commonMasks.functionType;
+    if (element is FunctionEntity) return abstractValueDomain.functionType;
     return inferrer.types.getInferredTypeOfMember(element).type;
   }
 
-  TypeMask getTypeOfParameter(Local element) {
+  AbstractValue getTypeOfParameter(Local element) {
     if (_disableTypeInference) return _dynamicType;
     // The inferrer stores the return type for a function, so we have to
     // be careful to not return it here.
     return inferrer.types.getInferredTypeOfParameter(element).type;
   }
 
-  TypeMask getTypeForNewList(T node) {
+  AbstractValue getTypeForNewList(T node) {
     if (_disableTypeInference) return _dynamicType;
     return inferrer.types.allocatedLists[node].type;
   }
@@ -108,7 +108,7 @@
     return info.checksGrowable;
   }
 
-  TypeMask getTypeOfSelector(Selector selector, TypeMask mask) {
+  AbstractValue getTypeOfSelector(Selector selector, AbstractValue receiver) {
     if (_disableTypeInference) return _dynamicType;
     // Bailout for closure calls. We're not tracking types of
     // closures.
@@ -116,30 +116,26 @@
     if (selector.isSetter || selector.isIndexSet) {
       return _dynamicType;
     }
-    if (inferrer.returnsListElementType(selector, mask)) {
-      ContainerTypeMask containerTypeMask = mask;
-      TypeMask elementType = containerTypeMask.elementType;
-      return elementType == null ? _dynamicType : elementType;
+    if (inferrer.returnsListElementType(selector, receiver)) {
+      return abstractValueDomain.getContainerElementType(receiver);
     }
-    if (inferrer.returnsMapValueType(selector, mask)) {
-      MapTypeMask mapTypeMask = mask;
-      TypeMask valueType = mapTypeMask.valueType;
-      return valueType == null ? _dynamicType : valueType;
+    if (inferrer.returnsMapValueType(selector, receiver)) {
+      return abstractValueDomain.getMapValueType(receiver);
     }
 
-    TypeMask result = const TypeMask.nonNullEmpty();
-    if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
-      result = inferrer.commonMasks.dynamicType;
+    if (inferrer.closedWorld.includesClosureCall(selector, receiver)) {
+      return abstractValueDomain.dynamicType;
     } else {
       Iterable<MemberEntity> elements =
-          inferrer.closedWorld.locateMembers(selector, mask);
+          inferrer.closedWorld.locateMembers(selector, receiver);
+      List<AbstractValue> types = <AbstractValue>[];
       for (MemberEntity element in elements) {
-        TypeMask type =
+        AbstractValue type =
             inferrer.typeOfMemberWithSelector(element, selector).type;
-        result = result.union(type, inferrer.closedWorld);
+        types.add(type);
       }
+      return abstractValueDomain.unionOfMany(types);
     }
-    return result;
   }
 
   Iterable<MemberEntity> getCallersOfForTesting(MemberEntity element) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index a6f2a77..cb9971a 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -610,19 +610,19 @@
       : super._internal(element);
 
   TypeMask handleSpecialCases(InferrerEngine inferrer) {
-    CommonMasks commonMasks = inferrer.commonMasks;
+    CommonMasks abstractValueDomain = inferrer.abstractValueDomain;
     if (_constructor.isFromEnvironmentConstructor) {
       if (_constructor.enclosingClass == inferrer.commonElements.intClass) {
         giveUp(inferrer);
-        return commonMasks.intType.nullable();
+        return abstractValueDomain.intType.nullable();
       } else if (_constructor.enclosingClass ==
           inferrer.commonElements.boolClass) {
         giveUp(inferrer);
-        return commonMasks.boolType.nullable();
+        return abstractValueDomain.boolType.nullable();
       } else if (_constructor.enclosingClass ==
           inferrer.commonElements.stringClass) {
         giveUp(inferrer);
-        return commonMasks.stringType.nullable();
+        return abstractValueDomain.stringType.nullable();
       }
     }
     return _handleFunctionCase(_constructor, inferrer);
@@ -1020,7 +1020,7 @@
     TypeMask receiverType = receiver.type;
 
     if (mask != receiverType) {
-      return receiverType == inferrer.commonMasks.dynamicType
+      return receiverType == inferrer.abstractValueDomain.dynamicType
           ? null
           : receiverType;
     } else {
@@ -1198,7 +1198,7 @@
     // for all these targets.
     TypeMask result;
     if (_hasClosureCallTargets) {
-      result = inferrer.commonMasks.dynamicType;
+      result = inferrer.abstractValueDomain.dynamicType;
     } else {
       result = inferrer.types
           .joinTypeMasks(_concreteTargets.map((MemberEntity element) {
diff --git a/pkg/compiler/lib/src/types/abstract_value_domain.dart b/pkg/compiler/lib/src/types/abstract_value_domain.dart
index 9de78ef..4b2849d 100644
--- a/pkg/compiler/lib/src/types/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/types/abstract_value_domain.dart
@@ -230,6 +230,10 @@
   /// [b].
   AbstractValue union(covariant AbstractValue a, covariant AbstractValue b);
 
+  /// Returns [AbstractValue] for the runtime values contained in at least one
+  /// of [values].
+  AbstractValue unionOfMany(List<AbstractValue> values);
+
   /// Returns [AbstractValue] for the runtime values that [a] and [b] have in
   /// common.
   AbstractValue intersection(
@@ -243,4 +247,12 @@
 
   /// Computes the [AbstractValue] corresponding to the constant [value].
   AbstractValue computeAbstractValueForConstant(ConstantValue value);
+
+  /// Returns the element type of [value] if it represents a container value
+  /// at runtime. Returns [dynamicType] otherwise.
+  AbstractValue getContainerElementType(AbstractValue value);
+
+  /// Returns the value type of [value] if it represents a map value at runtime.
+  /// Returns [dynamicType] otherwise.
+  AbstractValue getMapValueType(AbstractValue value);
 }
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index 9f5eb67..7039099 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -371,4 +371,29 @@
   AbstractValue computeAbstractValueForConstant(ConstantValue value) {
     return computeTypeMask(_closedWorld, value);
   }
+
+  @override
+  AbstractValue getMapValueType(AbstractValue value) {
+    if (value is MapTypeMask) {
+      return value.valueType ?? dynamicType;
+    }
+    return dynamicType;
+  }
+
+  @override
+  AbstractValue getContainerElementType(AbstractValue value) {
+    if (value is ContainerTypeMask) {
+      return value.elementType ?? dynamicType;
+    }
+    return dynamicType;
+  }
+
+  @override
+  AbstractValue unionOfMany(List<AbstractValue> values) {
+    TypeMask result = const TypeMask.nonNullEmpty();
+    for (TypeMask value in values) {
+      result = result.union(value, _closedWorld);
+    }
+    return result;
+  }
 }
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index c662f5b..26ad97d 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -11,8 +11,8 @@
 import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
+import 'abstract_value_domain.dart';
 
-import 'masks.dart';
 export 'masks.dart';
 
 /// Results about a single element (e.g. a method, parameter, or field)
@@ -31,33 +31,33 @@
 
   /// The inferred type when this result belongs to a parameter or field
   /// element, null otherwise.
-  TypeMask get type;
+  AbstractValue get type;
 
   /// The inferred return type when this result belongs to a function element.
-  TypeMask get returnType;
+  AbstractValue get returnType;
 
   /// Returns the type of a list new expression [node].
-  TypeMask typeOfNewList(T node);
+  AbstractValue typeOfNewList(T node);
 
   /// Returns the type of a list literal [node].
-  TypeMask typeOfListLiteral(T node);
+  AbstractValue typeOfListLiteral(T node);
 
   /// Returns the type of a send [node].
   // TODO(johnniwinther): Rename this.
-  TypeMask typeOfSend(T node);
+  AbstractValue typeOfSend(T node);
 
   /// Returns the type of the getter in a complex send-set [node], for example,
   /// the type of the `a.f` getter in `a.f += b`.
-  TypeMask typeOfGetter(T node);
+  AbstractValue typeOfGetter(T node);
 
   /// Returns the type of the iterator in a [loop].
-  TypeMask typeOfIterator(T node);
+  AbstractValue typeOfIterator(T node);
 
   /// Returns the type of the `moveNext` call of an iterator in a [loop].
-  TypeMask typeOfIteratorMoveNext(T node);
+  AbstractValue typeOfIteratorMoveNext(T node);
 
   /// Returns the type of the `current` getter of an iterator in a [loop].
-  TypeMask typeOfIteratorCurrent(T node);
+  AbstractValue typeOfIteratorCurrent(T node);
 }
 
 abstract class GlobalTypeInferenceMemberResult<T>
@@ -78,27 +78,27 @@
   // TODO(sigmund): store relevant data & drop reference to inference engine.
   final TypesInferrer<T> _inferrer;
   final bool _isJsInterop;
-  final TypeMask _dynamic;
 
   GlobalTypeInferenceElementResultImpl(
-      this._data, this._inferrer, this._isJsInterop, this._dynamic);
+      this._data, this._inferrer, this._isJsInterop);
 
   bool get throwsAlways {
-    TypeMask mask = this.returnType;
+    AbstractValue mask = this.returnType;
     // Always throws if the return type was inferred to be non-null empty.
-    return mask != null && mask.isEmpty;
+    return mask != null && _inferrer.abstractValueDomain.isEmpty(mask);
   }
 
-  TypeMask typeOfNewList(T node) => _inferrer.getTypeForNewList(node);
+  AbstractValue typeOfNewList(T node) => _inferrer.getTypeForNewList(node);
 
-  TypeMask typeOfListLiteral(T node) => _inferrer.getTypeForNewList(node);
+  AbstractValue typeOfListLiteral(T node) => _inferrer.getTypeForNewList(node);
 
-  TypeMask typeOfSend(T node) => _data?.typeOfSend(node);
-  TypeMask typeOfGetter(T node) => _data?.typeOfGetter(node);
-  TypeMask typeOfIterator(T node) => _data?.typeOfIterator(node);
-  TypeMask typeOfIteratorMoveNext(T node) =>
+  AbstractValue typeOfSend(T node) => _data?.typeOfSend(node);
+  AbstractValue typeOfGetter(T node) => _data?.typeOfGetter(node);
+  AbstractValue typeOfIterator(T node) => _data?.typeOfIterator(node);
+  AbstractValue typeOfIteratorMoveNext(T node) =>
       _data?.typeOfIteratorMoveNext(node);
-  TypeMask typeOfIteratorCurrent(T node) => _data?.typeOfIteratorCurrent(node);
+  AbstractValue typeOfIteratorCurrent(T node) =>
+      _data?.typeOfIteratorCurrent(node);
 }
 
 class GlobalTypeInferenceMemberResultImpl<T>
@@ -111,17 +111,18 @@
       this._owner,
       GlobalTypeInferenceElementData data,
       TypesInferrer inferrer,
-      bool isJsInterop,
-      TypeMask _dynamic)
-      : super(data, inferrer, isJsInterop, _dynamic);
+      bool isJsInterop)
+      : super(data, inferrer, isJsInterop);
 
   bool get isCalledOnce => _inferrer.isMemberCalledOnce(_owner);
 
-  TypeMask get returnType =>
-      _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfMember(_owner);
+  AbstractValue get returnType => _isJsInterop
+      ? _inferrer.abstractValueDomain.dynamicType
+      : _inferrer.getReturnTypeOfMember(_owner);
 
-  TypeMask get type =>
-      _isJsInterop ? _dynamic : _inferrer.getTypeOfMember(_owner);
+  AbstractValue get type => _isJsInterop
+      ? _inferrer.abstractValueDomain.dynamicType
+      : _inferrer.getTypeOfMember(_owner);
 }
 
 class GlobalTypeInferenceParameterResultImpl<T>
@@ -130,48 +131,50 @@
   // TODO(sigmund): delete, store data directly here.
   final Local _owner;
 
-  GlobalTypeInferenceParameterResultImpl(
-      this._owner, TypesInferrer inferrer, TypeMask _dynamic)
-      : super(null, inferrer, false, _dynamic);
+  GlobalTypeInferenceParameterResultImpl(this._owner, TypesInferrer inferrer)
+      : super(null, inferrer, false);
 
-  TypeMask get returnType =>
-      _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfParameter(_owner);
+  AbstractValue get returnType => _isJsInterop
+      ? _inferrer.abstractValueDomain.dynamicType
+      : _inferrer.getReturnTypeOfParameter(_owner);
 
-  TypeMask get type =>
-      _isJsInterop ? _dynamic : _inferrer.getTypeOfParameter(_owner);
+  AbstractValue get type => _isJsInterop
+      ? _inferrer.abstractValueDomain.dynamicType
+      : _inferrer.getTypeOfParameter(_owner);
 }
 
 /// Internal data used during type-inference to store intermediate results about
 /// a single element.
 abstract class GlobalTypeInferenceElementData<T> {
   // TODO(johnniwinther): Remove this. Maybe split by access/invoke.
-  TypeMask typeOfSend(T node);
-  TypeMask typeOfGetter(T node);
+  AbstractValue typeOfSend(T node);
+  AbstractValue typeOfGetter(T node);
 
-  void setTypeMask(T node, TypeMask mask);
+  void setTypeMask(T node, AbstractValue mask);
 
-  TypeMask typeOfIterator(T node);
+  AbstractValue typeOfIterator(T node);
 
-  TypeMask typeOfIteratorMoveNext(T node);
+  AbstractValue typeOfIteratorMoveNext(T node);
 
-  TypeMask typeOfIteratorCurrent(T node);
+  AbstractValue typeOfIteratorCurrent(T node);
 
-  void setIteratorTypeMask(T node, TypeMask mask);
+  void setIteratorTypeMask(T node, AbstractValue mask);
 
-  void setMoveNextTypeMask(T node, TypeMask mask);
+  void setMoveNextTypeMask(T node, AbstractValue mask);
 
-  void setCurrentTypeMask(T node, TypeMask mask);
+  void setCurrentTypeMask(T node, AbstractValue mask);
 }
 
 /// API to interact with the global type-inference engine.
 abstract class TypesInferrer<T> {
+  AbstractValueDomain get abstractValueDomain;
   void analyzeMain(FunctionEntity element);
-  TypeMask getReturnTypeOfMember(MemberEntity element);
-  TypeMask getReturnTypeOfParameter(Local element);
-  TypeMask getTypeOfMember(MemberEntity element);
-  TypeMask getTypeOfParameter(Local element);
-  TypeMask getTypeForNewList(T node);
-  TypeMask getTypeOfSelector(Selector selector, TypeMask mask);
+  AbstractValue getReturnTypeOfMember(MemberEntity element);
+  AbstractValue getReturnTypeOfParameter(Local element);
+  AbstractValue getTypeOfMember(MemberEntity element);
+  AbstractValue getTypeOfParameter(Local element);
+  AbstractValue getTypeForNewList(T node);
+  AbstractValue getTypeOfSelector(Selector selector, AbstractValue receiver);
   void clear();
   bool isMemberCalledOnce(MemberEntity element);
   bool isFixedArrayCheckedForGrowable(T node);
@@ -226,11 +229,9 @@
         parameter, () => createParameterResult(_inferrer, parameter));
   }
 
-  TypeMask get dynamicType => closedWorld.abstractValueDomain.dynamicType;
-
   /// Returns the type of a [selector] when applied to a receiver with the given
   /// type [mask].
-  TypeMask typeOfSelector(Selector selector, TypeMask mask) =>
+  AbstractValue typeOfSelector(Selector selector, AbstractValue mask) =>
       _inferrer.getTypeOfSelector(selector, mask);
 
   /// Returns whether a fixed-length constructor call goes through a growable