// Copyright (c) 2015, 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.

library dart2js.abstract_value_domain;

import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
import '../elements/entities.dart';
import '../universe/selector.dart';
import '../universe/world_builder.dart';
import '../world.dart';

enum AbstractBool { True, False, Maybe }

/// Strategy for the abstraction of runtime values used by the global type
/// inference.
abstract class AbstractValueStrategy {
  /// Creates the abstract value domain for [closedWorld].
  AbstractValueDomain createDomain(JClosedWorld closedWorld);

  /// Creates the [SelectorConstraintsStrategy] used by the backend enqueuer.
  SelectorConstraintsStrategy createSelectorStrategy();
}

/// A value in an abstraction of runtime values.
abstract class AbstractValue {}

/// A system that implements an abstraction over runtime values.
abstract class AbstractValueDomain {
  /// The [AbstractValue] that represents an unknown runtime value.
  AbstractValue get dynamicType;

  /// The [AbstractValue] that represents a non-null subtype of `Type` at
  /// runtime.
  AbstractValue get typeType;

  /// The [AbstractValue] that represents a non-null subtype of `Function` at
  /// runtime.
  AbstractValue get functionType;

  /// The [AbstractValue] that represents a non-null subtype of `bool` at
  /// runtime.
  AbstractValue get boolType;

  /// The [AbstractValue] that represents a non-null subtype of `int` at
  /// runtime.
  AbstractValue get intType;

  /// The [AbstractValue] that represents a non-null subtype of `double` at
  /// runtime.
  AbstractValue get doubleType;

  /// The [AbstractValue] that represents a non-null subtype of `num` at
  /// runtime.
  AbstractValue get numType;

  /// The [AbstractValue] that represents a non-null subtype of `String` at
  /// runtime.
  AbstractValue get stringType;

  /// The [AbstractValue] that represents a non-null subtype of `List` at
  /// runtime.
  AbstractValue get listType;

  /// The [AbstractValue] that represents a non-null subtype of `Map` at
  /// runtime.
  AbstractValue get mapType;

  /// The [AbstractValue] that represents a non-null value at runtime.
  AbstractValue get nonNullType;

  /// The [AbstractValue] that represents the `null` at runtime.
  AbstractValue get nullType;

  /// The [AbstractValue] that represents a non-null growable JavaScript array
  /// at runtime.
  AbstractValue get growableListType;

  /// The [AbstractValue] that represents a non-null fixed size JavaScript array
  /// at runtime.
  AbstractValue get fixedListType;

  /// The [AbstractValue] that represents a non-null 31-bit unsigned integer at
  /// runtime.
  AbstractValue get uint31Type;

  /// The [AbstractValue] that represents a non-null 32-bit unsigned integer at
  /// runtime.
  AbstractValue get uint32Type;

  /// The [AbstractValue] that represents a non-null unsigned integer at
  /// runtime.
  AbstractValue get positiveIntType;

  /// The [AbstractValue] that represents a non-null constant list literal at
  /// runtime.
  AbstractValue get constListType;

  /// The [AbstractValue] that represents a non-null constant map literal at
  /// runtime.
  AbstractValue get constMapType;

  /// The [AbstractValue] that represents the empty set of runtime values.
  AbstractValue get emptyType;

  /// The [AbstractValue] that represents a non-null instance at runtime of the
  /// `Iterable` class used for the `sync*` implementation.
  AbstractValue get syncStarIterableType;

  /// The [AbstractValue] that represents a non-null instance at runtime of the
  /// `Future` class used for the `async` implementation.
  AbstractValue get asyncFutureType;

  /// The [AbstractValue] that represents a non-null instance at runtime of the
  /// `Stream` class used for the `async*` implementation.
  AbstractValue get asyncStarStreamType;

  /// Creates an [AbstractValue] for a non-null exact instance of [cls].
  AbstractValue createNonNullExact(ClassEntity cls);

  /// Creates an [AbstractValue] for a potentially null exact instance of [cls].
  AbstractValue createNullableExact(ClassEntity cls);

  /// Creates an [AbstractValue] for a non-null instance that extends [cls].
  AbstractValue createNonNullSubclass(ClassEntity cls);

  /// Creates an [AbstractValue] for a non-null instance that implements [cls].
  AbstractValue createNonNullSubtype(ClassEntity cls);

  /// Creates an [AbstractValue] for a potentially null instance that implements
  /// [cls].
  AbstractValue createNullableSubtype(ClassEntity cls);

  /// Returns `true` if [value] is a native typed array or `null` at runtime.
  bool isTypedArray(covariant AbstractValue value);

