Proposed public API for the type system
Change-Id: I1980ffe05f246430e9dcb637eb3ac984ae1f4b1e
Reviewed-on: https://dart-review.googlesource.com/c/87240
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/dart/element/type_system.dart b/pkg/analyzer/lib/dart/element/type_system.dart
new file mode 100644
index 0000000..769a5d9
--- /dev/null
+++ b/pkg/analyzer/lib/dart/element/type_system.dart
@@ -0,0 +1,83 @@
+// 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';
+
+/// 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 Γ,
+ /// > written Γ ⊢ _T_ ⇔ _S_, iff either Γ ⊢ _S_
+ /// > <: _T_ or Γ ⊢ _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 [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);
+
+ /// 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);
+}