Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Unified Diff: frog/member.dart

Issue 8567010: Dynamically dispatch getters and setters on dynamically-typed variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: frog/member.dart
diff --git a/frog/member.dart b/frog/member.dart
index e7c2785b5dff942ce205494f958be0185bc5dd19..cea3f34b08f82133858298eef80c58f6fe6871ae 100644
--- a/frog/member.dart
+++ b/frog/member.dart
@@ -1369,7 +1369,9 @@ class MemberSet {
bool _treatAsField;
bool get treatAsField() {
if (_treatAsField == null) {
- _treatAsField = true;
+ // If this is the global MemberSet from world, always bind dynamically.
+ // Note: we need this for proper noSuchMethod and REPL behavior.
+ _treatAsField = !isVar;
for (var member in members) {
if (member.requiresFieldSyntax) {
_treatAsField = true;
@@ -1392,22 +1394,29 @@ class MemberSet {
Value _get(MethodGenerator context, Node node, Value target,
[bool isDynamic=false]) {
- if (members.length == 1) {
- return members[0]._get(context, node, target, isDynamic);
- }
+ // If this is the global MemberSet from world, always bind dynamically.
+ // Note: we need this for proper noSuchMethod and REPL behavior.
+ Value returnValue;
final targets = members.filter((m) => m.canGet);
- if (targets.length == 1) {
- return targets[0]._get(context, node, target, isDynamic);
- }
+ if (isVar) {
+ targets.forEach((m) => m._get(context, node, target, isDynamic: true));
nweiz 2011/11/15 00:04:08 This line seems to be slowing down the compilation
Jennifer Messerly 2011/11/15 04:44:34 Sounds like it. I'd try passing: --new_gen_heap_si
nweiz 2011/11/15 20:59:25 Increasing the heap size seems to do the trick. Is
Jennifer Messerly 2011/11/16 23:42:35 Yes, definitely increase it there too. Maybe frog.
+ returnValue = new Value(world.varType, null, node.span);
Jennifer Messerly 2011/11/15 04:44:34 I think you want to use a more precise type here,
nweiz 2011/11/15 20:59:25 Done. I guess I was too much in the mindset of --f
+ } else {
+ if (members.length == 1) {
+ return members[0]._get(context, node, target, isDynamic);
+ } else if (targets.length == 1) {
+ return targets[0]._get(context, node, target, isDynamic);
+ }
- Value returnValue = null;
- for (var member in targets) {
- final value = member._get(context, node, target, isDynamic:true);
- returnValue = _tryUnion(returnValue, value, node);
- }
- if (returnValue == null) {
- return _makeError(node, target, 'getter');
+ for (var member in targets) {
+ final value = member._get(context, node, target, isDynamic:true);
+ returnValue = _tryUnion(returnValue, value, node);
+ }
+ if (returnValue == null) {
+ return _makeError(node, target, 'getter');
+ }
}
+
if (returnValue.code == null) {
if (treatAsField) {
return new Value(returnValue.type, '${target.code}.$jsname',
@@ -1422,22 +1431,30 @@ class MemberSet {
Value _set(MethodGenerator context, Node node, Value target, Value value,
[bool isDynamic=false]) {
- if (members.length == 1) {
- return members[0]._set(context, node, target, value, isDynamic);
- }
+ // If this is the global MemberSet from world, always bind dynamically.
+ // Note: we need this for proper noSuchMethod and REPL behavior.
+ Value returnValue;
final targets = members.filter((m) => m.canSet);
- if (targets.length == 1) {
- return targets[0]._set(context, node, target, value, isDynamic);
- }
+ if (isVar) {
+ targets.forEach((m) =>
+ m._set(context, node, target, value, isDynamic: true));
+ returnValue = new Value(world.varType, null, node.span);
+ } else {
+ if (members.length == 1) {
+ return members[0]._set(context, node, target, value, isDynamic);
+ } else if (targets.length == 1) {
+ return targets[0]._set(context, node, target, value, isDynamic);
+ }
- Value returnValue = null;
- for (var member in targets) {
- final res = member._set(context, node, target, value, isDynamic:true);
- returnValue = _tryUnion(returnValue, res, node);
- }
- if (returnValue == null) {
- return _makeError(node, target, 'setter');
+ for (var member in targets) {
+ final res = member._set(context, node, target, value, isDynamic:true);
+ returnValue = _tryUnion(returnValue, res, node);
+ }
+ if (returnValue == null) {
+ return _makeError(node, target, 'setter');
+ }
}
+
if (returnValue.code == null) {
if (treatAsField) {
return new Value(returnValue.type,
@@ -1455,6 +1472,8 @@ class MemberSet {
// If this is the global MemberSet from world, always bind dynamically.
// Note: we need this for proper noSuchMethod and REPL behavior.
if (isVar && !isOperator) {
+ members.filter((m) => m.canInvoke(context, args)).forEach((m) =>
Jennifer Messerly 2011/11/15 04:44:34 why did you need this line? invokeOnVar already t
nweiz 2011/11/15 20:59:25 Oh, I suppose it does. I had assumed that it was n
+ m.invoke(context, node, target, args, isDynamic: true));
return invokeOnVar(context, node, target, args);
}

Powered by Google App Engine
This is Rietveld 408576698