// 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();
}
