// Copyright (c) 2012, 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 ssa;

abstract class HType {
  const HType();

  /**
   * Returns an [HType] with the given type mask. The factory method
   * takes care to track whether or not the resulting type may be a
   * primitive type.
   */
  factory HType.fromMask(TypeMask mask, Compiler compiler) {
    bool isNullable = mask.isNullable;
    if (mask.isEmpty) {
      return isNullable ? HType.NULL : HType.CONFLICTING;
    }

    JavaScriptBackend backend = compiler.backend;
    if (mask.containsOnlyInt(compiler)) {
      return isNullable ? HType.INTEGER_OR_NULL : HType.INTEGER;
    } else if (mask.containsOnlyDouble(compiler)) {
      return isNullable ? HType.DOUBLE_OR_NULL : HType.DOUBLE;
    } else if (mask.containsOnlyNum(compiler)
               || mask.satisfies(backend.jsNumberClass, compiler)) {
      return isNullable ? HType.NUMBER_OR_NULL : HType.NUMBER;
    } else if (mask.containsOnlyString(compiler)) {
      return isNullable ? HType.STRING_OR_NULL : HType.STRING;
    } else if (mask.containsOnlyBool(compiler)) {
      return isNullable ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN;
    } else if (mask.containsOnlyNull(compiler)) {
      return HType.NULL;
    }

    // TODO(kasperl): A lot of the code in the system currently
    // expects the top type to be 'unknown'. I'll rework this.
    if (mask.containsAll(compiler)) {
      return isNullable ? HType.UNKNOWN : HType.NON_NULL;
    }

    if (!isNullable) {
      if (mask.containsOnly(backend.jsFixedArrayClass)) {
        return HType.FIXED_ARRAY;
      } else if (mask.containsOnly(backend.jsExtendableArrayClass)) {
        return HType.EXTENDABLE_ARRAY;
      } else if (mask.satisfies(backend.jsMutableArrayClass, compiler)) {
        return HType.MUTABLE_ARRAY;
      } else if (mask.satisfies(backend.jsArrayClass, compiler)) {
        return HType.READABLE_ARRAY;
      } else if (mask.satisfies(backend.jsIndexableClass, compiler)) {
        return HType.INDEXABLE_PRIMITIVE;
      }
    }
    return new HBoundedType(mask);
  }

  factory HType.exact(DartType type, Compiler compiler) {
    TypeMask mask = new TypeMask.exact(type);
    return new HType.fromMask(mask, compiler);
  }

  factory HType.subclass(DartType type, Compiler compiler) {
    TypeMask mask = new TypeMask.subclass(type);
    return new HType.fromMask(mask, compiler);
  }

  factory HType.subtype(DartType type, Compiler compiler) {
    TypeMask mask = new TypeMask.subtype(type);
    return new HType.fromMask(mask, compiler);
  }

  factory HType.nonNullExact(DartType type, Compiler compiler) {
    TypeMask mask = new TypeMask.nonNullExact(type);
    return new HType.fromMask(mask, compiler);
  }

  factory HType.nonNullSubclass(DartType type, Compiler compiler) {
    TypeMask mask = new TypeMask.nonNullSubclass(type);
    return new HType.fromMask(mask, compiler);
  }

  factory HType.nonNullSubtype(DartType type, Compiler compiler) {
    TypeMask mask = new TypeMask.nonNullSubtype(type);
    return new HType.fromMask(mask, compiler);
  }

  factory HType.fromInferredType(TypeMask mask, Compiler compiler) {
    if (mask == null) return HType.UNKNOWN;
    return new HType.fromMask(mask, compiler);
  }

  factory HType.inferredReturnTypeForElement(
      Element element, Compiler compiler) {
    return new HType.fromInferredType(
        compiler.typesTask.getGuaranteedReturnTypeOfElement(element),
        compiler);
  }

  factory HType.inferredTypeForElement(Element element, Compiler compiler) {
    return new HType.fromInferredType(
        compiler.typesTask.getGuaranteedTypeOfElement(element),
        compiler);
  }

  factory HType.inferredTypeForSelector(Selector selector, Compiler compiler) {
    return new HType.fromInferredType(
        compiler.typesTask.getGuaranteedTypeOfSelector(selector),
        compiler);
  }

