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

part of dart.core;

/**
 * Error objects thrown in the case of a program failure.
 *
 * An `Error` object represents a program failure that the programmer
 * should have avoided.
 *
 * Examples include calling a function with invalid arguments,
 * or even with the wrong number of arguments,
 * or calling it at a time when it is not allowed.
 *
 * These are not errors that a caller should expect or catch -
 * if they occur, the program is erroneous,
 * and terminating the program may be the safest response.
 *
 * When deciding that a function throws an error,
 * the conditions where it happens should be clearly described,
 * and they should be detectable and predictable,
 * so the programmer using the function can avoid triggering the error.
 *
 * Such descriptions often uses words like
 * "must" or "must not" to describe the condition,
 * and if you see words like that in a function's documentation,
 * then not satisfying the requirement
 * is very likely to cause an error to be thrown.
 *
 * Example (from [String.contains]):
 *
 *        `startIndex` must not be negative or greater than `length`.
 *
 * In this case, an error will be thrown if `startIndex` is negative
 * or too large.
 *
 * If the conditions are not detectable before calling a function,
 * the called function should not throw an `Error`.
 * It may still throw a value,
 * but the caller will have to catch the thrown value,
 * effectively making it an alternative result rather than an error.
 * The thrown object can choose to implement [Exception]
 * to document that it represents an exceptional, but not erroneous, occurrence,
 * but it has no other effect than documentation.
 *
 * All non-`null` values can be thrown in Dart.
 * Objects extending `Error` are handled specially:
 * The first time they are thrown,
 * the stack trace at the throw point is recorded
 * and stored in the error object.
 * It can be retrieved using the [stackTrace] getter.
 * An error object that merely implements `Error`, and doesn't extend it,
 * will not store the stack trace automatically.
 *
 * Error objects are also used for system wide failures
 * like stack overflow or an out-of-memory situation.
 *
 * Since errors are not created to be caught,
 * there is no need for subclasses to distinguish the errors.
 * Instead subclasses have been created in order to make groups
 * of related errors easy to create with consistent error messages.
 * For example, the [String.contains] method will use a [RangeError]
 * if its `startIndex` isn't in the range `0..length`,
 * which is easily created by `new RangeError.range(startIndex, 0, length)`.
 */
class Error {
  Error(); // Prevent use as mixin.

  /**
   * Safely convert a value to a [String] description.
   *
   * The conversion is guaranteed to not throw, so it won't use the object's
   * toString method.
   */
  static String safeToString(Object object) {
    if (object is num || object is bool || null == object) {
      return object.toString();
    }
    if (object is String) {
      return _stringToSafeString(object);
    }
    return _objectToString(object);
  }

  /** Convert string to a valid string literal with no control characters. */
  external static String _stringToSafeString(String string);

  external static String _objectToString(Object object);

  external StackTrace get stackTrace;
}

/**
 * Error thrown by the runtime system when an assert statement fails.
 */
class AssertionError extends Error {
  /** Message describing the assertion error. */
  final Object message;
  AssertionError([this.message]);
  String toString() => "Assertion failed";
}

/**
 * Error thrown by the runtime system when a type assertion fails.
 */
class TypeError extends AssertionError {}

/**
 * Error thrown by the runtime system when a cast operation fails.
 */
class CastError extends Error {}

/**
 * Error thrown when attempting to throw [:null:].
 */
class NullThrownError extends Error {
  @pragma("vm:entry-point")
  NullThrownError();
  String toString() => "Throw of null.";
}

/**
 * Error thrown when a function is passed an unacceptable argument.
 */
class ArgumentError extends Error {
  /** Whether value was provided. */
  final bool _hasValue;
  /** The invalid value. */
  final invalidValue;
  /** Name of the invalid argument, if available. */
  final String name;
  /** Message describing the problem. */
  final message;

  /**
   * The [message] describes the erroneous argument.
   *
   * Existing code may be using `message` to hold the invalid value.
   * If the `message` is not a [String], it is assumed to be a value instead
   * of a message.
   */
  @pragma("vm:entry-point")
  ArgumentError([this.message])
      : invalidValue = null,
        _hasValue = false,
        name = null;

