Invoked when a non-existent method or property is accessed.
Classes can override noSuchMethod
to provide custom behavior.
If a value is returned, it becomes the result of the original invocation.
The default behavior is to throw a NoSuchMethodError
.
Source
noSuchMethod(Invocation invocation) {
throwError() {
super.noSuchMethod(invocation);
}
String name = _stripReservedNamePrefix(
mirrors.MirrorSystem.getName(invocation.memberName));
argsSafeForTypedInterop(invocation.positionalArguments);
if (invocation.isGetter) {
if (CHECK_JS_INVOCATIONS) {
var matches = _allowedGetters[invocation.memberName];
if (matches == null &&
!_allowedMethods.containsKey(invocation.memberName)) {
throwError();
}
var ret = _operator_getter(name);
if (matches != null) return ret;
if (ret is Function ||
(ret is JsFunction /* shouldn't be needed in the future*/) &&
_allowedMethods.containsKey(
invocation.memberName)) return ret; // Warning: we have not bound "this"... we could type check on the Function but that is of little value in Dart.
throwError();
} else {
// TODO(jacobr): should we throw if the JavaScript object doesn't have the property?
return _operator_getter(name);
}
} else if (invocation.isSetter) {
if (CHECK_JS_INVOCATIONS) {
var matches = _allowedSetters[invocation.memberName];
if (matches == null ||
!matches.checkInvocation(invocation)) throwError();
}
assert(name.endsWith("="));
name = name.substring(0, name.length - 1);
return _operator_setter(name, invocation.positionalArguments.first);
} else {
// TODO(jacobr): also allow calling getters that look like functions.
var matches;
if (CHECK_JS_INVOCATIONS) {
matches = _allowedMethods[invocation.memberName];
if (matches == null ||
!matches.checkInvocation(invocation)) throwError();
}
var ret = _callMethod(name, _buildArgs(invocation));
if (CHECK_JS_INVOCATIONS) {
if (!matches._checkReturnType(ret)) {
html.window.console.error("Return value for method: ${name} is "
"${ret.runtimeType} which is inconsistent with all typed "
"JS interop definitions for method ${name}.");
}
}
return ret;
}
}