  factory HType.inferredForNode(Element owner, Node node, Compiler compiler) {
    return new HType.fromInferredType(
        compiler.typesTask.getGuaranteedTypeOfNode(owner, node),
        compiler);
  }

  factory HType.fromNativeBehavior(native.NativeBehavior nativeBehavior,
                                   Compiler compiler) {
    if (nativeBehavior.typesReturned.isEmpty) return HType.UNKNOWN;

    HType result = nativeBehavior.typesReturned
        .map((type) => fromNativeType(type, compiler))
        .reduce((t1, t2) => t1.union(t2, compiler));
    assert(!result.isConflicting());
    return result;
  }

  // [type] is either an instance of [DartType] or special objects
  // like [native.SpecialType.JsObject], or [native.SpecialType.JsArray].
  static HType fromNativeType(type, Compiler compiler) {
    if (type == native.SpecialType.JsObject) {
      return new HType.nonNullExact(
          compiler.objectClass.computeType(compiler), compiler);
    } else if (type == native.SpecialType.JsArray) {
      return HType.READABLE_ARRAY;
    } else if (type.isVoid) {
      return HType.NULL;
    } else if (type.element == compiler.nullClass) {
      return HType.NULL;
    } else if (type.isDynamic) {
      return HType.UNKNOWN;
    } else if (compiler.world.hasAnySubtype(type.element)) {
      return new HType.nonNullSubtype(type, compiler);
    } else if (compiler.world.hasAnySubclass(type.element)) {
      return new HType.nonNullSubclass(type, compiler);
    } else {
      return new HType.nonNullExact(type, compiler);
    }
  }

  static const HType CONFLICTING = const HConflictingType();
  static const HType UNKNOWN = const HUnknownType();
  static const HType NON_NULL = const HNonNullType();
  static const HType BOOLEAN = const HBooleanType();
  static const HType NUMBER = const HNumberType();
  static const HType INTEGER = const HIntegerType();
  static const HType DOUBLE = const HDoubleType();
  static const HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType();
  static const HType STRING = const HStringType();
  static const HType READABLE_ARRAY = const HReadableArrayType();
  static const HType MUTABLE_ARRAY = const HMutableArrayType();
  static const HType FIXED_ARRAY = const HFixedArrayType();
  static const HType EXTENDABLE_ARRAY = const HExtendableArrayType();
  static const HType NULL = const HNullType();

  static const HType BOOLEAN_OR_NULL = const HBooleanOrNullType();
  static const HType NUMBER_OR_NULL = const HNumberOrNullType();
  static const HType INTEGER_OR_NULL = const HIntegerOrNullType();
  static const HType DOUBLE_OR_NULL = const HDoubleOrNullType();
  static const HType STRING_OR_NULL = const HStringOrNullType();

  bool isConflicting() => identical(this, CONFLICTING);
  bool isUnknown() => identical(this, UNKNOWN);
  bool isExact() => false;
  bool isNull() => false;
  bool isBoolean() => false;
  bool isNumber() => false;
  bool isInteger() => false;
  bool isDouble() => false;
  bool isString() => false;

  bool isFixedArray(Compiler compiler) => false;
  bool isReadableArray(Compiler compiler) => false;
  bool isMutableArray(Compiler compiler) => false;
  bool isExtendableArray(Compiler compiler) => false;

  bool isPrimitive() => false;
  bool isBooleanOrNull() => false;
  bool isNumberOrNull() => false;
  bool isIntegerOrNull() => false;
  bool isDoubleOrNull() => false;
  bool isStringOrNull() => false;
  bool isPrimitiveOrNull() => false;

  // TODO(kasperl): Get rid of this one.
  bool isIndexablePrimitive(Compiler compiler) => false;

  bool isIndexable(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return implementsInterface(backend.jsIndexableClass, compiler);
  }

  bool isMutableIndexable(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return implementsInterface(backend.jsMutableIndexableClass, compiler);
  }