  /**
   * Creates error containing the invalid [value].
   *
   * A message is built by suffixing the [message] argument with
   * the [name] argument (if provided) and the value. Example
   *
   *    "Invalid argument (foo): null"
   *
   * The `name` should match the argument name of the function, but if
   * the function is a method implementing an interface, and its argument
   * names differ from the interface, it might be more useful to use the
   * interface method's argument name (or just rename arguments to match).
   */
  @pragma("vm:entry-point")
  ArgumentError.value(value, [this.name, this.message])
      : invalidValue = value,
        _hasValue = true;

  /**
   * Create an argument error for a `null` argument that must not be `null`.
   */
  ArgumentError.notNull([this.name])
      : _hasValue = false,
        message = "Must not be null",
        invalidValue = null;

  /**
   * Throws if [argument] is `null`.
   */
  static void checkNotNull(Object argument, [String name]) {
    if (argument == null) throw ArgumentError.notNull(name);
  }

  // Helper functions for toString overridden in subclasses.
  String get _errorName => "Invalid argument${!_hasValue ? "(s)" : ""}";
  String get _errorExplanation => "";

  String toString() {
    String nameString = "";
    if (name != null) {
      nameString = " ($name)";
    }
    var message = (this.message == null) ? "" : ": ${this.message}";
    String prefix = "$_errorName$nameString$message";
    if (!_hasValue) return prefix;
    // If we know the invalid value, we can try to describe the problem.
    String explanation = _errorExplanation;
    String errorValue = Error.safeToString(invalidValue);
    return "$prefix$explanation: $errorValue";
  }
}

/**
 * Error thrown due to an index being outside a valid range.
 */
class RangeError extends ArgumentError {
  /** The minimum value that [value] is allowed to assume. */
  final num start;
  /** The maximum value that [value] is allowed to assume. */
  final num end;

  // TODO(lrn): This constructor should be called only with string values.
  // It currently isn't in all cases.
  /**
   * Create a new [RangeError] with the given [message].
   */
  @pragma("vm:entry-point")
  RangeError(var message)
      : start = null,
        end = null,
        super(message);

  /**
   * Create a new [RangeError] with a message for the given [value].
   *
   * An optional [name] can specify the argument name that has the
   * invalid value, and the [message] can override the default error
   * description.
   */
  RangeError.value(num value, [String name, String message])
      : start = null,
        end = null,
        super.value(
            value, name, (message != null) ? message : "Value not in range");

  /**
   * Create a new [RangeError] for a value being outside the valid range.
   *
   * The allowed range is from [minValue] to [maxValue], inclusive.
   * If `minValue` or `maxValue` are `null`, the range is infinite in
   * that direction.
   *
   * For a range from 0 to the length of something, end exclusive, use
   * [RangeError.index].
   *
   * An optional [name] can specify the argument name that has the
   * invalid value, and the [message] can override the default error
   * description.
   */
  @pragma("vm:entry-point")
  RangeError.range(num invalidValue, int minValue, int maxValue,
      [String name, String message])
      : start = minValue,
        end = maxValue,
        super.value(
            invalidValue, name, (message != null) ? message : "Invalid value");

  /**
   * Creates a new [RangeError] stating that [index] is not a valid index
   * into [indexable].
   *
   * An optional [name] can specify the argument name that has the
   * invalid value, and the [message] can override the default error
   * description.
   *
   * The [length] is the length of [indexable] at the time of the error.
   * If `length` is omitted, it defaults to `indexable.length`.
   */
  factory RangeError.index(int index, indexable,
      [String name, String message, int length]) = IndexError;

  /**
   * Check that a [value] lies in a specific interval.
   *
   * Throws if [value] is not in the interval.
   * The interval is from [minValue] to [maxValue], both inclusive.
   */
  static void checkValueInInterval(int value, int minValue, int maxValue,
      [String name, String message]) {
    if (value < minValue || value > maxValue) {
      throw new RangeError.range(value, minValue, maxValue, name, message);
    }
  }

  /**
   * Check that a value is a valid index into an indexable object.
   *
   * Throws if [index] is not a valid index into [indexable].
   *
   * An indexable object is one that has a `length` and a and index-operator
   * `[]` that accepts an index if `0 <= index < length`.
   *
   * If [length] is provided, it is used as the length of the indexable object,
   * otherwise the length is found as `indexable.length`.
   */
  static void checkValidIndex(int index, var indexable,
      [String name, int length, String message]) {
    if (length == null) length = indexable.length;
    // Comparing with `0` as receiver produces better dart2js type inference.
    if (0 > index || index >= length) {
      if (name == null) name = "index";
      throw new RangeError.index(index, indexable, name, message, length);
    }
  }

