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

/// Representation of the invocation of a member on an object.
///
/// This is the type of objects passed to [Object.noSuchMethod] when
/// an object doesn't support the member invocation that was attempted
/// on it.
abstract class Invocation {
  Invocation();

  /// Creates an invocation corresponding to a method invocation.
  ///
  /// The method invocation has no type arguments.
  /// If the named arguments are omitted, they default to no named arguments.
  factory Invocation.method(
          Symbol memberName, Iterable<Object?>? positionalArguments,
          [Map<Symbol, Object?>? namedArguments]) =>
      _Invocation.method(memberName, null, positionalArguments, namedArguments);

  /// Creates an invocation corresponding to a generic method invocation.
  ///
  /// If [typeArguments] is `null` or empty, the constructor is equivalent to
  /// calling [Invocation.method] with the remaining arguments.
  /// All the individual type arguments must be non-null.
  ///
  /// If the named arguments are omitted, they default to no named arguments.
  factory Invocation.genericMethod(Symbol memberName,
          Iterable<Type>? typeArguments, Iterable<Object?>? positionalArguments,
          [Map<Symbol, Object?>? namedArguments]) =>
      _Invocation.method(
          memberName, typeArguments, positionalArguments, namedArguments);

  /// Creates an invocation corresponding to a getter invocation.
  factory Invocation.getter(Symbol name) = _Invocation.getter;

  /// Creates an invocation corresponding to a setter invocation.
  ///
  /// This constructor accepts any [Symbol] as [memberName], but remember that
  /// *actual setter names* end in `=`, so the invocation corresponding
  /// to `object.member = value` is
  /// ```dart
  /// Invocation.setter(const Symbol("member="), value)
  /// ```
  factory Invocation.setter(Symbol memberName, Object? argument) =
      _Invocation.setter;

  /// The name of the invoked member.
  Symbol get memberName;

  /// An unmodifiable view of the type arguments of the call.
  ///
  /// If the member is a getter, setter or operator,
  /// the type argument list is always empty.
  List<Type> get typeArguments => const <Type>[];

  /// An unmodifiable view of the positional arguments of the call.
  ///
  /// If the member is a getter, the positional arguments list is
  /// always empty.
  List<dynamic> get positionalArguments;

  /// An unmodifiable view of the named arguments of the call.
  ///
  /// If the member is a getter, setter or operator,
  /// the named arguments map is always empty.
  Map<Symbol, dynamic> get namedArguments;

  /// Whether the invocation was a method call.
  bool get isMethod;

  /// Whether the invocation was a getter call.
  /// If so, all three types of arguments lists are empty.
  bool get isGetter;

  /// Whether the invocation was a setter call.
  ///
  /// If so, [positionalArguments] has exactly one positional
  /// argument, [namedArguments] is empty, and typeArguments is
  /// empty.
  bool get isSetter;

  /// Whether the invocation was a getter or a setter call.
  bool get isAccessor => isGetter || isSetter;
}

/// Implementation of [Invocation] used by its factory constructors.
class _Invocation implements Invocation {
  final Symbol memberName;
  final List<Type> typeArguments;
  // Positional arguments is `null` for getters only.
  final List<Object?>? _positional;
  // Named arguments is `null` for accessors only.
  final Map<Symbol, Object?>? _named;

  _Invocation.method(this.memberName, Iterable<Type>? types,
      Iterable<Object?>? positional, Map<Symbol, Object?>? named)
      : typeArguments = _ensureNonNullTypes(types),
        _positional = positional == null
            ? const <Object?>[]
            : List<Object?>.unmodifiable(positional),
        _named = (named == null || named.isEmpty)
            ? const <Symbol, Object?>{}
            : Map<Symbol, Object?>.unmodifiable(named);

  _Invocation.getter(this.memberName)
      : typeArguments = const <Type>[],
        _positional = null,
        _named = null;

  _Invocation.setter(this.memberName, Object? argument)
      : typeArguments = const <Type>[],
        _positional = List<Object?>.unmodifiable([argument]),
        _named = null;

  List<dynamic> get positionalArguments => _positional ?? const <Object>[];

  Map<Symbol, dynamic> get namedArguments => _named ?? const <Symbol, Object>{};

  bool get isMethod => _named != null;
  bool get isGetter => _positional == null;
  bool get isSetter => _positional != null && _named == null;
  bool get isAccessor => _named == null;

  /// Checks that the elements of [types] are not null.
  static List<Type> _ensureNonNullTypes(Iterable<Type>? types) {
    if (types == null) return const <Type>[];
    List<Type> typeArguments = List<Type>.unmodifiable(types);
    for (int i = 0; i < typeArguments.length; i++) {
      if (typeArguments[i] == null) {
        throw ArgumentError.value(types, "types",
            "Type arguments must be non-null, was null at index $i.");
      }
    }
    return typeArguments;
  }
}