  bool implementsInterface(ClassElement interfaceElement, Compiler compiler) {
    DartType interfaceType = interfaceElement.computeType(compiler);
    TypeMask mask = new TypeMask.subtype(interfaceType);
    return mask == mask.union(computeMask(compiler), compiler);
  }

  bool canBeNull() => false;
  bool canBePrimitive(Compiler compiler) => false;
  bool canBePrimitiveNumber(Compiler compiler) => false;
  bool canBePrimitiveString(Compiler compiler) => false;
  bool canBePrimitiveArray(Compiler compiler) => false;
  bool canBePrimitiveBoolean(Compiler compiler) => false;

  /** A type is useful it is not unknown, not conflicting, and not null. */
  bool isUseful() => !isUnknown() && !isConflicting() && !isNull();
  /** Alias for isReadableArray. */
  bool isArray(Compiler compiler) => isReadableArray(compiler);

  TypeMask computeMask(Compiler compiler);

  Selector refine(Selector selector, Compiler compiler) {
    // TODO(kasperl): Should we check if the refinement really is more
    // specialized than the starting point?
    TypeMask mask = computeMask(compiler);
    if (selector.mask == mask) return selector;
    return new TypedSelector(mask, selector);
  }

  /**
   * The intersection of two types is the intersection of its values. For
   * example:
   *   * INTEGER.intersect(NUMBER) => INTEGER.
   *   * DOUBLE.intersect(INTEGER) => CONFLICTING.
   *   * MUTABLE_ARRAY.intersect(READABLE_ARRAY) => MUTABLE_ARRAY.
   *
   * When there is no predefined type to represent the intersection returns
   * [CONFLICTING].
   *
   * An intersection with [UNKNOWN] returns the non-UNKNOWN type. An
   * intersection with [CONFLICTING] returns [CONFLICTING].
   */
  HType intersection(HType other, Compiler compiler) {
    TypeMask mask = computeMask(compiler);
    TypeMask otherMask = other.computeMask(compiler);
    TypeMask intersection = mask.intersection(otherMask, compiler);
    return new HType.fromMask(intersection, compiler);
  }

  /**
   * The union of two types is the union of its values. For example:
   *   * INTEGER.union(NUMBER) => NUMBER.
   *   * DOUBLE.union(INTEGER) => NUMBER.
   *   * MUTABLE_ARRAY.union(READABLE_ARRAY) => READABLE_ARRAY.
   *
   * When there is no predefined type to represent the union returns
   * [UNKNOWN].
   *
   * A union with [UNKNOWN] returns [UNKNOWN].
   * A union of [CONFLICTING] with any other types returns the other type.
   */
  HType union(HType other, Compiler compiler) {
    TypeMask mask = computeMask(compiler);
    TypeMask otherMask = other.computeMask(compiler);
    TypeMask union = mask.union(otherMask, compiler);
    return new HType.fromMask(union, compiler);
  }

  HType simplify(Compiler compiler) => this;
}

/** Used to represent [HType.UNKNOWN] and [HType.CONFLICTING]. */
abstract class HAnalysisType extends HType {
  final String name;
  const HAnalysisType(this.name);
  String toString() => name;
}

class HUnknownType extends HAnalysisType {
  const HUnknownType() : super("unknown");
  bool canBePrimitive(Compiler compiler) => true;
  bool canBeNull() => true;
  bool canBePrimitiveNumber(Compiler compiler) => true;
  bool canBePrimitiveString(Compiler compiler) => true;
  bool canBePrimitiveArray(Compiler compiler) => true;
  bool canBePrimitiveBoolean(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    DartType base = compiler.objectClass.computeType(compiler);
    return new TypeMask.subclass(base);
  }
}

class HNonNullType extends HAnalysisType {
  const HNonNullType() : super("non-null");
  bool canBePrimitive(Compiler compiler) => true;
  bool canBeNull() => false;
  bool canBePrimitiveNumber(Compiler compiler) => true;
  bool canBePrimitiveString(Compiler compiler) => true;
  bool canBePrimitiveArray(Compiler compiler) => true;
  bool canBePrimitiveBoolean(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    DartType base = compiler.objectClass.computeType(compiler);
    return new TypeMask.nonNullSubclass(base);
  }
}

