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:
Régis Crelier 2017-09-27 21:08:20 +00:00
parent 31fb4d3633
commit 8cf9ef22c4
23 changed files with 381 additions and 535 deletions

View file

@ -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 {

View file

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

View file

@ -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);

View file

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

View file

@ -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,

View file

@ -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();
}

View file

@ -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

View file

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

View file

@ -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) \

View file

@ -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 =

View file

@ -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).

View file

@ -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);

View file

@ -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());

View file

@ -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);

View file

@ -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()),

View file

@ -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_) \

View file

@ -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));
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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") \

View file

@ -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,

View file

@ -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.
*

View file

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