  /// Returns `true` if [value] could be a native typed array at runtime.
  bool couldBeTypedArray(covariant AbstractValue value);

  /// Returns the version of the abstract [value] that excludes `null`.
  AbstractValue excludeNull(covariant AbstractValue value);

  /// Returns the version of the abstract [value] that includes `null`.
  AbstractValue includeNull(covariant AbstractValue value);

  /// Returns `true` if [value] contains instances of [cls] at runtime.
  bool containsType(covariant AbstractValue value, ClassEntity cls);

  /// Returns `true` if [value] only contains subtypes of [cls] or `null` at
  /// runtime.
  bool containsOnlyType(covariant AbstractValue value, ClassEntity cls);

  /// Returns `true` if [value] is an instance of [cls] or `null` at runtime.
  // TODO(johnniwinther): Merge this with [isInstanceOf].
  bool isInstanceOfOrNull(covariant AbstractValue value, ClassEntity cls);

  /// Returns an [AbstractBool] that describes how [value] is known to be an
  /// instance of [cls] at runtime.
  ///
  /// If the returned value is `Abstract.True`, [value] is known _always_ to be
  /// an instance of [cls]. If the returned value is `Abstract.False`, [value]
  /// is known _never_ to be an instance of [cls]. If the returned value is
  /// `Abstract.Maybe` [value] might or might not be an instance of [cls] at
  /// runtime.
  AbstractBool isInstanceOf(AbstractValue value, ClassEntity cls);

  /// Returns `true` if [value] is empty set of runtime values.
  bool isEmpty(covariant AbstractValue value);

  /// Returns `true` if [value] is a non-null exact class at runtime.
  bool isExact(covariant AbstractValue value);

  /// Returns `true` if [value] is an exact class or `null` at runtime.
  bool isExactOrNull(covariant AbstractValue value);

  /// Returns the [ClassEntity] if this [value] is a non-null instance of an
  /// exact class at runtime, and `null` otherwise.
  ClassEntity getExactClass(covariant AbstractValue value);

  /// Returns `true` if [value] can be `null` at runtime.
  bool canBeNull(covariant AbstractValue value);

  /// Returns `true` if [value] is `null` at runtime.
  bool isNull(covariant AbstractValue value);

  /// Returns `true` if [value] could be a JavaScript bool, number, string,
  /// array or `null` at runtime.
  bool canBePrimitive(covariant AbstractValue value);

  /// Returns `true` if [value] could be a JavaScript number at runtime.
  bool canBePrimitiveNumber(covariant AbstractValue value);

  /// Returns `true` if [value] could be a JavaScript bool at runtime.
  bool canBePrimitiveBoolean(covariant AbstractValue value);

  /// Returns `true` if [value] could be a JavaScript array at runtime.
  bool canBePrimitiveArray(covariant AbstractValue value);

  /// Returns `true` if [value] is a JavaScript string, array, native HTML list
  /// or `null` at runtime.
  bool isIndexablePrimitive(covariant AbstractValue value);

  /// Returns `true` if [value] is a fixed-size or constant JavaScript array or
  /// `null` at
  /// runtime.
  bool isFixedArray(covariant AbstractValue value);

  /// Returns `true` if [value] is a growable JavaScript array or `null` at
  /// runtime.
  bool isExtendableArray(covariant AbstractValue value);

  /// Returns `true` if [value] is a mutable JavaScript array or `null` at
  /// runtime.
  bool isMutableArray(covariant AbstractValue value);

  /// Returns `true` if [value] is a mutable JavaScript array, native HTML list
  /// or `null` at runtime.
  bool isMutableIndexable(covariant AbstractValue value);

  /// Returns `true` if [value] is a JavaScript array or `null` at runtime.
  bool isArray(covariant AbstractValue value);

  /// Returns `true` if [value] could be a JavaScript string at runtime.
  bool canBePrimitiveString(covariant AbstractValue value);

  /// Return `true` if [value] could be an interceptor at runtime.
  bool canBeInterceptor(covariant AbstractValue value);

  /// Returns `true` if [value] is a non-null integer value at runtime.
  bool isInteger(covariant AbstractValue value);

  /// Returns `true` if [value] is a non-null 32 bit unsigned integer value at
  /// runtime.
  bool isUInt32(covariant AbstractValue value);

  /// Returns `true` if [value] is a non-null 31 bit unsigned integer value at
  /// runtime.
  bool isUInt31(covariant AbstractValue value);