  /**
   * Check that a range represents a slice of an indexable object.
   *
   * Throws if the range is not valid for an indexable object with
   * the given [length].
   * A range is valid for an indexable object with a given [length]
   *
   * if `0 <= [start] <= [end] <= [length]`.
   * An `end` of `null` is considered equivalent to `length`.
   *
   * The [startName] and [endName] defaults to `"start"` and `"end"`,
   * respectively.
   *
   * Returns the actual `end` value, which is `length` if `end` is `null`,
   * and `end` otherwise.
   */
  static int checkValidRange(int start, int end, int length,
      [String startName, String endName, String message]) {
    // Comparing with `0` as receiver produces better dart2js type inference.
    // Ditto `start > end` below.
    if (0 > start || start > length) {
      if (startName == null) startName = "start";
      throw new RangeError.range(start, 0, length, startName, message);
    }
    if (end != null) {
      if (start > end || end > length) {
        if (endName == null) endName = "end";
        throw new RangeError.range(end, start, length, endName, message);
      }
      return end;
    }
    return length;
  }

  /**
   * Check that an integer value isn't negative.
   *
   * Throws if the value is negative.
   */
  static void checkNotNegative(int value, [String name, String message]) {
    if (value < 0) throw new RangeError.range(value, 0, null, name, message);
  }

  String get _errorName => "RangeError";
  String get _errorExplanation {
    assert(_hasValue);
    String explanation = "";
    if (start == null) {
      if (end != null) {
        explanation = ": Not less than or equal to $end";
      }
      // If both are null, we don't add a description of the limits.
    } else if (end == null) {
      explanation = ": Not greater than or equal to $start";
    } else if (end > start) {
      explanation = ": Not in range $start..$end, inclusive";
    } else if (end < start) {
      explanation = ": Valid value range is empty";
    } else {
      // end == start.
      explanation = ": Only valid value is $start";
    }
    return explanation;
  }
}

/**
 * A specialized [RangeError] used when an index is not in the range
 * `0..indexable.length-1`.
 *
 * Also contains the indexable object, its length at the time of the error,
 * and the invalid index itself.
 */
class IndexError extends ArgumentError implements RangeError {
  /** The indexable object that [invalidValue] was not a valid index into. */
  final indexable;
  /** The length of [indexable] at the time of the error. */
  final int length;

  /**
   * Creates a new [IndexError] stating that [invalidValue] is not a valid index
   * into [indexable].
   *
   * The [length] is the length of [indexable] at the time of the error.
   * If `length` is omitted, it defaults to `indexable.length`.
   *
   * The message is used as part of the string representation of the error.
   */
  IndexError(int invalidValue, indexable,
      [String name, String message, int length])
      : this.indexable = indexable,
        this.length = (length != null) ? length : indexable.length,
        super.value(invalidValue, name,
            (message != null) ? message : "Index out of range");

  // Getters inherited from RangeError.
  int get start => 0;
  int get end => length - 1;

  String get _errorName => "RangeError";
  String get _errorExplanation {
    assert(_hasValue);
    if (invalidValue < 0) {
      return ": index must not be negative";
    }
    if (length == 0) {
      return ": no indices are valid";
    }
    return ": index should be less than $length";
  }
}

/**
 * Error thrown when control reaches the end of a switch case.
 *
 * The Dart specification requires this error to be thrown when
 * control reaches the end of a switch case (except the last case
 * of a switch) without meeting a break or similar end of the control
 * flow.
 */
class FallThroughError extends Error {
  FallThroughError();
  @pragma("vm:entry-point")
  external FallThroughError._create(String url, int line);

  external String toString();
}

/**
 * Error thrown when trying to instantiate an abstract class.
 */
class AbstractClassInstantiationError extends Error {
  final String _className;
  AbstractClassInstantiationError(String className) : _className = className;

  external String toString();
}

/**
 * Error thrown by the default implementation of [:noSuchMethod:] on [Object].
 */
class NoSuchMethodError extends Error {
  /**
   * Create a [NoSuchMethodError] corresponding to a failed method call.
   *
   * The [receiver] is the receiver of the method call.
   * That is, the object on which the method was attempted called.
   *
   * The [invocation] represents the method call that failed. It
   * should not be `null`.
   */
  external NoSuchMethodError.withInvocation(
      Object receiver, Invocation invocation);

