// 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.

/// This library defines individual world impacts.
///
/// We call these building blocks `uses`. Each `use` is a single impact of the
/// world. Some example uses are:
///
///  * an invocation of a top level function
///  * a call to the `foo()` method on an unknown class.
///  * an instantiation of class T
///
/// The different compiler stages combine these uses into `WorldImpact` objects,
/// which are later used to construct a closed-world understanding of the
/// program.
library dart2js.universe.use;

import '../common.dart';
import '../constants/values.dart';
import '../elements/types.dart';
import '../elements/entities.dart';
import '../js_model/closure.dart';
import '../util/util.dart' show equalElements, Hashing;
import 'call_structure.dart' show CallStructure;
import 'selector.dart' show Selector;
import 'world_builder.dart' show StrongModeConstraint;

enum DynamicUseKind {
  INVOKE,
  GET,
  SET,
}

/// The use of a dynamic property. [selector] defined the name and kind of the
/// property and [receiverConstraint] defines the known constraint for the object on which
/// the property is accessed.
class DynamicUse {
  final Selector selector;

  DynamicUse(this.selector);

  /// Short textual representation use for testing.
  String get shortText {
    StringBuffer sb = new StringBuffer();
    if (receiverConstraint != null) {
      var constraint = receiverConstraint;
      if (constraint is StrongModeConstraint) {
        if (constraint.isThis) {
          sb.write('<');
        } else if (constraint.isExact) {
          sb.write('=');
        }
        sb.write(constraint.cls.name);
      } else {
        sb.write(constraint);
      }
      sb.write('.');
    }
    sb.write(selector.name);
    if (typeArguments != null && typeArguments.isNotEmpty) {
      sb.write('<');
      sb.write(typeArguments.join(','));
      sb.write('>');
    }
    if (selector.isCall) {
      sb.write('(');
      sb.write(selector.callStructure.positionalArgumentCount);
      if (selector.callStructure.namedArgumentCount > 0) {
        sb.write(',');
        sb.write(selector.callStructure.getOrderedNamedArguments().join(','));
      }
      sb.write(')');
    } else if (selector.isSetter) {
      sb.write('=');
    }
    return sb.toString();
  }

  Object get receiverConstraint => null;

  DynamicUseKind get kind {
    if (selector.isGetter) {
      return DynamicUseKind.GET;
    } else if (selector.isSetter) {
      return DynamicUseKind.SET;
    } else {
      return DynamicUseKind.INVOKE;
    }
  }

  List<DartType> get typeArguments => const <DartType>[];

  int get hashCode => Hashing.listHash(
      typeArguments, Hashing.objectsHash(selector, receiverConstraint));

  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! DynamicUse) return false;
    return selector == other.selector &&
        receiverConstraint == other.receiverConstraint &&
        equalElements(typeArguments, other.typeArguments);
  }

  String toString() => '$selector,$receiverConstraint';
}

class GenericDynamicUse extends DynamicUse {
  final List<DartType> _typeArguments;

  GenericDynamicUse(Selector selector, [this._typeArguments])
      : super(selector) {
    assert(
        selector.callStructure.typeArgumentCount ==
            (_typeArguments?.length ?? 0),
        "Type argument count mismatch. Selector has "
        "${selector.callStructure.typeArgumentCount} but "
        "${typeArguments?.length ?? 0} were passed.");
  }

  List<DartType> get typeArguments => _typeArguments ?? const <DartType>[];
}

/// A dynamic use with a receiver constraint.
///
/// This is used in the codegen phase where receivers are constrained to a
/// type mask or similar.
class ConstrainedDynamicUse extends DynamicUse {
  final Object receiverConstraint;
  final List<DartType> _typeArguments;

  ConstrainedDynamicUse(
      Selector selector, this.receiverConstraint, this._typeArguments)
      : super(selector) {
    assert(
        selector.callStructure.typeArgumentCount ==
            (_typeArguments?.length ?? 0),
        "Type argument count mismatch. Selector has "
        "${selector.callStructure.typeArgumentCount} but "
        "${_typeArguments?.length ?? 0} were passed.");
  }

  List<DartType> get typeArguments => _typeArguments ?? const <DartType>[];
}