class HConflictingType extends HAnalysisType {
  const HConflictingType() : super("conflicting");
  bool canBePrimitive(Compiler compiler) => true;
  bool canBeNull() => false;

  TypeMask computeMask(Compiler compiler) {
    return new TypeMask.nonNullEmpty();
  }
}

abstract class HPrimitiveType extends HType {
  const HPrimitiveType();
  bool isPrimitive() => true;
  bool canBePrimitive(Compiler compiler) => true;
  bool isPrimitiveOrNull() => true;
}

class HNullType extends HPrimitiveType {
  const HNullType();
  bool canBeNull() => true;
  bool isNull() => true;
  String toString() => 'null type';
  bool isExact() => true;

  TypeMask computeMask(Compiler compiler) {
    return new TypeMask.empty();
  }
}

abstract class HPrimitiveOrNullType extends HType {
  const HPrimitiveOrNullType();
  bool canBePrimitive(Compiler compiler) => true;
  bool canBeNull() => true;
  bool isPrimitiveOrNull() => true;
}

class HBooleanOrNullType extends HPrimitiveOrNullType {
  const HBooleanOrNullType();
  String toString() => "boolean or null";
  bool isBooleanOrNull() => true;
  bool canBePrimitiveBoolean(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsBoolClass.computeType(compiler);
    return new TypeMask.exact(base);
  }
}

class HBooleanType extends HPrimitiveType {
  const HBooleanType();
  bool isBoolean() => true;
  bool isBooleanOrNull() => true;
  String toString() => "boolean";
  bool isExact() => true;
  bool canBePrimitiveBoolean(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsBoolClass.computeType(compiler);
    return new TypeMask.nonNullExact(base);
  }
}

class HNumberOrNullType extends HPrimitiveOrNullType {
  const HNumberOrNullType();
  bool isNumberOrNull() => true;
  String toString() => "number or null";
  bool canBePrimitiveNumber(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsNumberClass.computeType(compiler);
    return new TypeMask.subclass(base);
  }
}

class HNumberType extends HPrimitiveType {
  const HNumberType();
  bool isNumber() => true;
  bool isNumberOrNull() => true;
  String toString() => "number";
  bool canBePrimitiveNumber(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsNumberClass.computeType(compiler);
    return new TypeMask.nonNullSubclass(base);
  }
}

class HIntegerOrNullType extends HNumberOrNullType {
  const HIntegerOrNullType();
  bool isIntegerOrNull() => true;
  String toString() => "integer or null";

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsIntClass.computeType(compiler);
    return new TypeMask.exact(base);
  }
}

class HIntegerType extends HNumberType {
  const HIntegerType();
  bool isInteger() => true;
  bool isIntegerOrNull() => true;
  String toString() => "integer";
  bool isExact() => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsIntClass.computeType(compiler);
    return new TypeMask.nonNullExact(base);
  }
}

class HDoubleOrNullType extends HNumberOrNullType {
  const HDoubleOrNullType();
  bool isDoubleOrNull() => true;
  String toString() => "double or null";

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsDoubleClass.computeType(compiler);
    return new TypeMask.exact(base);
  }
}

class HDoubleType extends HNumberType {
  const HDoubleType();
  bool isDouble() => true;
  bool isDoubleOrNull() => true;
  String toString() => "double";
  bool isExact() => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsDoubleClass.computeType(compiler);
    return new TypeMask.nonNullExact(base);
  }
}

class HIndexablePrimitiveType extends HPrimitiveType {
  const HIndexablePrimitiveType();
  bool isIndexablePrimitive(Compiler compiler) => true;
  String toString() => "indexable";

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsIndexableClass.computeType(compiler);
    return new TypeMask.nonNullSubtype(base);
  }
}

class HStringOrNullType extends HPrimitiveOrNullType {
  const HStringOrNullType();
  bool isStringOrNull() => true;
  String toString() => "String or null";
  bool canBePrimitiveString(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsStringClass.computeType(compiler);
    return new TypeMask.exact(base);
  }
}

class HStringType extends HIndexablePrimitiveType {
  const HStringType();
  bool isString() => true;
  bool isStringOrNull() => true;
  String toString() => "String";
  bool isExact() => true;
  bool canBePrimitiveString(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsStringClass.computeType(compiler);
    return new TypeMask.nonNullExact(base);
  }
}

