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

/// Defines the type model. The type model is part of the
/// [element model](../dart_element_element/dart_element_element-library.html)
/// in that most types are defined by Dart code (the types `dynamic` and `void`
/// being the notable exceptions). All types are represented by an instance of a
/// subclass of [DartType].
///
/// Other than `dynamic` and `void`, all of the types define either the
/// interface defined by a class (an instance of [InterfaceType]) or the type of
/// a function (an instance of [FunctionType]).
///
/// We make a distinction between the declaration of a class (a [ClassElement])
/// and the type defined by that class (an [InterfaceType]). The biggest reason
/// for the distinction is to allow us to more cleanly represent the distinction
/// between type parameters and type arguments. For example, if we define a
/// class as `class Pair<K, V> {}`, the declarations of `K` and `V` represent
/// type parameters. But if we declare a variable as `Pair<String, int> pair;`
/// the references to `String` and `int` are type arguments.
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type_visitor.dart';
import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;

/// The type associated with elements in the element model.
///
/// Clients may not extend, implement or mix-in this class.
abstract class DartType {
  /// If this type is an instantiation of a type alias, return the type
  /// arguments used for the instantiation. Otherwise return `null`.
  List<DartType>? get aliasArguments;

  /// If this type is an instantiation of a type alias, return it.
  /// Otherwise return `null`.
  TypeAliasElement? get aliasElement;

  /// Return the name of this type as it should appear when presented to users
  /// in contexts such as error messages.
  ///
  /// Clients should not depend on the content of the returned value as it will
  /// be changed if doing so would improve the UX.
  @Deprecated('Use getDisplayString instead')
  String get displayName;

  /// Return the element representing the declaration of this type, or `null` if
  /// the type has not, or cannot, be associated with an element. The former
  /// case will occur if the element model is not yet complete; the latter case
  /// will occur if this object represents an undefined type.
  Element? get element;

  /// Return `true` if this type represents the bottom type.
  bool get isBottom;

  /// Return `true` if this type represents the type 'Future' defined in the
  /// dart:async library.
  bool get isDartAsyncFuture;

  /// Return `true` if this type represents the type 'FutureOr<T>' defined in
  /// the dart:async library.
  bool get isDartAsyncFutureOr;

  /// Return `true` if this type represents the type 'bool' defined in the
  /// dart:core library.
  bool get isDartCoreBool;

  /// Return `true` if this type represents the type 'double' defined in the
  /// dart:core library.
  bool get isDartCoreDouble;

  /// Return `true` if this type represents the type 'Function' defined in the
  /// dart:core library.
  bool get isDartCoreFunction;

  /// Return `true` if this type represents the type 'int' defined in the
  /// dart:core library.
  bool get isDartCoreInt;

  /// Returns `true` if this type represents the type 'Iterable' defined in the
  /// dart:core library.
  bool get isDartCoreIterable;

  /// Returns `true` if this type represents the type 'List' defined in the
  /// dart:core library.
  bool get isDartCoreList;

  /// Returns `true` if this type represents the type 'Map' defined in the
  /// dart:core library.
  bool get isDartCoreMap;

  /// Return `true` if this type represents the type 'Null' defined in the
  /// dart:core library.
  bool get isDartCoreNull;

  /// Return `true` if this type represents the type 'num' defined in the
  /// dart:core library.
  bool get isDartCoreNum;

  /// Return `true` if this type represents the type `Object` defined in the
  /// dart:core library.
  bool get isDartCoreObject;

  /// Returns `true` if this type represents the type 'Set' defined in the
  /// dart:core library.
  bool get isDartCoreSet;

  /// Return `true` if this type represents the type 'String' defined in the
  /// dart:core library.
  bool get isDartCoreString;

  /// Returns `true` if this type represents the type 'Symbol' defined in the
  /// dart:core library.
  bool get isDartCoreSymbol;

  /// Return `true` if this type represents the type 'dynamic'.
  bool get isDynamic;

  /// Return `true` if this type represents the type 'void'.
  bool get isVoid;

  /// Return the name of this type, or `null` if the type does not have a name,
  /// such as when the type represents the type of an unnamed function.
  @Deprecated('Check element, or use getDisplayString()')
  String? get name;

  /// Return the nullability suffix of this type.
  NullabilitySuffix get nullabilitySuffix;

  /// Use the given [visitor] to visit this type.
  R accept<R>(TypeVisitor<R> visitor);

  /// Use the given [visitor] to visit this type.
  R acceptWithArgument<R, A>(
    TypeVisitorWithArgument<R, A> visitor,
    A argument,
  );