  /// Returns `true` if [value] is a non-null unsigned integer value at runtime.
  bool isPositiveInteger(covariant AbstractValue value);

  /// Returns `true` if [value] is an unsigned integer value or `null` at
  /// runtime.
  bool isPositiveIntegerOrNull(covariant AbstractValue value);

  /// Returns `true` if [value] is an integer value or `null` at runtime.
  bool isIntegerOrNull(covariant AbstractValue value);

  /// Returns `true` if [value] is a non-null JavaScript number at runtime.
  bool isNumber(covariant AbstractValue value);

  /// Returns `true` if [value] is a JavaScript number or `null` at runtime.
  bool isNumberOrNull(covariant AbstractValue value);

  /// Returns `true` if [value] is a non-integer number at runtime.
  bool isDouble(covariant AbstractValue value);

  /// Returns `true` if [value] is a non-integer number or `null` at runtime.
  bool isDoubleOrNull(covariant AbstractValue value);

  /// Returns `true` if [value] is a JavaScript bool at runtime.
  bool isBoolean(covariant AbstractValue value);

  /// Returns `true` if [value] is a JavaScript bool or `null` at runtime.
  bool isBooleanOrNull(covariant AbstractValue value);

  /// Returns `true` if [value] is a JavaScript string at runtime.
  bool isString(covariant AbstractValue value);

  /// Returns `true` if [value] is a JavaScript string or `null` at runtime.
  bool isStringOrNull(covariant AbstractValue value);

  /// Returns `true` if [value] a non-null JavaScript primitive or `null`?
  // TODO(johnniwinther): This should probably not return true on `null`,
  // investigate.
  bool isPrimitive(covariant AbstractValue value);

  /// Returns `true` if [value] a JavaScript primitive, possible `null`.
  bool isPrimitiveOrNull(covariant AbstractValue value);

  /// Returns [AbstractValue] for the runtime values contained in either [a] or
  /// [b].
  AbstractValue union(covariant AbstractValue a, covariant AbstractValue b);

  /// Returns [AbstractValue] for the runtime values contained in at least one
  /// of [values].
  AbstractValue unionOfMany(Iterable<AbstractValue> values);

  /// Returns [AbstractValue] for the runtime values that [a] and [b] have in
  /// common.
  AbstractValue intersection(
      covariant AbstractValue a, covariant AbstractValue b);

  /// Returns `true` if [a] and [b] have no runtime values in common.
  bool areDisjoint(covariant AbstractValue a, covariant AbstractValue b);

  /// Returns `true` if [a] contains all non-null runtime values.
  bool containsAll(covariant AbstractValue a);

  /// Computes the [AbstractValue] corresponding to the constant [value].
  AbstractValue computeAbstractValueForConstant(ConstantValue value);

  /// Returns `true` if [value] represents a container value at runtime.
  bool isContainer(covariant AbstractValue value);

  /// Creates a container value specialization of [originalValue] with the
  /// inferred [element] runtime value and inferred runtime [length].
  ///
  /// The [allocationNode] is used to identify this particular map allocation.
  /// The [allocationElement] is used only for debugging.
  AbstractValue createContainerValue(
      AbstractValue originalValue,
      Object allocationNode,
      MemberEntity allocationElement,
      AbstractValue elementType,
      int length);

  /// Returns the element type of [value] if it represents a container value
  /// at runtime. Returns [dynamicType] otherwise.
  AbstractValue getContainerElementType(AbstractValue value);

  /// Return the known length of [value] if it represents a container value
  /// at runtime. Returns `null` if the length is unknown or if [value] doesn't
  /// represent a container value at runtime.
  int getContainerLength(AbstractValue value);

  /// Returns `true` if [value] represents a map value at runtime.
  bool isMap(covariant AbstractValue value);

  /// Creates a map value specialization of [originalValue] with the inferred
  /// [key] and [value] runtime values.
  ///
  /// The [allocationNode] is used to identify this particular map allocation.
  /// The [allocationElement] is used only for debugging.
  AbstractValue createMapValue(
      AbstractValue originalValue,
      Object allocationNode,
      MemberEntity allocationElement,
      AbstractValue key,
      AbstractValue value);

  /// Returns the key type of [value] if it represents a map value at runtime.
  /// Returns [dynamicType] otherwise.
  AbstractValue getMapKeyType(AbstractValue value);

  /// Returns the value type of [value] if it represents a map value at runtime.
  /// Returns [dynamicType] otherwise.
  AbstractValue getMapValueType(AbstractValue value);

