// 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 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 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] 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);
}
