Allow NoSuchMethodError.withInvocation to accept any Invocation.

Currently the VM only accepts an `_InvocationMirror` instance, not a user created `Invocation`.

Fixes #33124

Bug: http://dartbug.com/33124
Change-Id: Ifdc95861cbe632bc317ca8d9fb92cf0d3ae600f0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/140100
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
This commit is contained in:
Lasse Reichstein Holst Nielsen 2020-05-05 08:10:13 +00:00 committed by commit-bot@chromium.org
parent 497bdc5226
commit 2ca3555c44
4 changed files with 488 additions and 281 deletions

View file

@ -187,12 +187,12 @@ class NoSuchMethodError {
List _existingArgumentNames;
final Object _receiver;
final _InvocationMirror _invocation;
final Invocation _invocation;
@patch
NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
: _receiver = receiver,
_invocation = invocation as _InvocationMirror;
_invocation = invocation;
static void _throwNewInvocation(Object receiver, Invocation invocation) {
throw new NoSuchMethodError.withInvocation(receiver, invocation);
@ -285,155 +285,210 @@ class NoSuchMethodError {
@patch
String toString() {
// TODO(regis): Remove this null check once dart2js is updated.
if (_invocation == null) {
var invocation = _invocation;
if (invocation == null) {
// Use deprecated version of toString.
return _toStringDeprecated();
}
String memberName =
internal.Symbol.computeUnmangledName(_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]));
if (invocation is _InvocationMirror) {
String memberName =
internal.Symbol.computeUnmangledName(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'";
}
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.computeUnmangledName(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.");
}
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(", ");
}
break;
typeArgumentsBuf.write(Error.safeToString(typeArguments[i]));
}
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);
typeArgumentsBuf.write(">");
}
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");
}
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.computeUnmangledName(key));
argumentsBuf.write(": ");
argumentsBuf.write(Error.safeToString(value));
argumentCount++;
});
}
String existingSig =
_existingMethodSignature(_receiver, memberName, invocation._type);
String argsMsg = existingSig != null ? " with matching arguments" : "";
if (existingSig != null) {
msgBuf.write("\nFound: $memberName$existingSig");
}
String kindBuf;
if (kind >= 0 && kind < 5) {
kindBuf = (const [
"method",
"getter",
"setter",
"getter or setter",
"variable"
])[kind];
}
return msgBuf.toString();
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();
}
return _toStringPlain(_receiver, invocation);
}
/// Creates a string representation of an invocation.
///
/// Used for situations where there is no extra information available
/// about the failed invocation than the [Invocation] object and receiver,
/// which includes errors created using [NoSuchMethodError.withInvocation].
static String _toStringPlain(Object receiver, Invocation invocation) {
var name = _symbolToString(invocation.memberName);
var receiverType = "${receiver.runtimeType}";
if (invocation.isAccessor) {
return "NoSuchMethodError: $receiverType has no $name ${invocation.isGetter ? "getter" : "setter"}";
}
var buffer = StringBuffer("NoSuchMethodError")..write(": ");
buffer.write("$receiverType has no $name method accepting arguments ");
var separator = "";
if (invocation.typeArguments.isNotEmpty) {
buffer.write("<");
for (var type in invocation.typeArguments) {
buffer..write(separator)..write("_");
separator = ", ";
}
buffer.write(">");
separator = "";
}
buffer.write("(");
for (var argument in invocation.positionalArguments) {
buffer..write(separator)..write("_");
separator = ", ";
}
if (invocation.namedArguments.isNotEmpty) {
buffer..write(separator)..write("{");
separator = "";
for (var name in invocation.namedArguments.keys) {
buffer..write(separator)..write(_symbolToString(name))..write(": _");
separator = ",";
}
buffer.write("}");
}
buffer.write(")");
return buffer.toString();
}
static String _symbolToString(Symbol symbol) {
if (symbol is internal.Symbol) {
return internal.Symbol.computeUnmangledName(symbol);
}
return "$symbol";
}
// TODO(regis): Remove this function once dart2js is updated.

View file

