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

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

Issue 11267027: More fixes for super[] (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | tests/co19/co19-dart2dart.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 1388
1389 AstNode* Parser::ParseSuperOperator() { 1389 AstNode* Parser::ParseSuperOperator() {
1390 TRACE_PARSER("ParseSuperOperator"); 1390 TRACE_PARSER("ParseSuperOperator");
1391 AstNode* super_op = NULL; 1391 AstNode* super_op = NULL;
1392 const intptr_t operator_pos = TokenPos(); 1392 const intptr_t operator_pos = TokenPos();
1393 1393
1394 if (CurrentToken() == Token::kLBRACK) { 1394 if (CurrentToken() == Token::kLBRACK) {
1395 ConsumeToken(); 1395 ConsumeToken();
1396 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); 1396 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades);
1397 ExpectToken(Token::kRBRACK); 1397 ExpectToken(Token::kRBRACK);
1398
1399 if (Token::IsAssignmentOperator(CurrentToken()) &&
1400 (CurrentToken() != Token::kASSIGN)) {
1401 // Compound assignment. Ensure side effects in index expression
1402 // only execute once. If the index is not a local variable or an
1403 // literal, evaluate and save in a temporary local.
1404 if (!IsSimpleLocalOrLiteralNode(index_expr)) {
1405 LocalVariable* temp =
1406 CreateTempConstVariable(operator_pos, "lix");
1407 AstNode* save = new StoreLocalNode(operator_pos, temp, index_expr);
1408 current_block_->statements->Add(save);
1409 index_expr = new LoadLocalNode(operator_pos, temp);
1410 }
1411 }
1412
1413 // Resolve the [] operator function in the superclass.
1414 const String& index_operator_name =
1415 String::ZoneHandle(Symbols::IndexToken());
1416 const bool kResolveGetter = false;
1417 bool is_no_such_method = false;
1418 const Function& index_operator = Function::ZoneHandle(
1419 GetSuperFunction(operator_pos,
1420 index_operator_name,
1421 kResolveGetter,
1422 &is_no_such_method));
1423
1424 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos);
1425 AstNode* receiver = LoadReceiver(operator_pos); 1398 AstNode* receiver = LoadReceiver(operator_pos);
1426 index_op_arguments->Add(receiver); 1399 const Class& super_class = Class::ZoneHandle(current_class().SuperClass());
1427 index_op_arguments->Add(index_expr); 1400 ASSERT(!super_class.IsNull());
1428 1401 super_op =
1429 if (is_no_such_method) { 1402 new LoadIndexedNode(operator_pos, receiver, index_expr, super_class);
1430 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name,
1431 *index_op_arguments);
1432 }
1433 super_op = new StaticCallNode(
1434 operator_pos, index_operator, index_op_arguments);
1435
1436 if (Token::IsAssignmentOperator(CurrentToken())) {
1437 Token::Kind assignment_op = CurrentToken();
1438 ConsumeToken();
1439 AstNode* value = ParseExpr(kAllowConst, kConsumeCascades);
1440
1441 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value);
1442
1443 // Resolve the []= operator function in the superclass.
1444 const String& assign_index_operator_name =
1445 String::ZoneHandle(Symbols::AssignIndexToken());
1446 const bool kResolveGetter = false;
1447 bool is_no_such_method = false;
1448 const Function& assign_index_operator = Function::ZoneHandle(
1449 GetSuperFunction(operator_pos,
1450 assign_index_operator_name,
1451 kResolveGetter,
1452 &is_no_such_method));
1453
1454 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos);
1455 operator_args->Add(LoadReceiver(operator_pos));
1456 operator_args->Add(index_expr);
1457 operator_args->Add(value);
1458
1459 if (is_no_such_method) {
1460 operator_args = BuildNoSuchMethodArguments(assign_index_operator_name,
1461 *operator_args);
1462 }
1463 super_op = new StaticCallNode(
1464 operator_pos, assign_index_operator, operator_args);
1465 }
1466 } else if (Token::CanBeOverloaded(CurrentToken()) || 1403 } else if (Token::CanBeOverloaded(CurrentToken()) ||
1467 (CurrentToken() == Token::kNE)) { 1404 (CurrentToken() == Token::kNE)) {
1468 Token::Kind op = CurrentToken(); 1405 Token::Kind op = CurrentToken();
1469 ConsumeToken(); 1406 ConsumeToken();
1470 1407
1471 bool negate_result = false; 1408 bool negate_result = false;
1472 if (op == Token::kNE) { 1409 if (op == Token::kNE) {
1473 op = Token::kEQ; 1410 op = Token::kEQ;
1474 negate_result = true; 1411 negate_result = true;
1475 } 1412 }
(...skipping 5453 matching lines...) Expand 10 before | Expand all | Expand 10 after
6929 if (node->IsLoadIndexedNode()) { 6866 if (node->IsLoadIndexedNode()) {
6930 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); 6867 LoadIndexedNode* left_node = node->AsLoadIndexedNode();
6931 LoadIndexedNode* right_node = left_node; 6868 LoadIndexedNode* right_node = left_node;
6932 intptr_t token_pos = node->token_pos(); 6869 intptr_t token_pos = node->token_pos();
6933 node = NULL; // Do not use it. 6870 node = NULL; // Do not use it.
6934 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { 6871 if (!IsSimpleLocalOrLiteralNode(left_node->array())) {
6935 LocalVariable* temp = 6872 LocalVariable* temp =
6936 CreateTempConstVariable(token_pos, "lia"); 6873 CreateTempConstVariable(token_pos, "lia");
6937 StoreLocalNode* save = 6874 StoreLocalNode* save =
6938 new StoreLocalNode(token_pos, temp, left_node->array()); 6875 new StoreLocalNode(token_pos, temp, left_node->array());
6939 left_node = 6876 left_node = new LoadIndexedNode(token_pos,
6940 new LoadIndexedNode(token_pos, save, left_node->index_expr()); 6877 save,
6878 left_node->index_expr(),
6879 left_node->super_class());
6941 right_node = new LoadIndexedNode(token_pos, 6880 right_node = new LoadIndexedNode(token_pos,
6942 new LoadLocalNode(token_pos, temp), 6881 new LoadLocalNode(token_pos, temp),
6943 right_node->index_expr()); 6882 right_node->index_expr(),
6883 right_node->super_class());
6944 } 6884 }
6945 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { 6885 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) {
6946 LocalVariable* temp = 6886 LocalVariable* temp =
6947 CreateTempConstVariable(token_pos, "lix"); 6887 CreateTempConstVariable(token_pos, "lix");
6948 StoreLocalNode* save = 6888 StoreLocalNode* save =
6949 new StoreLocalNode(token_pos, temp, left_node->index_expr()); 6889 new StoreLocalNode(token_pos, temp, left_node->index_expr());
6950 left_node = new LoadIndexedNode(token_pos, 6890 left_node = new LoadIndexedNode(token_pos,
6951 left_node->array(), 6891 left_node->array(),
6952 save); 6892 save,
6893 left_node->super_class());
6953 right_node = new LoadIndexedNode(token_pos, 6894 right_node = new LoadIndexedNode(token_pos,
6954 right_node->array(), 6895 right_node->array(),
6955 new LoadLocalNode(token_pos, temp)); 6896 new LoadLocalNode(token_pos, temp),
6897 right_node->super_class());
6956 } 6898 }
6957 *expr = right_node; 6899 *expr = right_node;
6958 return left_node; 6900 return left_node;
6959 } 6901 }
6960 if (node->IsInstanceGetterNode()) { 6902 if (node->IsInstanceGetterNode()) {
6961 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); 6903 InstanceGetterNode* left_node = node->AsInstanceGetterNode();
6962 InstanceGetterNode* right_node = left_node; 6904 InstanceGetterNode* right_node = left_node;
6963 intptr_t token_pos = node->token_pos(); 6905 intptr_t token_pos = node->token_pos();
6964 node = NULL; // Do not use it. 6906 node = NULL; // Do not use it.
6965 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { 6907 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) {
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
7506 if (left->IsPrimaryNode()) { 7448 if (left->IsPrimaryNode()) {
7507 PrimaryNode* primary = left->AsPrimaryNode(); 7449 PrimaryNode* primary = left->AsPrimaryNode();
7508 if (primary->primary().IsFunction()) { 7450 if (primary->primary().IsFunction()) {
7509 array = LoadClosure(primary); 7451 array = LoadClosure(primary);
7510 } else if (primary->primary().IsClass()) { 7452 } else if (primary->primary().IsClass()) {
7511 ErrorMsg(bracket_pos, "cannot apply index operator to class"); 7453 ErrorMsg(bracket_pos, "cannot apply index operator to class");
7512 } else { 7454 } else {
7513 UNREACHABLE(); // Internal parser error. 7455 UNREACHABLE(); // Internal parser error.
7514 } 7456 }
7515 } 7457 }
7516 selector = new LoadIndexedNode(bracket_pos, array, index); 7458 selector = new LoadIndexedNode(bracket_pos,
7459 array,
7460 index,
7461 Class::ZoneHandle());
7517 } else if (CurrentToken() == Token::kLPAREN) { 7462 } else if (CurrentToken() == Token::kLPAREN) {
7518 if (left->IsPrimaryNode()) { 7463 if (left->IsPrimaryNode()) {
7519 PrimaryNode* primary = left->AsPrimaryNode(); 7464 PrimaryNode* primary = left->AsPrimaryNode();
7520 const intptr_t primary_pos = primary->token_pos(); 7465 const intptr_t primary_pos = primary->token_pos();
7521 if (primary->primary().IsFunction()) { 7466 if (primary->primary().IsFunction()) {
7522 Function& func = Function::CheckedHandle(primary->primary().raw()); 7467 Function& func = Function::CheckedHandle(primary->primary().raw());
7523 String& func_name = String::ZoneHandle(func.name()); 7468 String& func_name = String::ZoneHandle(func.name());
7524 if (func.is_static()) { 7469 if (func.is_static()) {
7525 // Parse static function call. 7470 // Parse static function call.
7526 Class& cls = Class::Handle(func.Owner()); 7471 Class& cls = Class::Handle(func.Owner());
(...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after
9502 } 9447 }
9503 } else if (CurrentToken() == Token::kLT || 9448 } else if (CurrentToken() == Token::kLT ||
9504 CurrentToken() == Token::kLBRACK || 9449 CurrentToken() == Token::kLBRACK ||
9505 CurrentToken() == Token::kINDEX || 9450 CurrentToken() == Token::kINDEX ||
9506 CurrentToken() == Token::kLBRACE) { 9451 CurrentToken() == Token::kLBRACE) {
9507 primary = ParseCompoundLiteral(); 9452 primary = ParseCompoundLiteral();
9508 } else if (CurrentToken() == Token::kSUPER) { 9453 } else if (CurrentToken() == Token::kSUPER) {
9509 if (current_function().is_static()) { 9454 if (current_function().is_static()) {
9510 ErrorMsg("cannot access superclass from static method"); 9455 ErrorMsg("cannot access superclass from static method");
9511 } 9456 }
9457 if (current_class().SuperClass() == Class::null()) {
9458 ErrorMsg("class '%s' does not have a superclass",
9459 String::Handle(current_class().Name()).ToCString());
9460 }
9512 ConsumeToken(); 9461 ConsumeToken();
9513 if (CurrentToken() == Token::kPERIOD) { 9462 if (CurrentToken() == Token::kPERIOD) {
9514 ConsumeToken(); 9463 ConsumeToken();
9515 const String& ident = *ExpectIdentifier("identifier expected"); 9464 const String& ident = *ExpectIdentifier("identifier expected");
9516 if (CurrentToken() == Token::kLPAREN) { 9465 if (CurrentToken() == Token::kLPAREN) {
9517 primary = ParseSuperCall(ident); 9466 primary = ParseSuperCall(ident);
9518 } else { 9467 } else {
9519 primary = ParseSuperFieldAccess(ident); 9468 primary = ParseSuperFieldAccess(ident);
9520 } 9469 }
9521 } else if ((CurrentToken() == Token::kLBRACK) || 9470 } else if ((CurrentToken() == Token::kLBRACK) ||
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
9839 void Parser::SkipQualIdent() { 9788 void Parser::SkipQualIdent() {
9840 ASSERT(IsIdentifier()); 9789 ASSERT(IsIdentifier());
9841 ConsumeToken(); 9790 ConsumeToken();
9842 if (CurrentToken() == Token::kPERIOD) { 9791 if (CurrentToken() == Token::kPERIOD) {
9843 ConsumeToken(); // Consume the kPERIOD token. 9792 ConsumeToken(); // Consume the kPERIOD token.
9844 ExpectIdentifier("identifier expected after '.'"); 9793 ExpectIdentifier("identifier expected after '.'");
9845 } 9794 }
9846 } 9795 }
9847 9796
9848 } // namespace dart 9797 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | tests/co19/co19-dart2dart.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698