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

Side by Side Diff: runtime/vm/parser.cc

Issue 11669015: Turn compile time errors related to missing getters and setters into invocation (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 return native_name; 1276 return native_name;
1277 } 1277 }
1278 1278
1279 1279
1280 // Resolve and return the dynamic function of the given name in the superclass. 1280 // Resolve and return the dynamic function of the given name in the superclass.
1281 // If it is not found, and resolve_getter is true, try to resolve a getter of 1281 // If it is not found, and resolve_getter is true, try to resolve a getter of
1282 // the same name. If it is still not found, return noSuchMethod and 1282 // the same name. If it is still not found, return noSuchMethod and
1283 // set is_no_such_method to true.. 1283 // set is_no_such_method to true..
1284 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, 1284 RawFunction* Parser::GetSuperFunction(intptr_t token_pos,
1285 const String& name, 1285 const String& name,
1286 ArgumentListNode* arguments,
1286 bool resolve_getter, 1287 bool resolve_getter,
1287 bool* is_no_such_method) { 1288 bool* is_no_such_method) {
1288 const Class& super_class = Class::Handle(current_class().SuperClass()); 1289 const Class& super_class = Class::Handle(current_class().SuperClass());
1289 if (super_class.IsNull()) { 1290 if (super_class.IsNull()) {
1290 ErrorMsg(token_pos, "class '%s' does not have a superclass", 1291 ErrorMsg(token_pos, "class '%s' does not have a superclass",
1291 String::Handle(current_class().Name()).ToCString()); 1292 String::Handle(current_class().Name()).ToCString());
1292 } 1293 }
1293 Function& super_func = 1294 Function& super_func = Function::Handle(
1294 Function::Handle(Resolver::ResolveDynamicAnyArgs(super_class, name)); 1295 Resolver::ResolveDynamicAnyArgs(super_class, name));
1295 if (super_func.IsNull() && resolve_getter) { 1296 if (!super_func.IsNull() &&
1297 !super_func.AreValidArguments(arguments->length(),
1298 arguments->names(),
1299 NULL)) {
1300 super_func = Function::null();
1301 } else if (super_func.IsNull() && resolve_getter) {
1296 const String& getter_name = String::ZoneHandle(Field::GetterName(name)); 1302 const String& getter_name = String::ZoneHandle(Field::GetterName(name));
1297 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); 1303 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name);
1298 ASSERT(super_func.IsNull() || 1304 ASSERT(super_func.IsNull() ||
1299 (super_func.kind() != RawFunction::kConstImplicitGetter)); 1305 (super_func.kind() != RawFunction::kConstImplicitGetter));
1300 } 1306 }
1301 if (super_func.IsNull()) { 1307 if (super_func.IsNull()) {
1302 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod()); 1308 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod());
1303 super_func = 1309 super_func =
1304 Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name); 1310 Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name);
1305 ASSERT(!super_func.IsNull()); 1311 ASSERT(!super_func.IsNull());
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 call_pos, function_name, function_args)); 1380 call_pos, function_name, function_args));
1375 return arguments; 1381 return arguments;
1376 } 1382 }
1377 1383
1378 1384
1379 AstNode* Parser::ParseSuperCall(const String& function_name) { 1385 AstNode* Parser::ParseSuperCall(const String& function_name) {
1380 TRACE_PARSER("ParseSuperCall"); 1386 TRACE_PARSER("ParseSuperCall");
1381 ASSERT(CurrentToken() == Token::kLPAREN); 1387 ASSERT(CurrentToken() == Token::kLPAREN);
1382 const intptr_t supercall_pos = TokenPos(); 1388 const intptr_t supercall_pos = TokenPos();
1383 1389
1390 // 'this' parameter is the first argument to super call.
1391 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1392 AstNode* receiver = LoadReceiver(supercall_pos);
1393 arguments->Add(receiver);
1394 ParseActualParameters(arguments, kAllowConst);
1395
1384 const bool kResolveGetter = true; 1396 const bool kResolveGetter = true;
1385 bool is_no_such_method = false; 1397 bool is_no_such_method = false;
1386 const Function& super_function = Function::ZoneHandle( 1398 const Function& super_function = Function::ZoneHandle(
1387 GetSuperFunction(supercall_pos, 1399 GetSuperFunction(supercall_pos,
1388 function_name, 1400 function_name,
1401 arguments,
1389 kResolveGetter, 1402 kResolveGetter,
1390 &is_no_such_method)); 1403 &is_no_such_method));
1391 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1392 if (super_function.IsGetterFunction() || 1404 if (super_function.IsGetterFunction() ||
1393 super_function.IsImplicitGetterFunction()) { 1405 super_function.IsImplicitGetterFunction()) {
1394 // 'this' is not passed as parameter to the closure.
1395 ParseActualParameters(arguments, kAllowConst);
1396 const Class& super_class = Class::ZoneHandle(current_class().SuperClass()); 1406 const Class& super_class = Class::ZoneHandle(current_class().SuperClass());
1397 AstNode* closure = new StaticGetterNode(supercall_pos, 1407 AstNode* closure = new StaticGetterNode(supercall_pos,
1398 LoadReceiver(supercall_pos), 1408 LoadReceiver(supercall_pos),
1399 /* is_super_getter */ true, 1409 /* is_super_getter */ true,
1400 super_class, 1410 super_class,
1401 function_name); 1411 function_name);
1402 EnsureExpressionTemp(); 1412 EnsureExpressionTemp();
1403 return new ClosureCallNode(supercall_pos, closure, arguments); 1413 // 'this' is not passed as parameter to the closure.
1414 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos);
1415 for (int i = 1; i < arguments->length(); i++) {
1416 closure_arguments->Add(arguments->NodeAt(i));
1417 }
1418 return new ClosureCallNode(supercall_pos, closure, closure_arguments);
1404 } 1419 }
1405 // 'this' parameter is the first argument to super call.
1406 AstNode* receiver = LoadReceiver(supercall_pos);
1407 arguments->Add(receiver);
1408 ParseActualParameters(arguments, kAllowConst);
1409 if (is_no_such_method) { 1420 if (is_no_such_method) {
1410 arguments = BuildNoSuchMethodArguments( 1421 arguments = BuildNoSuchMethodArguments(
1411 supercall_pos, function_name, *arguments); 1422 supercall_pos, function_name, *arguments);
1412 } 1423 }
1413 return new StaticCallNode(supercall_pos, super_function, arguments); 1424 return new StaticCallNode(supercall_pos, super_function, arguments);
1414 } 1425 }
1415 1426
1416 1427
1417 // Simple test if a node is side effect free. 1428 // Simple test if a node is side effect free.
1418 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { 1429 static bool IsSimpleLocalOrLiteralNode(AstNode* node) {
1419 if (node->IsLiteralNode()) { 1430 if (node->IsLiteralNode()) {
1420 return true; 1431 return true;
1421 } 1432 }
1422 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { 1433 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) {
1423 return true; 1434 return true;
1424 } 1435 }
1425 return false; 1436 return false;
1426 } 1437 }
1427 1438
1428 1439
1429 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { 1440 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) {
1430 ASSERT(super->IsSuper()); 1441 ASSERT(super->IsSuper());
1431 AstNode* super_op = NULL; 1442 AstNode* super_op = NULL;
1432 const intptr_t super_pos = super->token_pos(); 1443 const intptr_t super_pos = super->token_pos();
1433 if ((op == Token::kNEGATE) || 1444 if ((op == Token::kNEGATE) ||
1434 (op == Token::kBIT_NOT)) { 1445 (op == Token::kBIT_NOT)) {
1435 // Resolve the operator function in the superclass. 1446 // Resolve the operator function in the superclass.
1436 const String& operator_function_name = 1447 const String& operator_function_name =
1437 String::ZoneHandle(Symbols::New(Token::Str(op))); 1448 String::ZoneHandle(Symbols::New(Token::Str(op)));
1449 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos);
1450 AstNode* receiver = LoadReceiver(super_pos);
1451 op_arguments->Add(receiver);
1438 const bool kResolveGetter = false; 1452 const bool kResolveGetter = false;
1439 bool is_no_such_method = false; 1453 bool is_no_such_method = false;
1440 const Function& super_operator = Function::ZoneHandle( 1454 const Function& super_operator = Function::ZoneHandle(
1441 GetSuperFunction(super_pos, 1455 GetSuperFunction(super_pos,
1442 operator_function_name, 1456 operator_function_name,
1457 op_arguments,
1443 kResolveGetter, 1458 kResolveGetter,
1444 &is_no_such_method)); 1459 &is_no_such_method));
1445 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos);
1446 AstNode* receiver = LoadReceiver(super_pos);
1447 op_arguments->Add(receiver);
1448 if (is_no_such_method) { 1460 if (is_no_such_method) {
1449 op_arguments = BuildNoSuchMethodArguments( 1461 op_arguments = BuildNoSuchMethodArguments(
1450 super_pos, operator_function_name, *op_arguments); 1462 super_pos, operator_function_name, *op_arguments);
1451 } 1463 }
1452 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); 1464 super_op = new StaticCallNode(super_pos, super_operator, op_arguments);
1453 } else { 1465 } else {
1454 ErrorMsg(super_pos, "illegal super operator call"); 1466 ErrorMsg(super_pos, "illegal super operator call");
1455 } 1467 }
1456 return super_op; 1468 return super_op;
1457 } 1469 }
(...skipping 17 matching lines...) Expand all
1475 (CurrentToken() == Token::kNE)) { 1487 (CurrentToken() == Token::kNE)) {
1476 Token::Kind op = CurrentToken(); 1488 Token::Kind op = CurrentToken();
1477 ConsumeToken(); 1489 ConsumeToken();
1478 1490
1479 bool negate_result = false; 1491 bool negate_result = false;
1480 if (op == Token::kNE) { 1492 if (op == Token::kNE) {
1481 op = Token::kEQ; 1493 op = Token::kEQ;
1482 negate_result = true; 1494 negate_result = true;
1483 } 1495 }
1484 1496
1485 // Resolve the operator function in the superclass.
1486 const String& operator_function_name =
1487 String::Handle(Symbols::New(Token::Str(op)));
1488 const bool kResolveGetter = false;
1489 bool is_no_such_method = false;
1490 const Function& super_operator = Function::ZoneHandle(
1491 GetSuperFunction(operator_pos,
1492 operator_function_name,
1493 kResolveGetter,
1494 &is_no_such_method));
1495
1496 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); 1497 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR));
1497 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); 1498 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1);
1498 1499
1499 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); 1500 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos);
1500 AstNode* receiver = LoadReceiver(operator_pos); 1501 AstNode* receiver = LoadReceiver(operator_pos);
1501 op_arguments->Add(receiver); 1502 op_arguments->Add(receiver);
1502 op_arguments->Add(other_operand); 1503 op_arguments->Add(other_operand);
1503 1504
1505 // Resolve the operator function in the superclass.
1506 const String& operator_function_name =
1507 String::ZoneHandle(Symbols::New(Token::Str(op)));
1508 const bool kResolveGetter = false;
1509 bool is_no_such_method = false;
1510 const Function& super_operator = Function::ZoneHandle(
1511 GetSuperFunction(operator_pos,
1512 operator_function_name,
1513 op_arguments,
1514 kResolveGetter,
1515 &is_no_such_method));
1504 if (is_no_such_method) { 1516 if (is_no_such_method) {
1505 op_arguments = BuildNoSuchMethodArguments( 1517 op_arguments = BuildNoSuchMethodArguments(
1506 operator_pos, operator_function_name, *op_arguments); 1518 operator_pos, operator_function_name, *op_arguments);
1507 } 1519 }
1508 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); 1520 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
1509 if (negate_result) { 1521 if (negate_result) {
1510 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); 1522 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op);
1511 } 1523 }
1512 } 1524 }
1513 return super_op; 1525 return super_op;
1514 } 1526 }
1515 1527
1516 1528
1517 AstNode* Parser::CreateImplicitClosureNode(const Function& func, 1529 AstNode* Parser::CreateImplicitClosureNode(const Function& func,
1518 intptr_t token_pos, 1530 intptr_t token_pos,
1519 AstNode* receiver) { 1531 AstNode* receiver) {
1520 Function& implicit_closure_function = 1532 Function& implicit_closure_function =
1521 Function::ZoneHandle(func.ImplicitClosureFunction()); 1533 Function::ZoneHandle(func.ImplicitClosureFunction());
1522 if (receiver != NULL) { 1534 if (receiver != NULL) {
1523 // If we create an implicit instance closure from inside a closure of a 1535 // If we create an implicit instance closure from inside a closure of a
1524 // parameterized class, make sure that the receiver is captured as 1536 // parameterized class, make sure that the receiver is captured as
1525 // instantiator. 1537 // instantiator.
1526 if (current_block_->scope->function_level() > 0) { 1538 if (current_block_->scope->function_level() > 0) {
1527 const Class& signature_class = Class::Handle(func.signature_class()); 1539 const Class& signature_class = Class::Handle(
1540 implicit_closure_function.signature_class());
1528 if (signature_class.NumTypeParameters() > 0) { 1541 if (signature_class.NumTypeParameters() > 0) {
1529 CaptureInstantiator(); 1542 CaptureInstantiator();
1530 } 1543 }
1531 } 1544 }
1532 } 1545 }
1533 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); 1546 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL);
1534 } 1547 }
1535 1548
1536 1549
1537 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { 1550 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) {
(...skipping 20 matching lines...) Expand all
1558 field_pos, implicit_argument, true, super_class, field_name); 1571 field_pos, implicit_argument, true, super_class, field_name);
1559 } 1572 }
1560 } 1573 }
1561 if (super_getter.IsNull()) { 1574 if (super_getter.IsNull()) {
1562 // Check if this is an access to an implicit closure using 'super'. 1575 // Check if this is an access to an implicit closure using 'super'.
1563 // If a function exists of the specified field_name then try 1576 // If a function exists of the specified field_name then try
1564 // accessing it as a getter, at runtime we will handle this by 1577 // accessing it as a getter, at runtime we will handle this by
1565 // creating an implicit closure of the function and returning it. 1578 // creating an implicit closure of the function and returning it.
1566 const Function& super_function = Function::ZoneHandle( 1579 const Function& super_function = Function::ZoneHandle(
1567 Resolver::ResolveDynamicAnyArgs(super_class, field_name)); 1580 Resolver::ResolveDynamicAnyArgs(super_class, field_name));
1568 if (super_function.IsNull()) { 1581 if (!super_function.IsNull()) {
1569 ErrorMsg(field_pos, "field or getter '%s' not found in superclass", 1582 // In case CreateAssignmentNode is called later on this
1570 field_name.ToCString()); 1583 // CreateImplicitClosureNode, it will be replaced by a StaticSetterNode.
1584 return CreateImplicitClosureNode(super_function,
1585 field_pos,
1586 implicit_argument);
1571 } 1587 }
1572 return CreateImplicitClosureNode(super_function, 1588 // No function or field exists of the specified field_name.
1573 field_pos, 1589 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called.
1574 implicit_argument);
1575 } 1590 }
1576
1577 return new StaticGetterNode( 1591 return new StaticGetterNode(
1578 field_pos, implicit_argument, true, super_class, field_name); 1592 field_pos, implicit_argument, true, super_class, field_name);
1579 } 1593 }
1580 1594
1581 1595
1582 void Parser::GenerateSuperConstructorCall(const Class& cls, 1596 void Parser::GenerateSuperConstructorCall(const Class& cls,
1583 LocalVariable* receiver) { 1597 LocalVariable* receiver) {
1584 const intptr_t supercall_pos = TokenPos(); 1598 const intptr_t supercall_pos = TokenPos();
1585 const Class& super_class = Class::Handle(cls.SuperClass()); 1599 const Class& super_class = Class::Handle(cls.SuperClass());
1586 // Omit the implicit super() if there is no super class (i.e. 1600 // Omit the implicit super() if there is no super class (i.e.
(...skipping 5282 matching lines...) Expand 10 before | Expand all | Expand 10 after
6869 *expr = right_node; 6883 *expr = right_node;
6870 return left_node; 6884 return left_node;
6871 } 6885 }
6872 return *expr; 6886 return *expr;
6873 } 6887 }
6874 6888
6875 6889
6876 // Ensure that the expression temp is allocated for nodes that may need it. 6890 // Ensure that the expression temp is allocated for nodes that may need it.
6877 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { 6891 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) {
6878 AstNode* result = original->MakeAssignmentNode(rhs); 6892 AstNode* result = original->MakeAssignmentNode(rhs);
6879 if ((result == NULL) && original->IsStaticGetterNode()) {
6880 const String& setter_name = String::ZoneHandle(
6881 Field::SetterSymbol(original->AsStaticGetterNode()->field_name()));
6882 result = ThrowNoSuchMethodError(original->token_pos(), setter_name);
6883 }
6884 // TODO(hausner): if we decide to throw a no such method error on
6885 // assignment to a final variable, we need to do the same as in the
6886 // StaticGetterNode above.
6887 if ((result != NULL) && 6893 if ((result != NULL) &&
6888 (result->IsStoreIndexedNode() || 6894 (result->IsStoreIndexedNode() ||
6889 result->IsInstanceSetterNode() || 6895 result->IsInstanceSetterNode() ||
6890 result->IsStaticSetterNode() || 6896 result->IsStaticSetterNode() ||
6891 result->IsStoreStaticFieldNode() || 6897 result->IsStoreStaticFieldNode() ||
6892 result->IsStoreLocalNode())) { 6898 result->IsStoreLocalNode())) {
6893 EnsureExpressionTemp(); 6899 EnsureExpressionTemp();
6894 } 6900 }
6895 return result; 6901 return result;
6896 } 6902 }
(...skipping 2797 matching lines...) Expand 10 before | Expand all | Expand 10 after
9694 void Parser::SkipQualIdent() { 9700 void Parser::SkipQualIdent() {
9695 ASSERT(IsIdentifier()); 9701 ASSERT(IsIdentifier());
9696 ConsumeToken(); 9702 ConsumeToken();
9697 if (CurrentToken() == Token::kPERIOD) { 9703 if (CurrentToken() == Token::kPERIOD) {
9698 ConsumeToken(); // Consume the kPERIOD token. 9704 ConsumeToken(); // Consume the kPERIOD token.
9699 ExpectIdentifier("identifier expected after '.'"); 9705 ExpectIdentifier("identifier expected after '.'");
9700 } 9706 }
9701 } 9707 }
9702 9708
9703 } // namespace dart 9709 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698