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

/**
 * Code for classifying the semantics of identifiers appearing in a Dart file.
 */
library dart2js.access_semantics;

import '../constants/expressions.dart';
import '../elements/resolution_types.dart';
import '../elements/elements.dart';

/// Enum representing the different kinds of destinations which a property
/// access or method or function invocation might refer to.
enum AccessKind {
  /// The destination of the conditional access is an instance method, property,
  /// or field of a class, and thus must be determined dynamically.
  CONDITIONAL_DYNAMIC_PROPERTY,

  /// The destination of the access is an instance method, property, or field
  /// of a class, and thus must be determined dynamically.
  DYNAMIC_PROPERTY,

  // TODO(johnniwinther): Split these cases into captured and non-captured
  // local access.
  /// The destination of the access is a function that is defined locally within
  /// an enclosing function or method.
  LOCAL_FUNCTION,

  /// The destination of the access is a non-final variable that is defined
  /// locally within an enclosing function or method.
  LOCAL_VARIABLE,

  /// The destination of the access is a final variable that is defined locally
  /// within an enclosing function or method.
  FINAL_LOCAL_VARIABLE,

  /// The destination of the access is a variable that is defined as a non-final
  /// parameter to an enclosing function or method.
  PARAMETER,

  /// The destination of the access is a variable that is defined as a final
  /// parameter to an enclosing function or method.
  FINAL_PARAMETER,

  /// The destination of the access is a non-final field that is defined
  /// statically within a class.
  STATIC_FIELD,

  /// The destination of the access is a final field that is defined statically
  /// within a class.
  FINAL_STATIC_FIELD,

  /// The destination of the access is a method that is defined statically
  /// within a class.
  STATIC_METHOD,

  /// The destination of the access is a property getter that is defined
  /// statically within a class.
  STATIC_GETTER,

  /// The destination of the access is a property setter that is defined
  /// statically within a class.
  STATIC_SETTER,

  /// The destination of the access is a non-final top level variable defined
  /// within a library.
  TOPLEVEL_FIELD,

  /// The destination of the access is a final top level variable defined within
  /// a library.
  FINAL_TOPLEVEL_FIELD,

  /// The destination of the access is a top level method defined within a
  /// library.
  TOPLEVEL_METHOD,

  /// The destination of the access is a top level property getter defined
  /// within a library.
  TOPLEVEL_GETTER,

  /// The destination of the access is a top level property setter defined
  /// within a library.
  TOPLEVEL_SETTER,

  /// The destination of the access is a toplevel class, or named mixin
  /// application.
  CLASS_TYPE_LITERAL,

  /// The destination of the access is a function typedef.
  TYPEDEF_TYPE_LITERAL,

  /// The destination of the access is the built-in type "dynamic".
  DYNAMIC_TYPE_LITERAL,

  /// The destination of the access is a type parameter of the enclosing class.
  TYPE_PARAMETER_TYPE_LITERAL,

  /// The destination of the access is a (complex) expression. For instance the
  /// function expression `(){}` in the function expression invocation `(){}()`.
  EXPRESSION,

  /// The destination of the access is `this` of the enclosing class.
  THIS,

  /// The destination of the access is an instance method, property, or field
  /// of the enclosing class.
  THIS_PROPERTY,

  /// The destination of the access is a non-final field of the super class of
  /// the enclosing class.
  SUPER_FIELD,

  /// The destination of the access is a final field of the super class of the
  /// enclosing class.
  SUPER_FINAL_FIELD,

  /// The destination of the access is a method of the super class of the
  /// enclosing class.
  SUPER_METHOD,

  /// The destination of the access is a getter of the super class of the
  /// enclosing class.
  SUPER_GETTER,

  /// The destination of the access is a setter of the super class of the
  /// enclosing class.
  SUPER_SETTER,

  /// Compound access where read and write access different elements.
  /// See [CompoundAccessKind].
  COMPOUND,

  /// The destination of the access is a compile-time constant.
  CONSTANT,

  /// The destination of the access is unresolved in a static context.
  UNRESOLVED,

  /// The destination of the access is unresolved super access.
  UNRESOLVED_SUPER,

  /// The destination is invalid as an access. For instance a prefix used
  /// as an expression.
  INVALID,
}

enum CompoundAccessKind {
  /// Read from a static getter and write to a static setter.
  STATIC_GETTER_SETTER,

  /// Read from a static method (closurize) and write to a static setter.
  STATIC_METHOD_SETTER,

  /// Read from an unresolved static getter and write to a static setter.
  UNRESOLVED_STATIC_GETTER,

  /// Read from a static getter and write to an unresolved static setter.
  UNRESOLVED_STATIC_SETTER,

  /// Read from a top level getter and write to a top level setter.
  TOPLEVEL_GETTER_SETTER,

