mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:19:49 +00:00
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>
This commit is contained in:
parent
31fb4d3633
commit
8cf9ef22c4
|
@ -58,9 +58,8 @@ class CoreTypes {
|
|||
Constructor _externalNameDefaultConstructor;
|
||||
Class _invocationMirrorClass;
|
||||
Constructor _invocationMirrorDefaultConstructor;
|
||||
Constructor _invocationMirrorWithTypeConstructor;
|
||||
Class _noSuchMethodErrorClass;
|
||||
Constructor _noSuchMethodErrorDefaultConstructor;
|
||||
Constructor _noSuchMethodErrorImplementationConstructor;
|
||||
Procedure _listFromConstructor;
|
||||
Procedure _printProcedure;
|
||||
Procedure _identicalProcedure;
|
||||
|
@ -190,11 +189,6 @@ class CoreTypes {
|
|||
_index.getMember('dart:core', '_InvocationMirror', '');
|
||||
}
|
||||
|
||||
Constructor get invocationMirrorWithTypeConstructor {
|
||||
return _invocationMirrorWithTypeConstructor ??=
|
||||
_index.getMember('dart:core', '_InvocationMirror', '_withType');
|
||||
}
|
||||
|
||||
Class get iterableClass {
|
||||
return _iterableClass ??= _index.getClass('dart:core', 'Iterable');
|
||||
}
|
||||
|
@ -225,10 +219,11 @@ class CoreTypes {
|
|||
_index.getClass('dart:core', 'NoSuchMethodError');
|
||||
}
|
||||
|
||||
Constructor get noSuchMethodErrorDefaultConstructor {
|
||||
return _noSuchMethodErrorDefaultConstructor ??=
|
||||
// TODO(regis): Replace 'withInvocation' with '' after dart2js is fixed.
|
||||
_index.getMember('dart:core', 'NoSuchMethodError', 'withInvocation');
|
||||
/// An implementation-specific constructor suitable for use by
|
||||
/// `Target.instantiateNoSuchMethodError`.
|
||||
Constructor get noSuchMethodErrorImplementationConstructor {
|
||||
return _noSuchMethodErrorImplementationConstructor ??=
|
||||
_index.getMember('dart:core', 'NoSuchMethodError', '_withType');
|
||||
}
|
||||
|
||||
Class get nullClass {
|
||||
|
|
|
@ -170,25 +170,21 @@ class VmTarget extends Target {
|
|||
isConstructor: isConstructor,
|
||||
isTopLevel: isTopLevel);
|
||||
return new ConstructorInvocation(
|
||||
coreTypes.noSuchMethodErrorDefaultConstructor,
|
||||
coreTypes.noSuchMethodErrorImplementationConstructor,
|
||||
new Arguments(<Expression>[
|
||||
receiver,
|
||||
new ConstructorInvocation(
|
||||
coreTypes.invocationMirrorWithTypeConstructor,
|
||||
new Arguments(<Expression>[
|
||||
new SymbolLiteral(name)..fileOffset = offset,
|
||||
new IntLiteral(type)..fileOffset = offset,
|
||||
new NullLiteral(), // TODO(regis): Type arguments of generic function.
|
||||
_fixedLengthList(arguments.positional, arguments.fileOffset),
|
||||
new MapLiteral(new List<MapEntry>.from(
|
||||
arguments.named.map((NamedExpression arg) {
|
||||
return new MapEntry(
|
||||
new SymbolLiteral(arg.name)..fileOffset = arg.fileOffset,
|
||||
arg.value)
|
||||
..fileOffset = arg.fileOffset;
|
||||
})))
|
||||
..fileOffset = arguments.fileOffset
|
||||
]))
|
||||
new SymbolLiteral(name)..fileOffset = offset,
|
||||
new IntLiteral(type)..fileOffset = offset,
|
||||
_fixedLengthList(arguments.positional, arguments.fileOffset),
|
||||
new MapLiteral(new List<MapEntry>.from(
|
||||
arguments.named.map((NamedExpression arg) {
|
||||
return new MapEntry(
|
||||
new SymbolLiteral(arg.name)..fileOffset = arg.fileOffset,
|
||||
arg.value)
|
||||
..fileOffset = arg.fileOffset;
|
||||
})))
|
||||
..fileOffset = arguments.fileOffset,
|
||||
new NullLiteral()
|
||||
]));
|
||||
}
|
||||
|
||||
|
@ -214,10 +210,10 @@ class VmTarget extends Target {
|
|||
const int _FIELD = 3;
|
||||
const int _LOCAL_VAR = 4;
|
||||
// ignore: UNUSED_LOCAL_VARIABLE
|
||||
const int _KIND_SHIFT = 0;
|
||||
const int _KIND_BITS = 3;
|
||||
const int _TYPE_SHIFT = 0;
|
||||
const int _TYPE_BITS = 3;
|
||||
// ignore: UNUSED_LOCAL_VARIABLE
|
||||
const int _KIND_MASK = (1 << _KIND_BITS) - 1;
|
||||
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.
|
||||
|
@ -226,10 +222,10 @@ class VmTarget extends Target {
|
|||
const int _STATIC = 2;
|
||||
const int _CONSTRUCTOR = 3;
|
||||
const int _TOP_LEVEL = 4;
|
||||
const int _LEVEL_SHIFT = _KIND_BITS;
|
||||
const int _LEVEL_BITS = 3;
|
||||
const int _CALL_SHIFT = _TYPE_BITS;
|
||||
const int _CALL_BITS = 3;
|
||||
// ignore: UNUSED_LOCAL_VARIABLE
|
||||
const int _LEVEL_MASK = (1 << _LEVEL_BITS) - 1;
|
||||
const int _CALL_MASK = (1 << _CALL_BITS) - 1;
|
||||
|
||||
int type = -1;
|
||||
// For convenience, [isGetter] and [isSetter] takes precedence over
|
||||
|
@ -247,15 +243,15 @@ class VmTarget extends Target {
|
|||
}
|
||||
|
||||
if (isDynamic) {
|
||||
type |= (_DYNAMIC << _LEVEL_SHIFT);
|
||||
type |= (_DYNAMIC << _CALL_SHIFT);
|
||||
} else if (isSuper) {
|
||||
type |= (_SUPER << _LEVEL_SHIFT);
|
||||
type |= (_SUPER << _CALL_SHIFT);
|
||||
} else if (isStatic) {
|
||||
type |= (_STATIC << _LEVEL_SHIFT);
|
||||
type |= (_STATIC << _CALL_SHIFT);
|
||||
} else if (isConstructor) {
|
||||
type |= (_CONSTRUCTOR << _LEVEL_SHIFT);
|
||||
type |= (_CONSTRUCTOR << _CALL_SHIFT);
|
||||
} else if (isTopLevel) {
|
||||
type |= (_TOP_LEVEL << _LEVEL_SHIFT);
|
||||
type |= (_TOP_LEVEL << _CALL_SHIFT);
|
||||
}
|
||||
|
||||
return type;
|
||||
|
|
|
@ -173,22 +173,36 @@ class AbstractClassInstantiationError {
|
|||
|
||||
@patch
|
||||
class NoSuchMethodError {
|
||||
// TODO(regis): Move _receiver declaration here:
|
||||
// final Object _receiver;
|
||||
final _InvocationMirror _invocation;
|
||||
|
||||
@patch
|
||||
NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
|
||||
: _receiver = receiver,
|
||||
_invocation = invocation as _InvocationMirror;
|
||||
|
||||
// The compiler emits a call to _throwNew when it cannot resolve a static
|
||||
// method at compile time. The receiver is actually the literal class of the
|
||||
// unresolved method.
|
||||
static void _throwNew(Object receiver, String memberName, int invocation_type,
|
||||
Object typeArguments, List arguments, List argumentNames) {
|
||||
throw new NoSuchMethodError._withType(receiver, memberName, invocation_type,
|
||||
typeArguments, arguments, argumentNames);
|
||||
List arguments, List argumentNames, List existingArgumentNames) {
|
||||
int numNamedArguments = argumentNames == null ? 0 : argumentNames.length;
|
||||
int numPositionalArguments = arguments == null ? 0 : arguments.length;
|
||||
numPositionalArguments -= numNamedArguments;
|
||||
List positionalArguments;
|
||||
if (numPositionalArguments > 0) {
|
||||
// TODO(srdjan): Unresolvable static methods sometimes do not provide the
|
||||
// arguments, because the arguments are evaluated but not passed to the
|
||||
// throwing stub (see EffectGraphVisitor::BuildThrowNoSuchMethodError and
|
||||
// Parser::ThrowNoSuchMethodError)). There is no way to distinguish the
|
||||
// case of no arguments from the case of the arguments not being passed
|
||||
// in here, though. See https://github.com/dart-lang/sdk/issues/27572
|
||||
positionalArguments = arguments.sublist(0, numPositionalArguments);
|
||||
}
|
||||
Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
|
||||
for (int i = 0; i < numNamedArguments; i++) {
|
||||
var arg_value = arguments[numPositionalArguments + i];
|
||||
namedArguments[new Symbol(argumentNames[i])] = arg_value;
|
||||
}
|
||||
throw new NoSuchMethodError._withType(
|
||||
receiver,
|
||||
new Symbol(memberName),
|
||||
invocation_type,
|
||||
positionalArguments,
|
||||
namedArguments,
|
||||
existingArgumentNames);
|
||||
}
|
||||
|
||||
static void _throwNewIfNotLoaded(
|
||||
|
@ -196,22 +210,20 @@ class NoSuchMethodError {
|
|||
Object receiver,
|
||||
String memberName,
|
||||
int invocation_type,
|
||||
Object typeArguments,
|
||||
List arguments,
|
||||
List argumentNames) {
|
||||
List argumentNames,
|
||||
List existingArgumentNames) {
|
||||
if (!prefix.isLoaded()) {
|
||||
_throwNew(receiver, memberName, invocation_type, typeArguments, arguments,
|
||||
argumentNames);
|
||||
_throwNew(receiver, memberName, invocation_type, arguments, argumentNames,
|
||||
existingArgumentNames);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(regis): Deprecated member still used by dart2js to be removed.
|
||||
// Remember the type from the invocation mirror or static compilation
|
||||
// analysis when thrown directly with _throwNew. A negative value means
|
||||
// that no information is available.
|
||||
final int _invocation_type;
|
||||
|
||||
// TODO(regis): Deprecated constructor still used by dart2js to be removed.
|
||||
@patch
|
||||
NoSuchMethodError(Object receiver, Symbol memberName,
|
||||
List positionalArguments, Map<Symbol, dynamic> namedArguments,
|
||||
|
@ -223,204 +235,33 @@ class NoSuchMethodError {
|
|||
_existingArgumentNames = existingArgumentNames,
|
||||
_invocation_type = -1;
|
||||
|
||||
// Helper to build a map of named arguments.
|
||||
static Map<Symbol, dynamic> _NamedArgumentsMap(
|
||||
List arguments, List argumentNames) {
|
||||
Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
|
||||
int numPositionalArguments = arguments.length - argumentNames.length;
|
||||
for (int i = 0; i < argumentNames.length; i++) {
|
||||
var arg_value = arguments[numPositionalArguments + i];
|
||||
namedArguments[new Symbol(argumentNames[i])] = arg_value;
|
||||
}
|
||||
return namedArguments;
|
||||
}
|
||||
|
||||
// Constructor called from Exceptions::ThrowByType(kNoSuchMethod) and from
|
||||
// _throwNew above, taking a TypeArguments object rather than an unpacked list
|
||||
// of types, as well as a list of all arguments and a list of names, rather
|
||||
// than a separate list of positional arguments and a map of named arguments.
|
||||
// This constructor seems to be called with either strings or
|
||||
// values read from another NoSuchMethodError.
|
||||
//
|
||||
// NOTE: When making changes to this constructor, please also update
|
||||
// `VmTarget.instantiateNoSuchMethodError` in
|
||||
// `pkg/kernel/lib/target/vm.dart`.
|
||||
NoSuchMethodError._withType(
|
||||
this._receiver,
|
||||
String memberName,
|
||||
int invocation_type,
|
||||
Object typeArguments,
|
||||
List arguments,
|
||||
List argumentNames)
|
||||
: this._invocation = new _InvocationMirror._withType(
|
||||
new Symbol(memberName),
|
||||
invocation_type,
|
||||
typeArguments != null
|
||||
? _InvocationMirror._unpackTypeArguments(typeArguments)
|
||||
: null,
|
||||
argumentNames != null
|
||||
? arguments.sublist(0, arguments.length - argumentNames.length)
|
||||
: arguments,
|
||||
argumentNames != null
|
||||
? _NamedArgumentsMap(arguments, argumentNames)
|
||||
: null);
|
||||
|
||||
static String _existingMethodSignature(Object receiver, String methodName,
|
||||
int invocationType) native "NoSuchMethodError_existingMethodSignature";
|
||||
/*String|Symbol*/ memberName,
|
||||
this._invocation_type,
|
||||
this._arguments,
|
||||
Map<dynamic, dynamic> namedArguments,
|
||||
[List existingArgumentNames = null])
|
||||
: this._memberName =
|
||||
(memberName is String) ? new Symbol(memberName) : memberName,
|
||||
this._namedArguments = (namedArguments == null)
|
||||
? null
|
||||
: new Map<Symbol, dynamic>.fromIterable(namedArguments.keys,
|
||||
key: (k) => (k is String) ? new Symbol(k) : k,
|
||||
value: (k) => namedArguments[k]),
|
||||
this._existingArgumentNames = existingArgumentNames;
|
||||
|
||||
@patch
|
||||
String toString() {
|
||||
// TODO(regis): Remove this null check once dart2js is updated.
|
||||
if (_invocation == null) {
|
||||
// Use deprecated version of toString.
|
||||
return _toStringDeprecated();
|
||||
}
|
||||
String memberName =
|
||||
internal.Symbol.getUnmangledName(_invocation.memberName);
|
||||
var level = (_invocation._type >> _InvocationMirror._LEVEL_SHIFT) &
|
||||
_InvocationMirror._LEVEL_MASK;
|
||||
var kind = _invocation._type & _InvocationMirror._KIND_MASK;
|
||||
if (kind == _InvocationMirror._LOCAL_VAR) {
|
||||
return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
|
||||
}
|
||||
|
||||
StringBuffer typeArgumentsBuf = null;
|
||||
var typeArguments = _invocation.typeArguments;
|
||||
if ((typeArguments != null) && (typeArguments.length > 0)) {
|
||||
typeArgumentsBuf = new StringBuffer();
|
||||
typeArgumentsBuf.write("<");
|
||||
for (int i = 0; i < typeArguments.length; i++) {
|
||||
if (i > 0) {
|
||||
typeArgumentsBuf.write(", ");
|
||||
}
|
||||
typeArgumentsBuf.write(Error.safeToString(typeArguments[i]));
|
||||
}
|
||||
typeArgumentsBuf.write(">");
|
||||
}
|
||||
StringBuffer argumentsBuf = new StringBuffer();
|
||||
var positionalArguments = _invocation.positionalArguments;
|
||||
int argumentCount = 0;
|
||||
if (positionalArguments != null) {
|
||||
for (; argumentCount < positionalArguments.length; argumentCount++) {
|
||||
if (argumentCount > 0) {
|
||||
argumentsBuf.write(", ");
|
||||
}
|
||||
argumentsBuf
|
||||
.write(Error.safeToString(positionalArguments[argumentCount]));
|
||||
}
|
||||
}
|
||||
var namedArguments = _invocation.namedArguments;
|
||||
if (namedArguments != null) {
|
||||
namedArguments.forEach((Symbol key, var value) {
|
||||
if (argumentCount > 0) {
|
||||
argumentsBuf.write(", ");
|
||||
}
|
||||
argumentsBuf.write(internal.Symbol.getUnmangledName(key));
|
||||
argumentsBuf.write(": ");
|
||||
argumentsBuf.write(Error.safeToString(value));
|
||||
argumentCount++;
|
||||
});
|
||||
}
|
||||
String existingSig =
|
||||
_existingMethodSignature(_receiver, memberName, _invocation._type);
|
||||
String argsMsg = existingSig != null ? " with matching arguments" : "";
|
||||
|
||||
String kindBuf;
|
||||
if (kind >= 0 && kind < 5) {
|
||||
kindBuf = (const [
|
||||
"method",
|
||||
"getter",
|
||||
"setter",
|
||||
"getter or setter",
|
||||
"variable"
|
||||
])[kind];
|
||||
}
|
||||
|
||||
StringBuffer msgBuf = new StringBuffer("NoSuchMethodError: ");
|
||||
bool is_type_call = false;
|
||||
switch (level) {
|
||||
case _InvocationMirror._DYNAMIC:
|
||||
{
|
||||
if (_receiver == null) {
|
||||
if (existingSig != null) {
|
||||
msgBuf.writeln("The null object does not have a $kindBuf "
|
||||
"'$memberName'$argsMsg.");
|
||||
} else {
|
||||
msgBuf.writeln("The $kindBuf '$memberName' was called on null.");
|
||||
}
|
||||
} else {
|
||||
if (_receiver is _Closure) {
|
||||
msgBuf.writeln("Closure call with mismatched arguments: "
|
||||
"function '$memberName'");
|
||||
} else if (_receiver is _Type && memberName == "call") {
|
||||
is_type_call = true;
|
||||
String name = _receiver.toString();
|
||||
msgBuf.writeln("Attempted to use type '$name' as a function. "
|
||||
"Since types do not define a method 'call', this is not "
|
||||
"possible. Did you intend to call the $name constructor and "
|
||||
"forget the 'new' operator?");
|
||||
} else {
|
||||
msgBuf.writeln("Class '${_receiver.runtimeType}' has no instance "
|
||||
"$kindBuf '$memberName'$argsMsg.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case _InvocationMirror._SUPER:
|
||||
{
|
||||
msgBuf.writeln("Super class of class '${_receiver.runtimeType}' has "
|
||||
"no instance $kindBuf '$memberName'$argsMsg.");
|
||||
memberName = "super.$memberName";
|
||||
break;
|
||||
}
|
||||
case _InvocationMirror._STATIC:
|
||||
{
|
||||
msgBuf.writeln("No static $kindBuf '$memberName'$argsMsg "
|
||||
"declared in class '$_receiver'.");
|
||||
break;
|
||||
}
|
||||
case _InvocationMirror._CONSTRUCTOR:
|
||||
{
|
||||
msgBuf.writeln("No constructor '$memberName'$argsMsg declared "
|
||||
"in class '$_receiver'.");
|
||||
memberName = "new $memberName";
|
||||
break;
|
||||
}
|
||||
case _InvocationMirror._TOP_LEVEL:
|
||||
{
|
||||
msgBuf.writeln("No top-level $kindBuf '$memberName'$argsMsg "
|
||||
"declared.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (level == _InvocationMirror._TOP_LEVEL) {
|
||||
msgBuf.writeln("Receiver: top-level");
|
||||
} else {
|
||||
msgBuf.writeln("Receiver: ${Error.safeToString(_receiver)}");
|
||||
}
|
||||
|
||||
if (kind == _InvocationMirror._METHOD) {
|
||||
String m = is_type_call ? "$_receiver" : "$memberName";
|
||||
msgBuf.write("Tried calling: $m");
|
||||
if (typeArgumentsBuf != null) {
|
||||
msgBuf.write(typeArgumentsBuf);
|
||||
}
|
||||
msgBuf.write("($argumentsBuf)");
|
||||
} else if (argumentCount == 0) {
|
||||
msgBuf.write("Tried calling: $memberName");
|
||||
} else if (kind == _InvocationMirror._SETTER) {
|
||||
msgBuf.write("Tried calling: $memberName$argumentsBuf");
|
||||
} else {
|
||||
msgBuf.write("Tried calling: $memberName = $argumentsBuf");
|
||||
}
|
||||
|
||||
if (existingSig != null) {
|
||||
msgBuf.write("\nFound: $memberName$existingSig");
|
||||
}
|
||||
|
||||
return msgBuf.toString();
|
||||
}
|
||||
|
||||
// TODO(regis): Remove this function once dart2js is updated.
|
||||
String _toStringDeprecated() {
|
||||
var level = (_invocation_type >> _InvocationMirror._LEVEL_SHIFT) &
|
||||
_InvocationMirror._LEVEL_MASK;
|
||||
var type = _invocation_type & _InvocationMirror._KIND_MASK;
|
||||
var level = (_invocation_type >> _InvocationMirror._CALL_SHIFT) &
|
||||
_InvocationMirror._CALL_MASK;
|
||||
var type = _invocation_type & _InvocationMirror._TYPE_MASK;
|
||||
String memberName = (_memberName == null)
|
||||
? ""
|
||||
: internal.Symbol.getUnmangledName(_memberName);
|
||||
|
|
|
@ -14,7 +14,7 @@ class InvocationMirror : public AllStatic {
|
|||
// These enum correspond to the constants in invocation_mirror_patch.dart.
|
||||
// It is used to communicate the reason for statically thrown
|
||||
// NoSuchMethodErrors by the compiler.
|
||||
enum Kind {
|
||||
enum Type {
|
||||
// Constants describing the invocation type.
|
||||
// kField cannot be generated by regular invocation mirrors.
|
||||
kMethod = 0,
|
||||
|
@ -22,12 +22,12 @@ class InvocationMirror : public AllStatic {
|
|||
kSetter = 2,
|
||||
kField = 3,
|
||||
kLocalVar = 4,
|
||||
kKindShift = 0,
|
||||
kKindBits = 3,
|
||||
kKindMask = (1 << kKindBits) - 1
|
||||
kTypeShift = 0,
|
||||
kTypeBits = 3,
|
||||
kTypeMask = (1 << kTypeBits) - 1
|
||||
};
|
||||
|
||||
enum Level {
|
||||
enum Call {
|
||||
// These values, except kDynamic and kSuper, are only used when throwing
|
||||
// NoSuchMethodError for compile-time resolution failures.
|
||||
kDynamic = 0,
|
||||
|
@ -35,18 +35,13 @@ class InvocationMirror : public AllStatic {
|
|||
kStatic = 2,
|
||||
kConstructor = 3,
|
||||
kTopLevel = 4,
|
||||
kLevelShift = kKindBits,
|
||||
kLevelBits = 3,
|
||||
kLevelMask = (1 << kLevelBits) - 1
|
||||
kCallShift = kTypeBits,
|
||||
kCallBits = 3,
|
||||
kCallMask = (1 << kCallBits) - 1
|
||||
};
|
||||
|
||||
static int EncodeType(Level level, Kind kind) {
|
||||
return (level << kLevelShift) | kind;
|
||||
}
|
||||
|
||||
static void DecodeType(int type, Level* level, Kind* kind) {
|
||||
*level = static_cast<Level>(type >> kLevelShift);
|
||||
*kind = static_cast<Kind>(type & kKindMask);
|
||||
static int EncodeType(Call call, Type type) {
|
||||
return (call << kCallShift) | type;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -5,17 +5,18 @@
|
|||
// 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 kind.
|
||||
// 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 _KIND_SHIFT = 0;
|
||||
static const int _KIND_BITS = 3;
|
||||
static const int _KIND_MASK = (1 << _KIND_BITS) - 1;
|
||||
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.
|
||||
|
@ -24,9 +25,9 @@ class _InvocationMirror implements Invocation {
|
|||
static const int _STATIC = 2;
|
||||
static const int _CONSTRUCTOR = 3;
|
||||
static const int _TOP_LEVEL = 4;
|
||||
static const int _LEVEL_SHIFT = _KIND_BITS;
|
||||
static const int _LEVEL_BITS = 3;
|
||||
static const int _LEVEL_MASK = (1 << _LEVEL_BITS) - 1;
|
||||
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;
|
||||
|
@ -43,17 +44,10 @@ class _InvocationMirror implements Invocation {
|
|||
// External representation of the invocation mirror; populated on demand.
|
||||
Symbol _memberName;
|
||||
int _type;
|
||||
List<Type> _typeArguments;
|
||||
List _typeArguments;
|
||||
List _positionalArguments;
|
||||
Map<Symbol, dynamic> _namedArguments;
|
||||
|
||||
_InvocationMirror._withType(this._memberName, this._type, this._typeArguments,
|
||||
this._positionalArguments, this._namedArguments) {
|
||||
_typeArguments ??= const <Type>[];
|
||||
_positionalArguments ??= const [];
|
||||
_namedArguments ??= const {};
|
||||
}
|
||||
|
||||
void _setMemberNameAndType() {
|
||||
if (_functionName.startsWith("get:")) {
|
||||
_type = _GETTER;
|
||||
|
@ -63,7 +57,7 @@ class _InvocationMirror implements Invocation {
|
|||
_memberName =
|
||||
new internal.Symbol.unvalidated(_functionName.substring(4) + "=");
|
||||
} else {
|
||||
_type = _isSuperInvocation ? (_SUPER << _LEVEL_SHIFT) | _METHOD : _METHOD;
|
||||
_type = _isSuperInvocation ? (_SUPER << _CALL_SHIFT) | _METHOD : _METHOD;
|
||||
_memberName = new internal.Symbol.unvalidated(_functionName);
|
||||
}
|
||||
}
|
||||
|
@ -75,11 +69,11 @@ class _InvocationMirror implements Invocation {
|
|||
return _memberName;
|
||||
}
|
||||
|
||||
List<Type> get typeArguments {
|
||||
List get typeArguments {
|
||||
if (_typeArguments == null) {
|
||||
int typeArgsLen = _argumentsDescriptor[_TYPE_ARGS_LEN];
|
||||
if (typeArgsLen == 0) {
|
||||
return _typeArguments = const <Type>[];
|
||||
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
|
||||
|
@ -90,7 +84,7 @@ class _InvocationMirror implements Invocation {
|
|||
}
|
||||
|
||||
// Unpack the given TypeArguments object into a new list of individual types.
|
||||
static List<Type> _unpackTypeArguments(typeArguments)
|
||||
static List _unpackTypeArguments(typeArguments)
|
||||
native "InvocationMirror_unpackTypeArguments";
|
||||
|
||||
List get positionalArguments {
|
||||
|
@ -135,28 +129,28 @@ class _InvocationMirror implements Invocation {
|
|||
if (_type == null) {
|
||||
_setMemberNameAndType();
|
||||
}
|
||||
return (_type & _KIND_MASK) == _METHOD;
|
||||
return (_type & _TYPE_MASK) == _METHOD;
|
||||
}
|
||||
|
||||
bool get isAccessor {
|
||||
if (_type == null) {
|
||||
_setMemberNameAndType();
|
||||
}
|
||||
return (_type & _KIND_MASK) != _METHOD;
|
||||
return (_type & _TYPE_MASK) != _METHOD;
|
||||
}
|
||||
|
||||
bool get isGetter {
|
||||
if (_type == null) {
|
||||
_setMemberNameAndType();
|
||||
}
|
||||
return (_type & _KIND_MASK) == _GETTER;
|
||||
return (_type & _TYPE_MASK) == _GETTER;
|
||||
}
|
||||
|
||||
bool get isSetter {
|
||||
if (_type == null) {
|
||||
_setMemberNameAndType();
|
||||
}
|
||||
return (_type & _KIND_MASK) == _SETTER;
|
||||
return (_type & _TYPE_MASK) == _SETTER;
|
||||
}
|
||||
|
||||
_InvocationMirror(this._functionName, this._argumentsDescriptor,
|
||||
|
|
|
@ -45,21 +45,29 @@ static RawInstance* CreateMirror(const String& mirror_class_name,
|
|||
// receiver.
|
||||
static void ThrowNoSuchMethod(const Instance& receiver,
|
||||
const String& function_name,
|
||||
const Function& function,
|
||||
const Array& arguments,
|
||||
const Array& argument_names,
|
||||
const InvocationMirror::Level level,
|
||||
const InvocationMirror::Kind kind) {
|
||||
const InvocationMirror::Call call,
|
||||
const InvocationMirror::Type type) {
|
||||
const Smi& invocation_type =
|
||||
Smi::Handle(Smi::New(InvocationMirror::EncodeType(level, kind)));
|
||||
Smi::Handle(Smi::New(InvocationMirror::EncodeType(call, type)));
|
||||
|
||||
const Array& args = Array::Handle(Array::New(6));
|
||||
args.SetAt(0, receiver);
|
||||
args.SetAt(1, function_name);
|
||||
args.SetAt(2, invocation_type);
|
||||
// TODO(regis): Support invocation of generic functions with type arguments.
|
||||
args.SetAt(3, Object::null_type_arguments());
|
||||
args.SetAt(4, arguments);
|
||||
args.SetAt(5, argument_names);
|
||||
args.SetAt(3, arguments);
|
||||
if (!argument_names.IsNull() && (argument_names.Length() > 0)) {
|
||||
// Empty and null are treated differently for some reason. Don't pass empty
|
||||
// to match the non-reflective error.
|
||||
args.SetAt(4, argument_names);
|
||||
}
|
||||
if (!function.IsNull()) {
|
||||
const Array& array = Array::Handle(Array::New(1));
|
||||
array.SetAt(0, String::Handle(function.UserVisibleFormalParameters()));
|
||||
args.SetAt(5, array);
|
||||
}
|
||||
|
||||
const Library& libcore = Library::Handle(Library::CoreLibrary());
|
||||
const Class& NoSuchMethodError =
|
||||
|
@ -647,9 +655,8 @@ static RawInstance* InvokeLibraryGetter(const Library& library,
|
|||
}
|
||||
|
||||
if (throw_nsm_if_absent) {
|
||||
ThrowNoSuchMethod(AbstractType::Handle(
|
||||
Class::Handle(library.toplevel_class()).RareType()),
|
||||
getter_name, Object::null_array(), Object::null_array(),
|
||||
ThrowNoSuchMethod(Instance::null_instance(), getter_name, getter,
|
||||
Object::null_array(), Object::null_array(),
|
||||
InvocationMirror::kTopLevel, InvocationMirror::kGetter);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -683,7 +690,7 @@ static RawInstance* InvokeClassGetter(const Class& klass,
|
|||
}
|
||||
if (throw_nsm_if_absent) {
|
||||
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), getter_name,
|
||||
Object::null_array(), Object::null_array(),
|
||||
getter, Object::null_array(), Object::null_array(),
|
||||
InvocationMirror::kStatic, InvocationMirror::kGetter);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1489,7 +1496,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 5) {
|
|||
if (function.IsNull() || !function.AreValidArguments(args_descriptor, NULL) ||
|
||||
!function.is_reflectable()) {
|
||||
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), function_name,
|
||||
args, arg_names, InvocationMirror::kStatic,
|
||||
function, args, arg_names, InvocationMirror::kStatic,
|
||||
InvocationMirror::kMethod);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1548,8 +1555,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
|
|||
|
||||
if (setter.IsNull() || !setter.is_reflectable()) {
|
||||
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
|
||||
internal_setter_name, args, Object::null_array(),
|
||||
InvocationMirror::kStatic, InvocationMirror::kSetter);
|
||||
internal_setter_name, setter, args,
|
||||
Object::null_array(), InvocationMirror::kStatic,
|
||||
InvocationMirror::kSetter);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
@ -1568,7 +1576,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
|
|||
args.SetAt(0, value);
|
||||
|
||||
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
|
||||
internal_setter_name, args, Object::null_array(),
|
||||
internal_setter_name, setter, args, Object::null_array(),
|
||||
InvocationMirror::kStatic, InvocationMirror::kSetter);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1613,8 +1621,8 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) {
|
|||
(lookup_constructor.kind() != RawFunction::kConstructor) ||
|
||||
!lookup_constructor.is_reflectable()) {
|
||||
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
|
||||
external_constructor_name, explicit_args, arg_names,
|
||||
InvocationMirror::kConstructor,
|
||||
external_constructor_name, lookup_constructor,
|
||||
explicit_args, arg_names, InvocationMirror::kConstructor,
|
||||
InvocationMirror::kMethod);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1687,8 +1695,8 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) {
|
|||
if (!redirected_constructor.AreValidArguments(args_descriptor, NULL)) {
|
||||
external_constructor_name = redirected_constructor.name();
|
||||
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
|
||||
external_constructor_name, explicit_args, arg_names,
|
||||
InvocationMirror::kConstructor,
|
||||
external_constructor_name, redirected_constructor,
|
||||
explicit_args, arg_names, InvocationMirror::kConstructor,
|
||||
InvocationMirror::kMethod);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -1779,10 +1787,9 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) {
|
|||
|
||||
if (function.IsNull() || !function.AreValidArguments(args_descriptor, NULL) ||
|
||||
!function.is_reflectable()) {
|
||||
ThrowNoSuchMethod(AbstractType::Handle(
|
||||
Class::Handle(library.toplevel_class()).RareType()),
|
||||
function_name, args, arg_names,
|
||||
InvocationMirror::kTopLevel, InvocationMirror::kMethod);
|
||||
ThrowNoSuchMethod(Instance::null_instance(), function_name, function, args,
|
||||
arg_names, InvocationMirror::kTopLevel,
|
||||
InvocationMirror::kMethod);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
@ -1830,10 +1837,9 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) {
|
|||
args.SetAt(0, value);
|
||||
|
||||
if (setter.IsNull() || !setter.is_reflectable()) {
|
||||
ThrowNoSuchMethod(AbstractType::Handle(
|
||||
Class::Handle(library.toplevel_class()).RareType()),
|
||||
internal_setter_name, args, Object::null_array(),
|
||||
InvocationMirror::kTopLevel, InvocationMirror::kSetter);
|
||||
ThrowNoSuchMethod(Instance::null_instance(), internal_setter_name, setter,
|
||||
args, Object::null_array(), InvocationMirror::kTopLevel,
|
||||
InvocationMirror::kSetter);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
@ -1852,10 +1858,9 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) {
|
|||
const Array& args = Array::Handle(Array::New(kNumArgs));
|
||||
args.SetAt(0, value);
|
||||
|
||||
ThrowNoSuchMethod(AbstractType::Handle(
|
||||
Class::Handle(library.toplevel_class()).RareType()),
|
||||
internal_setter_name, args, Object::null_array(),
|
||||
InvocationMirror::kTopLevel, InvocationMirror::kSetter);
|
||||
ThrowNoSuchMethod(Instance::null_instance(), internal_setter_name, setter,
|
||||
args, Object::null_array(), InvocationMirror::kTopLevel,
|
||||
InvocationMirror::kSetter);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
|
|
@ -62,13 +62,59 @@ DEFINE_NATIVE_ENTRY(Object_toString, 1) {
|
|||
if (instance.IsString()) {
|
||||
return instance.raw();
|
||||
}
|
||||
if (instance.IsAbstractType()) {
|
||||
return AbstractType::Cast(instance).UserVisibleName();
|
||||
}
|
||||
const char* c_str = instance.ToCString();
|
||||
return String::New(c_str);
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Object_noSuchMethod, 6) {
|
||||
const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Bool, is_method, arguments->NativeArgAt(1));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(String, member_name, arguments->NativeArgAt(2));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Smi, invocation_type, arguments->NativeArgAt(3));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Instance, func_args, arguments->NativeArgAt(4));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Instance, func_named_args,
|
||||
arguments->NativeArgAt(5));
|
||||
const Array& dart_arguments = Array::Handle(Array::New(6));
|
||||
dart_arguments.SetAt(0, instance);
|
||||
dart_arguments.SetAt(1, member_name);
|
||||
dart_arguments.SetAt(2, invocation_type);
|
||||
dart_arguments.SetAt(3, func_args);
|
||||
dart_arguments.SetAt(4, func_named_args);
|
||||
|
||||
if (is_method.value()) {
|
||||
// Report if a function with same name (but different arguments) has been
|
||||
// found.
|
||||
Function& function = Function::Handle();
|
||||
if (instance.IsClosure()) {
|
||||
function = Closure::Cast(instance).function();
|
||||
} else {
|
||||
Class& instance_class = Class::Handle(instance.clazz());
|
||||
const bool is_super_call =
|
||||
((invocation_type.Value() >> InvocationMirror::kCallShift) &
|
||||
InvocationMirror::kCallMask) == InvocationMirror::kSuper;
|
||||
if (!is_super_call) {
|
||||
function = instance_class.LookupDynamicFunction(member_name);
|
||||
}
|
||||
while (function.IsNull()) {
|
||||
instance_class = instance_class.SuperClass();
|
||||
if (instance_class.IsNull()) break;
|
||||
function = instance_class.LookupDynamicFunction(member_name);
|
||||
}
|
||||
}
|
||||
if (!function.IsNull()) {
|
||||
const intptr_t total_num_parameters = function.NumParameters();
|
||||
const Array& array = Array::Handle(Array::New(total_num_parameters - 1));
|
||||
// Skip receiver.
|
||||
for (int i = 1; i < total_num_parameters; i++) {
|
||||
array.SetAt(i - 1, String::Handle(function.ParameterNameAt(i)));
|
||||
}
|
||||
dart_arguments.SetAt(5, array);
|
||||
}
|
||||
}
|
||||
Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments);
|
||||
return Object::null();
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Object_runtimeType, 1) {
|
||||
const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0));
|
||||
if (instance.IsString()) {
|
||||
|
@ -339,11 +385,6 @@ DEFINE_NATIVE_ENTRY(InvocationMirror_unpackTypeArguments, 1) {
|
|||
const intptr_t len = type_arguments.Length();
|
||||
ASSERT(len > 0);
|
||||
const Array& type_list = Array::Handle(zone, Array::New(len));
|
||||
TypeArguments& type_list_type_args =
|
||||
TypeArguments::Handle(zone, TypeArguments::New(1));
|
||||
type_list_type_args.SetTypeAt(0, Type::Handle(zone, Type::DartTypeType()));
|
||||
type_list_type_args = type_list_type_args.Canonicalize();
|
||||
type_list.SetTypeArguments(type_list_type_args);
|
||||
AbstractType& type = AbstractType::Handle(zone);
|
||||
for (intptr_t i = 0; i < len; i++) {
|
||||
type = type_arguments.TypeAt(i);
|
||||
|
@ -353,42 +394,4 @@ DEFINE_NATIVE_ENTRY(InvocationMirror_unpackTypeArguments, 1) {
|
|||
return type_list.raw();
|
||||
}
|
||||
|
||||
DEFINE_NATIVE_ENTRY(NoSuchMethodError_existingMethodSignature, 3) {
|
||||
const Instance& receiver = Instance::CheckedHandle(arguments->NativeArgAt(0));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(String, method_name, arguments->NativeArgAt(1));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Smi, invocation_type, arguments->NativeArgAt(2));
|
||||
InvocationMirror::Level level;
|
||||
InvocationMirror::Kind kind;
|
||||
InvocationMirror::DecodeType(invocation_type.Value(), &level, &kind);
|
||||
|
||||
Function& function = Function::Handle();
|
||||
if (receiver.IsType()) {
|
||||
Class& cls = Class::Handle(Type::Cast(receiver).type_class());
|
||||
if (level == InvocationMirror::kConstructor) {
|
||||
function = cls.LookupConstructor(method_name);
|
||||
if (function.IsNull()) {
|
||||
function = cls.LookupFactory(method_name);
|
||||
}
|
||||
} else {
|
||||
function = cls.LookupStaticFunction(method_name);
|
||||
}
|
||||
} else if (receiver.IsClosure()) {
|
||||
function = Closure::Cast(receiver).function();
|
||||
} else {
|
||||
Class& cls = Class::Handle(receiver.clazz());
|
||||
if (level != InvocationMirror::kSuper) {
|
||||
function = cls.LookupDynamicFunction(method_name);
|
||||
}
|
||||
while (function.IsNull()) {
|
||||
cls = cls.SuperClass();
|
||||
if (cls.IsNull()) break;
|
||||
function = cls.LookupDynamicFunction(method_name);
|
||||
}
|
||||
}
|
||||
if (!function.IsNull()) {
|
||||
return function.UserVisibleSignature();
|
||||
}
|
||||
return String::null();
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
|
|
@ -38,10 +38,17 @@ class Object {
|
|||
// A statically dispatched version of Object.toString.
|
||||
static String _toString(obj) native "Object_toString";
|
||||
|
||||
_noSuchMethod(bool isMethod, String memberName, int type, List arguments,
|
||||
Map<String, dynamic> namedArguments) native "Object_noSuchMethod";
|
||||
|
||||
@patch
|
||||
dynamic noSuchMethod(Invocation invocation) {
|
||||
// TODO(regis): Remove temp constructor identifier 'withInvocation'.
|
||||
throw new NoSuchMethodError.withInvocation(this, invocation);
|
||||
return _noSuchMethod(
|
||||
invocation.isMethod,
|
||||
internal.Symbol.getName(invocation.memberName),
|
||||
invocation._type,
|
||||
invocation.positionalArguments,
|
||||
_symbolMapToStringMap(invocation.namedArguments));
|
||||
}
|
||||
|
||||
@patch
|
||||
|
@ -63,4 +70,12 @@ class Object {
|
|||
// feedback. Returns receiver.
|
||||
_as(instantiatorTypeArguments, functionTypeArguments, type)
|
||||
native "Object_as";
|
||||
|
||||
static _symbolMapToStringMap(Map<Symbol, dynamic> map) {
|
||||
var result = new Map<String, dynamic>();
|
||||
map.forEach((Symbol key, value) {
|
||||
result[internal.Symbol.getName(key)] = value;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace dart {
|
|||
V(Object_getHash, 1) \
|
||||
V(Object_setHash, 2) \
|
||||
V(Object_toString, 1) \
|
||||
V(Object_noSuchMethod, 6) \
|
||||
V(Object_runtimeType, 1) \
|
||||
V(Object_haveSameRuntimeType, 2) \
|
||||
V(Object_instanceOf, 4) \
|
||||
|
@ -315,7 +316,6 @@ namespace dart {
|
|||
V(Internal_inquireIs64Bit, 0) \
|
||||
V(Internal_prependTypeArguments, 3) \
|
||||
V(InvocationMirror_unpackTypeArguments, 1) \
|
||||
V(NoSuchMethodError_existingMethodSignature, 3) \
|
||||
V(LinkedHashMap_getIndex, 1) \
|
||||
V(LinkedHashMap_setIndex, 2) \
|
||||
V(LinkedHashMap_getData, 1) \
|
||||
|
|
|
@ -4228,12 +4228,6 @@ StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
|
|||
Value* invocation_type_value = Bind(
|
||||
new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(invocation_type))));
|
||||
arguments->Add(PushArgument(invocation_type_value));
|
||||
// Object typeArguments.
|
||||
Value* type_arguments_value = Bind(new (Z) ConstantInstr(
|
||||
function_arguments == NULL
|
||||
? TypeArguments::ZoneHandle(Z, TypeArguments::null())
|
||||
: function_arguments->type_arguments()));
|
||||
arguments->Add(PushArgument(type_arguments_value));
|
||||
// List arguments.
|
||||
if (function_arguments == NULL) {
|
||||
Value* arguments_value =
|
||||
|
@ -4255,6 +4249,10 @@ StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
|
|||
Value* argument_names_value = Bind(cinstr);
|
||||
arguments->Add(PushArgument(argument_names_value));
|
||||
|
||||
// List existingArgumentNames.
|
||||
Value* existing_argument_names_value =
|
||||
Bind(new (Z) ConstantInstr(Array::ZoneHandle(Z, Array::null())));
|
||||
arguments->Add(PushArgument(existing_argument_names_value));
|
||||
// Resolve and call NoSuchMethodError._throwNew.
|
||||
const Library& core_lib = Library::Handle(Z, Library::CoreLibrary());
|
||||
const Class& cls =
|
||||
|
|
|
@ -1481,15 +1481,15 @@ Fragment FlowGraphBuilder::ThrowNoSuchMethodError() {
|
|||
instructions += IntConstant(-1);
|
||||
instructions += PushArgument(); // invocation_type
|
||||
|
||||
instructions += NullConstant();
|
||||
instructions += PushArgument(); // type arguments
|
||||
|
||||
instructions += NullConstant();
|
||||
instructions += PushArgument(); // arguments
|
||||
|
||||
instructions += NullConstant();
|
||||
instructions += PushArgument(); // argumentNames
|
||||
|
||||
instructions += NullConstant();
|
||||
instructions += PushArgument(); // existingArgumentNames
|
||||
|
||||
instructions += StaticCall(TokenPosition::kNoSource, throw_function, 6);
|
||||
// Leave "result" on the stack since callers expect it to be there (even
|
||||
// though the function will result in an exception).
|
||||
|
|
|
@ -1701,77 +1701,93 @@ TEST_CASE(DebuggerAPI_StackTraceDump1) {
|
|||
static void StackTraceDump2ExceptionHandler(Dart_IsolateId isolate_id,
|
||||
Dart_Handle exception_object,
|
||||
Dart_StackTrace trace) {
|
||||
const int kStackTraceLen = 4;
|
||||
const int kStackTraceLen = 5;
|
||||
static const char* expected_trace[kStackTraceLen] = {
|
||||
"Object.noSuchMethod", "Test.local1_to_func1", "Test.func1", "main"};
|
||||
"Object._noSuchMethod", "Object.noSuchMethod", "Test.local1_to_func1",
|
||||
"Test.func1", "main"};
|
||||
|
||||
intptr_t trace_len;
|
||||
Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
|
||||
EXPECT_VALID(res);
|
||||
EXPECT_EQ(kStackTraceLen, trace_len);
|
||||
|
||||
// Frame 0 corresponding to "Object.noSuchMethod".
|
||||
Dart_Handle frame0_locals = Dart_NewList(4);
|
||||
// Frame 0 corresponding to "Object._noSuchMethod".
|
||||
Dart_Handle frame0_locals = Dart_NewList(12);
|
||||
Dart_ListSetAt(frame0_locals, 0, NewString("this"));
|
||||
Dart_ListSetAt(frame0_locals, 1, Dart_Null());
|
||||
Dart_ListSetAt(frame0_locals, 2, NewString("invocation"));
|
||||
Dart_ListSetAt(frame0_locals, 2, NewString("isMethod"));
|
||||
Dart_ListSetAt(frame0_locals, 3, Dart_Null());
|
||||
Dart_ListSetAt(frame0_locals, 4, NewString("memberName"));
|
||||
Dart_ListSetAt(frame0_locals, 5, Dart_Null());
|
||||
Dart_ListSetAt(frame0_locals, 6, NewString("type"));
|
||||
Dart_ListSetAt(frame0_locals, 7, Dart_Null());
|
||||
Dart_ListSetAt(frame0_locals, 8, NewString("arguments"));
|
||||
Dart_ListSetAt(frame0_locals, 9, Dart_Null());
|
||||
Dart_ListSetAt(frame0_locals, 10, NewString("namedArguments"));
|
||||
Dart_ListSetAt(frame0_locals, 11, Dart_Null());
|
||||
|
||||
// Frame 1 corresponding to "Test.local1_to_func1".
|
||||
Dart_Handle frame1_locals = Dart_NewList(14);
|
||||
Dart_ListSetAt(frame1_locals, 0, NewString("i"));
|
||||
Dart_ListSetAt(frame1_locals, 1, Dart_NewInteger(11));
|
||||
Dart_ListSetAt(frame1_locals, 2, NewString("j"));
|
||||
Dart_ListSetAt(frame1_locals, 3, Dart_NewInteger(22));
|
||||
Dart_ListSetAt(frame1_locals, 4, NewString("k"));
|
||||
Dart_ListSetAt(frame1_locals, 5, Dart_NewInteger(33));
|
||||
Dart_ListSetAt(frame1_locals, 6, NewString("l"));
|
||||
Dart_ListSetAt(frame1_locals, 7, Dart_NewInteger(44));
|
||||
Dart_ListSetAt(frame1_locals, 8, NewString("m"));
|
||||
Dart_ListSetAt(frame1_locals, 9, Dart_NewInteger(55));
|
||||
Dart_ListSetAt(frame1_locals, 10, NewString("this"));
|
||||
Dart_ListSetAt(frame1_locals, 11, Dart_Null());
|
||||
Dart_ListSetAt(frame1_locals, 12, NewString("func"));
|
||||
Dart_ListSetAt(frame1_locals, 13, Dart_Null());
|
||||
// Frame 1 corresponding to "Object.noSuchMethod".
|
||||
Dart_Handle frame1_locals = Dart_NewList(4);
|
||||
Dart_ListSetAt(frame1_locals, 0, NewString("this"));
|
||||
Dart_ListSetAt(frame1_locals, 1, Dart_Null());
|
||||
Dart_ListSetAt(frame1_locals, 2, NewString("invocation"));
|
||||
Dart_ListSetAt(frame1_locals, 3, Dart_Null());
|
||||
|
||||
// Frame 2 corresponding to "Test.func1".
|
||||
Dart_Handle frame2_locals = Dart_NewList(18);
|
||||
Dart_ListSetAt(frame2_locals, 0, NewString("this"));
|
||||
Dart_ListSetAt(frame2_locals, 1, Dart_Null());
|
||||
Dart_ListSetAt(frame2_locals, 2, NewString("func"));
|
||||
Dart_ListSetAt(frame2_locals, 3, Dart_Null());
|
||||
Dart_ListSetAt(frame2_locals, 4, NewString("i"));
|
||||
Dart_ListSetAt(frame2_locals, 5, Dart_NewInteger(11));
|
||||
Dart_ListSetAt(frame2_locals, 6, NewString("j"));
|
||||
Dart_ListSetAt(frame2_locals, 7, Dart_NewInteger(22));
|
||||
Dart_ListSetAt(frame2_locals, 8, NewString("k"));
|
||||
Dart_ListSetAt(frame2_locals, 9, Dart_NewInteger(33));
|
||||
Dart_ListSetAt(frame2_locals, 10, NewString("l"));
|
||||
Dart_ListSetAt(frame2_locals, 11, Dart_NewInteger(44));
|
||||
Dart_ListSetAt(frame2_locals, 12, NewString("m"));
|
||||
Dart_ListSetAt(frame2_locals, 13, Dart_NewInteger(55));
|
||||
Dart_ListSetAt(frame2_locals, 14, NewString("local1_to_func1"));
|
||||
Dart_ListSetAt(frame2_locals, 15, Dart_Null());
|
||||
Dart_ListSetAt(frame2_locals, 16, NewString("sum"));
|
||||
Dart_ListSetAt(frame2_locals, 17, Dart_NewInteger(0));
|
||||
// Frame 2 corresponding to "Test.local1_to_func1".
|
||||
Dart_Handle frame2_locals = Dart_NewList(14);
|
||||
Dart_ListSetAt(frame2_locals, 0, NewString("i"));
|
||||
Dart_ListSetAt(frame2_locals, 1, Dart_NewInteger(11));
|
||||
Dart_ListSetAt(frame2_locals, 2, NewString("j"));
|
||||
Dart_ListSetAt(frame2_locals, 3, Dart_NewInteger(22));
|
||||
Dart_ListSetAt(frame2_locals, 4, NewString("k"));
|
||||
Dart_ListSetAt(frame2_locals, 5, Dart_NewInteger(33));
|
||||
Dart_ListSetAt(frame2_locals, 6, NewString("l"));
|
||||
Dart_ListSetAt(frame2_locals, 7, Dart_NewInteger(44));
|
||||
Dart_ListSetAt(frame2_locals, 8, NewString("m"));
|
||||
Dart_ListSetAt(frame2_locals, 9, Dart_NewInteger(55));
|
||||
Dart_ListSetAt(frame2_locals, 10, NewString("this"));
|
||||
Dart_ListSetAt(frame2_locals, 11, Dart_Null());
|
||||
Dart_ListSetAt(frame2_locals, 12, NewString("func"));
|
||||
Dart_ListSetAt(frame2_locals, 13, Dart_Null());
|
||||
|
||||
// Frame 3 corresponding to "main".
|
||||
Dart_Handle frame3_locals = Dart_NewList(12);
|
||||
Dart_ListSetAt(frame3_locals, 0, NewString("i"));
|
||||
Dart_ListSetAt(frame3_locals, 1, Dart_NewInteger(10));
|
||||
Dart_ListSetAt(frame3_locals, 2, NewString("j"));
|
||||
Dart_ListSetAt(frame3_locals, 3, Dart_NewInteger(20));
|
||||
Dart_ListSetAt(frame3_locals, 4, NewString("local_to_main"));
|
||||
Dart_ListSetAt(frame3_locals, 5, Dart_Null());
|
||||
Dart_ListSetAt(frame3_locals, 6, NewString("sum"));
|
||||
Dart_ListSetAt(frame3_locals, 7, Dart_NewInteger(0));
|
||||
Dart_ListSetAt(frame3_locals, 8, NewString("value"));
|
||||
Dart_ListSetAt(frame3_locals, 9, Dart_Null());
|
||||
Dart_ListSetAt(frame3_locals, 10, NewString("func1"));
|
||||
Dart_ListSetAt(frame3_locals, 11, Dart_Null());
|
||||
// Frame 3 corresponding to "Test.func1".
|
||||
Dart_Handle frame3_locals = Dart_NewList(18);
|
||||
Dart_ListSetAt(frame3_locals, 0, NewString("this"));
|
||||
Dart_ListSetAt(frame3_locals, 1, Dart_Null());
|
||||
Dart_ListSetAt(frame3_locals, 2, NewString("func"));
|
||||
Dart_ListSetAt(frame3_locals, 3, Dart_Null());
|
||||
Dart_ListSetAt(frame3_locals, 4, NewString("i"));
|
||||
Dart_ListSetAt(frame3_locals, 5, Dart_NewInteger(11));
|
||||
Dart_ListSetAt(frame3_locals, 6, NewString("j"));
|
||||
Dart_ListSetAt(frame3_locals, 7, Dart_NewInteger(22));
|
||||
Dart_ListSetAt(frame3_locals, 8, NewString("k"));
|
||||
Dart_ListSetAt(frame3_locals, 9, Dart_NewInteger(33));
|
||||
Dart_ListSetAt(frame3_locals, 10, NewString("l"));
|
||||
Dart_ListSetAt(frame3_locals, 11, Dart_NewInteger(44));
|
||||
Dart_ListSetAt(frame3_locals, 12, NewString("m"));
|
||||
Dart_ListSetAt(frame3_locals, 13, Dart_NewInteger(55));
|
||||
Dart_ListSetAt(frame3_locals, 14, NewString("local1_to_func1"));
|
||||
Dart_ListSetAt(frame3_locals, 15, Dart_Null());
|
||||
Dart_ListSetAt(frame3_locals, 16, NewString("sum"));
|
||||
Dart_ListSetAt(frame3_locals, 17, Dart_NewInteger(0));
|
||||
|
||||
// Frame 4 corresponding to "main".
|
||||
Dart_Handle frame4_locals = Dart_NewList(12);
|
||||
Dart_ListSetAt(frame4_locals, 0, NewString("i"));
|
||||
Dart_ListSetAt(frame4_locals, 1, Dart_NewInteger(10));
|
||||
Dart_ListSetAt(frame4_locals, 2, NewString("j"));
|
||||
Dart_ListSetAt(frame4_locals, 3, Dart_NewInteger(20));
|
||||
Dart_ListSetAt(frame4_locals, 4, NewString("local_to_main"));
|
||||
Dart_ListSetAt(frame4_locals, 5, Dart_Null());
|
||||
Dart_ListSetAt(frame4_locals, 6, NewString("sum"));
|
||||
Dart_ListSetAt(frame4_locals, 7, Dart_NewInteger(0));
|
||||
Dart_ListSetAt(frame4_locals, 8, NewString("value"));
|
||||
Dart_ListSetAt(frame4_locals, 9, Dart_Null());
|
||||
Dart_ListSetAt(frame4_locals, 10, NewString("func1"));
|
||||
Dart_ListSetAt(frame4_locals, 11, Dart_Null());
|
||||
|
||||
Dart_Handle expected_locals[] = {frame0_locals, frame1_locals, frame2_locals,
|
||||
frame3_locals};
|
||||
frame3_locals, frame4_locals};
|
||||
breakpoint_hit_counter++;
|
||||
VerifyStackTrace(trace, expected_trace, expected_locals, kStackTraceLen,
|
||||
true);
|
||||
|
|
|
@ -1463,26 +1463,25 @@ RawError* Object::Init(Isolate* isolate, kernel::Program* kernel_program) {
|
|||
core_lib);
|
||||
pending_classes.Add(library_prefix_cls);
|
||||
|
||||
RegisterPrivateClass(type_cls, Symbols::_Type(), core_lib);
|
||||
RegisterPrivateClass(type_cls, Symbols::Type(), core_lib);
|
||||
pending_classes.Add(type_cls);
|
||||
|
||||
RegisterPrivateClass(type_ref_cls, Symbols::_TypeRef(), core_lib);
|
||||
RegisterPrivateClass(type_ref_cls, Symbols::TypeRef(), core_lib);
|
||||
pending_classes.Add(type_ref_cls);
|
||||
|
||||
RegisterPrivateClass(type_parameter_cls, Symbols::_TypeParameter(),
|
||||
RegisterPrivateClass(type_parameter_cls, Symbols::TypeParameter(),
|
||||
core_lib);
|
||||
pending_classes.Add(type_parameter_cls);
|
||||
|
||||
RegisterPrivateClass(bounded_type_cls, Symbols::_BoundedType(), core_lib);
|
||||
RegisterPrivateClass(bounded_type_cls, Symbols::BoundedType(), core_lib);
|
||||
pending_classes.Add(bounded_type_cls);
|
||||
|
||||
RegisterPrivateClass(mixin_app_type_cls, Symbols::_MixinAppType(),
|
||||
core_lib);
|
||||
RegisterPrivateClass(mixin_app_type_cls, Symbols::MixinAppType(), core_lib);
|
||||
pending_classes.Add(mixin_app_type_cls);
|
||||
|
||||
cls = Class::New<Integer>();
|
||||
object_store->set_integer_implementation_class(cls);
|
||||
RegisterPrivateClass(cls, Symbols::_IntegerImplementation(), core_lib);
|
||||
RegisterPrivateClass(cls, Symbols::IntegerImplementation(), core_lib);
|
||||
pending_classes.Add(cls);
|
||||
|
||||
cls = Class::New<Smi>();
|
||||
|
@ -1657,17 +1656,6 @@ RawError* Object::Init(Isolate* isolate, kernel::Program* kernel_program) {
|
|||
type = object_store->object_type();
|
||||
stacktrace_cls.set_super_type(type);
|
||||
|
||||
// Abstract class that represents the Dart class Type.
|
||||
// Note that this class is implemented by Dart class _AbstractType.
|
||||
cls = Class::New<Instance>(kIllegalCid);
|
||||
cls.set_num_type_arguments(0);
|
||||
cls.set_num_own_type_arguments(0);
|
||||
cls.set_is_prefinalized();
|
||||
RegisterClass(cls, Symbols::Type(), core_lib);
|
||||
pending_classes.Add(cls);
|
||||
type = Type::NewNonParameterizedType(cls);
|
||||
object_store->set_type_type(type);
|
||||
|
||||
// Abstract class that represents the Dart class Function.
|
||||
cls = Class::New<Instance>(kIllegalCid);
|
||||
cls.set_num_type_arguments(0);
|
||||
|
@ -7067,6 +7055,16 @@ void Function::DropUncompiledConvertedClosureFunction() const {
|
|||
}
|
||||
}
|
||||
|
||||
RawString* Function::UserVisibleFormalParameters() const {
|
||||
Thread* thread = Thread::Current();
|
||||
Zone* zone = thread->zone();
|
||||
// Typically 3, 5,.. elements in 'pieces', e.g.:
|
||||
// '_LoadRequest', CommaSpace, '_LoadError'.
|
||||
GrowableHandlePtrArray<const String> pieces(zone, 5);
|
||||
BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces);
|
||||
return Symbols::FromConcatAll(thread, pieces);
|
||||
}
|
||||
|
||||
void Function::BuildSignatureParameters(
|
||||
Thread* thread,
|
||||
Zone* zone,
|
||||
|
@ -16412,10 +16410,6 @@ RawType* Type::DartFunctionType() {
|
|||
return Isolate::Current()->object_store()->function_type();
|
||||
}
|
||||
|
||||
RawType* Type::DartTypeType() {
|
||||
return Isolate::Current()->object_store()->type_type();
|
||||
}
|
||||
|
||||
RawType* Type::NewNonParameterizedType(const Class& type_class) {
|
||||
ASSERT(type_class.NumTypeArguments() == 0);
|
||||
Type& type = Type::Handle(type_class.CanonicalType());
|
||||
|
|
|
@ -2046,6 +2046,10 @@ class Function : public Object {
|
|||
intptr_t num_free_fun_type_params = kMaxInt32,
|
||||
TrailPtr trail = NULL) const;
|
||||
|
||||
// Build a string of the form 'T, {B b, C c}' representing the user
|
||||
// visible formal parameters of the function.
|
||||
RawString* UserVisibleFormalParameters() const;
|
||||
|
||||
// Reloading support:
|
||||
void Reparent(const Class& new_cls) const;
|
||||
void ZeroEdgeCounters() const;
|
||||
|
@ -6022,9 +6026,6 @@ class Type : public AbstractType {
|
|||
// The 'Function' type.
|
||||
static RawType* DartFunctionType();
|
||||
|
||||
// The 'Type' type.
|
||||
static RawType* DartTypeType();
|
||||
|
||||
// The finalized type of the given non-parameterized class.
|
||||
static RawType* NewNonParameterizedType(const Class& type_class);
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ ObjectStore::ObjectStore()
|
|||
null_class_(Class::null()),
|
||||
null_type_(Type::null()),
|
||||
function_type_(Type::null()),
|
||||
type_type_(Type::null()),
|
||||
closure_class_(Class::null()),
|
||||
number_type_(Type::null()),
|
||||
int_type_(Type::null()),
|
||||
|
|
|
@ -69,9 +69,6 @@ class ObjectStore {
|
|||
RawType* function_type() const { return function_type_; }
|
||||
void set_function_type(const Type& value) { function_type_ = value.raw(); }
|
||||
|
||||
RawType* type_type() const { return type_type_; }
|
||||
void set_type_type(const Type& value) { type_type_ = value.raw(); }
|
||||
|
||||
RawClass* closure_class() const { return closure_class_; }
|
||||
void set_closure_class(const Class& value) { closure_class_ = value.raw(); }
|
||||
|
||||
|
@ -514,7 +511,6 @@ class ObjectStore {
|
|||
V(RawClass*, null_class_) \
|
||||
V(RawType*, null_type_) \
|
||||
V(RawType*, function_type_) \
|
||||
V(RawType*, type_type_) \
|
||||
V(RawClass*, closure_class_) \
|
||||
V(RawType*, number_type_) \
|
||||
V(RawType*, int_type_) \
|
||||
|
|
|
@ -1657,16 +1657,16 @@ SequenceNode* Parser::ParseImplicitClosure(const Function& func) {
|
|||
// deopt because the generated AST will change.
|
||||
func.SetIsOptimizable(false);
|
||||
|
||||
InvocationMirror::Kind im_kind;
|
||||
InvocationMirror::Type im_type;
|
||||
if (parent.IsImplicitGetterFunction()) {
|
||||
im_kind = InvocationMirror::kGetter;
|
||||
im_type = InvocationMirror::kGetter;
|
||||
} else if (parent.IsImplicitSetterFunction()) {
|
||||
im_kind = InvocationMirror::kSetter;
|
||||
im_type = InvocationMirror::kSetter;
|
||||
} else {
|
||||
im_kind = InvocationMirror::kMethod;
|
||||
im_type = InvocationMirror::kMethod;
|
||||
}
|
||||
call = ThrowNoSuchMethodError(TokenPos(), owner, func_name, func_args,
|
||||
InvocationMirror::kStatic, im_kind,
|
||||
InvocationMirror::kStatic, im_type,
|
||||
NULL); // No existing function.
|
||||
}
|
||||
|
||||
|
@ -2981,9 +2981,9 @@ AstNode* Parser::CheckDuplicateFieldInit(
|
|||
// Object receiver,
|
||||
// String memberName,
|
||||
// int invocation_type,
|
||||
// Object typeArguments,
|
||||
// List arguments,
|
||||
// List argumentNames);
|
||||
// List argumentNames,
|
||||
// List existingArgumentNames);
|
||||
|
||||
ArgumentListNode* nsm_args = new (Z) ArgumentListNode(init_pos);
|
||||
// Object receiver.
|
||||
|
@ -3000,10 +3000,6 @@ AstNode* Parser::CheckDuplicateFieldInit(
|
|||
nsm_args->Add(new (Z) LiteralNode(
|
||||
init_pos, Smi::ZoneHandle(Z, Smi::New(invocation_type))));
|
||||
|
||||
// Object typeArguments.
|
||||
nsm_args->Add(new (Z)
|
||||
LiteralNode(init_pos, Object::null_type_arguments()));
|
||||
|
||||
// List arguments.
|
||||
GrowableArray<AstNode*> setter_args;
|
||||
setter_args.Add(init_value);
|
||||
|
@ -3015,6 +3011,11 @@ AstNode* Parser::CheckDuplicateFieldInit(
|
|||
// The missing implicit setter of the field has no argument names.
|
||||
nsm_args->Add(new (Z) LiteralNode(init_pos, Object::null_array()));
|
||||
|
||||
// List existingArgumentNames.
|
||||
// There is no setter for the final field, thus there are
|
||||
// no existing names.
|
||||
nsm_args->Add(new (Z) LiteralNode(init_pos, Object::null_array()));
|
||||
|
||||
AstNode* nsm_call = MakeStaticCall(
|
||||
Symbols::NoSuchMethodError(),
|
||||
Library::PrivateCoreLibName(Symbols::ThrowNew()), nsm_args);
|
||||
|
@ -10855,6 +10856,7 @@ SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos,
|
|||
return node->AsSequenceNode();
|
||||
}
|
||||
|
||||
// Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew.
|
||||
AstNode* Parser::ThrowTypeError(TokenPosition type_pos,
|
||||
const AbstractType& type,
|
||||
LibraryPrefix* prefix) {
|
||||
|
@ -10888,8 +10890,8 @@ AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos,
|
|||
const Class& cls,
|
||||
const String& function_name,
|
||||
ArgumentListNode* function_arguments,
|
||||
InvocationMirror::Level im_level,
|
||||
InvocationMirror::Kind im_kind,
|
||||
InvocationMirror::Call im_call,
|
||||
InvocationMirror::Type im_type,
|
||||
const Function* func,
|
||||
const LibraryPrefix* prefix) {
|
||||
ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos);
|
||||
|
@ -10919,18 +10921,13 @@ AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos,
|
|||
call_pos, String::ZoneHandle(Z, Symbols::New(T, function_name))));
|
||||
// Smi invocation_type.
|
||||
if (cls.IsTopLevel()) {
|
||||
ASSERT(im_level == InvocationMirror::kStatic ||
|
||||
im_level == InvocationMirror::kTopLevel);
|
||||
im_level = InvocationMirror::kTopLevel;
|
||||
ASSERT(im_call == InvocationMirror::kStatic ||
|
||||
im_call == InvocationMirror::kTopLevel);
|
||||
im_call = InvocationMirror::kTopLevel;
|
||||
}
|
||||
arguments->Add(new (Z) LiteralNode(
|
||||
call_pos, Smi::ZoneHandle(Z, Smi::New(InvocationMirror::EncodeType(
|
||||
im_level, im_kind)))));
|
||||
// Type arguments.
|
||||
arguments->Add(new (Z) LiteralNode(
|
||||
call_pos, function_arguments == NULL
|
||||
? TypeArguments::ZoneHandle(Z, TypeArguments::null())
|
||||
: function_arguments->type_arguments()));
|
||||
im_call, im_type)))));
|
||||
// List arguments.
|
||||
if (function_arguments == NULL) {
|
||||
arguments->Add(new (Z) LiteralNode(call_pos, Object::null_array()));
|
||||
|
@ -10946,6 +10943,38 @@ AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos,
|
|||
} else {
|
||||
arguments->Add(new (Z) LiteralNode(call_pos, function_arguments->names()));
|
||||
}
|
||||
|
||||
// List existingArgumentNames.
|
||||
// Check if there exists a function with the same name unless caller
|
||||
// has done the lookup already. If there is a function with the same
|
||||
// name but incompatible parameters, inform the NoSuchMethodError what the
|
||||
// expected parameters are.
|
||||
Function& function = Function::Handle(Z);
|
||||
if (func != NULL) {
|
||||
function = func->raw();
|
||||
} else {
|
||||
function = cls.LookupStaticFunction(function_name);
|
||||
}
|
||||
Array& array = Array::ZoneHandle(Z);
|
||||
// An unpatched external function is treated as an unresolved function.
|
||||
if (!function.IsNull() && !function.is_external()) {
|
||||
// The constructor for NoSuchMethodError takes a list of existing
|
||||
// parameter names to produce a descriptive error message explaining
|
||||
// the parameter mismatch. The problem is that the array of names
|
||||
// does not describe which parameters are optional positional or
|
||||
// named, which can lead to confusing error messages.
|
||||
// Since the NoSuchMethodError class only uses the list to produce
|
||||
// a string describing the expected parameters, we construct a more
|
||||
// descriptive string here and pass it as the only element of the
|
||||
// "existingArgumentNames" array of the NoSuchMethodError constructor.
|
||||
// TODO(13471): Separate the implementations of NoSuchMethodError
|
||||
// between dart2js and VM. Update the constructor to accept a string
|
||||
// describing the formal parameters of an incompatible call target.
|
||||
array = Array::New(1, Heap::kOld);
|
||||
array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters()));
|
||||
}
|
||||
arguments->Add(new (Z) LiteralNode(call_pos, array));
|
||||
|
||||
return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments);
|
||||
}
|
||||
|
||||
|
@ -14489,7 +14518,7 @@ AstNode* Parser::ParsePrimary() {
|
|||
pieces.Add(ident);
|
||||
const String& qualified_name =
|
||||
String::ZoneHandle(Z, Symbols::FromConcatAll(T, pieces));
|
||||
InvocationMirror::Kind call_kind = CurrentToken() == Token::kLPAREN
|
||||
InvocationMirror::Type call_type = CurrentToken() == Token::kLPAREN
|
||||
? InvocationMirror::kMethod
|
||||
: InvocationMirror::kGetter;
|
||||
// Note: Adding a statement to current block is a hack, parsing an
|
||||
|
@ -14497,7 +14526,7 @@ AstNode* Parser::ParsePrimary() {
|
|||
current_block_->statements->Add(ThrowNoSuchMethodError(
|
||||
qual_ident_pos, current_class(), qualified_name,
|
||||
NULL, // No arguments.
|
||||
InvocationMirror::kTopLevel, call_kind,
|
||||
InvocationMirror::kTopLevel, call_type,
|
||||
NULL, // No existing function.
|
||||
&prefix));
|
||||
}
|
||||
|
|
|
@ -920,8 +920,8 @@ class Parser : public ValueObject {
|
|||
const Class& cls,
|
||||
const String& function_name,
|
||||
ArgumentListNode* function_arguments,
|
||||
InvocationMirror::Level level,
|
||||
InvocationMirror::Kind kind,
|
||||
InvocationMirror::Call call,
|
||||
InvocationMirror::Type type,
|
||||
const Function* func,
|
||||
const LibraryPrefix* prefix = NULL);
|
||||
|
||||
|
|
|
@ -176,13 +176,12 @@ DEFINE_RUNTIME_ENTRY(NullError, 0) {
|
|||
Smi::Handle(Smi::New(InvocationMirror::EncodeType(
|
||||
InvocationMirror::kDynamic, InvocationMirror::kMethod)));
|
||||
|
||||
const Array& args = Array::Handle(Array::New(7));
|
||||
const Array& args = Array::Handle(Array::New(6));
|
||||
args.SetAt(0, /* instance */ Object::null_object());
|
||||
args.SetAt(1, /* member_name */ Object::null_object());
|
||||
args.SetAt(2, invocation_type);
|
||||
args.SetAt(3, /* func_type_args */ Object::null_object());
|
||||
args.SetAt(4, /* func_args */ Object::null_object());
|
||||
args.SetAt(5, /* func_arg_names */ Object::null_object());
|
||||
args.SetAt(3, /* func_args */ Object::null_object());
|
||||
args.SetAt(4, /* func_named_args */ Object::null_object());
|
||||
Exceptions::ThrowByType(Exceptions::kNoSuchMethod, args);
|
||||
}
|
||||
|
||||
|
|
|
@ -154,12 +154,11 @@ class ObjectPointerVisitor;
|
|||
V(null, "null") \
|
||||
V(Dynamic, "dynamic") \
|
||||
V(UnresolvedClass, "UnresolvedClass") \
|
||||
V(Type, "Type") \
|
||||
V(_Type, "_Type") \
|
||||
V(_TypeRef, "_TypeRef") \
|
||||
V(_TypeParameter, "_TypeParameter") \
|
||||
V(_BoundedType, "_BoundedType") \
|
||||
V(_MixinAppType, "_MixinAppType") \
|
||||
V(Type, "_Type") \
|
||||
V(TypeRef, "_TypeRef") \
|
||||
V(TypeParameter, "_TypeParameter") \
|
||||
V(BoundedType, "_BoundedType") \
|
||||
V(MixinAppType, "_MixinAppType") \
|
||||
V(TypeArguments, "TypeArguments") \
|
||||
V(Patch, "patch") \
|
||||
V(PatchClass, "PatchClass") \
|
||||
|
@ -198,7 +197,7 @@ class ObjectPointerVisitor;
|
|||
V(LanguageError, "LanguageError") \
|
||||
V(UnhandledException, "UnhandledException") \
|
||||
V(UnwindError, "UnwindError") \
|
||||
V(_IntegerImplementation, "_IntegerImplementation") \
|
||||
V(IntegerImplementation, "_IntegerImplementation") \
|
||||
V(Number, "num") \
|
||||
V(_Smi, "_Smi") \
|
||||
V(_Mint, "_Mint") \
|
||||
|
|
|
@ -543,11 +543,6 @@ class StringBuffer {
|
|||
|
||||
@patch
|
||||
class NoSuchMethodError {
|
||||
@patch
|
||||
NoSuchMethodError.withInvocation(Object receiver, Invocation invocation) {
|
||||
// UNIMPLEMENTED
|
||||
}
|
||||
|
||||
@patch
|
||||
NoSuchMethodError(Object receiver, Symbol memberName,
|
||||
List positionalArguments, Map<Symbol, dynamic> namedArguments,
|
||||
|
|
|
@ -430,27 +430,12 @@ class AbstractClassInstantiationError extends Error {
|
|||
* Error thrown by the default implementation of [:noSuchMethod:] on [Object].
|
||||
*/
|
||||
class NoSuchMethodError extends Error {
|
||||
// Deprecated members to be removed.
|
||||
final Object _receiver;
|
||||
final Symbol _memberName;
|
||||
final List _arguments;
|
||||
final Map<Symbol, dynamic> _namedArguments;
|
||||
final List _existingArgumentNames;
|
||||
|
||||
/**
|
||||
* Create a [NoSuchMethodError] corresponding to a failed method call.
|
||||
*
|
||||
* The [receiver] is the receiver of the method call.
|
||||
* That is, the object on which the method was attempted called.
|
||||
*
|
||||
* The [invocation] represents the method call that failed. It
|
||||
* should not be `null`.
|
||||
*/
|
||||
@Deprecated("Dart 2.0. Will be renamed to become default constructor")
|
||||
external NoSuchMethodError.withInvocation(
|
||||
Object receiver, Invocation invocation);
|
||||
|
||||
// Deprecated constructor to be removed after dart2js updates to the above.
|
||||
/**
|
||||
* Create a [NoSuchMethodError] corresponding to a failed method call.
|
||||
*
|
||||
|
|
|
@ -15,26 +15,18 @@ abstract class Invocation {
|
|||
/** The name of the invoked member. */
|
||||
Symbol get memberName;
|
||||
|
||||
/**
|
||||
* An unmodifiable view of the type arguments of the call.
|
||||
*
|
||||
* If the call is not generic, the type arguments list is empty.
|
||||
*/
|
||||
List<Type> get typeArguments;
|
||||
|
||||
/**
|
||||
* An unmodifiable view of the positional arguments of the call.
|
||||
*
|
||||
* If the member is a getter, the positional arguments list is
|
||||
* empty.
|
||||
* If the member is a getter, the positional arguments is empty.
|
||||
*/
|
||||
List 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 empty.
|
||||
* If the member is a getter, setter or operator, the named arguments
|
||||
* is empty.
|
||||
*/
|
||||
Map<Symbol, dynamic> get namedArguments;
|
||||
|
||||
|
@ -43,16 +35,15 @@ abstract class Invocation {
|
|||
|
||||
/**
|
||||
* Whether the invocation was a getter call.
|
||||
* If so, all three types of arguments lists are empty.
|
||||
* If so, both types of arguments is 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.
|
||||
* If so, [positionalArguments] has exactly one positional argument,
|
||||
* and [namedArguments] is empty.
|
||||
*/
|
||||
bool get isSetter;
|
||||
|
||||
|
|
Loading…
Reference in a new issue