  /// Return the canonical interface that this type implements for [element],
  /// or `null` if such an interface does not exist.
  ///
  /// For example, given the following definitions
  /// ```
  /// class A<E> {}
  /// class B<E> implements A<E> {}
  /// class C implements A<String> {}
  /// ```
  /// Asking the type `B<int>` for the type associated with `A` will return the
  /// type `A<int>`. Asking the type `C` for the type associated with `A` will
  /// return the type `A<String>`.
  ///
  /// For a [TypeParameterType] with a bound (declared or promoted), returns
  /// the interface implemented by the bound.
  InterfaceType? asInstanceOf(ClassElement element);

  /// Return the presentation of this type as it should appear when presented
  /// to users in contexts such as error messages.
  ///
  /// If [withNullability] is `true`, then [NullabilitySuffix.question] and
  /// [NullabilitySuffix.star] will be be represented as `?` and `*`.
  /// [NullabilitySuffix.none] does not have any explicit presentation.
  ///
  /// If [withNullability] is `false`, nullability suffixes will not be
  /// included into the presentation.
  ///
  /// Clients should not depend on the content of the returned value as it will
  /// be changed if doing so would improve the UX.
  String getDisplayString({required bool withNullability});

  /// If this type is a [TypeParameterType], returns its bound if it has one, or
  /// [objectType] otherwise.
  ///
  /// For any other type, returns `this`. Applies recursively -- if the bound is
  /// itself a type parameter, that is resolved too.
  DartType resolveToBound(DartType objectType);
}

/// The type `dynamic` is a type which is a supertype of all other types, just
/// like `Object`, with the difference that the static analysis assumes that
/// every member access has a corresponding member with a signature that
/// admits the given access.
abstract class DynamicType implements DartType {}

/// The type of a function, method, constructor, getter, or setter. Function
/// types come in three variations:
///
/// * The types of functions that only have required parameters. These have the
///   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.
/// * The types of functions with optional positional parameters. These have the
///   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
///   &hellip;, T<sub>n+k</sub>]) &rarr; T</i>.
/// * The types of functions with named parameters. These have the general form
///   <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
///   T<sub>xk</sub> xk}) &rarr; T</i>.
///
/// Clients may not extend, implement or mix-in this class.
abstract class FunctionType implements DartType {
  /// Return a map from the names of named parameters to the types of the named
  /// parameters of this type of function. The entries in the map will be
  /// iterated in the same order as the order in which the named parameters were
  /// defined. If there were no named parameters declared then the map will be
  /// empty.
  Map<String, DartType> get namedParameterTypes;

  /// The names of the required positional parameters of this type of function,
  /// in the order that the parameters appear.
  List<String> get normalParameterNames;

  /// Return a list containing the types of the normal parameters of this type
  /// of function. The parameter types are in the same order as they appear in
  /// the declaration of the function.
  List<DartType> get normalParameterTypes;

  /// The names of the optional positional parameters of this type of function,
  /// in the order that the parameters appear.
  List<String> get optionalParameterNames;

  /// Return a map from the names of optional (positional) parameters to the
  /// types of the optional parameters of this type of function. The entries in
  /// the map will be iterated in the same order as the order in which the
  /// optional parameters were defined. If there were no optional parameters
  /// declared then the map will be empty.
  List<DartType> get optionalParameterTypes;

  /// Return a list containing the parameters elements of this type of function.
  /// The parameter types are in the same order as they appear in the
  /// declaration of the function.
  List<ParameterElement> get parameters;

  /// Return the type of object returned by this type of function.
  DartType get returnType;

  /// The formal type parameters of this generic function.
  /// For example `<T> T -> T`.
  ///
  /// TODO(scheglov) Remove the mention for "typeParameters".
  /// These are distinct from the `typeParameters` list, which contains type
  /// parameters from surrounding contexts, and thus are free type variables
  /// from the perspective of this function type.
  List<TypeParameterElement> get typeFormals;

  /// Produces a new function type by substituting type parameters of this
  /// function type with the given [argumentTypes]. The resulting function
  /// type will have no type parameters.
  FunctionType instantiate(List<DartType> argumentTypes);
}

/// The type introduced by either a class or an interface, or a reference to
/// such a type.
///
/// Clients may not extend, implement or mix-in this class.
abstract class InterfaceType implements ParameterizedType {
  /// Return a list containing all of the accessors (getters and setters)
  /// declared in this type.
  List<PropertyAccessorElement> get accessors;

  /// Return all the super-interfaces implemented by this interface. This
  /// includes superclasses, mixins, interfaces, and superclass constraints.
  List<InterfaceType> get allSupertypes;