@ -184,13 +184,13 @@ class NoSuchMethodError {
List? _existingArgumentNames;
final Object _receiver;
final _InvocationMirror? _invocation;
final Invocation? _invocation;
// Issue(dartbug.com/127160): Remove the cast to [_InvocationMirror].
@patch
NoSuchMethodError.withInvocation(Object receiver, Invocation invocation)
: _receiver = receiver,
_invocation = invocation as _InvocationMirror;
_invocation = invocation;
static void _throwNewInvocation(Object receiver, Invocation invocation) {
throw new NoSuchMethodError.withInvocation(receiver, invocation);
@ -288,152 +288,208 @@ class NoSuchMethodError {
// Use deprecated version of toString.
return _toStringDeprecated();
}
var internalName = localInvocation.memberName as internal.Symbol;
String memberName = internal.Symbol.computeUnmangledName(internalName);
if (localInvocation is _InvocationMirror) {
var internalName = localInvocation.memberName as internal.Symbol;
String memberName = internal.Symbol.computeUnmangledName(internalName);
var level = (localInvocation._type >> _InvocationMirror._LEVEL_SHIFT) &
_InvocationMirror._LEVEL_MASK;
var kind = localInvocation._type & _InvocationMirror._KIND_MASK;
if (kind == _InvocationMirror._LOCAL_VAR) {
return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
}
StringBuffer? typeArgumentsBuf = null;
final typeArguments = localInvocation.typeArguments;
if ((typeArguments != null) && (typeArguments.length > 0)) {
final argsBuf = new StringBuffer();
argsBuf.write("<");
for (int i = 0; i < typeArguments.length; i++) {
if (i > 0) {
argsBuf.write(", ");
}
argsBuf.write(Error.safeToString(typeArguments[i]));
var level = (localInvocation._type >> _InvocationMirror._LEVEL_SHIFT) &
_InvocationMirror._LEVEL_MASK;
var kind = localInvocation._type & _InvocationMirror._KIND_MASK;
if (kind == _InvocationMirror._LOCAL_VAR) {
return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
}
argsBuf.write(">");
typeArgumentsBuf = argsBuf;
}
StringBuffer argumentsBuf = new StringBuffer();
var positionalArguments = localInvocation.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 = localInvocation.namedArguments;
if (namedArguments != null) {
namedArguments.forEach((Symbol key, var value) {
if (argumentCount > 0) {
argumentsBuf.write(", ");
}
var internalName = key as internal.Symbol;
argumentsBuf.write(internal.Symbol.computeUnmangledName(internalName));
argumentsBuf.write(": ");
argumentsBuf.write(Error.safeToString(value));
argumentCount++;
});
}
String? existingSig =
_existingMethodSignature(_receiver, memberName, localInvocation._type);
String argsMsg = existingSig != null ? " with matching arguments" : "";
assert(kind >= 0 && kind < 5);
final String kindBuf = (const [
"method",
"getter",
"setter",
"getter or setter",
"variable"
])[kind];
StringBuffer msgBuf = new StringBuffer("NoSuchMethodError: ");
bool isTypeCall = 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") {
isTypeCall = 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.");
}
StringBuffer? typeArgumentsBuf = null;
final typeArguments = localInvocation.typeArguments;
if ((typeArguments != null) && (typeArguments.length > 0)) {
final argsBuf = new StringBuffer();
argsBuf.write("<");
for (int i = 0; i < typeArguments.length; i++) {
if (i > 0) {
argsBuf.write(", ");
}
break;
argsBuf.write(Error.safeToString(typeArguments[i]));
}
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 = isTypeCall ? "$_receiver" : "$memberName";
msgBuf.write("Tried calling: $m");
if (typeArgumentsBuf != null) {
msgBuf.write(typeArgumentsBuf);
argsBuf.write(">");
typeArgumentsBuf = argsBuf;
}
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");
}
StringBuffer argumentsBuf = new StringBuffer();
var positionalArguments = localInvocation.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 = localInvocation.namedArguments;
if (namedArguments != null) {
namedArguments.forEach((Symbol key, var value) {
if (argumentCount > 0) {
argumentsBuf.write(", ");
}
var internalName = key as internal.Symbol;
argumentsBuf
.write(internal.Symbol.computeUnmangledName(internalName));
argumentsBuf.write(": ");
argumentsBuf.write(Error.safeToString(value));
argumentCount++;
});
}
String? existingSig = _existingMethodSignature(
_receiver, memberName, localInvocation._type);
String argsMsg = existingSig != null ? " with matching arguments" : "";
if (existingSig != null) {
msgBuf.write("\nFound: $memberName$existingSig");
}
assert(kind >= 0 && kind < 5);
final String kindBuf = (const [
"method",
"getter",
"setter",
"getter or setter",
"variable"
])[kind];
return msgBuf.toString();
StringBuffer msgBuf = new StringBuffer("NoSuchMethodError: ");
bool isTypeCall = 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") {
isTypeCall = 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 = isTypeCall ? "$_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();
}
return _toStringPlain(_receiver, localInvocation);
}
/// Creates a string representation of an invocation.
///
/// Used for situations where there is no extra information available
/// about the failed invocation than the [Invocation] object and receiver,
/// which includes errors created using [NoSuchMethodError.withInvocation].
static String _toStringPlain(Object receiver, Invocation invocation) {
var name = _symbolToString(invocation.memberName);
var receiverType = "${receiver.runtimeType}";
if (invocation.isAccessor) {
return "NoSuchMethodError: $receiverType has no $name "
"${invocation.isGetter ? "getter" : "setter"}";
}
var buffer = StringBuffer("NoSuchMethodError")..write(": ");
buffer.write("$receiverType has no $name method accepting arguments ");
var separator = "";
if (invocation.typeArguments.isNotEmpty) {
buffer.write("<");
for (var type in invocation.typeArguments) {
buffer..write(separator)..write("_");
separator = ", ";
}
buffer.write(">");
separator = "";
}
buffer.write("(");
for (var argument in invocation.positionalArguments) {
buffer..write(separator)..write("_");
separator = ", ";
}
if (invocation.namedArguments.isNotEmpty) {
buffer..write(separator)..write("{");
separator = "";
for (var name in invocation.namedArguments.keys) {
buffer..write(separator)..write(_symbolToString(name))..write(": _");
separator = ",";
}
buffer.write("}");
}
buffer.write(")");
return buffer.toString();
}
static String _symbolToString(Symbol symbol) {
if (symbol is internal.Symbol) {
return internal.Symbol.computeUnmangledName(symbol);
}
return "$symbol";
}
// TODO(regis): Remove this function once dart2js is updated.

View file

@ -0,0 +1,48 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
main() {
// Using withInvocation constructor.
var receiver = Object();
{
var invocationGet = Invocation.getter(#foo);
var errorGet = NoSuchMethodError.withInvocation(receiver, invocationGet);
var errorString = errorGet.toString();
Expect.isTrue(errorString.contains("foo"), "01: $errorString");
Expect.isTrue(errorString.contains("getter"), "02: $errorString");
}
{
var invocationSet = Invocation.setter(#foo, 42);
var error = NoSuchMethodError.withInvocation(receiver, invocationSet);
var errorString = error.toString();
Expect.isTrue(errorString.contains("foo"), "03: $errorString");
Expect.isTrue(errorString.contains("setter"), "04: $errorString");
}
{
var invocationCall = Invocation.method(#foo, [42]);
var error = NoSuchMethodError.withInvocation(receiver, invocationCall);
var errorString = error.toString();
Expect.isTrue(errorString.contains("foo"), "05: $errorString");
Expect.isTrue(errorString.contains("method"), "06: $errorString");
Expect.isTrue(errorString.contains("(_)"), "07: $errorString");
}
{
var invocationCall = Invocation.method(#foo, [42], {#bar: 37});
var error = NoSuchMethodError.withInvocation(receiver, invocationCall);
var errorString = error.toString();
Expect.isTrue(errorString.contains("foo"), "08: $errorString");
Expect.isTrue(errorString.contains("method"), "09: $errorString");
Expect.isTrue(errorString.contains("(_, {bar: _})"), "10: $errorString");
}
{
var invocationCall = Invocation.genericMethod(#foo, [int], [42]);
var error = NoSuchMethodError.withInvocation(receiver, invocationCall);
var errorString = error.toString();
Expect.isTrue(errorString.contains("foo"), "11: $errorString");
Expect.isTrue(errorString.contains("method"), "12: $errorString");
Expect.isTrue(errorString.contains("<_>(_)"), "13: $errorString");
}
}

View file

@ -0,0 +1,48 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
main() {
// Using withInvocation constructor.
var receiver = Object();
{
var invocationGet = Invocation.getter(#foo);
var errorGet = NoSuchMethodError.withInvocation(receiver, invocationGet);
var errorString = errorGet.toString();
Expect.isTrue(errorString.contains("foo"), "01: $errorString");
Expect.isTrue(errorString.contains("getter"), "02: $errorString");
}
{
var invocationSet = Invocation.setter(#foo, 42);
var error = NoSuchMethodError.withInvocation(receiver, invocationSet);
var errorString = error.toString();
Expect.isTrue(errorString.contains("foo"), "03: $errorString");
Expect.isTrue(errorString.contains("setter"), "04: $errorString");
}
{
var invocationCall = Invocation.method(#foo, [42]);
var error = NoSuchMethodError.withInvocation(receiver, invocationCall);
var errorString = error.toString();
Expect.isTrue(errorString.contains("foo"), "05: $errorString");
Expect.isTrue(errorString.contains("method"), "06: $errorString");
Expect.isTrue(errorString.contains("(_)"), "07: $errorString");
}
{
var invocationCall = Invocation.method(#foo, [42], {#bar: 37});
var error = NoSuchMethodError.withInvocation(receiver, invocationCall);
var errorString = error.toString();
Expect.isTrue(errorString.contains("foo"), "08: $errorString");
Expect.isTrue(errorString.contains("method"), "09: $errorString");
Expect.isTrue(errorString.contains("(_, {bar: _})"), "10: $errorString");
}
{
var invocationCall = Invocation.genericMethod(#foo, [int], [42]);
var error = NoSuchMethodError.withInvocation(receiver, invocationCall);
var errorString = error.toString();
Expect.isTrue(errorString.contains("foo"), "11: $errorString");
Expect.isTrue(errorString.contains("method"), "12: $errorString");
Expect.isTrue(errorString.contains("<_>(_)"), "13: $errorString");
}
}