OLD | NEW |
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 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1379 if (node->IsLiteralNode()) { | 1379 if (node->IsLiteralNode()) { |
1380 return true; | 1380 return true; |
1381 } | 1381 } |
1382 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { | 1382 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { |
1383 return true; | 1383 return true; |
1384 } | 1384 } |
1385 return false; | 1385 return false; |
1386 } | 1386 } |
1387 | 1387 |
1388 | 1388 |
| 1389 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
| 1390 ASSERT(super->IsSuper()); |
| 1391 AstNode* super_op = NULL; |
| 1392 const intptr_t super_pos = super->token_pos(); |
| 1393 if ((op == Token::kNEGATE) || |
| 1394 (op == Token::kBIT_NOT)) { |
| 1395 // Resolve the operator function in the superclass. |
| 1396 const String& operator_function_name = |
| 1397 String::ZoneHandle(Symbols::New(Token::Str(op))); |
| 1398 const bool kResolveGetter = false; |
| 1399 bool is_no_such_method = false; |
| 1400 const Function& super_operator = Function::ZoneHandle( |
| 1401 GetSuperFunction(super_pos, |
| 1402 operator_function_name, |
| 1403 kResolveGetter, |
| 1404 &is_no_such_method)); |
| 1405 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
| 1406 AstNode* receiver = LoadReceiver(super_pos); |
| 1407 op_arguments->Add(receiver); |
| 1408 CheckFunctionIsCallable(super_pos, super_operator); |
| 1409 if (is_no_such_method) { |
| 1410 op_arguments = BuildNoSuchMethodArguments(operator_function_name, |
| 1411 *op_arguments); |
| 1412 } |
| 1413 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
| 1414 } else { |
| 1415 ErrorMsg(super_pos, "illegal super operator call"); |
| 1416 } |
| 1417 return super_op; |
| 1418 } |
| 1419 |
| 1420 |
1389 AstNode* Parser::ParseSuperOperator() { | 1421 AstNode* Parser::ParseSuperOperator() { |
1390 TRACE_PARSER("ParseSuperOperator"); | 1422 TRACE_PARSER("ParseSuperOperator"); |
1391 AstNode* super_op = NULL; | 1423 AstNode* super_op = NULL; |
1392 const intptr_t operator_pos = TokenPos(); | 1424 const intptr_t operator_pos = TokenPos(); |
1393 | 1425 |
1394 if (CurrentToken() == Token::kLBRACK) { | 1426 if (CurrentToken() == Token::kLBRACK) { |
1395 ConsumeToken(); | 1427 ConsumeToken(); |
1396 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 1428 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
1397 ExpectToken(Token::kRBRACK); | 1429 ExpectToken(Token::kRBRACK); |
1398 AstNode* receiver = LoadReceiver(operator_pos); | 1430 AstNode* receiver = LoadReceiver(operator_pos); |
(...skipping 5251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6650 const String& cls_name = String::Handle(Symbols::NoSuchMethodError()); | 6682 const String& cls_name = String::Handle(Symbols::NoSuchMethodError()); |
6651 const String& func_name = String::Handle(Symbols::ThrowNew()); | 6683 const String& func_name = String::Handle(Symbols::ThrowNew()); |
6652 return MakeStaticCall(cls_name, func_name, arguments); | 6684 return MakeStaticCall(cls_name, func_name, arguments); |
6653 } | 6685 } |
6654 | 6686 |
6655 | 6687 |
6656 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 6688 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
6657 TRACE_PARSER("ParseBinaryExpr"); | 6689 TRACE_PARSER("ParseBinaryExpr"); |
6658 ASSERT(min_preced >= 4); | 6690 ASSERT(min_preced >= 4); |
6659 AstNode* left_operand = ParseUnaryExpr(); | 6691 AstNode* left_operand = ParseUnaryExpr(); |
| 6692 if (left_operand->IsPrimaryNode() && |
| 6693 (left_operand->AsPrimaryNode()->IsSuper())) { |
| 6694 ErrorMsg(left_operand->token_pos(), "illegal use of 'super'"); |
| 6695 } |
6660 if (IsLiteral("as")) { // Not a reserved word. | 6696 if (IsLiteral("as")) { // Not a reserved word. |
6661 token_kind_ = Token::kAS; | 6697 token_kind_ = Token::kAS; |
6662 } | 6698 } |
6663 int current_preced = Token::Precedence(CurrentToken()); | 6699 int current_preced = Token::Precedence(CurrentToken()); |
6664 while (current_preced >= min_preced) { | 6700 while (current_preced >= min_preced) { |
6665 while (Token::Precedence(CurrentToken()) == current_preced) { | 6701 while (Token::Precedence(CurrentToken()) == current_preced) { |
6666 Token::Kind op_kind = CurrentToken(); | 6702 Token::Kind op_kind = CurrentToken(); |
6667 if (op_kind == Token::kTIGHTADD) { | 6703 if (op_kind == Token::kTIGHTADD) { |
6668 op_kind = Token::kADD; | 6704 op_kind = Token::kADD; |
6669 } | 6705 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6713 op_pos, op_kind, left_operand, right_operand); | 6749 op_pos, op_kind, left_operand, right_operand); |
6714 } | 6750 } |
6715 } | 6751 } |
6716 current_preced--; | 6752 current_preced--; |
6717 } | 6753 } |
6718 return left_operand; | 6754 return left_operand; |
6719 } | 6755 } |
6720 | 6756 |
6721 | 6757 |
6722 bool Parser::IsAssignableExpr(AstNode* expr) { | 6758 bool Parser::IsAssignableExpr(AstNode* expr) { |
6723 return expr->IsPrimaryNode() | 6759 return (expr->IsLoadLocalNode() && !expr->AsLoadLocalNode()->HasPseudo()) |
6724 || (expr->IsLoadLocalNode() && !expr->AsLoadLocalNode()->HasPseudo()) | |
6725 || expr->IsLoadStaticFieldNode() | 6760 || expr->IsLoadStaticFieldNode() |
6726 || expr->IsStaticGetterNode() | 6761 || expr->IsStaticGetterNode() |
6727 || expr->IsInstanceGetterNode() | 6762 || expr->IsInstanceGetterNode() |
6728 || expr->IsLoadIndexedNode(); | 6763 || expr->IsLoadIndexedNode() |
| 6764 || (expr->IsPrimaryNode() && !expr->AsPrimaryNode()->IsSuper()); |
6729 } | 6765 } |
6730 | 6766 |
6731 | 6767 |
6732 AstNode* Parser::ParseExprList() { | 6768 AstNode* Parser::ParseExprList() { |
6733 TRACE_PARSER("ParseExprList"); | 6769 TRACE_PARSER("ParseExprList"); |
6734 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); | 6770 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); |
6735 if (CurrentToken() == Token::kCOMMA) { | 6771 if (CurrentToken() == Token::kCOMMA) { |
6736 // Collect comma-separated expressions in a non scope owning sequence node. | 6772 // Collect comma-separated expressions in a non scope owning sequence node. |
6737 SequenceNode* list = new SequenceNode(TokenPos(), NULL); | 6773 SequenceNode* list = new SequenceNode(TokenPos(), NULL); |
6738 list->Add(expressions); | 6774 list->Add(expressions); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7075 unary_op = Token::kNEGATE; | 7111 unary_op = Token::kNEGATE; |
7076 } | 7112 } |
7077 ConsumeToken(); | 7113 ConsumeToken(); |
7078 expr = ParseUnaryExpr(); | 7114 expr = ParseUnaryExpr(); |
7079 if (unary_op == Token::kTIGHTADD) { | 7115 if (unary_op == Token::kTIGHTADD) { |
7080 // kTIGHADD is added only in front of a number literal. | 7116 // kTIGHADD is added only in front of a number literal. |
7081 if (!expr->IsLiteralNode()) { | 7117 if (!expr->IsLiteralNode()) { |
7082 ErrorMsg(op_pos, "unexpected operator '+'"); | 7118 ErrorMsg(op_pos, "unexpected operator '+'"); |
7083 } | 7119 } |
7084 // Expression is the literal itself. | 7120 // Expression is the literal itself. |
| 7121 } else if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { |
| 7122 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); |
7085 } else { | 7123 } else { |
7086 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 7124 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
7087 } | 7125 } |
7088 } else if (IsIncrementOperator(CurrentToken())) { | 7126 } else if (IsIncrementOperator(CurrentToken())) { |
7089 Token::Kind incr_op = CurrentToken(); | 7127 Token::Kind incr_op = CurrentToken(); |
7090 ConsumeToken(); | 7128 ConsumeToken(); |
7091 expr = ParseUnaryExpr(); | 7129 expr = ParseUnaryExpr(); |
7092 if (!IsAssignableExpr(expr)) { | 7130 if (!IsAssignableExpr(expr)) { |
7093 ErrorMsg("expression is not assignable"); | 7131 ErrorMsg("expression is not assignable"); |
7094 } | 7132 } |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7342 return access; | 7380 return access; |
7343 } | 7381 } |
7344 | 7382 |
7345 | 7383 |
7346 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 7384 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
7347 if (!node->IsPrimaryNode()) { | 7385 if (!node->IsPrimaryNode()) { |
7348 return node; | 7386 return node; |
7349 } | 7387 } |
7350 PrimaryNode* primary = node->AsPrimaryNode(); | 7388 PrimaryNode* primary = node->AsPrimaryNode(); |
7351 if (primary->primary().IsString()) { | 7389 if (primary->primary().IsString()) { |
| 7390 if (primary->IsSuper()) { |
| 7391 return primary; |
| 7392 } |
7352 // In a static method, evaluation of an unresolved identifier causes a | 7393 // In a static method, evaluation of an unresolved identifier causes a |
7353 // NoSuchMethodError to be thrown. | 7394 // NoSuchMethodError to be thrown. |
7354 // In an instance method, we convert this into a getter call | 7395 // In an instance method, we convert this into a getter call |
7355 // for a field (which may be defined in a subclass.) | 7396 // for a field (which may be defined in a subclass.) |
7356 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 7397 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
7357 if (current_function().is_static() || | 7398 if (current_function().is_static() || |
7358 current_function().IsInFactoryScope()) { | 7399 current_function().IsInFactoryScope()) { |
7359 return ThrowNoSuchMethodError(primary->token_pos(), name); | 7400 return ThrowNoSuchMethodError(primary->token_pos(), name); |
7360 } else { | 7401 } else { |
7361 AstNode* receiver = LoadReceiver(primary->token_pos()); | 7402 AstNode* receiver = LoadReceiver(primary->token_pos()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7393 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 7434 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
7394 AstNode* left = primary; | 7435 AstNode* left = primary; |
7395 while (true) { | 7436 while (true) { |
7396 AstNode* selector = NULL; | 7437 AstNode* selector = NULL; |
7397 if (CurrentToken() == Token::kPERIOD) { | 7438 if (CurrentToken() == Token::kPERIOD) { |
7398 ConsumeToken(); | 7439 ConsumeToken(); |
7399 if (left->IsPrimaryNode()) { | 7440 if (left->IsPrimaryNode()) { |
7400 if (left->AsPrimaryNode()->primary().IsFunction()) { | 7441 if (left->AsPrimaryNode()->primary().IsFunction()) { |
7401 left = LoadClosure(left->AsPrimaryNode()); | 7442 left = LoadClosure(left->AsPrimaryNode()); |
7402 } else { | 7443 } else { |
| 7444 // Super field access handled in ParseSuperFieldAccess(), |
| 7445 // super calls handled in ParseSuperCall(). |
| 7446 ASSERT(!left->AsPrimaryNode()->IsSuper()); |
7403 left = LoadFieldIfUnresolved(left); | 7447 left = LoadFieldIfUnresolved(left); |
7404 } | 7448 } |
7405 } | 7449 } |
7406 const intptr_t ident_pos = TokenPos(); | 7450 const intptr_t ident_pos = TokenPos(); |
7407 String* ident = ExpectIdentifier("identifier expected"); | 7451 String* ident = ExpectIdentifier("identifier expected"); |
7408 if (CurrentToken() == Token::kLPAREN) { | 7452 if (CurrentToken() == Token::kLPAREN) { |
7409 // Identifier followed by a opening paren: method call. | 7453 // Identifier followed by a opening paren: method call. |
7410 if (left->IsPrimaryNode() | 7454 if (left->IsPrimaryNode() |
7411 && left->AsPrimaryNode()->primary().IsClass()) { | 7455 && left->AsPrimaryNode()->primary().IsClass()) { |
7412 // Static method call prefixed with class name. | 7456 // Static method call prefixed with class name. |
(...skipping 17 matching lines...) Expand all Loading... |
7430 if (cls.IsNull()) { | 7474 if (cls.IsNull()) { |
7431 // Instance field access. | 7475 // Instance field access. |
7432 selector = CallGetter(ident_pos, left, *ident); | 7476 selector = CallGetter(ident_pos, left, *ident); |
7433 } else { | 7477 } else { |
7434 // Static field access. | 7478 // Static field access. |
7435 selector = | 7479 selector = |
7436 ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade); | 7480 ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade); |
7437 } | 7481 } |
7438 } | 7482 } |
7439 } else if (CurrentToken() == Token::kLBRACK) { | 7483 } else if (CurrentToken() == Token::kLBRACK) { |
| 7484 // Super index operator handled in ParseSuperOperator(). |
| 7485 ASSERT(!left->IsPrimaryNode() || !left->AsPrimaryNode()->IsSuper()); |
| 7486 |
7440 const intptr_t bracket_pos = TokenPos(); | 7487 const intptr_t bracket_pos = TokenPos(); |
7441 ConsumeToken(); | 7488 ConsumeToken(); |
7442 left = LoadFieldIfUnresolved(left); | 7489 left = LoadFieldIfUnresolved(left); |
7443 const bool saved_mode = SetAllowFunctionLiterals(true); | 7490 const bool saved_mode = SetAllowFunctionLiterals(true); |
7444 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); | 7491 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); |
7445 SetAllowFunctionLiterals(saved_mode); | 7492 SetAllowFunctionLiterals(saved_mode); |
7446 ExpectToken(Token::kRBRACK); | 7493 ExpectToken(Token::kRBRACK); |
7447 AstNode* array = left; | 7494 AstNode* array = left; |
7448 if (left->IsPrimaryNode()) { | 7495 if (left->IsPrimaryNode()) { |
7449 PrimaryNode* primary = left->AsPrimaryNode(); | 7496 PrimaryNode* primary = left->AsPrimaryNode(); |
(...skipping 25 matching lines...) Expand all Loading... |
7475 if (current_function().is_static()) { | 7522 if (current_function().is_static()) { |
7476 ErrorMsg(primary_pos, | 7523 ErrorMsg(primary_pos, |
7477 "cannot access instance method '%s' " | 7524 "cannot access instance method '%s' " |
7478 "from static function", | 7525 "from static function", |
7479 func_name.ToCString()); | 7526 func_name.ToCString()); |
7480 } | 7527 } |
7481 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); | 7528 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); |
7482 } | 7529 } |
7483 } else if (primary->primary().IsString()) { | 7530 } else if (primary->primary().IsString()) { |
7484 // Primary is an unresolved name. | 7531 // Primary is an unresolved name. |
| 7532 if (primary->IsSuper()) { |
| 7533 ErrorMsg(primary->token_pos(), "illegal use of super"); |
| 7534 } |
7485 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 7535 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
7486 if (current_function().is_static()) { | 7536 if (current_function().is_static()) { |
7487 selector = ThrowNoSuchMethodError(primary->token_pos(), name); | 7537 selector = ThrowNoSuchMethodError(primary->token_pos(), name); |
7488 } else { | 7538 } else { |
7489 // Treat as call to unresolved (instance) method. | 7539 // Treat as call to unresolved (instance) method. |
7490 AstNode* receiver = LoadReceiver(primary->token_pos()); | 7540 AstNode* receiver = LoadReceiver(primary->token_pos()); |
7491 selector = ParseInstanceCall(receiver, name); | 7541 selector = ParseInstanceCall(receiver, name); |
7492 } | 7542 } |
7493 } else if (primary->primary().IsClass()) { | 7543 } else if (primary->primary().IsClass()) { |
7494 ErrorMsg(left->token_pos(), | 7544 ErrorMsg(left->token_pos(), |
(...skipping 14 matching lines...) Expand all Loading... |
7509 if (primary->primary().IsFunction()) { | 7559 if (primary->primary().IsFunction()) { |
7510 // Treat as implicit closure. | 7560 // Treat as implicit closure. |
7511 left = LoadClosure(primary); | 7561 left = LoadClosure(primary); |
7512 } else if (left->AsPrimaryNode()->primary().IsClass()) { | 7562 } else if (left->AsPrimaryNode()->primary().IsClass()) { |
7513 Class& cls = Class::CheckedHandle( | 7563 Class& cls = Class::CheckedHandle( |
7514 left->AsPrimaryNode()->primary().raw()); | 7564 left->AsPrimaryNode()->primary().raw()); |
7515 String& cls_name = String::Handle(cls.Name()); | 7565 String& cls_name = String::Handle(cls.Name()); |
7516 ErrorMsg(left->token_pos(), | 7566 ErrorMsg(left->token_pos(), |
7517 "illegal use of class name '%s'", | 7567 "illegal use of class name '%s'", |
7518 cls_name.ToCString()); | 7568 cls_name.ToCString()); |
| 7569 } else if (primary->IsSuper()) { |
| 7570 // Return "super" to handle unary super operator calls, |
| 7571 // or to report illegal use of "super" otherwise. |
| 7572 left = primary; |
7519 } else { | 7573 } else { |
7520 UNREACHABLE(); // Internal parser error. | 7574 UNREACHABLE(); // Internal parser error. |
7521 } | 7575 } |
7522 } | 7576 } |
7523 // Done parsing selectors. | 7577 // Done parsing selectors. |
7524 return left; | 7578 return left; |
7525 } | 7579 } |
7526 ASSERT(selector != NULL); | 7580 ASSERT(selector != NULL); |
7527 left = selector; | 7581 left = selector; |
7528 } | 7582 } |
(...skipping 1936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9465 if (CurrentToken() == Token::kLPAREN) { | 9519 if (CurrentToken() == Token::kLPAREN) { |
9466 primary = ParseSuperCall(ident); | 9520 primary = ParseSuperCall(ident); |
9467 } else { | 9521 } else { |
9468 primary = ParseSuperFieldAccess(ident); | 9522 primary = ParseSuperFieldAccess(ident); |
9469 } | 9523 } |
9470 } else if ((CurrentToken() == Token::kLBRACK) || | 9524 } else if ((CurrentToken() == Token::kLBRACK) || |
9471 Token::CanBeOverloaded(CurrentToken()) || | 9525 Token::CanBeOverloaded(CurrentToken()) || |
9472 (CurrentToken() == Token::kNE)) { | 9526 (CurrentToken() == Token::kNE)) { |
9473 primary = ParseSuperOperator(); | 9527 primary = ParseSuperOperator(); |
9474 } else { | 9528 } else { |
9475 ErrorMsg("illegal super call"); | 9529 primary = new PrimaryNode(TokenPos(), |
| 9530 String::ZoneHandle(Symbols::Super())); |
9476 } | 9531 } |
9477 } else if (CurrentToken() == Token::kCONDITIONAL) { | 9532 } else if (CurrentToken() == Token::kCONDITIONAL) { |
9478 primary = ParseArgumentDefinitionTest(); | 9533 primary = ParseArgumentDefinitionTest(); |
9479 } else { | 9534 } else { |
9480 UnexpectedToken(); | 9535 UnexpectedToken(); |
9481 } | 9536 } |
9482 return primary; | 9537 return primary; |
9483 } | 9538 } |
9484 | 9539 |
9485 | 9540 |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9788 void Parser::SkipQualIdent() { | 9843 void Parser::SkipQualIdent() { |
9789 ASSERT(IsIdentifier()); | 9844 ASSERT(IsIdentifier()); |
9790 ConsumeToken(); | 9845 ConsumeToken(); |
9791 if (CurrentToken() == Token::kPERIOD) { | 9846 if (CurrentToken() == Token::kPERIOD) { |
9792 ConsumeToken(); // Consume the kPERIOD token. | 9847 ConsumeToken(); // Consume the kPERIOD token. |
9793 ExpectIdentifier("identifier expected after '.'"); | 9848 ExpectIdentifier("identifier expected after '.'"); |
9794 } | 9849 } |
9795 } | 9850 } |
9796 | 9851 |
9797 } // namespace dart | 9852 } // namespace dart |
OLD | NEW |