| 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 6246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6257 new LoadLocalNode(cascade_pos, *cascade_receiver_var); | 6257 new LoadLocalNode(cascade_pos, *cascade_receiver_var); |
| 6258 if (Token::IsIdentifier(LookaheadToken(1))) { | 6258 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 6259 // Replace .. with . for ParseSelectors(). | 6259 // Replace .. with . for ParseSelectors(). |
| 6260 token_kind_ = Token::kPERIOD; | 6260 token_kind_ = Token::kPERIOD; |
| 6261 } else if (LookaheadToken(1) == Token::kLBRACK) { | 6261 } else if (LookaheadToken(1) == Token::kLBRACK) { |
| 6262 ConsumeToken(); | 6262 ConsumeToken(); |
| 6263 } else { | 6263 } else { |
| 6264 ErrorMsg("identifier or [ expected after .."); | 6264 ErrorMsg("identifier or [ expected after .."); |
| 6265 } | 6265 } |
| 6266 expr = ParseSelectors(load_cascade_receiver, true); | 6266 expr = ParseSelectors(load_cascade_receiver, true); |
| 6267 |
| 6268 // Assignments after a cascade are part of the cascade. The |
| 6269 // assigned expression must not contain cascades. |
| 6270 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 6271 Token::Kind assignment_op = CurrentToken(); |
| 6272 const intptr_t assignment_pos = TokenPos(); |
| 6273 ConsumeToken(); |
| 6274 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); |
| 6275 AstNode* left_expr = expr; |
| 6276 if (assignment_op != Token::kASSIGN) { |
| 6277 // Compound assignment: store inputs with side effects into |
| 6278 // temporary locals. |
| 6279 left_expr = PrepareCompoundAssignmentNodes(&expr); |
| 6280 } |
| 6281 right_expr = |
| 6282 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 6283 AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr); |
| 6284 if (assign_expr == NULL) { |
| 6285 ErrorMsg(assignment_pos, |
| 6286 "left hand side of '%s' is not assignable", |
| 6287 Token::Str(assignment_op)); |
| 6288 } |
| 6289 expr = assign_expr; |
| 6290 } |
| 6267 current_block_->statements->Add(expr); | 6291 current_block_->statements->Add(expr); |
| 6268 } | 6292 } |
| 6269 // Result of the cascade is the receiver. | 6293 // Result of the cascade is the receiver. |
| 6270 return new LoadLocalNode(cascade_pos, *cascade_receiver_var); | 6294 return new LoadLocalNode(cascade_pos, *cascade_receiver_var); |
| 6271 } | 6295 } |
| 6272 | 6296 |
| 6273 | 6297 |
| 6274 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 6298 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
| 6275 bool consume_cascades) { | 6299 bool consume_cascades) { |
| 6276 TRACE_PARSER("ParseExpr"); | 6300 TRACE_PARSER("ParseExpr"); |
| 6277 const intptr_t expr_pos = TokenPos(); | 6301 const intptr_t expr_pos = TokenPos(); |
| 6278 AstNode* expr = ParseConditionalExpr(); | 6302 AstNode* expr = ParseConditionalExpr(); |
| 6279 if (!Token::IsAssignmentOperator(CurrentToken())) { | 6303 if (!Token::IsAssignmentOperator(CurrentToken())) { |
| 6280 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { | 6304 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
| 6281 return ParseCascades(expr); | 6305 return ParseCascades(expr); |
| 6282 } | 6306 } |
| 6283 if (require_compiletime_const) { | 6307 if (require_compiletime_const) { |
| 6284 expr = FoldConstExpr(expr_pos, expr); | 6308 expr = FoldConstExpr(expr_pos, expr); |
| 6285 } | 6309 } |
| 6286 return expr; | 6310 return expr; |
| 6287 } | 6311 } |
| 6288 // Assignment expressions. | 6312 // Assignment expressions. |
| 6289 Token::Kind assignment_op = CurrentToken(); | 6313 Token::Kind assignment_op = CurrentToken(); |
| 6290 const intptr_t assignment_pos = TokenPos(); | 6314 const intptr_t assignment_pos = TokenPos(); |
| 6291 ConsumeToken(); | 6315 ConsumeToken(); |
| 6292 const intptr_t right_expr_pos = TokenPos(); | 6316 const intptr_t right_expr_pos = TokenPos(); |
| 6293 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 6317 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 6294 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); | 6318 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); |
| 6295 } | 6319 } |
| 6296 AstNode* right_expr = ParseExpr(require_compiletime_const, kConsumeCascades); | 6320 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 6297 AstNode* left_expr = expr; | 6321 AstNode* left_expr = expr; |
| 6298 if (assignment_op != Token::kASSIGN) { | 6322 if (assignment_op != Token::kASSIGN) { |
| 6299 // Compound assignment: store inputs with side effects into temp. locals. | 6323 // Compound assignment: store inputs with side effects into temp. locals. |
| 6300 left_expr = PrepareCompoundAssignmentNodes(&expr); | 6324 left_expr = PrepareCompoundAssignmentNodes(&expr); |
| 6301 } | 6325 } |
| 6302 right_expr = | 6326 right_expr = |
| 6303 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 6327 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 6304 AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr); | 6328 AstNode* assign_expr = CreateAssignmentNode(left_expr, right_expr); |
| 6305 if (assign_expr == NULL) { | 6329 if (assign_expr == NULL) { |
| 6306 ErrorMsg(assignment_pos, | 6330 ErrorMsg(assignment_pos, |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6510 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 6534 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
| 6511 TRACE_PARSER("ParseClosureCall"); | 6535 TRACE_PARSER("ParseClosureCall"); |
| 6512 const intptr_t call_pos = TokenPos(); | 6536 const intptr_t call_pos = TokenPos(); |
| 6513 ASSERT(CurrentToken() == Token::kLPAREN); | 6537 ASSERT(CurrentToken() == Token::kLPAREN); |
| 6514 EnsureExpressionTemp(); | 6538 EnsureExpressionTemp(); |
| 6515 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 6539 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 6516 return new ClosureCallNode(call_pos, closure, arguments); | 6540 return new ClosureCallNode(call_pos, closure, arguments); |
| 6517 } | 6541 } |
| 6518 | 6542 |
| 6519 | 6543 |
| 6520 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, | |
| 6521 const String& field_name, | |
| 6522 bool consume_cascades) { | |
| 6523 TRACE_PARSER("ParseInstanceFieldAccess"); | |
| 6524 AstNode* access = NULL; | |
| 6525 const intptr_t call_pos = TokenPos(); | |
| 6526 if (Token::IsAssignmentOperator(CurrentToken())) { | |
| 6527 Token::Kind assignment_op = CurrentToken(); | |
| 6528 ConsumeToken(); | |
| 6529 AstNode* value = ParseExpr(kAllowConst, consume_cascades); | |
| 6530 AstNode* load_access = | |
| 6531 new InstanceGetterNode(call_pos, receiver, field_name); | |
| 6532 AstNode* left_load_access = load_access; | |
| 6533 if (assignment_op != Token::kASSIGN) { | |
| 6534 // Compound assignment: store inputs with side effects into temp. locals. | |
| 6535 left_load_access = PrepareCompoundAssignmentNodes(&load_access); | |
| 6536 } | |
| 6537 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); | |
| 6538 access = CreateAssignmentNode(left_load_access, value); | |
| 6539 } else { | |
| 6540 access = CallGetter(call_pos, receiver, field_name); | |
| 6541 } | |
| 6542 return access; | |
| 6543 } | |
| 6544 | |
| 6545 | |
| 6546 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 6544 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
| 6547 intptr_t ident_pos) { | 6545 intptr_t ident_pos) { |
| 6548 // If the static field has an initializer, initialize the field at compile | 6546 // If the static field has an initializer, initialize the field at compile |
| 6549 // time, which is only possible if the field is const. | 6547 // time, which is only possible if the field is const. |
| 6550 AstNode* initializing_getter = RunStaticFieldInitializer(field); | 6548 AstNode* initializing_getter = RunStaticFieldInitializer(field); |
| 6551 if (initializing_getter != NULL) { | 6549 if (initializing_getter != NULL) { |
| 6552 // The field is not yet initialized and could not be initialized at compile | 6550 // The field is not yet initialized and could not be initialized at compile |
| 6553 // time. The getter will initialize the field. | 6551 // time. The getter will initialize the field. |
| 6554 return initializing_getter; | 6552 return initializing_getter; |
| 6555 } | 6553 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 6567 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, | 6565 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, |
| 6568 const String& field_name, | 6566 const String& field_name, |
| 6569 intptr_t ident_pos, | 6567 intptr_t ident_pos, |
| 6570 bool consume_cascades) { | 6568 bool consume_cascades) { |
| 6571 TRACE_PARSER("ParseStaticFieldAccess"); | 6569 TRACE_PARSER("ParseStaticFieldAccess"); |
| 6572 AstNode* access = NULL; | 6570 AstNode* access = NULL; |
| 6573 const intptr_t call_pos = TokenPos(); | 6571 const intptr_t call_pos = TokenPos(); |
| 6574 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); | 6572 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); |
| 6575 Function& func = Function::ZoneHandle(); | 6573 Function& func = Function::ZoneHandle(); |
| 6576 if (Token::IsAssignmentOperator(CurrentToken())) { | 6574 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 6577 Token::Kind assignment_op = CurrentToken(); | 6575 // Make sure an assignment is legal. |
| 6578 if (field.IsNull()) { | 6576 if (field.IsNull()) { |
| 6579 // No field, check if we have an explicit setter function. | 6577 // No field, check if we have an explicit setter function. |
| 6580 const String& setter_name = | 6578 const String& setter_name = |
| 6581 String::ZoneHandle(Field::SetterName(field_name)); | 6579 String::ZoneHandle(Field::SetterName(field_name)); |
| 6582 const int kNumArguments = 1; // value. | 6580 const int kNumArguments = 1; // value. |
| 6583 const Array& kNoArgumentNames = Array::Handle(); | 6581 const Array& kNoArgumentNames = Array::Handle(); |
| 6584 func = Resolver::ResolveStatic(cls, | 6582 func = Resolver::ResolveStatic(cls, |
| 6585 setter_name, | 6583 setter_name, |
| 6586 kNumArguments, | 6584 kNumArguments, |
| 6587 kNoArgumentNames, | 6585 kNoArgumentNames, |
| 6588 Resolver::kIsQualified); | 6586 Resolver::kIsQualified); |
| 6589 if (func.IsNull()) { | 6587 if (func.IsNull()) { |
| 6590 // No field or explicit setter function, this is an error. | 6588 // No field or explicit setter function, this is an error. |
| 6591 ErrorMsg(ident_pos, "unknown static field '%s'", | 6589 ErrorMsg(ident_pos, "unknown static field '%s'", |
| 6592 field_name.ToCString()); | 6590 field_name.ToCString()); |
| 6593 return access; | |
| 6594 } | 6591 } |
| 6595 } | 6592 |
| 6596 ConsumeToken(); | |
| 6597 AstNode* value = ParseExpr(kAllowConst, consume_cascades); | |
| 6598 AstNode* load_access = NULL; | |
| 6599 if (field.IsNull()) { | |
| 6600 // No field found, we must have at least a setter function defined. | |
| 6601 ASSERT(!func.IsNull()); | |
| 6602 // Explicit setter function for the field found, field does not exist. | 6593 // Explicit setter function for the field found, field does not exist. |
| 6603 // Create a getter node first in case it is needed. If getter node | 6594 // Create a getter node first in case it is needed. If getter node |
| 6604 // is used as part of, e.g., "+=", and the explicit getter does not | 6595 // is used as part of, e.g., "+=", and the explicit getter does not |
| 6605 // exist, and error will be reported by the code generator. | 6596 // exist, and error will be reported by the code generator. |
| 6606 load_access = new StaticGetterNode(call_pos, | 6597 access = new StaticGetterNode(call_pos, |
| 6607 NULL, | 6598 NULL, |
| 6608 Class::ZoneHandle(cls.raw()), | 6599 Class::ZoneHandle(cls.raw()), |
| 6609 String::ZoneHandle(field_name.raw())); | 6600 String::ZoneHandle(field_name.raw())); |
| 6610 } else { | 6601 } else { |
| 6611 // Field exists. | 6602 // Field exists. |
| 6612 if (field.is_final()) { | 6603 if (field.is_final()) { |
| 6613 // Field has been marked as final, report an error as the field | 6604 // Field has been marked as final, report an error as the field |
| 6614 // is not settable. | 6605 // is not settable. |
| 6615 ErrorMsg(ident_pos, | 6606 ErrorMsg(ident_pos, |
| 6616 "field '%s' is const static, cannot assign to it", | 6607 "field '%s' is const static, cannot assign to it", |
| 6617 field_name.ToCString()); | 6608 field_name.ToCString()); |
| 6618 return access; | |
| 6619 } | 6609 } |
| 6620 load_access = GenerateStaticFieldLookup(field, TokenPos()); | 6610 access = GenerateStaticFieldLookup(field, TokenPos()); |
| 6621 } | 6611 } |
| 6622 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); | |
| 6623 access = CreateAssignmentNode(load_access, value); | |
| 6624 } else { // Not Token::IsAssignmentOperator(CurrentToken()). | 6612 } else { // Not Token::IsAssignmentOperator(CurrentToken()). |
| 6625 if (field.IsNull()) { | 6613 if (field.IsNull()) { |
| 6626 // No field, check if we have an explicit getter function. | 6614 // No field, check if we have an explicit getter function. |
| 6627 const String& getter_name = | 6615 const String& getter_name = |
| 6628 String::ZoneHandle(Field::GetterName(field_name)); | 6616 String::ZoneHandle(Field::GetterName(field_name)); |
| 6629 const int kNumArguments = 0; // no arguments. | 6617 const int kNumArguments = 0; // no arguments. |
| 6630 const Array& kNoArgumentNames = Array::Handle(); | 6618 const Array& kNoArgumentNames = Array::Handle(); |
| 6631 func = Resolver::ResolveStatic(cls, | 6619 func = Resolver::ResolveStatic(cls, |
| 6632 getter_name, | 6620 getter_name, |
| 6633 kNumArguments, | 6621 kNumArguments, |
| 6634 kNoArgumentNames, | 6622 kNoArgumentNames, |
| 6635 Resolver::kIsQualified); | 6623 Resolver::kIsQualified); |
| 6636 if (func.IsNull()) { | 6624 if (func.IsNull()) { |
| 6637 // We might be referring to an implicit closure, check to see if | 6625 // We might be referring to an implicit closure, check to see if |
| 6638 // there is a function of the same name. | 6626 // there is a function of the same name. |
| 6639 func = cls.LookupStaticFunction(field_name); | 6627 func = cls.LookupStaticFunction(field_name); |
| 6640 if (func.IsNull()) { | 6628 if (func.IsNull()) { |
| 6641 // No field or explicit getter function, this is an error. | 6629 // No field or explicit getter function, this is an error. |
| 6642 ErrorMsg(ident_pos, | 6630 ErrorMsg(ident_pos, |
| 6643 "unknown static field '%s'", field_name.ToCString()); | 6631 "unknown static field '%s'", field_name.ToCString()); |
| 6644 return access; | |
| 6645 } | 6632 } |
| 6646 access = CreateImplicitClosureNode(func, call_pos, NULL); | 6633 access = CreateImplicitClosureNode(func, call_pos, NULL); |
| 6647 } else { | 6634 } else { |
| 6648 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); | 6635 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); |
| 6649 access = new StaticGetterNode(call_pos, | 6636 access = new StaticGetterNode(call_pos, |
| 6650 NULL, | 6637 NULL, |
| 6651 Class::ZoneHandle(cls.raw()), | 6638 Class::ZoneHandle(cls.raw()), |
| 6652 field_name); | 6639 field_name); |
| 6653 } | 6640 } |
| 6654 } else { | 6641 } else { |
| 6655 return GenerateStaticFieldLookup(field, TokenPos()); | 6642 access = GenerateStaticFieldLookup(field, TokenPos()); |
| 6656 } | 6643 } |
| 6657 } | 6644 } |
| 6658 return access; | 6645 return access; |
| 6659 } | 6646 } |
| 6660 | 6647 |
| 6661 | 6648 |
| 6662 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 6649 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
| 6663 if (!node->IsPrimaryNode()) { | 6650 if (!node->IsPrimaryNode()) { |
| 6664 return node; | 6651 return node; |
| 6665 } | 6652 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6739 if (left->IsPrimaryNode()) { | 6726 if (left->IsPrimaryNode()) { |
| 6740 PrimaryNode* primary_node = left->AsPrimaryNode(); | 6727 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 6741 if (primary_node->primary().IsClass()) { | 6728 if (primary_node->primary().IsClass()) { |
| 6742 // If the primary node referred to a class we are loading a | 6729 // If the primary node referred to a class we are loading a |
| 6743 // qualified static field. | 6730 // qualified static field. |
| 6744 cls ^= primary_node->primary().raw(); | 6731 cls ^= primary_node->primary().raw(); |
| 6745 } | 6732 } |
| 6746 } | 6733 } |
| 6747 if (cls.IsNull()) { | 6734 if (cls.IsNull()) { |
| 6748 // Instance field access. | 6735 // Instance field access. |
| 6749 selector = ParseInstanceFieldAccess(left, *ident, !is_cascade); | 6736 selector = CallGetter(ident_pos, left, *ident); |
| 6750 } else { | 6737 } else { |
| 6751 // Static field access. | 6738 // Static field access. |
| 6752 selector = | 6739 selector = |
| 6753 ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade); | 6740 ParseStaticFieldAccess(cls, *ident, ident_pos, !is_cascade); |
| 6754 } | 6741 } |
| 6755 } | 6742 } |
| 6756 } else if (CurrentToken() == Token::kLBRACK) { | 6743 } else if (CurrentToken() == Token::kLBRACK) { |
| 6757 const intptr_t bracket_pos = TokenPos(); | 6744 const intptr_t bracket_pos = TokenPos(); |
| 6758 ConsumeToken(); | 6745 ConsumeToken(); |
| 6759 left = LoadFieldIfUnresolved(left); | 6746 left = LoadFieldIfUnresolved(left); |
| (...skipping 1865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8625 ConsumeToken(); // Handle pseudo-keyword identifiers. | 8612 ConsumeToken(); // Handle pseudo-keyword identifiers. |
| 8626 } else { | 8613 } else { |
| 8627 UnexpectedToken(); | 8614 UnexpectedToken(); |
| 8628 UNREACHABLE(); | 8615 UNREACHABLE(); |
| 8629 } | 8616 } |
| 8630 break; | 8617 break; |
| 8631 } | 8618 } |
| 8632 } | 8619 } |
| 8633 | 8620 |
| 8634 | 8621 |
| 8635 void Parser::SkipPostfixExpr() { | 8622 void Parser::SkipSelectors() { |
| 8636 SkipPrimary(); | |
| 8637 while (true) { | 8623 while (true) { |
| 8638 if (CurrentToken() == Token::kPERIOD) { | 8624 if ((CurrentToken() == Token::kPERIOD) || |
| 8625 (CurrentToken() == Token::kCASCADE)) { |
| 8639 ConsumeToken(); | 8626 ConsumeToken(); |
| 8640 ExpectIdentifier("identifier expected"); | 8627 ExpectIdentifier("identifier expected"); |
| 8641 } else if (CurrentToken() == Token::kLBRACK) { | 8628 } else if (CurrentToken() == Token::kLBRACK) { |
| 8642 ConsumeToken(); | 8629 ConsumeToken(); |
| 8643 SkipNestedExpr(); | 8630 SkipNestedExpr(); |
| 8644 ExpectToken(Token::kRBRACK); | 8631 ExpectToken(Token::kRBRACK); |
| 8645 } else if (CurrentToken() == Token::kLPAREN) { | 8632 } else if (CurrentToken() == Token::kLPAREN) { |
| 8646 SkipActualParameters(); | 8633 SkipActualParameters(); |
| 8647 } else { | 8634 } else { |
| 8648 break; | 8635 break; |
| 8649 } | 8636 } |
| 8650 } | 8637 } |
| 8638 } |
| 8639 |
| 8640 void Parser::SkipPostfixExpr() { |
| 8641 SkipPrimary(); |
| 8642 SkipSelectors(); |
| 8651 if (IsIncrementOperator(CurrentToken())) { | 8643 if (IsIncrementOperator(CurrentToken())) { |
| 8652 ConsumeToken(); | 8644 ConsumeToken(); |
| 8653 } | 8645 } |
| 8654 } | 8646 } |
| 8655 | 8647 |
| 8656 | 8648 |
| 8657 void Parser::SkipUnaryExpr() { | 8649 void Parser::SkipUnaryExpr() { |
| 8658 if (IsPrefixOperator(CurrentToken()) || | 8650 if (IsPrefixOperator(CurrentToken()) || |
| 8659 IsIncrementOperator(CurrentToken())) { | 8651 IsIncrementOperator(CurrentToken())) { |
| 8660 ConsumeToken(); | 8652 ConsumeToken(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 8681 ConsumeToken(); | 8673 ConsumeToken(); |
| 8682 SkipExpr(); | 8674 SkipExpr(); |
| 8683 ExpectToken(Token::kCOLON); | 8675 ExpectToken(Token::kCOLON); |
| 8684 SkipExpr(); | 8676 SkipExpr(); |
| 8685 } | 8677 } |
| 8686 } | 8678 } |
| 8687 | 8679 |
| 8688 | 8680 |
| 8689 void Parser::SkipExpr() { | 8681 void Parser::SkipExpr() { |
| 8690 SkipConditionalExpr(); | 8682 SkipConditionalExpr(); |
| 8683 if (CurrentToken() == Token::kCASCADE) { |
| 8684 SkipSelectors(); |
| 8685 } |
| 8691 if (Token::IsAssignmentOperator(CurrentToken())) { | 8686 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 8692 ConsumeToken(); | 8687 ConsumeToken(); |
| 8693 SkipExpr(); | 8688 SkipExpr(); |
| 8694 } | 8689 } |
| 8695 } | 8690 } |
| 8696 | 8691 |
| 8697 | 8692 |
| 8698 void Parser::SkipNestedExpr() { | 8693 void Parser::SkipNestedExpr() { |
| 8699 const bool saved_mode = SetAllowFunctionLiterals(true); | 8694 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 8700 SkipExpr(); | 8695 SkipExpr(); |
| 8701 SetAllowFunctionLiterals(saved_mode); | 8696 SetAllowFunctionLiterals(saved_mode); |
| 8702 } | 8697 } |
| 8703 | 8698 |
| 8704 | 8699 |
| 8705 void Parser::SkipQualIdent() { | 8700 void Parser::SkipQualIdent() { |
| 8706 ASSERT(IsIdentifier()); | 8701 ASSERT(IsIdentifier()); |
| 8707 ConsumeToken(); | 8702 ConsumeToken(); |
| 8708 if (CurrentToken() == Token::kPERIOD) { | 8703 if (CurrentToken() == Token::kPERIOD) { |
| 8709 ConsumeToken(); // Consume the kPERIOD token. | 8704 ConsumeToken(); // Consume the kPERIOD token. |
| 8710 ExpectIdentifier("identifier expected after '.'"); | 8705 ExpectIdentifier("identifier expected after '.'"); |
| 8711 } | 8706 } |
| 8712 } | 8707 } |
| 8713 | 8708 |
| 8714 } // namespace dart | 8709 } // namespace dart |
| OLD | NEW |