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

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: Code review changes, frogsh 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
« no previous file with comments | « frog/frogsh ('k') | tests/language/language.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/member.dart
diff --git a/frog/member.dart b/frog/member.dart
index e7c2785b5dff942ce205494f958be0185bc5dd19..a23c5c43e185d5af246af38e2da0411cd8efbd0c 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));
+ returnValue = new Value(_foldTypes(targets), null, node.span);
+ } 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(_foldTypes(targets), 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,
@@ -1549,12 +1566,14 @@ class MemberSet {
final mset = context.findMembers(name).members;
final targets = mset.filter((m) => m.canInvoke(context, args));
- final returnType = reduce(map(targets, (t) => t.returnType), Type.union);
- stub = new VarMethodSet(stubName, targets, args, returnType);
+ stub = new VarMethodSet(stubName, targets, args, _foldTypes(targets));
world.objectType.varStubs[stubName] = stub;
}
return stub;
}
+
+ Type _foldTypes(List<Member> targets) =>
+ reduce(map(targets, (t) => t.returnType), Type.union, world.varType);
}
/**
« no previous file with comments | « frog/frogsh ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698