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

import 'package:analyzer/dart/element/type.dart';
import 'package:meta/meta.dart';

/// A representation of the operations defined for the type system.
///
/// Clients may not extend, implement or mix-in this class.
abstract class TypeSystem {
  /// Return the result of applying the function "flatten" to the given [type].
  ///
  /// For the Dart 2.0 type system, the function is defined in the Dart Language
  /// Specification, section 16.11 Function Expressions:
  ///
  /// > We define the auxiliary function _flatten(T)_, which is used below and
  /// > in other sections, as follows:
  /// >
  /// > * If _T_ is `FutureOr<`_S_`>` for some _S_ then _flatten(T)_ = _S_.
  /// >
  /// > * Otherwise if _T_ <: `Future` then let _S_ be a type such that _T_ <:
  /// >   `Future<`_S_`>` and for all _R_, if _T_ <: `Future<`_R_`>` then _S_ <:
  /// >   _R_. This ensures that `Future<`_S_`>` is the most specific generic
  /// >   instantiation of `Future` that is a supertype of _T_. Note that _S_ is
  /// >   well-defined because of the requirements on superinterfaces. Then
  /// >   _flatten(T)_ = _S_.
  /// >
  /// > * In any other circumstance, _flatten(T)_ = _T_.
  ///
  /// The subtype relationship (<:) can be tested using [isSubtypeOf].
  ///
  /// Other type systems may define this operation differently.
  DartType flatten(DartType type);

  /// Return `true` if the [rightType] is assignable to the [leftType].
  ///
  /// For the Dart 2.0 type system, the definition of this relationship is given
  /// in the Dart Language Specification, section 19.4 Subtypes:
  ///
  /// > A type _T_ may be assigned to a type _S_ in an environment &Gamma;,
  /// > written &Gamma; &#8866; _T_ &hArr; _S_, iff either &Gamma; &#8866; _S_
  /// > <: _T_ or &Gamma; &#8866; _T_ <: _S_. In this case we say that the types
  /// > _S_ and _T_ are assignable.
  ///
  /// The subtype relationship (<:) can be tested using [isSubtypeOf].
  ///
  /// Other type systems may define this operation differently. In particular,
  /// while the operation is commutative in the Dart 2.0 type system, that is
  /// not a requirement of a type system, so the order of the arguments is
  /// important.
  bool isAssignableTo(DartType leftType, DartType rightType);

  /// Return `true` if the [type] is a non-nullable type.
  ///
  /// We say that a type `T` is non-nullable if `T <: Object`. This is
  /// equivalent to the syntactic criterion that `T` is any of:
  /// - `Object`, `int`, `bool`, `Never`, `Function`
  /// - Any function type
  /// - Any class type or generic class type
  /// - `FutureOr<S>` where `S` is non-nullable
  /// - `X extends S` where `S` is non-nullable
  /// - `X & S` where `S` is non-nullable
  ///
  /// The result of this method is undefined when the experiment 'non-nullable'
  /// is not enabled.
  @experimental
  bool isNonNullable(DartType type);

  /// Return `true` if the [type] is a nullable type.
  ///
  /// We say that a type `T` is nullable if `Null <: T`. This is equivalent to
  /// the syntactic criterion that `T` is any of:
  /// - `Null`
  /// - `S?` for some `S`
  /// - `FutureOr<S>` for some `S` where `S` is nullable
  /// - `dynamic`
  /// - `void`
  ///
  /// The result of this method is undefined when the experiment 'non-nullable'
  /// is not enabled.
  @experimental
  bool isNullable(DartType type);

  /// Return `true` if the [type] is a potentially non-nullable type.
  ///
  /// We say that a type `T` is potentially non-nullable if `T` is not nullable.
  /// Note that this is different from saying that `T` is non-nullable. For
  /// example, a type variable `X extends Object?` is a type which is
  /// potentially non-nullable but not non-nullable.
  ///
  /// The result of this method is undefined when the experiment 'non-nullable'
  /// is not enabled.
  @experimental
  bool isPotentiallyNonNullable(DartType type);

  /// Return `true` if the [type] is a potentially nullable type.
  ///
  /// We say that a type `T` is potentially nullable if `T` is not non-nullable.
  /// Note that this is different from saying that `T` is nullable. For example,
  /// a type variable `X extends Object?` is a type which is potentially
  /// nullable but not nullable.
  ///
  /// The result of this method is undefined when the experiment 'non-nullable'
  /// is not enabled.
  @experimental
  bool isPotentiallyNullable(DartType type);

  /// Return `true` if the [leftType] is a subtype of the [rightType].
  ///
  /// For the Dart 2.0 type system, the rules governing the subtype relationship
  /// are given in the Dart Language Specification, section 19.4 Subtypes.
  ///
  /// Other type systems may define this operation differently.
  bool isSubtypeOf(DartType leftType, DartType rightType);

  /// Compute the least upper bound of two types. This operation if commutative,
  /// meaning that `leastUpperBound(t, s) == leastUpperBound(s, t)` for all `t`
  /// and `s`.
  ///
  /// For the Dart 2.0 type system, the definition of the least upper bound is
  /// given in the Dart Language Specification, section 19.9.2 Least Upper
  /// Bounds.
  ///
  /// Other type systems may define this operation differently.
  DartType leastUpperBound(DartType leftType, DartType rightType);

  /// Returns a non-nullable version of [type].  This is equivalent to the
  /// operation `NonNull` defined in the spec.
  DartType promoteToNonNull(DartType type);

  /// Return the result of resolving the bounds of the given [type].
  ///
  /// For the Dart 2.0 type system, the definition of resolving to bounds is
  /// defined by the following. If the given [type] is a [TypeParameterType] and
  /// it has a bound, return the result of resolving its bound (as per this
  /// method). If the [type] is a [TypeParameterType] and it does not have a
  /// bound, return the type `Object`. For any other type, return the given
  /// type.
  ///
  /// Other type systems may define this operation differently.
  DartType resolveToBound(DartType type);
}