enum StaticUseKind {
  STATIC_TEAR_OFF,
  SUPER_TEAR_OFF,
  SUPER_FIELD_SET,
  FIELD_GET,
  FIELD_SET,
  CLOSURE,
  CLOSURE_CALL,
  CALL_METHOD,
  CONSTRUCTOR_INVOKE,
  CONST_CONSTRUCTOR_INVOKE,
  REDIRECTION,
  DIRECT_INVOKE,
  INLINING,
  INVOKE,
  GET,
  SET,
  INIT,
  REFLECT,
}

/// Statically known use of an [Entity].
// TODO(johnniwinther): Create backend-specific implementations with better
// invariants.
class StaticUse {
  final Entity element;
  final StaticUseKind kind;
  final int hashCode;
  final InterfaceType type;
  final CallStructure callStructure;

  StaticUse.internal(Entity element, this.kind,
      {this.type, this.callStructure, typeArgumentsHash: 0})
      : this.element = element,
        this.hashCode = Hashing.objectsHash(
            element, kind, type, typeArgumentsHash, callStructure);

  /// Short textual representation use for testing.
  String get shortText {
    StringBuffer sb = new StringBuffer();
    switch (kind) {
      case StaticUseKind.FIELD_SET:
      case StaticUseKind.SUPER_FIELD_SET:
      case StaticUseKind.SET:
        sb.write('set:');
        break;
      case StaticUseKind.INIT:
        sb.write('init:');
        break;
      case StaticUseKind.CLOSURE:
        sb.write('def:');
        break;
      default:
    }
    if (element is MemberEntity) {
      MemberEntity member = element;
      if (member.enclosingClass != null) {
        sb.write(member.enclosingClass.name);
        sb.write('.');
      }
    }
    if (element.name == null) {
      sb.write('<anonymous>');
    } else {
      sb.write(element.name);
    }
    if (typeArguments != null && typeArguments.isNotEmpty) {
      sb.write('<');
      sb.write(typeArguments.join(','));
      sb.write('>');
    }
    if (callStructure != null) {
      sb.write('(');
      sb.write(callStructure.positionalArgumentCount);
      if (callStructure.namedArgumentCount > 0) {
        sb.write(',');
        sb.write(callStructure.getOrderedNamedArguments().join(','));
      }
      sb.write(')');
    }
    return sb.toString();
  }

  List<DartType> get typeArguments => null;

  /// Invocation of a static or top-level [element] with the given
  /// [callStructure].
  factory StaticUse.staticInvoke(
      FunctionEntity element, CallStructure callStructure,
      [List<DartType> typeArguments]) {
    assert(
        element.isStatic || element.isTopLevel,
        failedAt(
            element,
            "Static invoke element $element must be a top-level "
            "or static method."));
    return new GenericStaticUse(
        element, StaticUseKind.INVOKE, callStructure, typeArguments);
  }

  /// Closurization of a static or top-level function [element].
  factory StaticUse.staticTearOff(FunctionEntity element) {
    assert(
        element.isStatic || element.isTopLevel,
        failedAt(
            element,
            "Static tear-off element $element must be a top-level "
            "or static method."));
    return new StaticUse.internal(element, StaticUseKind.STATIC_TEAR_OFF);
  }

  /// Read access of a static or top-level field or getter [element].
  factory StaticUse.staticGet(MemberEntity element) {
    assert(
        element.isStatic || element.isTopLevel,
        failedAt(
            element,
            "Static get element $element must be a top-level "
            "or static method."));
    assert(
        element.isField || element.isGetter,
        failedAt(element,
            "Static get element $element must be a field or a getter."));
    return new StaticUse.internal(element, StaticUseKind.GET);
  }

  /// Write access of a static or top-level field or setter [element].
  factory StaticUse.staticSet(MemberEntity element) {
    assert(
        element.isStatic || element.isTopLevel,
        failedAt(
            element,
            "Static set element $element "
            "must be a top-level or static method."));
    assert(
        element.isField || element.isSetter,
        failedAt(element,
            "Static set element $element must be a field or a setter."));
    return new StaticUse.internal(element, StaticUseKind.SET);
  }