  /// Read from a top level method (closurize) and write to top level setter.
  TOPLEVEL_METHOD_SETTER,

  /// Read from an unresolved top level getter and write to a top level setter.
  UNRESOLVED_TOPLEVEL_GETTER,

  /// Read from a top level getter and write to an unresolved top level setter.
  UNRESOLVED_TOPLEVEL_SETTER,

  /// Read from one superclass field and write to another.
  SUPER_FIELD_FIELD,

  /// Read from a superclass field and write to a superclass setter.
  SUPER_FIELD_SETTER,

  /// Read from a superclass getter and write to a superclass setter.
  SUPER_GETTER_SETTER,

  /// Read from a superclass method (closurize) and write to a superclass
  /// setter.
  SUPER_METHOD_SETTER,

  /// Read from a superclass getter and write to a superclass field.
  SUPER_GETTER_FIELD,

  /// Read from a superclass where the getter is unresolved.
  // TODO(johnniwinther): Use [AccessKind.SUPER_GETTER] when the erroneous
  // element is no longer needed.
  UNRESOLVED_SUPER_GETTER,

  /// Read from a superclass getter and write to an unresolved setter.
  // TODO(johnniwinther): Use [AccessKind.SUPER_SETTER] when the erroneous
  // element is no longer needed.
  UNRESOLVED_SUPER_SETTER,
}

/**
 * Data structure used to classify the semantics of a property access or method
 * or function invocation.
 */
abstract class AccessSemantics {
  /**
   * The kind of access.
   */
  final AccessKind kind;

  /**
   * The element being accessed, if statically known.  This will be null if
   * [kind] is DYNAMIC or if the element is undefined (e.g. an attempt to
   * access a non-existent static method in a class).
   */
  Element get element => null;

  ConstantExpression get constant => null;

  /// The element for the getter in case of a compound access,
  /// [element] otherwise.
  Element get getter => element;

  /// The element for the setter in case of a compound access,
  /// [element] otherwise.
  Element get setter => element;

  Name get name => null;

  const AccessSemantics._(this.kind);

  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.write('AccessSemantics[');
    sb.write('kind=$kind,');
    if (element != null) {
      if (getter != setter) {
        sb.write('getter=');
        sb.write('${getter}');
        sb.write(',setter=');
        sb.write('${setter}');
      } else {
        sb.write('element=');
        sb.write('${element}');
      }
    } else if (name != null) {
      sb.write('name=');
      sb.write(name);
    }
    sb.write(']');
    return sb.toString();
  }
}

class DynamicAccess extends AccessSemantics {
  final Name name;

  const DynamicAccess.expression()
      : name = null,
        super._(AccessKind.EXPRESSION);

  const DynamicAccess.thisAccess()
      : name = null,
        super._(AccessKind.THIS);

  const DynamicAccess.thisProperty(this.name)
      : super._(AccessKind.THIS_PROPERTY);

  const DynamicAccess.dynamicProperty(this.name)
      : super._(AccessKind.DYNAMIC_PROPERTY);

  const DynamicAccess.ifNotNullProperty(this.name)
      : super._(AccessKind.CONDITIONAL_DYNAMIC_PROPERTY);
}

class ConstantAccess extends AccessSemantics {
  final ConstantExpression constant;

  ConstantAccess(AccessKind kind, this.constant) : super._(kind);

  ConstantAccess.classTypeLiteral(this.constant)
      : super._(AccessKind.CLASS_TYPE_LITERAL);

  ConstantAccess.typedefTypeLiteral(this.constant)
      : super._(AccessKind.TYPEDEF_TYPE_LITERAL);

  ConstantAccess.dynamicTypeLiteral(this.constant)
      : super._(AccessKind.DYNAMIC_TYPE_LITERAL);
}

class StaticAccess extends AccessSemantics {
  final Element element;

  StaticAccess.internal(AccessKind kind, this.element) : super._(kind);

  StaticAccess.superSetter(MethodElement this.element)
      : super._(AccessKind.SUPER_SETTER);

  StaticAccess.superField(FieldElement this.element)
      : super._(AccessKind.SUPER_FIELD);

  StaticAccess.superFinalField(FieldElement this.element)
      : super._(AccessKind.SUPER_FINAL_FIELD);

  StaticAccess.superMethod(MethodElement this.element)
      : super._(AccessKind.SUPER_METHOD);

  StaticAccess.superGetter(MethodElement this.element)
      : super._(AccessKind.SUPER_GETTER);

  StaticAccess.typeParameterTypeLiteral(TypeVariableElement this.element)
      : super._(AccessKind.TYPE_PARAMETER_TYPE_LITERAL);

  StaticAccess.localFunction(LocalFunctionElement this.element)
      : super._(AccessKind.LOCAL_FUNCTION);

