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