  /// Invocation of the lazy initializer for a static or top-level field
  /// [element].
  factory StaticUse.staticInit(FieldEntity element) {
    assert(
        element.isStatic || element.isTopLevel,
        failedAt(
            element,
            "Static init element $element must be a top-level "
            "or static method."));
    assert(element.isField,
        failedAt(element, "Static init element $element must be a field."));
    return new StaticUse.internal(element, StaticUseKind.INIT);
  }

  /// Invocation of a super method [element] with the given [callStructure].
  factory StaticUse.superInvoke(
      FunctionEntity element, CallStructure callStructure,
      [List<DartType> typeArguments]) {
    assert(
        element.isInstanceMember,
        failedAt(element,
            "Super invoke element $element must be an instance method."));
    return new GenericStaticUse(
        element, StaticUseKind.INVOKE, callStructure, typeArguments);
  }

  /// Read access of a super field or getter [element].
  factory StaticUse.superGet(MemberEntity element) {
    assert(
        element.isInstanceMember,
        failedAt(
            element, "Super get element $element must be an instance method."));
    assert(
        element.isField || element.isGetter,
        failedAt(element,
            "Super get element $element must be a field or a getter."));
    return new StaticUse.internal(element, StaticUseKind.GET);
  }

  /// Write access of a super field [element].
  factory StaticUse.superFieldSet(FieldEntity element) {
    assert(
        element.isInstanceMember,
        failedAt(
            element, "Super set element $element must be an instance method."));
    assert(element.isField,
        failedAt(element, "Super set element $element must be a field."));
    return new StaticUse.internal(element, StaticUseKind.SUPER_FIELD_SET);
  }

  /// Write access of a super setter [element].
  factory StaticUse.superSetterSet(FunctionEntity element) {
    assert(
        element.isInstanceMember,
        failedAt(
            element, "Super set element $element must be an instance method."));
    assert(element.isSetter,
        failedAt(element, "Super set element $element must be a setter."));
    return new StaticUse.internal(element, StaticUseKind.SET);
  }

  /// Closurization of a super method [element].
  factory StaticUse.superTearOff(FunctionEntity element) {
    assert(
        element.isInstanceMember && element.isFunction,
        failedAt(element,
            "Super invoke element $element must be an instance method."));
    return new StaticUse.internal(element, StaticUseKind.SUPER_TEAR_OFF);
  }

  /// Invocation of a constructor [element] through a this or super
  /// constructor call with the given [callStructure].
  factory StaticUse.superConstructorInvoke(
      ConstructorEntity element, CallStructure callStructure) {
    assert(
        element.isGenerativeConstructor,
        failedAt(
            element,
            "Constructor invoke element $element must be a "
            "generative constructor."));
    return new StaticUse.internal(element, StaticUseKind.INVOKE,
        callStructure: callStructure);
  }

  /// Invocation of a constructor (body) [element] through a this or super
  /// constructor call with the given [callStructure].
  factory StaticUse.constructorBodyInvoke(
      ConstructorBodyEntity element, CallStructure callStructure) {
    return new StaticUse.internal(element, StaticUseKind.INVOKE,
        callStructure: callStructure);
  }

  /// Direct invocation of a generator (body) [element], as a static call or
  /// through a this or super constructor call.
  factory StaticUse.generatorBodyInvoke(FunctionEntity element) {
    return new StaticUse.internal(element, StaticUseKind.INVOKE);
  }

  /// Direct invocation of a method [element] with the given [callStructure].
  factory StaticUse.directInvoke(FunctionEntity element,
      CallStructure callStructure, List<DartType> typeArguments) {
    assert(
        element.isInstanceMember,
        failedAt(element,
            "Direct invoke element $element must be an instance member."));
    assert(element.isFunction,
        failedAt(element, "Direct invoke element $element must be a method."));
    return new GenericStaticUse(
        element, StaticUseKind.DIRECT_INVOKE, callStructure, typeArguments);
  }

  /// Direct read access of a field or getter [element].
  factory StaticUse.directGet(MemberEntity element) {
    assert(
        element.isInstanceMember,
        failedAt(element,
            "Direct get element $element must be an instance member."));
    assert(
        element.isField || element.isGetter,
        failedAt(element,
            "Direct get element $element must be a field or a getter."));
    return new StaticUse.internal(element, StaticUseKind.GET);
  }

