content: // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
  // for details. All rights reserved. Use of this source code is governed by a
  // BSD-style license that can be found in the LICENSE file.
  
  part of types;
  
  /**
   * A type mask represents a set of contained classes, but the
   * operations on it are not guaranteed to be precise and they may
   * yield conservative answers that contain too many classes.
   */
  abstract class TypeMask {
    factory TypeMask(ClassElement base, int kind, bool isNullable)
        => new FlatTypeMask(base, kind, isNullable);
  
    const factory TypeMask.empty() = FlatTypeMask.empty;
  
    factory TypeMask.exact(ClassElement base)
        => new FlatTypeMask.exact(base);
    factory TypeMask.subclass(ClassElement base)
        => new FlatTypeMask.subclass(base);
    factory TypeMask.subtype(ClassElement base)
        => new FlatTypeMask.subtype(base);
  
    const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
    factory TypeMask.nonNullExact(ClassElement base)
        => new FlatTypeMask.nonNullExact(base);
    factory TypeMask.nonNullSubclass(ClassElement base)
        => new FlatTypeMask.nonNullSubclass(base);
    factory TypeMask.nonNullSubtype(ClassElement base)
        => new FlatTypeMask.nonNullSubtype(base);
  
    factory TypeMask.unionOf(Iterable<TypeMask> masks, Compiler compiler) {
      return UnionTypeMask.unionOf(masks, compiler);
    }
  
    /**
     * Returns a nullable variant of [this] type mask.
     */
    TypeMask nullable();
  
    /**
     * Returns a non-nullable variant of [this] type mask.
     */
    TypeMask nonNullable();
  
    TypeMask simplify(Compiler compiler);
  
    bool get isEmpty;
    bool get isNullable;
    bool get isExact;
  
    bool get isUnion;
    bool get isContainer;
    bool get isForwarding;
  
    bool containsOnlyInt(Compiler compiler);
    bool containsOnlyDouble(Compiler compiler);
    bool containsOnlyNum(Compiler compiler);
    bool containsOnlyNull(Compiler compiler);
    bool containsOnlyBool(Compiler compiler);
    bool containsOnlyString(Compiler compiler);
    bool containsOnly(ClassElement element);
  
    /**
     * Returns whether this type mask is a subtype of [other].
     */
    bool isInMask(TypeMask other, Compiler compiler);
  
    /**
     * Returns whether [other] is a subtype of this type mask.
     */
    bool containsMask(TypeMask other, Compiler compiler);
  
    /**
     * Returns whether this type mask is an instance of [cls].
     */
    bool satisfies(ClassElement cls, Compiler compiler);
  
    /**
     * Returns whether or not this type mask contains the given type.
     */
    bool contains(ClassElement type, Compiler compiler);
  
    /**
     * Returns whether or not this type mask contains all types.
     */
    bool containsAll(Compiler compiler);
  
    /**
     * Returns the [ClassElement] if this type represents a single class,
     * otherwise returns `null`.  This method is conservative.
     */
    ClassElement singleClass(Compiler compiler);
  
    /**
     * Returns the classes this type mask can be.
     */
    Iterable<ClassElement> containedClasses(Compiler compiler);
  
    /**
     * Returns a type mask representing the union of [this] and [other].
     */
    TypeMask union(TypeMask other, Compiler compiler);
  
    /**
     * Returns a type mask representing the intersection of [this] and [other].
     */
    TypeMask intersection(TypeMask other, Compiler compiler);
  
    /**
     * Returns whether this [TypeMask] understands [selector].
     */
    bool understands(Selector selector, Compiler compiler);
  
    /**
     * Returns whether this [TypeMask] applied to [selector] can hit a
     * [noSuchMethod].
     */
    bool needsNoSuchMethodHandling(Selector selector, Compiler compiler);
  
    /**
     * Returns whether [element] is a potential target when being
     * invoked on this type mask. [selector] is used to ensure library
     * privacy is taken into account.
     */
    bool canHit(Element element, Selector selector, Compiler compiler);
  
    /**
     * Returns the [element] that is known to always be hit at runtime
     * on this mask. Returns null if there is none.
     */
    Element locateSingleElement(Selector selector, Compiler compiler);
  }
  