  // Deprecated constructor to be removed after dart2js updates to the above.
  /**
   * Create a [NoSuchMethodError] corresponding to a failed method call.
   *
   * The [receiver] is the receiver of the method call.
   * That is, the object on which the method was attempted called.
   * If the receiver is `null`, it is interpreted as a call to a top-level
   * function of a library.
   *
   * The [memberName] is a [Symbol] representing the name of the called method
   * or accessor. It should not be `null`.
   *
   * The [positionalArguments] is a list of the positional arguments that the
   * method was called with. If `null`, it is considered equivalent to the
   * empty list.
   *
   * The [namedArguments] is a map from [Symbol]s to the values of named
   * arguments that the method was called with.
   *
   * This constructor does not handle type arguments.
   * To include type variables, create an [Invocation] and use
   * [NoSuchMethodError.withInvocation].
   */
  @Deprecated("Use NoSuchMethod.withInvocation instead")
  external NoSuchMethodError(Object receiver, Symbol memberName,
      List positionalArguments, Map<Symbol, dynamic> namedArguments,
      [@deprecated List existingArgumentNames = null]);

  external String toString();
}

/**
 * The operation was not allowed by the object.
 *
 * This [Error] is thrown when an instance cannot implement one of the methods
 * in its signature.
 */
class UnsupportedError extends Error {
  final String message;
  @pragma("vm:entry-point")
  UnsupportedError(this.message);
  String toString() => "Unsupported operation: $message";
}

/**
 * Thrown by operations that have not been implemented yet.
 *
 * This [Error] is thrown by unfinished code that hasn't yet implemented
 * all the features it needs.
 *
 * If a class is not intending to implement the feature, it should throw
 * an [UnsupportedError] instead. This error is only intended for
 * use during development.
 */
class UnimplementedError extends Error implements UnsupportedError {
  final String message;
  UnimplementedError([this.message]);
  String toString() => (this.message != null
      ? "UnimplementedError: $message"
      : "UnimplementedError");
}

/**
 * The operation was not allowed by the current state of the object.
 *
 * This is a generic error used for a variety of different erroneous
 * actions. The message should be descriptive.
 */
class StateError extends Error {
  final String message;
  StateError(this.message);
  String toString() => "Bad state: $message";
}

/**
 * Error occurring when a collection is modified during iteration.
 *
 * Some modifications may be allowed for some collections, so each collection
 * ([Iterable] or similar collection of values) should declare which operations
 * are allowed during an iteration.
 */
class ConcurrentModificationError extends Error {
  /** The object that was modified in an incompatible way. */
  final Object modifiedObject;

  ConcurrentModificationError([this.modifiedObject]);

  String toString() {
    if (modifiedObject == null) {
      return "Concurrent modification during iteration.";
    }
    return "Concurrent modification during iteration: "
        "${Error.safeToString(modifiedObject)}.";
  }
}

class OutOfMemoryError implements Error {
  @pragma("vm:entry-point")
  const OutOfMemoryError();
  String toString() => "Out of Memory";

  StackTrace get stackTrace => null;
}

class StackOverflowError implements Error {
  @pragma("vm:entry-point")
  const StackOverflowError();
  String toString() => "Stack Overflow";

  StackTrace get stackTrace => null;
}

/**
 * Error thrown when a lazily initialized variable cannot be initialized.
 *
 * A static/library variable with an initializer expression is initialized
 * the first time it is read. If evaluating the initializer expression causes
 * another read of the variable, this error is thrown.
 */
class CyclicInitializationError extends Error {
  final String variableName;
  @pragma("vm:entry-point")
  CyclicInitializationError([this.variableName]);
  String toString() => variableName == null
      ? "Reading static variable during its initialization"
      : "Reading static variable '$variableName' during its initialization";
}

/// Used by Fasta to wrap constant expressions so an illegal constant expression
/// will throw an error.
class _ConstantHelper {
  _isNumStringBoolOrNull(Object e) {
    return e is num || e is String || e is bool || e == null;
  }

  _isNumStringOrNull(Object e) {
    return e is num || e is String || e == null;
  }

  _isNumOrNull(Object e) {
    return e is num || e == null;
  }

  _isIntOrNull(Object e) {
    return e is int || e == null;
  }

  ////////////////////////////////////////

  // An expression of one of the forms e1 == e2 or e1 != e2 where e1 and e2 are
  // constant expressions that evaluate to a numeric, string or boolean value or
  // to null.

