Files
sdk/runtime/lib/invocation_mirror_patch.dart
T
Régis Crelier 8cf9ef22c4 Revert "Dart Core Lib change to support generic functions in class NoSuchMethodError."
This reverts commit db15f5d73b.

Dart2js and Kernel tests are comparing text that has changed because of
the core lib change.

Change-Id: I1d33716a3d6e6a077aa1f1a9ad7cc37825d31fa6
Reviewed-on: https://dart-review.googlesource.com/9082
Reviewed-by: Siva Chandra <sivachandra@google.com>
2017-09-27 21:08:20 +00:00

165 lines
5.7 KiB
Dart

// 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.
// NOTE: When making changes to this class, please also update
// `VmTarget.instantiateInvocation` and `VmTarget._invocationType` in
// `pkg/kernel/lib/target/vm.dart`.
// TODO(regis): See above NOTE.
class _InvocationMirror implements Invocation {
// Constants describing the invocation type.
// _FIELD cannot be generated by regular invocation mirrors.
static const int _METHOD = 0;
static const int _GETTER = 1;
static const int _SETTER = 2;
static const int _FIELD = 3;
static const int _LOCAL_VAR = 4;
static const int _TYPE_SHIFT = 0;
static const int _TYPE_BITS = 3;
static const int _TYPE_MASK = (1 << _TYPE_BITS) - 1;
// These values, except _DYNAMIC and _SUPER, are only used when throwing
// NoSuchMethodError for compile-time resolution failures.
static const int _DYNAMIC = 0;
static const int _SUPER = 1;
static const int _STATIC = 2;
static const int _CONSTRUCTOR = 3;
static const int _TOP_LEVEL = 4;
static const int _CALL_SHIFT = _TYPE_BITS;
static const int _CALL_BITS = 3;
static const int _CALL_MASK = (1 << _CALL_BITS) - 1;
// ArgumentsDescriptor layout. Keep in sync with enum in dart_entry.h.
static const int _TYPE_ARGS_LEN = 0;
static const int _COUNT = 1;
static const int _POSITIONAL_COUNT = 2;
static const int _FIRST_NAMED_ENTRY = 3;
// Internal representation of the invocation mirror.
final String _functionName;
final List _argumentsDescriptor;
final List _arguments;
final bool _isSuperInvocation;
// External representation of the invocation mirror; populated on demand.
Symbol _memberName;
int _type;
List _typeArguments;
List _positionalArguments;
Map<Symbol, dynamic> _namedArguments;
void _setMemberNameAndType() {
if (_functionName.startsWith("get:")) {
_type = _GETTER;
_memberName = new internal.Symbol.unvalidated(_functionName.substring(4));
} else if (_functionName.startsWith("set:")) {
_type = _SETTER;
_memberName =
new internal.Symbol.unvalidated(_functionName.substring(4) + "=");
} else {
_type = _isSuperInvocation ? (_SUPER << _CALL_SHIFT) | _METHOD : _METHOD;
_memberName = new internal.Symbol.unvalidated(_functionName);
}
}
Symbol get memberName {
if (_memberName == null) {
_setMemberNameAndType();
}
return _memberName;
}
List get typeArguments {
if (_typeArguments == null) {
int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN];
if (typeArgsLen == 0) {
return _typeArguments = const [];
}
// A TypeArguments object does not have a corresponding Dart class and
// cannot be accessed as an array in Dart. Therefore, we need a native
// call to unpack the individual types into a list.
_typeArguments = _unpackTypeArguments(_arguments[0]);
}
return _typeArguments;
}
// Unpack the given TypeArguments object into a new list of individual types.
static List _unpackTypeArguments(typeArguments)
native "InvocationMirror_unpackTypeArguments";
List get positionalArguments {
if (_positionalArguments == null) {
// The argument descriptor counts the receiver, but not the type arguments
// as positional arguments.
int numPositionalArguments = _argumentsDescriptor[_POSITIONAL_COUNT] - 1;
if (numPositionalArguments == 0) {
return _positionalArguments = const [];
}
// Exclude receiver and type args in the returned list.
int receiverIndex = _argumentsDescriptor[_TYPE_ARGS_LEN] > 0 ? 1 : 0;
_positionalArguments = new _ImmutableList._from(
_arguments, receiverIndex + 1, numPositionalArguments);
}
return _positionalArguments;
}
Map<Symbol, dynamic> get namedArguments {
if (_namedArguments == null) {
int numArguments = _argumentsDescriptor[_COUNT] - 1; // Exclude receiver.
int numPositionalArguments = _argumentsDescriptor[_POSITIONAL_COUNT] - 1;
int numNamedArguments = numArguments - numPositionalArguments;
if (numNamedArguments == 0) {
return _namedArguments = const {};
}
int receiverIndex = _argumentsDescriptor[_TYPE_ARGS_LEN] > 0 ? 1 : 0;
_namedArguments = new Map<Symbol, dynamic>();
for (int i = 0; i < numNamedArguments; i++) {
int namedEntryIndex = _FIRST_NAMED_ENTRY + 2 * i;
String arg_name = _argumentsDescriptor[namedEntryIndex];
var arg_value = _arguments[
receiverIndex + _argumentsDescriptor[namedEntryIndex + 1]];
_namedArguments[new internal.Symbol.unvalidated(arg_name)] = arg_value;
}
_namedArguments = new Map.unmodifiable(_namedArguments);
}
return _namedArguments;
}
bool get isMethod {
if (_type == null) {
_setMemberNameAndType();
}
return (_type & _TYPE_MASK) == _METHOD;
}
bool get isAccessor {
if (_type == null) {
_setMemberNameAndType();
}
return (_type & _TYPE_MASK) != _METHOD;
}
bool get isGetter {
if (_type == null) {
_setMemberNameAndType();
}
return (_type & _TYPE_MASK) == _GETTER;
}
bool get isSetter {
if (_type == null) {
_setMemberNameAndType();
}
return (_type & _TYPE_MASK) == _SETTER;
}
_InvocationMirror(this._functionName, this._argumentsDescriptor,
this._arguments, this._isSuperInvocation);
static _allocateInvocationMirror(String functionName,
List argumentsDescriptor, List arguments, bool isSuperInvocation) {
return new _InvocationMirror(
functionName, argumentsDescriptor, arguments, isSuperInvocation);
}
}