  /// Returns `true` if [value] represents a dictionary value, that is, a map
  /// with strings as keys, at runtime.
  bool isDictionary(covariant AbstractValue value);

  /// Creates a dictionary value specialization of [originalValue] with the
  /// inferred [key] and [value] runtime values.
  ///
  /// The [allocationNode] is used to identify this particular map allocation.
  /// The [allocationElement] is used only for debugging.
  AbstractValue createDictionaryValue(
      AbstractValue originalValue,
      Object allocationNode,
      MemberEntity allocationElement,
      AbstractValue key,
      AbstractValue value,
      Map<String, AbstractValue> mappings);

  /// Returns `true` if [value] is a dictionary value which contains [key] as
  /// a key.
  bool containsDictionaryKey(AbstractValue value, String key);

  /// Returns the value type for [key] in [value] if it represents a dictionary
  /// value at runtime. Returns [dynamicType] otherwise.
  AbstractValue getDictionaryValueForKey(AbstractValue value, String key);

  /// Returns `true` if [specialization] is a specialization of
  /// [generalization].
  ///
  /// Specializations are created through [createPrimitiveValue],
  /// [createMapValue], [createDictionaryValue] and [createContainerValue].
  bool isSpecializationOf(
      AbstractValue specialization, AbstractValue generalization);

  /// Returns the value of which [value] is a specialization. Return `null` if
  /// [value] is not a specialization.
  ///
  /// Specializations are created through [createPrimitiveValue],
  /// [createMapValue], [createDictionaryValue] and [createContainerValue].
  AbstractValue getGeneralization(AbstractValue value);

  /// Return the object identifying the allocation of [value] if it is an
  /// allocation based specialization. Otherwise returns `null`.
  ///
  /// Allocation based specializations are created through [createMapValue],
  /// [createDictionaryValue] and [createContainerValue]
  Object getAllocationNode(AbstractValue value);

  /// Return the allocation element of [value] if it is an allocation based
  /// specialization. Otherwise returns `null`.
  ///
  /// Allocation based specializations are created through [createMapValue],
  /// [createDictionaryValue] and [createContainerValue]
  MemberEntity getAllocationElement(AbstractValue value);

  /// Returns `true` if [value] a known primitive JavaScript value at runtime.
  bool isPrimitiveValue(covariant AbstractValue value);

  /// Creates a primitive value specialization of [originalValue] with the
  /// inferred primitive constant [value].
  AbstractValue createPrimitiveValue(
      AbstractValue originalValue, PrimitiveConstantValue value);

  /// Returns the primitive JavaScript value of [value] if it represents a
  /// primitive JavaScript value at runtime, value at runtime. Returns `null`
  /// otherwise.
  PrimitiveConstantValue getPrimitiveValue(covariant AbstractValue value);

  /// Compute the type of all potential receivers of the set of live [members].
  AbstractValue computeReceiver(Iterable<MemberEntity> members);

  /// Returns whether [member] is a potential target when being
  /// invoked on a [receiver]. [selector] is used to ensure library privacy is
  /// taken into account.
  bool canHit(AbstractValue receiver, MemberEntity member, Selector selector);

  /// Returns whether [selector] invoked on a [receiver] can hit a
  /// [noSuchMethod].
  bool needsNoSuchMethodHandling(AbstractValue receiver, Selector selector);

  /// Returns `true` if the set of runtime values of [subset] are all in the set
  /// of runtime values of [superset].
  bool contains(AbstractValue superset, AbstractValue subset);

  /// Returns `true` if the set of runtime values of [subset] are all in the set
  /// of runtime values of [superset].
  bool isIn(AbstractValue subset, AbstractValue superset);

  /// Returns the [MemberEntity] that is known to always be hit at runtime
  /// [receiver].
  ///
  /// Returns `null` if 0 or more than 1 member can be hit at runtime.
  MemberEntity locateSingleMember(AbstractValue receiver, Selector selector);

  /// Returns `true` if [value] is an indexable JavaScript value at runtime.
  bool isJsIndexable(covariant AbstractValue value);

  /// Returns `true` if [value] is an indexable and iterable JavaScript value at
  /// runtime.
  ///
  /// JavaScript arrays are both indexable and iterable whereas JavaScript
  /// strings are indexable but not iterable.
  bool isJsIndexableAndIterable(AbstractValue value);

  /// Returns `true` if [value] is an JavaScript indexable of fixed length.
  bool isFixedLengthJsIndexable(AbstractValue value);

  /// Returns compact a textual representation for [value] used for debugging.
  String getCompactText(AbstractValue value);
}