  /// Direct write access of a field [element].
  factory StaticUse.directSet(FieldEntity element) {
    assert(
        element.isInstanceMember,
        failedAt(element,
            "Direct set element $element must be an instance member."));
    assert(element.isField,
        failedAt(element, "Direct set element $element must be a field."));
    return new StaticUse.internal(element, StaticUseKind.SET);
  }

  /// Constructor invocation of [element] with the given [callStructure].
  factory StaticUse.constructorInvoke(
      ConstructorEntity element, CallStructure callStructure) {
    assert(
        element.isConstructor,
        failedAt(element,
            "Constructor invocation element $element must be a constructor."));
    return new StaticUse.internal(element, StaticUseKind.INVOKE,
        callStructure: callStructure);
  }

  /// Constructor invocation of [element] with the given [callStructure] on
  /// [type].
  factory StaticUse.typedConstructorInvoke(ConstructorEntity element,
      CallStructure callStructure, InterfaceType type) {
    assert(type != null,
        failedAt(element, "No type provided for constructor invocation."));
    assert(
        element.isConstructor,
        failedAt(
            element,
            "Typed constructor invocation element $element "
            "must be a constructor."));
    return new StaticUse.internal(element, StaticUseKind.CONSTRUCTOR_INVOKE,
        type: type, callStructure: callStructure);
  }

  /// Constant constructor invocation of [element] with the given
  /// [callStructure] on [type].
  factory StaticUse.constConstructorInvoke(ConstructorEntity element,
      CallStructure callStructure, InterfaceType type) {
    assert(type != null,
        failedAt(element, "No type provided for constructor invocation."));
    assert(
        element.isConstructor,
        failedAt(
            element,
            "Const constructor invocation element $element "
            "must be a constructor."));
    return new StaticUse.internal(
        element, StaticUseKind.CONST_CONSTRUCTOR_INVOKE,
        type: type, callStructure: callStructure);
  }

  /// Constructor redirection to [element] on [type].
  factory StaticUse.constructorRedirect(
      ConstructorEntity element, InterfaceType type) {
    assert(type != null,
        failedAt(element, "No type provided for constructor redirection."));
    assert(
        element.isConstructor,
        failedAt(element,
            "Constructor redirection element $element must be a constructor."));
    return new StaticUse.internal(element, StaticUseKind.REDIRECTION,
        type: type);
  }

  /// Initialization of an instance field [element].
  factory StaticUse.fieldInit(FieldEntity element) {
    assert(
        element.isInstanceMember,
        failedAt(
            element, "Field init element $element must be an instance field."));
    return new StaticUse.internal(element, StaticUseKind.INIT);
  }

  /// Read access of an instance field or boxed field [element].
  factory StaticUse.fieldGet(FieldEntity element) {
    assert(
        element.isInstanceMember || element is JRecordField,
        failedAt(element,
            "Field init element $element must be an instance or boxed field."));
    return new StaticUse.internal(element, StaticUseKind.FIELD_GET);
  }

  /// Write access of an instance field or boxed field [element].
  factory StaticUse.fieldSet(FieldEntity element) {
    assert(
        element.isInstanceMember || element is JRecordField,
        failedAt(element,
            "Field init element $element must be an instance or boxed field."));
    return new StaticUse.internal(element, StaticUseKind.FIELD_SET);
  }

  /// Read of a local function [element].
  factory StaticUse.closure(Local element) {
    return new StaticUse.internal(element, StaticUseKind.CLOSURE);
  }

  /// An invocation of a local function [element] with the provided
  /// [callStructure] and [typeArguments].
  factory StaticUse.closureCall(Local element, CallStructure callStructure,
      List<DartType> typeArguments) {
    return new GenericStaticUse(
        element, StaticUseKind.CLOSURE_CALL, callStructure, typeArguments);
  }

  /// Read of a call [method] on a closureClass.
  factory StaticUse.callMethod(FunctionEntity method) {
    return new StaticUse.internal(method, StaticUseKind.CALL_METHOD);
  }

