| Index: pkg/compiler/lib/src/world.dart
 | 
| diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
 | 
| index 87090deb797ef77020dc2caf090676d0e593a610..6ce4b16ccc34c0a5acaba7ce20bacf790ea1591e 100644
 | 
| --- a/pkg/compiler/lib/src/world.dart
 | 
| +++ b/pkg/compiler/lib/src/world.dart
 | 
| @@ -19,7 +19,7 @@ import 'elements/elements.dart'
 | 
|          TypedefElement,
 | 
|          VariableElement;
 | 
|  import 'ordered_typeset.dart';
 | 
| -import 'types/masks.dart' show TypeMask, FlatTypeMask;
 | 
| +import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
 | 
|  import 'universe/class_set.dart';
 | 
|  import 'universe/function_set.dart' show FunctionSet;
 | 
|  import 'universe/selector.dart' show Selector;
 | 
| @@ -38,30 +38,7 @@ abstract class ClassWorld {
 | 
|    // TODO(johnniwinther): Refine this into a `BackendClasses` interface.
 | 
|    Backend get backend;
 | 
|  
 | 
| -  // TODO(johnniwinther): Remove the need for this getter.
 | 
| -  @deprecated
 | 
| -  Compiler get compiler;
 | 
| -
 | 
| -  /// The [ClassElement] for the [Object] class defined in 'dart:core'.
 | 
| -  ClassElement get objectClass;
 | 
| -
 | 
| -  /// The [ClassElement] for the [Function] class defined in 'dart:core'.
 | 
| -  ClassElement get functionClass;
 | 
| -
 | 
| -  /// The [ClassElement] for the [bool] class defined in 'dart:core'.
 | 
| -  ClassElement get boolClass;
 | 
| -
 | 
| -  /// The [ClassElement] for the [num] class defined in 'dart:core'.
 | 
| -  ClassElement get numClass;
 | 
| -
 | 
| -  /// The [ClassElement] for the [int] class defined in 'dart:core'.
 | 
| -  ClassElement get intClass;
 | 
| -
 | 
| -  /// The [ClassElement] for the [double] class defined in 'dart:core'.
 | 
| -  ClassElement get doubleClass;
 | 
| -
 | 
| -  /// The [ClassElement] for the [String] class defined in 'dart:core'.
 | 
| -  ClassElement get stringClass;
 | 
| +  CoreClasses get coreClasses;
 | 
|  
 | 
|    /// Returns `true` if [cls] is either directly or indirectly instantiated.
 | 
|    bool isInstantiated(ClassElement cls);
 | 
| @@ -185,18 +162,98 @@ abstract class ClassWorld {
 | 
|    ///
 | 
|    /// If [cls] is provided, the dump will contain only classes related to [cls].
 | 
|    String dump([ClassElement cls]);
 | 
| +
 | 
| +  /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
 | 
| +  /// of known classes.
 | 
| +  ///
 | 
| +  /// This method is only provided for testing. For queries on classes, use the
 | 
| +  /// methods defined in [ClassWorld].
 | 
| +  ClassHierarchyNode getClassHierarchyNode(ClassElement cls);
 | 
| +}
 | 
| +
 | 
| +/// The [ClosedWorld] represents the information known about a program when
 | 
| +/// compiling with closed-world semantics.
 | 
| +///
 | 
| +/// This expands [ClassWorld] with information about live functions,
 | 
| +/// side effects, and selectors with known single targets.
 | 
| +abstract class ClosedWorld extends ClassWorld {
 | 
| +  /// Returns the [FunctionSet] containing all live functions in the closed
 | 
| +  /// world.
 | 
| +  FunctionSet get allFunctions;
 | 
| +
 | 
| +  /// Returns `true` if the field [element] is known to be effectively final.
 | 
| +  bool fieldNeverChanges(Element element);
 | 
| +
 | 
| +  /// Extends the receiver type [mask] for calling [selector] to take live
 | 
| +  /// `noSuchMethod` handlers into account.
 | 
| +  TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask);
 | 
| +
 | 
| +  /// Returns all resolved typedefs.
 | 
| +  Iterable<TypedefElement> get allTypedefs;
 | 
| +
 | 
| +  /// Returns the single [Element] that matches a call to [selector] on a
 | 
| +  /// receiver of type [mask]. If multiple targets exist, `null` is returned.
 | 
| +  Element locateSingleElement(Selector selector, TypeMask mask);
 | 
| +
 | 
| +  /// Returns the single field that matches a call to [selector] on a
 | 
| +  /// receiver of type [mask]. If multiple targets exist or the single target
 | 
| +  /// is not a field, `null` is returned.
 | 
| +  VariableElement locateSingleField(Selector selector, TypeMask mask);
 | 
| +
 | 
| +  /// Returns the side effects of executing [element].
 | 
| +  SideEffects getSideEffectsOfElement(Element element);
 | 
| +
 | 
| +  /// Returns the side effects of calling [selector] on a receiver of type
 | 
| +  /// [mask].
 | 
| +  SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask);
 | 
