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

/**
 * The interface used to access the result of constant evaluation.
 *
 * Because the analyzer does not have any of the code under analysis loaded, it
 * does not do real evaluation. Instead it performs a symbolic computation and
 * presents those results through this interface.
 *
 * Instances of these constant values are accessed through the
 * [element model](../element/element.dart).
 */
import 'package:analyzer/dart/element/type.dart';

/**
 * A representation of the value of a compile-time constant expression.
 *
 * Note that, unlike the mirrors system, the object being represented does *not*
 * exist. This interface allows static analysis tools to determine something
 * about the state of the object that would exist if the code that creates the
 * object were executed, but none of the code being analyzed is actually
 * executed.
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class DartObject {
  /**
   * Return `true` if the value of the object being represented is known.
   *
   * This method will return `false` if
   * * the value being represented is the value of a declared variable (a
   *   variable whose value is provided at run-time using a `-D` command-line
   *   option), or
   * * the value is a function.
   *
   * The result of this method does not imply anything about the state of
   * object representations returned by the method [getField], those that are
   * elements of the list returned by [toListValue], or the keys or values in
   * the map returned by [toMapValue]. For example, a representation of a list
   * can return `true` even if one or more of the elements of that list would
   * return `false`.
   */
  bool get hasKnownValue;

  /**
   * Return `true` if the object being represented represents the value 'null'.
   */
  bool get isNull;

  /**
   * Return a representation of the type of the object being represented.
   *
   * For values resulting from the invocation of a 'const' constructor, this
   * will be a representation of the run-time type of the object.
   *
   * For values resulting from a literal expression, this will be a
   * representation of the static type of the value -- `int` for integer
   * literals, `List` for list literals, etc. -- even when the static type is an
   * abstract type (such as `List`) and hence will never be the run-time type of
   * the represented object.
   *
   * For values resulting from any other kind of expression, this will be a
   * representation of the result of evaluating the expression.
   *
   * Return `null` if the expression cannot be evaluated, either because it is
   * not a valid constant expression or because one or more of the values used
   * in the expression does not have a known value.
   *
   * This method can return a representation of the type, even if this object
   * would return `false` from [hasKnownValue].
   */
  ParameterizedType get type;

  /**
   * Return a representation of the value of the field with the given [name].
   *
   * Return `null` if either the object being represented does not have a field
   * with the given name or if the implementation of the class of the object is
   * invalid, making it impossible to determine that value of the field.
   *
   * Note that, unlike the mirrors API, this method does *not* invoke a getter;
   * it simply returns a representation of the known state of a field.
   */
  DartObject getField(String name);

  /**
   * Return a boolean corresponding to the value of the object being
   * represented, or `null` if
   * * this object is not of type 'bool',
   * * the value of the object being represented is not known, or
   * * the value of the object being represented is `null`.
   */
  bool toBoolValue();

  /**
   * Return a double corresponding to the value of the object being represented,
   * or `null`
   * if
   * * this object is not of type 'double',
   * * the value of the object being represented is not known, or
   * * the value of the object being represented is `null`.
   */
  double toDoubleValue();

  /**
   * Return an integer corresponding to the value of the object being
   * represented, or `null` if
   * * this object is not of type 'int',
   * * the value of the object being represented is not known, or
   * * the value of the object being represented is `null`.
   */
  int toIntValue();

  /**
   * Return a list corresponding to the value of the object being represented,
   * or `null` if
   * * this object is not of type 'List', or
   * * the value of the object being represented is `null`.
   */
  List<DartObject> toListValue();

  /**
   * Return a map corresponding to the value of the object being represented, or
   * `null` if
   * * this object is not of type 'Map', or
   * * the value of the object being represented is `null`.
   */
  Map<DartObject, DartObject> toMapValue();

  /**
   * Return a set corresponding to the value of the object being represented,
   * or `null` if
   * * this object is not of type 'Set', or
   * * the value of the object being represented is `null`.
   */
  Set<DartObject> toSetValue();

  /**
   * Return a string corresponding to the value of the object being represented,
   * or `null` if
   * * this object is not of type 'String',
   * * the value of the object being represented is not known, or
   * * the value of the object being represented is `null`.
   */
  String toStringValue();

  /**
   * Return a string corresponding to the value of the object being represented,
   * or `null` if
   * * this object is not of type 'Symbol', or
   * * the value of the object being represented is `null`.
   * (We return the string
   */
  String toSymbolValue();

  /**
   * Return the representation of the type corresponding to the value of the
   * object being represented, or `null` if
   * * this object is not of type 'Type', or
   * * the value of the object being represented is `null`.
   */
  DartType toTypeValue();
}