  /// Return a list containing all of the constructors declared in this type.
  List<ConstructorElement> get constructors;

  @override
  ClassElement get element;

  /// Return a list containing all of the interfaces that are implemented by
  /// this interface. Note that this is <b>not</b>, in general, equivalent to
  /// getting the interfaces from this type's element because the types returned
  /// by this method will have had their type parameters replaced.
  List<InterfaceType> get interfaces;

  /// Return a list containing all of the methods declared in this type.
  List<MethodElement> get methods;

  /// Return a list containing all of the mixins that are applied to the class
  /// being extended in order to derive the superclass of this class. Note that
  /// this is <b>not</b>, in general, equivalent to getting the mixins from this
  /// type's element because the types returned by this method will have had
  /// their type parameters replaced.
  List<InterfaceType> get mixins;

  /// Return the type representing the superclass of this type, or null if this
  /// type represents the class 'Object'. Note that this is <b>not</b>, in
  /// general, equivalent to getting the superclass from this type's element
  /// because the type returned by this method will have had it's type
  /// parameters replaced.
  InterfaceType? get superclass;

  /// Return a list containing all of the super-class constraints that this
  /// mixin declaration declares. The list will be empty if this class does not
  /// represent a mixin declaration.
  List<InterfaceType> get superclassConstraints;

  /// Return the element representing the getter with the given [name] that is
  /// declared in this class, or `null` if this class does not declare a getter
  /// with the given name.
  PropertyAccessorElement? getGetter(String name);

  /// Return the element representing the method with the given [name] that is
  /// declared in this class, or `null` if this class does not declare a method
  /// with the given name.
  MethodElement? getMethod(String name);

  /// Return the element representing the setter with the given [name] that is
  /// declared in this class, or `null` if this class does not declare a setter
  /// with the given name.
  PropertyAccessorElement? getSetter(String name);

  /// Return the element representing the constructor that results from looking
  /// up the constructor with the given [name] in this class with respect to the
  /// given [library], or `null` if the look up fails. The behavior of this
  /// method is defined by the Dart Language Specification in section 12.11.1:
  /// <blockquote>
  /// If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be
  /// the constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor
  /// <i>T<i>. Otherwise, if <i>q</i> is not defined or not accessible, a
  /// NoSuchMethodException is thrown.
  /// </blockquote>
  ConstructorElement? lookUpConstructor(String? name, LibraryElement library);

  /// Return the element representing the getter that results from looking up
  /// the getter with the given [name] in this class with respect to the given
  /// [library], or `null` if the look up fails. The behavior of this method is
  /// defined by the Dart Language Specification in section 12.15.1:
  /// <blockquote>
  /// The result of looking up getter (respectively setter) <i>m</i> in class
  /// <i>C</i> with respect to library <i>L</i> is:
  /// * If <i>C</i> declares an instance getter (respectively setter) named
  ///   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
  ///   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
  ///   superclass <i>S</i>, then the result of the lookup is the result of
  ///   looking up getter (respectively setter) <i>m</i> in <i>S</i> with
  ///   respect to <i>L</i>. Otherwise, we say that the lookup has failed.
  /// </blockquote>
  @Deprecated('Use lookupGetter2 instead')
  PropertyAccessorElement? lookUpGetter(String name, LibraryElement library);

  /// Return the getter with the given [name].
  ///
  /// If [concrete] is `true`, then the concrete implementation is returned,
  /// from this type, or its superclass.
  ///
  /// If [inherited] is `true`, then only getters from the superclass are
  /// considered.
  ///
  /// If [recoveryStatic] is `true`, then static getters of the class,
  /// and its superclasses are considered. Clients should not use it.
  PropertyAccessorElement? lookUpGetter2(
    String name,
    LibraryElement library, {
    bool concrete = false,
    bool inherited = false,
    bool recoveryStatic = false,
  });

  /// Return the element representing the getter that results from looking up
  /// the getter with the given [name] in the superclass of this class with
  /// respect to the given [library], or `null` if the look up fails. The
  /// behavior of this method is defined by the Dart Language Specification in
  /// section 12.15.1:
  /// <blockquote>
  /// The result of looking up getter (respectively setter) <i>m</i> in class
  /// <i>C</i> with respect to library <i>L</i> is:
  /// * If <i>C</i> declares an instance getter (respectively setter) named
  ///   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
  ///   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
  ///   superclass <i>S</i>, then the result of the lookup is the result of
  ///   looking up getter (respectively setter) <i>m</i> in <i>S</i> with
  ///   respect to <i>L</i>. Otherwise, we say that the lookup has failed.
  /// </blockquote>
  @Deprecated('Use lookupGetter2 instead')
  PropertyAccessorElement? lookUpGetterInSuperclass(
      String name, LibraryElement? library);

