Skip to content
This repository has been archived by the owner on Feb 22, 2018. It is now read-only.

Commit

Permalink
fix(parser): Workaround dart2js bugs in latest version of Dart SDK 1.2.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kasper Lund authored and mhevery committed Jan 27, 2014
1 parent 1e40344 commit dddc3c8
Showing 1 changed file with 31 additions and 5 deletions.
36 changes: 31 additions & 5 deletions lib/core/parser/eval_access.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ abstract class AccessReflective {
_assignToNonExisting(scope, value) => null;

static Function createInvokeClosure(InstanceMirror mirror, Symbol symbol) {
if (!hasMember(mirror, symbol)) return null;
if (!hasMethod(mirror, symbol)) return null;
return relaxFnArgs(([a0, a1, a2, a3, a4, a5]) {
var arguments = stripTrailingNulls([a0, a1, a2, a3, a4, a5]);
return mirror.invoke(symbol, arguments).reflectee;
Expand All @@ -131,17 +131,22 @@ abstract class AccessReflective {
return list;
}

static bool hasMember(InstanceMirror mirror, Symbol symbol) {
static bool hasMethod(InstanceMirror mirror, Symbol symbol) {
return hasMethodHelper(mirror.type, symbol);
}

static final objectClassMirror = reflectClass(Object);
static final Set<Symbol> objectClassInstanceMethods =
new Set<Symbol>.from([#toString, #noSuchMethod]);

static final Function hasMethodHelper = (() {
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;
objectClassMirror.instanceMembers;
// For SDK 1.2 we have to use a somewhat complicated helper for this
// to work around bugs in the dart2js implementation.
return hasInstanceMethod;
} 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;
Expand All @@ -151,6 +156,27 @@ abstract class AccessReflective {
}
return null;
})();

static bool hasInstanceMethod(type, symbol) {
// Always allow instance methods found in the Object class. This makes
// it easier to work around a few bugs in the dart2js implementation.
if (objectClassInstanceMethods.contains(symbol)) return true;
// Work around http://dartbug.com/16309 which causes access to the
// instance members of certain builtin types to throw exceptions
// while traversing the superclass chain.
var mirror;
try {
mirror = type.instanceMembers[symbol];
} on UnsupportedError catch (e) {
mirror = type.declarations[symbol];
}
// Work around http://dartbug.com/15760 which causes noSuchMethod
// forwarding stubs to be treated as members of all classes. We have
// already checked for the real instance methods in Object, so if the
// owner of this method is Object we simply filter it out.
if (mirror is !MethodMirror) return false;
return mirror.owner != objectClassMirror;
}
}

/**
Expand Down

0 comments on commit dddc3c8

Please sign in to comment.