diff --git a/lib/core/parser/backend.dart b/lib/core/parser/backend.dart index b0d000799..80c3f39ac 100644 --- a/lib/core/parser/backend.dart +++ b/lib/core/parser/backend.dart @@ -41,15 +41,33 @@ class GetterSetter { return l; } - _maybeInvoke(instanceMirror, symbol) { - if (instanceMirror.type.members.containsKey(symbol)) { - MethodMirror methodMirror = instanceMirror.type.members[symbol]; - return relaxFnArgs(([a0, a1, a2, a3, a4, a5]) { - var args = stripTrailingNulls([a0, a1, a2, a3, a4, a5]); - return instanceMirror.invoke(symbol, args).reflectee; - }); + static bool hasMethod(InstanceMirror mirror, Symbol symbol) { + return hasMethodHelper(mirror.type, symbol); + } + + static final Function hasMethodHelper = computeHasMethodHelper(); + static Function computeHasMethodHelper() { + var objectType = reflect(Object).type; + try { + // Use ClassMirror.instanceMembers if available. It contains local + // as well as inherited members. + objectType.instanceMembers; + return (type, symbol) => type.instanceMembers[symbol] is MethodMirror; + } on NoSuchMethodError catch (e) { + // For SDK 1.0 we fall back to just using the local members. + return (type, symbol) => type.members[symbol] is MethodMirror; + } on UnimplementedError catch (e) { + // For SDK 1.1 we fall back to just using the local declarations. + return (type, symbol) => type.declarations[symbol] is MethodMirror; } - return null; + } + + _maybeInvoke(InstanceMirror mirror, Symbol symbol) { + if (!hasMethod(mirror, symbol)) return null; + return relaxFnArgs(([a0, a1, a2, a3, a4, a5]) { + var args = stripTrailingNulls([a0, a1, a2, a3, a4, a5]); + return mirror.invoke(symbol, args).reflectee; + }); } Map _getter_cache = {}; diff --git a/lib/core/scope.dart b/lib/core/scope.dart index 6381c638d..643f35105 100644 --- a/lib/core/scope.dart +++ b/lib/core/scope.dart @@ -774,7 +774,9 @@ _toJson(obj) { // work-around dartbug.com/14130 try { ret = mirror.function.source; - } on NoSuchMethodError catch (e) {} + } on NoSuchMethodError catch (e) { + } on UnimplementedError catch (e) { + } } return true; })()); @@ -790,6 +792,7 @@ String _source(obj) { try { return "FN: ${m.function.source}"; } on NoSuchMethodError catch (e) { + } on UnimplementedError catch (e) { } } }