| +
 | 
| +  /// Returns `true` if [element] is guaranteed not to throw an exception.
 | 
| +  bool getCannotThrow(Element element);
 | 
| +
 | 
| +  /// Returns `true` if [element] is called in a loop.
 | 
| +  // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'?
 | 
| +  bool isCalledInLoop(Element element);
 | 
| +
 | 
| +  /// Returns `true` if [element] might be passed to `Function.apply`.
 | 
| +  // TODO(johnniwinther): Is this 'passed invocation target` or
 | 
| +  // `passed as argument`?
 | 
| +  bool getMightBePassedToApply(Element element);
 | 
|  }
 | 
|  
 | 
| -class World implements ClassWorld {
 | 
| -  ClassElement get objectClass => coreClasses.objectClass;
 | 
| -  ClassElement get functionClass => coreClasses.functionClass;
 | 
| -  ClassElement get boolClass => coreClasses.boolClass;
 | 
| -  ClassElement get numClass => coreClasses.numClass;
 | 
| -  ClassElement get intClass => coreClasses.intClass;
 | 
| -  ClassElement get doubleClass => coreClasses.doubleClass;
 | 
| -  ClassElement get stringClass => coreClasses.stringClass;
 | 
| -  ClassElement get nullClass => coreClasses.nullClass;
 | 
| +/// Interface for computing side effects and uses of elements. This is used
 | 
| +/// during type inference to compute the [ClosedWorld] for code generation.
 | 
| +abstract class ClosedWorldRefiner {
 | 
| +  /// Registers the side [effects] of executing [element].
 | 
| +  void registerSideEffects(Element element, SideEffects effects);
 | 
|  
 | 
| +  /// Registers the executing of [element] as without side effects.
 | 
| +  void registerSideEffectsFree(Element element);
 | 
| +
 | 
| +  /// Returns the currently known side effects of executing [element].
 | 
| +  SideEffects getCurrentlyKnownSideEffects(Element element);
 | 
| +
 | 
| +  /// Registers that [element] might be passed to `Function.apply`.
 | 
| +  // TODO(johnniwinther): Is this 'passed invocation target` or
 | 
| +  // `passed as argument`?
 | 
| +  void registerMightBePassedToApply(Element element);
 | 
| +
 | 
| +  /// Returns `true` if [element] might be passed to `Function.apply` given the
 | 
| +  /// currently inferred information.
 | 
| +  bool getCurrentlyKnownMightBePassedToApply(Element element);
 | 
| +
 | 
| +  /// Registers that [element] is called in a loop.
 | 
| +  // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'?
 | 
| +  void addFunctionCalledInLoop(Element element);
 | 
| +
 | 
| +  /// Registers that [element] is guaranteed not to throw an exception.
 | 
| +  void registerCannotThrow(Element element);
 | 
| +
 | 
| +  /// Adds the closure class [cls] to the inference world. The class is
 | 
| +  /// considered directly instantiated.
 | 
| +  void registerClosureClass(ClassElement cls);
 | 
| +}
 | 
| +
 | 
| +class World implements ClosedWorld, ClosedWorldRefiner {
 | 
|    /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
 | 
|    /// `FlatTypeMask.flags` property.
 | 
|    List<Map<ClassElement, TypeMask>> canonicalizedTypeMasks =
 | 
| @@ -221,10 +278,10 @@ class World implements ClassWorld {
 | 
|      assert(checkInvariants(x));
 | 
|      assert(checkInvariants(y, mustBeInstantiated: false));
 | 
|  
 | 
| -    if (y == objectClass) return true;
 | 
| -    if (x == objectClass) return false;
 | 
| +    if (y == coreClasses.objectClass) return true;
 | 
| +    if (x == coreClasses.objectClass) return false;
 | 
|      if (x.asInstanceOf(y) != null) return true;
 | 
| -    if (y != functionClass) return false;
 | 
| +    if (y != coreClasses.functionClass) return false;
 | 
|      return x.callType != null;
 | 
|    }
 | 
|  
 | 
| @@ -233,8 +290,8 @@ class World implements ClassWorld {
 | 
|      assert(checkInvariants(x));
 | 
|      assert(checkInvariants(y));
 | 
|  
 | 
| -    if (y == objectClass) return true;
 | 
| -    if (x == objectClass) return false;
 | 
| +    if (y == coreClasses.objectClass) return true;
 | 
| +    if (x == coreClasses.objectClass) return false;
 | 
|      while (x != null && x.hierarchyDepth >= y.hierarchyDepth) {
 | 
|        if (x == y) return true;
 | 
|        x = x.superclass;
 | 
| @@ -262,7 +319,7 @@ class World implements ClassWorld {
 | 
|  
 | 
|    /// Returns `true` if [cls] is implemented by an instantiated class.
 | 
|    bool isImplemented(ClassElement cls) {
 | 
| -    return compiler.resolverWorld.isImplemented(cls);
 | 
| +    return _compiler.resolverWorld.isImplemented(cls);
 | 
|    }
 | 
|  
 | 
|    /// Returns an iterable over the directly instantiated classes that extend
 | 
| @@ -394,7 +451,7 @@ class World implements ClassWorld {
 | 
|    /// extend it.
 | 
|    bool hasOnlySubclasses(ClassElement cls) {
 | 
|      // TODO(johnniwinther): move this to ClassSet?
 | 
| -    if (cls == objectClass) return true;
 | 
| +    if (cls == coreClasses.objectClass) return true;
 | 
|      ClassSet classSet = _classSets[cls.declaration];
 | 
|      if (classSet == null) {
 | 
|        // Vacuously true.
 | 
| @@ -442,7 +499,7 @@ class World implements ClassWorld {
 | 
|      List<ClassElement> commonSupertypes = <ClassElement>[];
 | 
|      OUTER:
 | 
|      for (Link<DartType> link = typeSet[depth];
 | 
| -        link.head.element != objectClass;
 | 
| +        link.head.element != coreClasses.objectClass;
 | 
|          link = link.tail) {
 | 
|        ClassElement cls = link.head.element;
 | 
|        for (Link<OrderedTypeSet> link = otherTypeSets;
 | 
| @@ -454,7 +511,7 @@ class World implements ClassWorld {
 | 
|        }
 | 
|        commonSupertypes.add(cls);
 | 
|      }
 | 
| -    commonSupertypes.add(objectClass);
 | 
| +    commonSupertypes.add(coreClasses.objectClass);
 | 
|      return commonSupertypes;
 | 
|    }
 | 
|  
 | 
| @@ -547,8 +604,9 @@ class World implements ClassWorld {
 | 
|      return subclasses.contains(type);
 | 
|    }
 | 
|  
 | 
| -  final Compiler compiler;
 | 
| -  Backend get backend => compiler.backend;
 | 
| +  final Compiler _compiler;
 | 
| +  Backend get backend => _compiler.backend;
 | 
| +  CommonMasks get commonMasks => _compiler.commonMasks;
 | 
|    final FunctionSet allFunctions;
 | 
|    final Set<Element> functionsCalledInLoop = new Set<Element>();
 | 
|    final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>();
 | 
| @@ -580,11 +638,11 @@ class World implements ClassWorld {
 | 
|  
 | 
|    final Set<Element> alreadyPopulated;
 | 
|  
 | 
| -  bool get isClosed => compiler.phase > Compiler.PHASE_RESOLVING;
 | 
| +  bool get isClosed => _compiler.phase > Compiler.PHASE_RESOLVING;
 | 
|  
 | 
|    // Used by selectors.
 | 
|    bool isForeign(Element element) {
 | 
| -    return compiler.backend.isForeign(element);
 | 
| +    return backend.isForeign(element);
 | 
|    }
 | 
|  
 | 
|    Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) {
 | 
| @@ -593,18 +651,24 @@ class World implements ClassWorld {
 | 
|  
 | 
|    World(Compiler compiler)
 | 
|        : allFunctions = new FunctionSet(compiler),
 | 
| -        this.compiler = compiler,
 | 
| +        this._compiler = compiler,
 | 
|          alreadyPopulated = compiler.cacheStrategy.newSet();
 | 
|  
 | 
| -  CoreClasses get coreClasses => compiler.coreClasses;
 | 
| +  CoreClasses get coreClasses => _compiler.coreClasses;
 | 
|  
 | 
| -  DiagnosticReporter get reporter => compiler.reporter;
 | 
| +  DiagnosticReporter get reporter => _compiler.reporter;
 | 
|  
 | 
|    /// Called to add [cls] to the set of known classes.
 | 
|    ///
 | 
|    /// This ensures that class hierarchy queries can be performed on [cls] and
 | 
|    /// classes that extend or implement it.
 | 
| -  void registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) {
 | 
| +  void registerClass(ClassElement cls) => _registerClass(cls);
 | 
| +
 | 
| +  void registerClosureClass(ClassElement cls) {
 | 
| +    _registerClass(cls, isDirectlyInstantiated: true);
 | 
| +  }
 | 
| +
 | 
| +  void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) {
 | 
|      _ensureClassSet(cls);
 | 
|      if (isDirectlyInstantiated) {
 | 
|        _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
 | 
| @@ -693,7 +757,7 @@ class World implements ClassWorld {
 | 
|      /// properties of the [ClassHierarchyNode] for [cls].
 | 
|  
 | 
|      void addSubtypes(ClassElement cls) {
 | 
| -      if (compiler.options.hasIncrementalSupport &&
 | 
| +      if (_compiler.options.hasIncrementalSupport &&
 | 
|            !alreadyPopulated.add(cls)) {
 | 
|          return;
 | 
|        }
 | 
| @@ -722,7 +786,7 @@ class World implements ClassWorld {
 | 
|      // classes: if the superclass of these classes require RTI, then
 | 
|      // they also need RTI, so that a constructor passes the type
 | 
|      // variables to the super constructor.
 | 
| -    compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes);
 | 
| +    _compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes);
 | 
|    }
 | 
|  
 | 
|    @override
 | 
| @@ -764,17 +828,17 @@ class World implements ClassWorld {
 | 
|    }
 | 
|  
 | 
|    Element locateSingleElement(Selector selector, TypeMask mask) {
 | 
| -    mask ??= compiler.commonMasks.dynamicType;
 | 
| -    return mask.locateSingleElement(selector, compiler);
 | 
| +    mask ??= commonMasks.dynamicType;
 | 
| +    return mask.locateSingleElement(selector, _compiler);
 | 
|    }
 | 
|  
 | 
|    TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
 | 
|      bool canReachAll = true;
 | 
|      if (mask != null) {
 | 
| -      canReachAll = compiler.enabledInvokeOn &&
 | 
| +      canReachAll = _compiler.enabledInvokeOn &&
 | 
|            mask.needsNoSuchMethodHandling(selector, this);
 | 
|      }
 | 
| -    return canReachAll ? compiler.commonMasks.dynamicType : mask;
 | 
| +    return canReachAll ? commonMasks.dynamicType : mask;
 | 
|    }
 | 
|  
 | 
|    void addFunctionCalledInLoop(Element element) {
 | 
| @@ -799,8 +863,8 @@ class World implements ClassWorld {
 | 
|        return true;
 | 
|      }
 | 
|      if (element.isInstanceMember) {
 | 
| -      return !compiler.resolverWorld.hasInvokedSetter(element, this) &&
 | 
| -          !compiler.resolverWorld.fieldSetters.contains(element);
 | 
| +      return !_compiler.resolverWorld.hasInvokedSetter(element, this) &&
 | 
| +          !_compiler.resolverWorld.fieldSetters.contains(element);
 | 
|      }
 | 
|      return false;
 | 
|    }
 | 
| @@ -819,6 +883,11 @@ class World implements ClassWorld {
 | 
|      });
 | 
|    }
 | 
|  
 | 
| +  @override
 | 
| +  SideEffects getCurrentlyKnownSideEffects(Element element) {
 | 
| +    return getSideEffectsOfElement(element);
 | 
| +  }
 | 
| +
 | 
|    void registerSideEffects(Element element, SideEffects effects) {
 | 
|      if (sideEffectsFreeElements.contains(element)) return;
 | 
|      sideEffects[element.declaration] = effects;
 | 
| @@ -878,5 +947,10 @@ class World implements ClassWorld {
 | 
|      return functionsThatMightBePassedToApply.contains(element);
 | 
|    }
 | 
|  
 | 
| -  bool get hasClosedWorldAssumption => !compiler.options.hasIncrementalSupport;
 | 
| +  @override
 | 
| +  bool getCurrentlyKnownMightBePassedToApply(Element element) {
 | 
| +    return getMightBePassedToApply(element);
 | 
| +  }
 | 
| +
 | 
| +  bool get hasClosedWorldAssumption => !_compiler.options.hasIncrementalSupport;
 | 
|  }
 | 
| 
 |