Chromium Code Reviews| 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) { |