Alexandre's answer is correct, but I'd like to add something.
I assume that the delegation to Proxy
is an implementation detail, and we don't want the user to be exposed to it. In that case, we should have some handling of cases where methods are called on parser
that are not supported by Proxy
. Right now, if you do this:
void main() {
var parser = new Parser();
print(parser.foo());
}
You get this error:
Unhandled exception:
Compile-time error during mirrored execution: <Dart_Invoke: did not find static method 'Proxy.foo'.>
I would write the code in noSuchMethod
a little differently. Before delegating to Proxy
, I would check that Proxy
supports the method I'm about to invoke. If Proxy
supports it, I would invoke the method on Proxy
as Alexandre describes in his answer. If Proxy
does not support the method, I would throw a NoSuchMethodError
.
Here is a revised version of the answer:
import 'dart:mirrors';
class Parser {
noSuchMethod(Invocation invocation) {
ClassMirror cm = reflectClass(Proxy);
if (cm.methods.keys.contains(invocation.memberName)) {
return cm.invoke(invocation.memberName
, invocation.positionalArguments
/*, invocation.namedArguments*/ // not implemented yet
).reflectee;
}
throw new NoSuchMethodError(this,
_symbolToString(invocation.memberName),
invocation.positionalArguments,
_symbolMapToStringMap(invocation.namedArguments));
}
}
String _symbolToString(Symbol symbol) => MirrorSystem.getName(symbol);
Map<String, dynamic> _symbolMapToStringMap(Map<Symbol, dynamic> map) {
if (map == null) return null;
var result = new Map<String, dynamic>();
map.forEach((Symbol key, value) {
result[_symbolToString(key)] = value;
});
return result;
}
class Proxy {
static String hello() { return "hello"; }
static String world() { return "world"; }
}
main(){
var parser = new Parser();
print(parser.hello());
print(parser.world());
print(parser.foo());
}
And here is the output from running this code:
hello
world
Unhandled exception:
NoSuchMethodError : method not found: 'foo'
Receiver: Instance of 'Parser'
Arguments: []