|  | // 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. | 
|  | @pragma("wasm:entry-point") | 
|  | 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. | 
|  | @pragma("wasm:entry-point") | 
|  | 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. | 
|  | @pragma("wasm:entry-point") | 
|  | 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) | 
|  | /// ``` | 
|  | @pragma("wasm:entry-point") | 
|  | 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; | 
|  | } | 
|  | } |