  /// Look up the member with the given [name] in this type and all extended
  /// and mixed in classes, and by default including [thisType]. If the search
  /// fails, this will then search interfaces.
  ///
  /// Return the element representing the member that was found, or `null` if
  /// there is no getter with the given name.
  ///
  /// The [library] determines if a private member name is visible, and does not
  /// need to be supplied for public names.
  @Deprecated('Use lookupGetter2 instead')
  PropertyAccessorElement? lookUpInheritedGetter(String name,
      {LibraryElement? library, bool thisType = true});

  /// Look up the member with the given [name] in this type and all extended
  /// and mixed in classes, starting from this type. If the search fails,
  /// search interfaces.
  ///
  /// Return the element representing the member that was found, or `null` if
  /// there is no getter with the given name.
  ///
  /// The [library] determines if a private member name is visible, and does not
  /// need to be supplied for public names.
  @Deprecated('Use lookupGetter2 and/or lookupMethod2 instead')
  ExecutableElement? lookUpInheritedGetterOrMethod(String name,
      {LibraryElement? library});

  /// Look up the member with the given [name] in this type and all extended
  /// and mixed in classes, and by default including [thisType]. If the search
  /// fails, this will then search interfaces.
  ///
  /// Return the element representing the member that was found, or `null` if
  /// there is no getter with the given name.
  ///
  /// The [library] determines if a private member name is visible, and does not
  /// need to be supplied for public names.
  @Deprecated('Use lookupMethod2 instead')
  MethodElement? lookUpInheritedMethod(String name,
      {LibraryElement? library, bool thisType = true});

  /// Look up the member with the given [name] in this type and all extended
  /// and mixed in classes, and by default including [thisType]. If the search
  /// fails, this will then search interfaces.
  ///
  /// Return the element representing the member that was found, or `null` if
  /// there is no getter with the given name.
  ///
  /// The [library] determines if a private member name is visible, and does not
  /// need to be supplied for public names.
  @Deprecated('Use lookupSetter2 instead')
  PropertyAccessorElement? lookUpInheritedSetter(String name,
      {LibraryElement? library, bool thisType = true});

  /// Return the element representing the method that results from looking up
  /// the method with the given [name] in this class with respect to the given
  /// [library], or `null` if the look up fails. The behavior of this method is
  /// defined by the Dart Language Specification in section 12.15.1:
  /// <blockquote>
  /// The result of looking up method <i>m</i> in class <i>C</i> with respect to
  /// library <i>L</i> is:
  /// * If <i>C</i> declares an instance method named <i>m</i> that is
  ///   accessible to <i>L</i>, then that method is the result of the lookup.
  ///   Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the
  ///   lookup is the result of looking up method <i>m</i> in <i>S</i> with
  ///   respect to <i>L</i> Otherwise, we say that the lookup has failed.
  /// </blockquote>
  @Deprecated('Use lookupMethod2 instead')
  MethodElement? lookUpMethod(String name, LibraryElement library);

  /// Return the method with the given [name].
  ///
  /// If [concrete] is `true`, then the concrete implementation is returned,
  /// from this type, or its superclass.
  ///
  /// If [inherited] is `true`, then only methods from the superclass are
  /// considered.
  ///
  /// If [recoveryStatic] is `true`, then static methods of the class,
  /// and its superclasses are considered. Clients should not use it.
  MethodElement? lookUpMethod2(
    String name,
    LibraryElement library, {
    bool concrete = false,
    bool inherited = false,
    bool recoveryStatic = false,
  });

  /// Return the element representing the method that results from looking up
  /// the method with the given [name] in the superclass of this class with
  /// respect to the given [library], or `null` if the look up fails. The
  /// behavior of this method is defined by the Dart Language Specification in
  /// section 12.15.1:
  /// <blockquote>
  /// The result of looking up method <i>m</i> in class <i>C</i> with respect to
  /// library <i>L</i> is:
  /// * If <i>C</i> declares an instance method named <i>m</i> that is
  ///   accessible to <i>L</i>, then that method is the result of the lookup.
  ///   Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the
  /// * lookup is the result of looking up method <i>m</i> in <i>S</i> with
  ///   respect to <i>L</i>.
  /// * Otherwise, we say that the lookup has failed.
  /// </blockquote>
  @Deprecated('Use lookupMethod2 instead')
  MethodElement? lookUpMethodInSuperclass(String name, LibraryElement library);

