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

Unified Diff: frog/member.dart

Issue 8540030: Fix dispatch on MemberSets to always go dynamic if needed. (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
« no previous file with comments | « frog/frogsh ('k') | frog/type.dart » ('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 4e5eac3e59ce279662ccbdd60bcbe310bffa0161..e7c2785b5dff942ce205494f958be0185bc5dd19 100644
--- a/frog/member.dart
+++ b/frog/member.dart
@@ -120,6 +120,9 @@ class Member implements Named {
bool get isConst() => false;
bool get isFactory() => false;
+ bool get isOperator() => name.startsWith('\$');
+ bool get isCallMethod() => name == '\$call';
+
bool get prefersPropertySyntax() => true;
bool get requiresFieldSyntax() => false;
@@ -927,7 +930,7 @@ class MethodMember extends Member {
node.span);
}
- if (name.startsWith('\$')) {
+ if (isOperator) {
return _invokeBuiltin(context, node, target, args, argsCode, isDynamic);
}
@@ -1219,7 +1222,7 @@ class MethodMember extends Member {
node.span);
}
- if (name == '\$call') {
+ if (isCallMethod) {
declaringType.markUsed();
return new Value(inferredResult,
'${target.code}(${Strings.join(argsCode, ", ")})', node.span);
@@ -1282,7 +1285,7 @@ class MethodMember extends Member {
}
// TODO(jimhug): need a better annotation for being an operator method
- if (name.startsWith('\$') && !name.startsWith('\$call') && isStatic) {
+ if (isOperator && isStatic && !isCallMethod) {
world.error('operator method may not be static "${name}"', span);
}
@@ -1333,9 +1336,11 @@ class MemberSet {
final String name;
final List<Member> members;
final String jsname;
+ final bool isVar;
- MemberSet(Member member):
- name = member.name, members = [member], jsname = member.jsname;
+ MemberSet(Member member, [bool isVar=false]):
nweiz 2011/11/14 21:28:15 Does isVar also need to be set for the library-loc
+ name = member.name, members = [member], jsname = member.jsname,
+ isVar = isVar;
toString() => '$name:${members.length}';
@@ -1343,10 +1348,12 @@ class MemberSet {
bool get containsProperties() => members.some((m) => m is PropertyMember);
bool get containsMethods() => members.some((m) => m is MethodMember);
+
void add(Member member) => members.add(member);
// TODO(jimhug): Always false, or is this needed?
bool get isStatic() => members.length == 1 && members[0].isStatic;
+ bool get isOperator() => members[0].isOperator;
bool canInvoke(MethodGenerator context, Arguments args) =>
members.some((m) => m.canInvoke(context, args));
@@ -1445,6 +1452,12 @@ class MemberSet {
Value invoke(MethodGenerator context, Node node, Value target,
Arguments args, [bool isDynamic=false]) {
+ // If this is the global MemberSet from world, always bind dynamically.
+ // Note: we need this for proper noSuchMethod and REPL behavior.
+ if (isVar && !isOperator) {
+ return invokeOnVar(context, node, target, args);
+ }
+
if (members.length == 1) {
return members[0].invoke(context, node, target, args, isDynamic);
}
@@ -1463,9 +1476,9 @@ class MemberSet {
return _makeError(node, target, 'method');
}
- // If we fail to unify the resulting code, implement as a var call.
if (returnValue.code == null) {
- if (name.startsWith('\$')) {
+ // TODO(jmesserly): make operators less special.
+ if (isOperator) {
return target.invokeSpecial(name, args, returnValue.type);
} else {
return invokeOnVar(context, node, target, args);
@@ -1477,7 +1490,8 @@ class MemberSet {
Value invokeOnVar(MethodGenerator context, Node node, Value target,
Arguments args) {
- return getVarMember(context, node, args).invoke(context, node, target, args);
+ var member = getVarMember(context, node, args);
+ return member.invoke(context, node, target, args);
}
Value _union(Value x, Value y, Node node) {
« no previous file with comments | « frog/frogsh ('k') | frog/type.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698