Implement super operator calls

Review URL: http://codereview.chromium.org//8222015

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@335 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
hausner@google.com 2011-10-11 16:49:35 +00:00
parent 3c48e145c4
commit a487770657
4 changed files with 75 additions and 3 deletions

View file

@ -1028,6 +1028,46 @@ AstNode* Parser::ParseSuperCall(const String& function_name) {
}
AstNode* Parser::ParseSuperOperator() {
AstNode* super_op = NULL;
const intptr_t operator_pos = token_index_;
const Class& super_class = Class::Handle(current_class().SuperClass());
if (super_class.IsNull()) {
ErrorMsg(operator_pos, "class '%s' does not have a superclass",
String::Handle(current_class().Name()).ToCString());
}
if (CurrentToken() == Token::kLBRACK) {
Unimplemented("Not yet implemented: super[expr]");
} else if (Token::CanBeOverloaded(CurrentToken())) {
Token::Kind op = CurrentToken();
ConsumeToken();
// Resolve the operator function in the superclass.
const String& operator_function_name =
String::ZoneHandle(String::NewSymbol(Token::Str(op)));
const Function& super_operator = Function::ZoneHandle(
ResolveDynamicFunction(super_class, operator_function_name));
if (super_operator.IsNull()) {
ErrorMsg(operator_pos, "operator '%s' not found in super class",
Token::Str(op));
}
ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR));
AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1);
ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos);
AstNode* receiver = LoadReceiver(operator_pos);
op_arguments->Add(receiver);
op_arguments->Add(other_operand);
CheckFunctionIsCallable(operator_pos, super_operator);
super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
}
return super_op;
}
AstNode* Parser::CreateImplicitClosureNode(const Function& func,
intptr_t token_pos,
AstNode* receiver) {
@ -6625,10 +6665,10 @@ AstNode* Parser::ParsePrimary() {
} else {
primary = ParseSuperFieldAccess(ident);
}
} else if (CurrentToken() == Token::kLBRACK) {
Unimplemented("Don't know yet how to interpret super[expr]");
} else if (Token::CanBeOverloaded(CurrentToken())) {
primary = ParseSuperOperator();
} else {
ErrorMsg("Expected '.' or '[' after super");
ErrorMsg("Illegal super call");
}
} else {
UnexpectedToken();

View file

@ -232,6 +232,7 @@ class Parser : ValueObject {
const Array& interfaces);
AstNode* ParseSuperCall(const String& function_name);
AstNode* ParseSuperFieldAccess(const String& field_name);
AstNode* ParseSuperOperator();
static void SetupDefaultsForOptionalParams(const ParamList* params,
Array& default_values);

View file

@ -96,6 +96,7 @@ NullToStringTest: Fail # Bug 5421978
FunctionTypeAliasTest: Crash # Bug 4519208.
# Other bugs (or unimplemented features) in dartc.
SuperOperatorTest: Fail # Bug 4995463.
GenericTest: Fail # Bug 5393302 (missing call to super constructor)
Throw7NegativeTest: Fail # Bug 4208459.
Throw3Test: Fail # Bug 4205624.

View file

@ -0,0 +1,30 @@
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Dart test for testing super operator calls
class A {
String val = "";
operator + (String s) {
val = val + s;
return this;
}
}
class B extends A {
operator + (String s) {
super + (s + s);
return this;
}
}
main () {
var a = new A();
a = a + "William";
Expect.equals("William", a.val);
a = new B();
a += "Tell";
Expect.equals("TellTell", a.val);
}