  equals(Object e1, Object e2, Function onError) {
    if (!_isNumStringBoolOrNull((e1)) || !_isNumStringBoolOrNull(e2)) onError();
    return e1 == e2;
  }

  notEquals(Object e1, Object e2, Function onError) {
    if (!_isNumStringBoolOrNull((e1)) || !_isNumStringBoolOrNull(e2)) onError();
    return e1 != e2;
  }

  ////////////////////////////////////////

  // An expression of one of the forms !e, e1 && e2 or e1 || e2 , where e, e1
  // and e2 are constant expressions that evaluate to a boolean value.

  not(Object e, Function onError) {
    if (e is! bool) onError();
    return !e;
  }

  logicalAnd(Object e1, Object e2, Function onError) {
    if (e1 is! bool || e2 is! bool) onError();
    return e1 && e2;
  }

  logicalOr(Object e1, Object e2, Function onError) {
    if (e1 is! bool || e2 is! bool) onError();
    return e1 || e2;
  }

  ////////////////////////////////////////

  // An expression of one of the forms  ~e, e1 ˆ e2, e1 & e2, e1 | e2, e1 >> e2
  // or e1 << e2, where e, e1 and e2 are constant expressions that evaluate to
  // an integer value or to null.

  bitwiseNot(dynamic e, Function onError) {
    if (!_isIntOrNull(e)) onError();
    return ~e;
  }

  bitwiseXor(dynamic e1, dynamic e2, Function onError) {
    if (!_isIntOrNull(e1) || !_isIntOrNull(e2)) onError();
    return e1 ^ e2;
  }

  bitwiseAnd(dynamic e1, dynamic e2, Function onError) {
    if (!_isIntOrNull(e1) || !_isIntOrNull(e2)) onError();
    return e1 & e2;
  }

  bitwiseOr(dynamic e1, dynamic e2, Function onError) {
    if (!_isIntOrNull(e1) || !_isIntOrNull(e2)) onError();
    return e1 | e2;
  }

  rightShift(dynamic e1, dynamic e2, Function onError) {
    if (!_isIntOrNull(e1) || !_isIntOrNull(e2)) onError();
    return e1 >> e2;
  }

  leftShift(dynamic e1, dynamic e2, Function onError) {
    if (!_isIntOrNull(e1) || !_isIntOrNull(e2)) onError();
    return e1 << e2;
  }

  ////////////////////////////////////////

  // An expression of the form e1 + e2 where e1 and e2 are constant expressions
  // that evaluate to a numeric or string value or to null.

  plus(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumStringOrNull(e1) || !_isNumStringOrNull(e2)) onError();
    return e1 + e2;
  }

  ////////////////////////////////////////

  // An expression of one of the forms -e, e1 - e2, e1 * e2, e1 / e2, e1 ~/ e2,
  // e1 > e2, e1 < e2, e1 >= e2, e1 <= e2 or e1 % e2, where e, e1 and e2 are
  // constant expressions that evaluate to a numeric value or to null.

  unary_minus(dynamic e, Function onError) {
    if (!_isNumOrNull(e)) onError();
    return -e;
  }

  minus(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 - e2;
  }

  times(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 * e2;
  }

  div(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 / e2;
  }

  integerDiv(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 ~/ e2;
  }

  greater(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 > e2;
  }

  less(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 < e2;
  }

  greaterEqual(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 >= e2;
  }

  lessEqual(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 <= e2;
  }

  mod(dynamic e1, dynamic e2, Function onError) {
    if (!_isNumOrNull(e1) || !_isNumOrNull(e2)) onError();
    return e1 % e2;
  }

  ////////////////////////////////////////

  // An expression of the form e1 ? e2 : e3 where e1, e2 and e3 are constant
  // expressions and e1 evaluates to a boolean value.

  conditional(Object e1, Object e2, Object e3, Function onError) {
    if (e1 is! bool) onError();
    return e1 ? e2 : e3;
  }

  ////////////////////////////////////////

  // An expression of the form e1 ?? e2 where e1 and e2 are constant expressions.

  ifNull(Object e1, Object e2, Object e3, Function onError) {
    if (e1 is! bool) onError();
    return e1 ?? e2;
  }

  ////////////////////////////////////////

  // An expression of the form e.length where e is a constant expression that
  // evaluates to a string value.

  dotLength(dynamic e, Function onError) {
    if (e is! String) onError();
    return e.length();
  }
}
