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

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

Issue 1273033007: Fix ??= AST modification (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months 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
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/nullaware_opt_test.dart » ('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 "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 8626 matching lines...) Expand 10 before | Expand all | Expand 10 after
8637 } 8637 }
8638 current_block_->scope->AddVariable(loop_var); 8638 current_block_->scope->AddVariable(loop_var);
8639 loop_var_assignment = new(Z) StoreLocalNode( 8639 loop_var_assignment = new(Z) StoreLocalNode(
8640 loop_var_assignment_pos, loop_var, iterator_current); 8640 loop_var_assignment_pos, loop_var, iterator_current);
8641 } else { 8641 } else {
8642 AstNode* loop_var_primary = 8642 AstNode* loop_var_primary =
8643 ResolveIdent(loop_var_pos, *loop_var_name, false); 8643 ResolveIdent(loop_var_pos, *loop_var_name, false);
8644 ASSERT(!loop_var_primary->IsPrimaryNode()); 8644 ASSERT(!loop_var_primary->IsPrimaryNode());
8645 loop_var_assignment = CreateAssignmentNode(loop_var_primary, 8645 loop_var_assignment = CreateAssignmentNode(loop_var_primary,
8646 iterator_current, 8646 iterator_current,
8647 false,
srdjan 2015/08/11 19:26:10 Add comment /*is_compound */
8647 loop_var_name, 8648 loop_var_name,
8648 loop_var_assignment_pos); 8649 loop_var_assignment_pos);
8649 ASSERT(loop_var_assignment != NULL); 8650 ASSERT(loop_var_assignment != NULL);
8650 } 8651 }
8651 current_block_->statements->Add(loop_var_assignment); 8652 current_block_->statements->Add(loop_var_assignment);
8652 8653
8653 // Now parse the for-in loop statement or block. 8654 // Now parse the for-in loop statement or block.
8654 if (CurrentToken() == Token::kLBRACE) { 8655 if (CurrentToken() == Token::kLBRACE) {
8655 ConsumeToken(); 8656 ConsumeToken();
8656 ParseStatementSequence(); 8657 ParseStatementSequence();
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
8855 } 8856 }
8856 current_block_->scope->AddVariable(loop_var); 8857 current_block_->scope->AddVariable(loop_var);
8857 loop_var_assignment = new(Z) StoreLocalNode( 8858 loop_var_assignment = new(Z) StoreLocalNode(
8858 loop_var_assignment_pos, loop_var, iterator_current); 8859 loop_var_assignment_pos, loop_var, iterator_current);
8859 } else { 8860 } else {
8860 AstNode* loop_var_primary = 8861 AstNode* loop_var_primary =
8861 ResolveIdent(loop_var_pos, *loop_var_name, false); 8862 ResolveIdent(loop_var_pos, *loop_var_name, false);
8862 ASSERT(!loop_var_primary->IsPrimaryNode()); 8863 ASSERT(!loop_var_primary->IsPrimaryNode());
8863 loop_var_assignment = CreateAssignmentNode(loop_var_primary, 8864 loop_var_assignment = CreateAssignmentNode(loop_var_primary,
8864 iterator_current, 8865 iterator_current,
8866 false,
srdjan 2015/08/11 19:26:10 ditto
8865 loop_var_name, 8867 loop_var_name,
8866 loop_var_assignment_pos); 8868 loop_var_assignment_pos);
8867 ASSERT(loop_var_assignment != NULL); 8869 ASSERT(loop_var_assignment != NULL);
8868 } 8870 }
8869 current_block_->statements->Add(loop_var_assignment); 8871 current_block_->statements->Add(loop_var_assignment);
8870 8872
8871 // Now parse the for-in loop statement or block. 8873 // Now parse the for-in loop statement or block.
8872 if (CurrentToken() == Token::kLBRACE) { 8874 if (CurrentToken() == Token::kLBRACE) {
8873 ConsumeToken(); 8875 ConsumeToken();
8874 ParseStatementSequence(); 8876 ParseStatementSequence();
(...skipping 1687 matching lines...) Expand 10 before | Expand all | Expand 10 after
10562 token = CurrentToken(); 10564 token = CurrentToken();
10563 ConsumeToken(); 10565 ConsumeToken();
10564 } 10566 }
10565 ASSERT(TokenPos() == end_pos); 10567 ASSERT(TokenPos() == end_pos);
10566 return Token::IsIdentifier(token) || (token == Token::kRBRACK); 10568 return Token::IsIdentifier(token) || (token == Token::kRBRACK);
10567 } 10569 }
10568 10570
10569 10571
10570 AstNode* Parser::CreateAssignmentNode(AstNode* original, 10572 AstNode* Parser::CreateAssignmentNode(AstNode* original,
10571 AstNode* rhs, 10573 AstNode* rhs,
10574 bool is_compound,
10572 const String* left_ident, 10575 const String* left_ident,
10573 intptr_t left_pos) { 10576 intptr_t left_pos) {
10574 AstNode* result = original->MakeAssignmentNode(rhs); 10577 AstNode* result = original->MakeAssignmentNode(rhs);
10575 if (result == NULL) { 10578 if (result == NULL) {
10576 String& name = String::ZoneHandle(Z); 10579 String& name = String::ZoneHandle(Z);
10577 const Class* target_cls = &current_class(); 10580 const Class* target_cls = &current_class();
10578 if (original->IsTypeNode()) { 10581 if (original->IsTypeNode()) {
10579 name = Symbols::New(original->AsTypeNode()->TypeName()); 10582 name = Symbols::New(original->AsTypeNode()->TypeName());
10580 } else if (original->IsLoadStaticFieldNode()) { 10583 } else if (original->IsLoadStaticFieldNode()) {
10581 name = original->AsLoadStaticFieldNode()->field().name(); 10584 name = original->AsLoadStaticFieldNode()->field().name();
(...skipping 19 matching lines...) Expand all
10601 InvocationMirror::kLocalVar : InvocationMirror::kSetter, 10604 InvocationMirror::kLocalVar : InvocationMirror::kSetter,
10602 NULL)); // No existing function. 10605 NULL)); // No existing function.
10603 result = let_node; 10606 result = let_node;
10604 } 10607 }
10605 // The compound assignment operator a ??= b is different from other 10608 // The compound assignment operator a ??= b is different from other
10606 // a op= b assignments. If a is non-null, the assignment to a must be 10609 // a op= b assignments. If a is non-null, the assignment to a must be
10607 // dropped: 10610 // dropped:
10608 // normally: a op= b ==> a = a op b 10611 // normally: a op= b ==> a = a op b
10609 // however: a ??= b ==> a ?? (a = b) 10612 // however: a ??= b ==> a ?? (a = b)
10610 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) 10613 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b)
10611 if (rhs->IsBinaryOpNode() && 10614 if (is_compound &&
10615 rhs->IsBinaryOpNode() &&
10612 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { 10616 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) {
10613 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); 10617 BinaryOpNode* ifnull = rhs->AsBinaryOpNode();
10614 AstNode* modified_assign = 10618 AstNode* modified_assign =
10615 CreateAssignmentNode(ifnull->left(), 10619 CreateAssignmentNode(original,
10616 ifnull->right(), 10620 ifnull->right(),
10621 false,
srdjan 2015/08/11 19:26:10 ditto
10617 left_ident, 10622 left_ident,
10618 left_pos); 10623 left_pos);
10619 result = new(Z) BinaryOpNode(rhs->token_pos(), 10624 result = new(Z) BinaryOpNode(rhs->token_pos(),
10620 Token::kIFNULL, 10625 Token::kIFNULL,
10621 original, 10626 ifnull->left(),
10622 modified_assign); 10627 modified_assign);
10623 } 10628 }
10624 return result; 10629 return result;
10625 } 10630 }
10626 10631
10627 10632
10628 AstNode* Parser::ParseCascades(AstNode* expr) { 10633 AstNode* Parser::ParseCascades(AstNode* expr) {
10629 intptr_t cascade_pos = TokenPos(); 10634 intptr_t cascade_pos = TokenPos();
10630 LetNode* cascade = new(Z) LetNode(cascade_pos); 10635 LetNode* cascade = new(Z) LetNode(cascade_pos);
10631 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); 10636 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr);
(...skipping 21 matching lines...) Expand all
10653 const intptr_t assignment_pos = TokenPos(); 10658 const intptr_t assignment_pos = TokenPos();
10654 ConsumeToken(); 10659 ConsumeToken();
10655 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); 10660 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades);
10656 if (assignment_op != Token::kASSIGN) { 10661 if (assignment_op != Token::kASSIGN) {
10657 // Compound assignment: store inputs with side effects into 10662 // Compound assignment: store inputs with side effects into
10658 // temporary locals. 10663 // temporary locals.
10659 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 10664 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
10660 right_expr = 10665 right_expr =
10661 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); 10666 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
10662 AstNode* assign_expr = 10667 AstNode* assign_expr =
10663 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); 10668 CreateAssignmentNode(expr, right_expr, true, expr_ident, expr_pos);
srdjan 2015/08/11 19:26:10 comment what true means (and below false). Also at
10664 ASSERT(assign_expr != NULL); 10669 ASSERT(assign_expr != NULL);
10665 let_expr->AddNode(assign_expr); 10670 let_expr->AddNode(assign_expr);
10666 expr = let_expr; 10671 expr = let_expr;
10667 } else { 10672 } else {
10668 right_expr = 10673 right_expr =
10669 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); 10674 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
10670 AstNode* assign_expr = 10675 AstNode* assign_expr =
10671 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); 10676 CreateAssignmentNode(expr, right_expr, false, expr_ident, expr_pos);
10672 ASSERT(assign_expr != NULL); 10677 ASSERT(assign_expr != NULL);
10673 expr = assign_expr; 10678 expr = assign_expr;
10674 } 10679 }
10675 } 10680 }
10676 cascade->AddNode(expr); 10681 cascade->AddNode(expr);
10677 } 10682 }
10678 // The result is an expression with the (side effects of the) cascade 10683 // The result is an expression with the (side effects of the) cascade
10679 // sequence followed by the (value of the) receiver temp variable load. 10684 // sequence followed by the (value of the) receiver temp variable load.
10680 cascade->AddNode(new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); 10685 cascade->AddNode(new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var));
10681 return cascade; 10686 return cascade;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
10766 ReportError(right_expr_pos, 10771 ReportError(right_expr_pos,
10767 "expression is not a valid compile-time constant"); 10772 "expression is not a valid compile-time constant");
10768 } 10773 }
10769 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); 10774 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades);
10770 if (assignment_op != Token::kASSIGN) { 10775 if (assignment_op != Token::kASSIGN) {
10771 // Compound assignment: store inputs with side effects into temp. locals. 10776 // Compound assignment: store inputs with side effects into temp. locals.
10772 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 10777 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
10773 AstNode* assigned_value = 10778 AstNode* assigned_value =
10774 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); 10779 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
10775 AstNode* assign_expr = 10780 AstNode* assign_expr =
10776 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); 10781 CreateAssignmentNode(expr, assigned_value, true, expr_ident, expr_pos);
10777 ASSERT(assign_expr != NULL); 10782 ASSERT(assign_expr != NULL);
10778 let_expr->AddNode(assign_expr); 10783 let_expr->AddNode(assign_expr);
10779 return let_expr; 10784 return let_expr;
10780 } else { 10785 } else {
10781 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); 10786 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr);
10782 AstNode* assign_expr = 10787 AstNode* assign_expr =
10783 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); 10788 CreateAssignmentNode(expr, assigned_value, false, expr_ident, expr_pos);
10784 ASSERT(assign_expr != NULL); 10789 ASSERT(assign_expr != NULL);
10785 return assign_expr; 10790 return assign_expr;
10786 } 10791 }
10787 } 10792 }
10788 10793
10789 10794
10790 LiteralNode* Parser::ParseConstExpr() { 10795 LiteralNode* Parser::ParseConstExpr() {
10791 TRACE_PARSER("ParseConstExpr"); 10796 TRACE_PARSER("ParseConstExpr");
10792 intptr_t expr_pos = TokenPos(); 10797 intptr_t expr_pos = TokenPos();
10793 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); 10798 AstNode* expr = ParseExpr(kRequireConst, kNoCascades);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
10867 } 10872 }
10868 // Is prefix. 10873 // Is prefix.
10869 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 10874 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
10870 Token::Kind binary_op = 10875 Token::Kind binary_op =
10871 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 10876 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
10872 BinaryOpNode* add = new(Z) BinaryOpNode( 10877 BinaryOpNode* add = new(Z) BinaryOpNode(
10873 op_pos, 10878 op_pos,
10874 binary_op, 10879 binary_op,
10875 expr, 10880 expr,
10876 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); 10881 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1))));
10877 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); 10882 AstNode* store =
10883 CreateAssignmentNode(expr, add, true, expr_ident, expr_pos);
10878 ASSERT(store != NULL); 10884 ASSERT(store != NULL);
10879 let_expr->AddNode(store); 10885 let_expr->AddNode(store);
10880 expr = let_expr; 10886 expr = let_expr;
10881 } else { 10887 } else {
10882 expr = ParsePostfixExpr(); 10888 expr = ParsePostfixExpr();
10883 } 10889 }
10884 return expr; 10890 return expr;
10885 } 10891 }
10886 10892
10887 10893
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
11584 // Not prefix. 11590 // Not prefix.
11585 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 11591 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
11586 LocalVariable* temp = let_expr->AddInitializer(expr); 11592 LocalVariable* temp = let_expr->AddInitializer(expr);
11587 Token::Kind binary_op = 11593 Token::Kind binary_op =
11588 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 11594 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
11589 BinaryOpNode* add = new(Z) BinaryOpNode( 11595 BinaryOpNode* add = new(Z) BinaryOpNode(
11590 expr_pos, 11596 expr_pos,
11591 binary_op, 11597 binary_op,
11592 new(Z) LoadLocalNode(expr_pos, temp), 11598 new(Z) LoadLocalNode(expr_pos, temp),
11593 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1)))); 11599 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1))));
11594 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); 11600 AstNode* store =
11601 CreateAssignmentNode(expr, add, true, expr_ident, expr_pos);
11595 ASSERT(store != NULL); 11602 ASSERT(store != NULL);
11596 // The result is a pair of the (side effects of the) store followed by 11603 // The result is a pair of the (side effects of the) store followed by
11597 // the (value of the) initial value temp variable load. 11604 // the (value of the) initial value temp variable load.
11598 let_expr->AddNode(store); 11605 let_expr->AddNode(store);
11599 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp)); 11606 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp));
11600 return let_expr; 11607 return let_expr;
11601 } 11608 }
11602 return expr; 11609 return expr;
11603 } 11610 }
11604 11611
(...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after
14064 void Parser::SkipQualIdent() { 14071 void Parser::SkipQualIdent() {
14065 ASSERT(IsIdentifier()); 14072 ASSERT(IsIdentifier());
14066 ConsumeToken(); 14073 ConsumeToken();
14067 if (CurrentToken() == Token::kPERIOD) { 14074 if (CurrentToken() == Token::kPERIOD) {
14068 ConsumeToken(); // Consume the kPERIOD token. 14075 ConsumeToken(); // Consume the kPERIOD token.
14069 ExpectIdentifier("identifier expected after '.'"); 14076 ExpectIdentifier("identifier expected after '.'");
14070 } 14077 }
14071 } 14078 }
14072 14079
14073 } // namespace dart 14080 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/nullaware_opt_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698