  StaticAccess.localVariable(LocalVariableElement this.element)
      : super._(AccessKind.LOCAL_VARIABLE);

  StaticAccess.finalLocalVariable(LocalVariableElement this.element)
      : super._(AccessKind.FINAL_LOCAL_VARIABLE);

  StaticAccess.parameter(ParameterElement this.element)
      : super._(AccessKind.PARAMETER);

  StaticAccess.finalParameter(ParameterElement this.element)
      : super._(AccessKind.FINAL_PARAMETER);

  StaticAccess.staticField(FieldElement this.element)
      : super._(AccessKind.STATIC_FIELD);

  StaticAccess.finalStaticField(FieldElement this.element)
      : super._(AccessKind.FINAL_STATIC_FIELD);

  StaticAccess.staticMethod(MethodElement this.element)
      : super._(AccessKind.STATIC_METHOD);

  StaticAccess.staticGetter(MethodElement this.element)
      : super._(AccessKind.STATIC_GETTER);

  StaticAccess.staticSetter(MethodElement this.element)
      : super._(AccessKind.STATIC_SETTER);

  StaticAccess.topLevelField(FieldElement this.element)
      : super._(AccessKind.TOPLEVEL_FIELD);

  StaticAccess.finalTopLevelField(FieldElement this.element)
      : super._(AccessKind.FINAL_TOPLEVEL_FIELD);

  StaticAccess.topLevelMethod(MethodElement this.element)
      : super._(AccessKind.TOPLEVEL_METHOD);

  StaticAccess.topLevelGetter(MethodElement this.element)
      : super._(AccessKind.TOPLEVEL_GETTER);

  StaticAccess.topLevelSetter(MethodElement this.element)
      : super._(AccessKind.TOPLEVEL_SETTER);

  StaticAccess.unresolved(this.element) : super._(AccessKind.UNRESOLVED);

  StaticAccess.unresolvedSuper(this.element)
      : super._(AccessKind.UNRESOLVED_SUPER);

  StaticAccess.invalid(this.element) : super._(AccessKind.INVALID);
}

class CompoundAccessSemantics extends AccessSemantics {
  final CompoundAccessKind compoundAccessKind;
  final Element getter;
  final Element setter;

  CompoundAccessSemantics(this.compoundAccessKind, this.getter, this.setter)
      : super._(AccessKind.COMPOUND);

  Element get element => setter;

  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.write('CompoundAccessSemantics[');
    sb.write('kind=$compoundAccessKind');
    if (getter != null) {
      sb.write(',getter=');
      sb.write('${getter}');
    }
    if (setter != null) {
      sb.write(',setter=');
      sb.write('${setter}');
    }
    sb.write(']');
    return sb.toString();
  }
}

/// Enum representing the different kinds of destinations which a constructor
/// invocation might refer to.
enum ConstructorAccessKind {
  /// An invocation of a (redirecting) generative constructor.
  ///
  /// For instance
  ///     class C {
  ///       C();
  ///       C.redirect() : this();
  ///     }
  ///     m1() => new C();
  ///     m2() => new C.redirect();
  ///
  GENERATIVE,

  /// An invocation of a (redirecting) factory constructor.
  ///
  /// For instance
  ///     class C {
  ///       factory C() => new C._();
  ///       factory C.redirect() => C._;
  ///       C._();
  ///     }
  ///     m1() => new C();
  ///     m2() => new C.redirect();
  ///
  FACTORY,

  /// An invocation of a (redirecting) generative constructor of an abstract
  /// class.
  ///
  /// For instance
  ///     abstract class C {
  ///       C();
  ///     }
  ///     m() => new C();
  ///
  ABSTRACT,

  /// An invocation of a constructor on an unresolved type.
  ///
  /// For instance
  ///     m() => new Unresolved();
  ///
  UNRESOLVED_TYPE,

  /// An invocation of an unresolved constructor.
  ///
  /// For instance
  ///     class C {
  ///       C();
  ///     }
  ///     m() => new C.unresolved();
  ///
  UNRESOLVED_CONSTRUCTOR,

  /// An const invocation of an non-constant constructor.
  ///
  /// For instance
  ///     class C {
  ///       C();
  ///     }
  ///     m() => const C();
  ///
  NON_CONSTANT_CONSTRUCTOR,

  /// An invocation of a constructor with incompatible arguments.
  ///
  /// For instance
  ///     class C {
  ///       C();
  ///     }
  ///     m() => new C(true);
  ///
  INCOMPATIBLE,
}

/// Data structure used to classify the semantics of a constructor invocation.
class ConstructorAccessSemantics {
  /// The kind of constructor invocation.
  final ConstructorAccessKind kind;

  /// The invoked constructor.
  final Element element;

  /// The type on which the constructor is invoked.
  final ResolutionDartType type;

  ConstructorAccessSemantics(this.kind, this.element, this.type);

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