  /// Use of [element] through reflection.
  factory StaticUse.mirrorUse(MemberEntity element) {
    return new StaticUse.internal(element, StaticUseKind.REFLECT);
  }

  /// Implicit method/constructor invocation of [element] created by the
  /// backend.
  factory StaticUse.implicitInvoke(FunctionEntity element) {
    return new StaticUse.internal(element, StaticUseKind.INVOKE);
  }

  /// Inlining of [element].
  factory StaticUse.constructorInlining(
      ConstructorEntity element, InterfaceType instanceType) {
    return new StaticUse.internal(element, StaticUseKind.INLINING,
        type: instanceType);
  }

  /// Inlining of [element].
  factory StaticUse.methodInlining(
      FunctionEntity element, List<DartType> typeArguments) {
    return new GenericStaticUse.methodInlining(element, typeArguments);
  }

  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! StaticUse) return false;
    return element == other.element &&
        kind == other.kind &&
        type == other.type &&
        callStructure == other.callStructure &&
        equalElements(typeArguments, other.typeArguments);
  }

  String toString() =>
      'StaticUse($element,$kind,$type,$typeArguments,$callStructure)';
}

class GenericStaticUse extends StaticUse {
  final List<DartType> typeArguments;

  GenericStaticUse(Entity entity, StaticUseKind kind,
      CallStructure callStructure, this.typeArguments)
      : super.internal(entity, kind,
            callStructure: callStructure,
            typeArgumentsHash: Hashing.listHash(typeArguments)) {
    assert(
        (callStructure?.typeArgumentCount ?? 0) == (typeArguments?.length ?? 0),
        failedAt(
            element,
            "Type argument count mismatch. Call structure has "
            "${callStructure?.typeArgumentCount ?? 0} but "
            "${typeArguments?.length ?? 0} were passed."));
  }

  GenericStaticUse.methodInlining(FunctionEntity entity, this.typeArguments)
      : super.internal(entity, StaticUseKind.INLINING,
            typeArgumentsHash: Hashing.listHash(typeArguments));
}

enum TypeUseKind {
  IS_CHECK,
  AS_CAST,
  CATCH_TYPE,
  TYPE_LITERAL,
  INSTANTIATION,
  NATIVE_INSTANTIATION,
  IMPLICIT_CAST,
  PARAMETER_CHECK,
  RTI_VALUE,
  TYPE_ARGUMENT,
}

/// Use of a [DartType].
class TypeUse {
  final DartType type;
  final TypeUseKind kind;
  final int hashCode;

  TypeUse.internal(DartType type, TypeUseKind kind)
      : this.type = type,
        this.kind = kind,
        this.hashCode = Hashing.objectHash(type, Hashing.objectHash(kind));

  /// Short textual representation use for testing.
  String get shortText {
    StringBuffer sb = new StringBuffer();
    switch (kind) {
      case TypeUseKind.IS_CHECK:
        sb.write('is:');
        break;
      case TypeUseKind.AS_CAST:
        sb.write('as:');
        break;
      case TypeUseKind.CATCH_TYPE:
        sb.write('catch:');
        break;
      case TypeUseKind.TYPE_LITERAL:
        sb.write('lit:');
        break;
      case TypeUseKind.INSTANTIATION:
        sb.write('inst:');
        break;
      case TypeUseKind.NATIVE_INSTANTIATION:
        sb.write('native:');
        break;
      case TypeUseKind.IMPLICIT_CAST:
        sb.write('impl:');
        break;
      case TypeUseKind.PARAMETER_CHECK:
        sb.write('param:');
        break;
      case TypeUseKind.RTI_VALUE:
        sb.write('rti:');
        break;
      case TypeUseKind.TYPE_ARGUMENT:
        sb.write('typeArg:');
        break;
    }
    sb.write(type);
    return sb.toString();
  }

  /// [type] used in an is check, like `e is T` or `e is! T`.
  factory TypeUse.isCheck(DartType type) {
    return new TypeUse.internal(type, TypeUseKind.IS_CHECK);
  }