class HReadableArrayType extends HIndexablePrimitiveType {
  const HReadableArrayType();
  bool isReadableArray(Compiler compiler) => true;
  String toString() => "readable array";
  bool canBePrimitiveArray(Compiler compiler) => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsArrayClass.computeType(compiler);
    return new TypeMask.nonNullSubclass(base);
  }
}

class HMutableArrayType extends HReadableArrayType {
  const HMutableArrayType();
  bool isMutableArray(Compiler compiler) => true;
  String toString() => "mutable array";

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsMutableArrayClass.computeType(compiler);
    return new TypeMask.nonNullSubclass(base);
  }
}

class HFixedArrayType extends HMutableArrayType {
  const HFixedArrayType();
  bool isFixedArray(Compiler compiler) => true;
  String toString() => "fixed array";
  bool isExact() => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsFixedArrayClass.computeType(compiler);
    return new TypeMask.nonNullExact(base);
  }
}

class HExtendableArrayType extends HMutableArrayType {
  const HExtendableArrayType();
  bool isExtendableArray(Compiler compiler) => true;
  String toString() => "extendable array";
  bool isExact() => true;

  TypeMask computeMask(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType base = backend.jsExtendableArrayClass.computeType(compiler);
    return new TypeMask.nonNullExact(base);
  }
}

class HBoundedType extends HType {
  final TypeMask mask;
  const HBoundedType(this.mask);

  bool isExact() => mask.isExact;

  bool canBeNull() => mask.isNullable;

  bool canBePrimitive(Compiler compiler) {
    return canBePrimitiveNumber(compiler)
        || canBePrimitiveArray(compiler)
        || canBePrimitiveBoolean(compiler)
        || canBePrimitiveString(compiler);
  }

  bool canBePrimitiveNumber(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType jsNumberType = backend.jsNumberClass.computeType(compiler);
    DartType jsIntType = backend.jsIntClass.computeType(compiler);
    DartType jsDoubleType = backend.jsDoubleClass.computeType(compiler);
    return mask.contains(jsNumberType, compiler)
        || mask.contains(jsIntType, compiler)
        || mask.contains(jsDoubleType, compiler);
  }

  bool canBePrimitiveBoolean(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType jsBoolType = backend.jsBoolClass.computeType(compiler);
    return mask.contains(jsBoolType, compiler);
  }

  bool canBePrimitiveArray(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType jsArrayType = backend.jsArrayClass.rawType;
    DartType jsFixedArrayType = backend.jsFixedArrayClass.rawType;
    DartType jsExtendableArrayType = backend.jsExtendableArrayClass.rawType;
    return mask.contains(jsArrayType, compiler)
        || mask.contains(jsFixedArrayType, compiler)
        || mask.contains(jsExtendableArrayType, compiler);
  }

  bool isIndexablePrimitive(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return mask.containsOnlyString(compiler)
        || mask.satisfies(backend.jsIndexableClass, compiler);
  }

  bool isFixedArray(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return mask.containsOnly(backend.jsFixedArrayClass);
  }

  bool isExtendableArray(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return mask.containsOnly(backend.jsExtendableArrayClass);
  }

  bool isMutableArray(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return mask.satisfies(backend.jsMutableArrayClass, compiler);
  }

  bool isReadableArray(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    return mask.satisfies(backend.jsArrayClass, compiler);
  }

  bool canBePrimitiveString(Compiler compiler) {
    JavaScriptBackend backend = compiler.backend;
    DartType jsStringType = backend.jsStringClass.computeType(compiler);
    return mask.contains(jsStringType, compiler);
  }

  TypeMask computeMask(Compiler compiler) => mask;

  HType simplify(Compiler compiler) {
    return new HType.fromMask(mask.simplify(compiler), compiler);
  }

  bool operator ==(HType other) {
    if (other is !HBoundedType) return false;
    HBoundedType bounded = other;
    return mask == bounded.mask;
  }

  String toString() {
    return 'BoundedType(mask=$mask)';
  }
}