  /// Return the element representing the setter that results from looking up
  /// the setter with the given [name] in this class with respect to the given
  /// [library], or `null` if the look up fails. The behavior of this method is
  /// defined by the Dart Language Specification in section 12.16:
  /// <blockquote>
  /// The result of looking up getter (respectively setter) <i>m</i> in class
  /// <i>C</i> with respect to library <i>L</i> is:
  /// * If <i>C</i> declares an instance getter (respectively setter) named
  ///   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
  ///   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
  ///   superclass <i>S</i>, then the result of the lookup is the result of
  ///   looking up getter (respectively setter) <i>m</i> in <i>S</i> with
  ///   respect to <i>L</i>. Otherwise, we say that the lookup has failed.
  /// </blockquote>
  @Deprecated('Use lookupSetter2 instead')
  PropertyAccessorElement? lookUpSetter(String name, LibraryElement library);

  /// Return the setter with the given [name].
  ///
  /// If [concrete] is `true`, then the concrete implementation is returned,
  /// from this type, or its superclass.
  ///
  /// If [inherited] is `true`, then only setters from the superclass are
  /// considered.
  ///
  /// If [recoveryStatic] is `true`, then static setters of the class,
  /// and its superclasses are considered. Clients should not use it.
  PropertyAccessorElement? lookUpSetter2(
    String name,
    LibraryElement library, {
    bool concrete = false,
    bool inherited = false,
    bool recoveryStatic = false,
  });

  /// Return the element representing the setter that results from looking up
  /// the setter with the given [name] in the superclass of this class with
  /// respect to the given [library], or `null` if the look up fails. The
  /// behavior of this method is defined by the Dart Language Specification in
  /// section 12.16:
  /// <blockquote>
  /// The result of looking up getter (respectively setter) <i>m</i> in class
  /// <i>C</i> with respect to library <i>L</i> is:
  /// * If <i>C</i> declares an instance getter (respectively setter) named
  ///   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
  ///   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
  ///   superclass <i>S</i>, then the result of the lookup is the result of
  ///   looking up getter (respectively setter) <i>m</i> in <i>S</i> with
  ///   respect to <i>L</i>. Otherwise, we say that the lookup has failed.
  /// </blockquote>
  @Deprecated('Use lookupSetter2 instead')
  PropertyAccessorElement? lookUpSetterInSuperclass(
      String name, LibraryElement library);

  /// Returns a "smart" version of the "least upper bound" of the given types.
  ///
  /// If these types have the same element and differ only in terms of the type
  /// arguments, attempts to find a compatible set of type arguments.
  ///
  /// Otherwise, returns the same result as [DartType.getLeastUpperBound].
  // TODO(brianwilkerson) This needs to be deprecated and moved to TypeSystem.
  static InterfaceType getSmartLeastUpperBound(
          InterfaceType first, InterfaceType second) =>
      InterfaceTypeImpl.getSmartLeastUpperBound(first, second);
}

/// The type `Never` represents the uninhabited bottom type.
abstract class NeverType implements DartType {}

/// A type that can track substituted type parameters, either for itself after
/// instantiation, or from a surrounding context.
///
/// For example, given a class `Foo<T>`, after instantiation with S for T, it
/// will track the substitution `{S/T}`.
///
/// This substitution will be propagated to its members. For example, say our
/// `Foo<T>` class has a field `T bar;`. When we look up this field, we will get
/// back a [FieldElement] that tracks the substituted type as `{S/T}T`, so when
/// we ask for the field type we will get `S`.
///
/// Clients may not extend, implement or mix-in this class.
abstract class ParameterizedType implements DartType {
  /// Return the type arguments used to instantiate this type.
  ///
  /// An [InterfaceType] always has type arguments.
  ///
  /// A [FunctionType] has type arguments only if it is a result of a typedef
  /// instantiation, otherwise the result is `null`.
  List<DartType> get typeArguments;
}

/// The type introduced by a type parameter.
///
/// Clients may not extend, implement or mix-in this class.
abstract class TypeParameterType implements DartType {
  /// Return the type representing the bound associated with this parameter,
  /// or `dynamic` if there was no explicit bound.
  DartType get bound;

  /// An object that can be used to identify this type parameter with `==`.
  ///
  /// Depending on the use, [bound] may also need to be taken into account.
  /// A given type parameter, it may have different bounds in different scopes.
  /// Always consult the bound if that could be relevant.
  ElementLocation get definition;

  @override
  TypeParameterElement get element;
}

/// The special type `void` is used to indicate that the value of an
/// expression is meaningless, and intended to be discarded.
abstract class VoidType implements DartType {}