  /// [type] used in an as cast, like `e as T`.
  factory TypeUse.asCast(DartType type) {
    return new TypeUse.internal(type, TypeUseKind.AS_CAST);
  }

  /// [type] used as a parameter type or field type in Dart 2, like `T` in:
  ///
  ///    method(T t) {}
  ///    T field;
  ///
  factory TypeUse.parameterCheck(DartType type) {
    return new TypeUse.internal(type, TypeUseKind.PARAMETER_CHECK);
  }

  /// [type] used in an implicit cast in Dart 2, like `T` in
  ///
  ///    dynamic foo = new Object();
  ///    T bar = foo; // Implicitly `T bar = foo as T`.
  ///
  factory TypeUse.implicitCast(DartType type) {
    return new TypeUse.internal(type, TypeUseKind.IMPLICIT_CAST);
  }

  /// [type] used in a on type catch clause, like `try {} on T catch (e) {}`.
  factory TypeUse.catchType(DartType type) {
    return new TypeUse.internal(type, TypeUseKind.CATCH_TYPE);
  }

  /// [type] used as a type literal, like `foo() => T;`.
  factory TypeUse.typeLiteral(DartType type) {
    return new TypeUse.internal(type, TypeUseKind.TYPE_LITERAL);
  }

  /// [type] used in an instantiation, like `new T();`.
  factory TypeUse.instantiation(InterfaceType type) {
    return new TypeUse.internal(type, TypeUseKind.INSTANTIATION);
  }

  /// [type] used in a native instantiation.
  factory TypeUse.nativeInstantiation(InterfaceType type) {
    return new TypeUse.internal(type, TypeUseKind.NATIVE_INSTANTIATION);
  }

  /// [type] used as a direct RTI value.
  factory TypeUse.constTypeLiteral(DartType type) {
    return new TypeUse.internal(type, TypeUseKind.RTI_VALUE);
  }

  /// [type] used in a `instanceof` check.
  factory TypeUse.instanceConstructor(DartType type) {
    // TODO(johnniwinther,sra): Use a separate use kind if constructors is no
    // longer used for RTI.
    return new TypeUse.internal(type, TypeUseKind.RTI_VALUE);
  }

  /// [type] used directly as a type argument.
  ///
  /// The happens during optimization where a type variable can be replaced by
  /// an invariable type argument derived from a constant receiver.
  factory TypeUse.typeArgument(DartType type) {
    return new TypeUse.internal(type, TypeUseKind.TYPE_ARGUMENT);
  }

  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! TypeUse) return false;
    return type == other.type && kind == other.kind;
  }

  String toString() => 'TypeUse($type,$kind)';
}

enum ConstantUseKind {
  // A constant that is directly accessible in code.
  DIRECT,
  // A constant that is only accessible through other constants.
  INDIRECT,
}

/// Use of a [ConstantValue].
class ConstantUse {
  final ConstantValue value;
  final ConstantUseKind kind;
  final int hashCode;

  ConstantUse._(this.value, this.kind)
      : this.hashCode = Hashing.objectHash(value, kind.hashCode);

  /// Short textual representation use for testing.
  String get shortText {
    return value.toDartText();
  }

  /// Constant used as the initial value of a field.
  ConstantUse.init(ConstantValue value) : this._(value, ConstantUseKind.DIRECT);

  /// Type constant used for registration of custom elements.
  ConstantUse.customElements(TypeConstantValue value)
      : this._(value, ConstantUseKind.DIRECT);

  /// Constant used through mirrors.
  // TODO(johnniwinther): Maybe if this is `DIRECT` and we can avoid the
  // extra calls to `addCompileTimeConstantForEmission`.
  ConstantUse.mirrors(ConstantValue value)
      : this._(value, ConstantUseKind.INDIRECT);

  /// Constant used for accessing type variables through mirrors.
  ConstantUse.typeVariableMirror(ConstantValue value)
      : this._(value, ConstantUseKind.DIRECT);

  /// Constant literal used on code.
  ConstantUse.literal(ConstantValue value)
      : this._(value, ConstantUseKind.DIRECT);

  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! ConstantUse) return false;
    return value == other.value;
  }

  String toString() => 'ConstantUse(${value.toStructuredText()},$kind)';
}
