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

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: Address review comments 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 10552 matching lines...) Expand 10 before | Expand all | Expand 10 after
10563 ConsumeToken(); 10563 ConsumeToken();
10564 } 10564 }
10565 ASSERT(TokenPos() == end_pos); 10565 ASSERT(TokenPos() == end_pos);
10566 return Token::IsIdentifier(token) || (token == Token::kRBRACK); 10566 return Token::IsIdentifier(token) || (token == Token::kRBRACK);
10567 } 10567 }
10568 10568
10569 10569
10570 AstNode* Parser::CreateAssignmentNode(AstNode* original, 10570 AstNode* Parser::CreateAssignmentNode(AstNode* original,
10571 AstNode* rhs, 10571 AstNode* rhs,
10572 const String* left_ident, 10572 const String* left_ident,
10573 intptr_t left_pos) { 10573 intptr_t left_pos,
10574 bool is_compound /* = false */) {
10574 AstNode* result = original->MakeAssignmentNode(rhs); 10575 AstNode* result = original->MakeAssignmentNode(rhs);
10575 if (result == NULL) { 10576 if (result == NULL) {
10576 String& name = String::ZoneHandle(Z); 10577 String& name = String::ZoneHandle(Z);
10577 const Class* target_cls = &current_class(); 10578 const Class* target_cls = &current_class();
10578 if (original->IsTypeNode()) { 10579 if (original->IsTypeNode()) {
10579 name = Symbols::New(original->AsTypeNode()->TypeName()); 10580 name = Symbols::New(original->AsTypeNode()->TypeName());
10580 } else if (original->IsLoadStaticFieldNode()) { 10581 } else if (original->IsLoadStaticFieldNode()) {
10581 name = original->AsLoadStaticFieldNode()->field().name(); 10582 name = original->AsLoadStaticFieldNode()->field().name();
10582 target_cls = &Class::Handle(Z, 10583 target_cls = &Class::Handle(Z,
10583 original->AsLoadStaticFieldNode()->field().owner()); 10584 original->AsLoadStaticFieldNode()->field().owner());
(...skipping 17 matching lines...) Expand all
10601 InvocationMirror::kLocalVar : InvocationMirror::kSetter, 10602 InvocationMirror::kLocalVar : InvocationMirror::kSetter,
10602 NULL)); // No existing function. 10603 NULL)); // No existing function.
10603 result = let_node; 10604 result = let_node;
10604 } 10605 }
10605 // The compound assignment operator a ??= b is different from other 10606 // 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 10607 // a op= b assignments. If a is non-null, the assignment to a must be
10607 // dropped: 10608 // dropped:
10608 // normally: a op= b ==> a = a op b 10609 // normally: a op= b ==> a = a op b
10609 // however: a ??= b ==> a ?? (a = b) 10610 // however: a ??= b ==> a ?? (a = b)
10610 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) 10611 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b)
10611 if (rhs->IsBinaryOpNode() && 10612 if (is_compound &&
10613 rhs->IsBinaryOpNode() &&
10612 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { 10614 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) {
10613 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); 10615 BinaryOpNode* ifnull = rhs->AsBinaryOpNode();
10614 AstNode* modified_assign = 10616 AstNode* modified_assign =
10615 CreateAssignmentNode(ifnull->left(), 10617 CreateAssignmentNode(original,
10616 ifnull->right(), 10618 ifnull->right(),
10617 left_ident, 10619 left_ident,
10618 left_pos); 10620 left_pos);
10619 result = new(Z) BinaryOpNode(rhs->token_pos(), 10621 result = new(Z) BinaryOpNode(rhs->token_pos(),
10620 Token::kIFNULL, 10622 Token::kIFNULL,
10621 original, 10623 ifnull->left(),
10622 modified_assign); 10624 modified_assign);
10623 } 10625 }
10624 return result; 10626 return result;
10625 } 10627 }
10626 10628
10627 10629
10628 AstNode* Parser::ParseCascades(AstNode* expr) { 10630 AstNode* Parser::ParseCascades(AstNode* expr) {
10629 intptr_t cascade_pos = TokenPos(); 10631 intptr_t cascade_pos = TokenPos();
10630 LetNode* cascade = new(Z) LetNode(cascade_pos); 10632 LetNode* cascade = new(Z) LetNode(cascade_pos);
10631 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); 10633 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr);
(...skipping 21 matching lines...) Expand all
10653 const intptr_t assignment_pos = TokenPos(); 10655 const intptr_t assignment_pos = TokenPos();
10654 ConsumeToken(); 10656 ConsumeToken();
10655 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); 10657 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades);
10656 if (assignment_op != Token::kASSIGN) { 10658 if (assignment_op != Token::kASSIGN) {
10657 // Compound assignment: store inputs with side effects into 10659 // Compound assignment: store inputs with side effects into
10658 // temporary locals. 10660 // temporary locals.
10659 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 10661 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
10660 right_expr = 10662 right_expr =
10661 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); 10663 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
10662 AstNode* assign_expr = 10664 AstNode* assign_expr =
10663 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); 10665 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos, true);
10664 ASSERT(assign_expr != NULL); 10666 ASSERT(assign_expr != NULL);
10665 let_expr->AddNode(assign_expr); 10667 let_expr->AddNode(assign_expr);
10666 expr = let_expr; 10668 expr = let_expr;
10667 } else { 10669 } else {
10668 right_expr = 10670 right_expr =
10669 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); 10671 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
10670 AstNode* assign_expr = 10672 AstNode* assign_expr =
10671 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); 10673 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos);
10672 ASSERT(assign_expr != NULL); 10674 ASSERT(assign_expr != NULL);
10673 expr = assign_expr; 10675 expr = assign_expr;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
10766 ReportError(right_expr_pos, 10768 ReportError(right_expr_pos,
10767 "expression is not a valid compile-time constant"); 10769 "expression is not a valid compile-time constant");
10768 } 10770 }
10769 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); 10771 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades);
10770 if (assignment_op != Token::kASSIGN) { 10772 if (assignment_op != Token::kASSIGN) {
10771 // Compound assignment: store inputs with side effects into temp. locals. 10773 // Compound assignment: store inputs with side effects into temp. locals.
10772 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 10774 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
10773 AstNode* assigned_value = 10775 AstNode* assigned_value =
10774 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); 10776 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr);
10775 AstNode* assign_expr = 10777 AstNode* assign_expr =
10776 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); 10778 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos, true);
10777 ASSERT(assign_expr != NULL); 10779 ASSERT(assign_expr != NULL);
10778 let_expr->AddNode(assign_expr); 10780 let_expr->AddNode(assign_expr);
10779 return let_expr; 10781 return let_expr;
10780 } else { 10782 } else {
10781 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); 10783 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr);
10782 AstNode* assign_expr = 10784 AstNode* assign_expr =
10783 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); 10785 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos);
10784 ASSERT(assign_expr != NULL); 10786 ASSERT(assign_expr != NULL);
10785 return assign_expr; 10787 return assign_expr;
10786 } 10788 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
10867 } 10869 }
10868 // Is prefix. 10870 // Is prefix.
10869 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 10871 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
10870 Token::Kind binary_op = 10872 Token::Kind binary_op =
10871 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 10873 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
10872 BinaryOpNode* add = new(Z) BinaryOpNode( 10874 BinaryOpNode* add = new(Z) BinaryOpNode(
10873 op_pos, 10875 op_pos,
10874 binary_op, 10876 binary_op,
10875 expr, 10877 expr,
10876 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); 10878 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1))));
10877 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); 10879 AstNode* store =
10880 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true);
10878 ASSERT(store != NULL); 10881 ASSERT(store != NULL);
10879 let_expr->AddNode(store); 10882 let_expr->AddNode(store);
10880 expr = let_expr; 10883 expr = let_expr;
10881 } else { 10884 } else {
10882 expr = ParsePostfixExpr(); 10885 expr = ParsePostfixExpr();
10883 } 10886 }
10884 return expr; 10887 return expr;
10885 } 10888 }
10886 10889
10887 10890
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
11584 // Not prefix. 11587 // Not prefix.
11585 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 11588 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
11586 LocalVariable* temp = let_expr->AddInitializer(expr); 11589 LocalVariable* temp = let_expr->AddInitializer(expr);
11587 Token::Kind binary_op = 11590 Token::Kind binary_op =
11588 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 11591 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
11589 BinaryOpNode* add = new(Z) BinaryOpNode( 11592 BinaryOpNode* add = new(Z) BinaryOpNode(
11590 expr_pos, 11593 expr_pos,
11591 binary_op, 11594 binary_op,
11592 new(Z) LoadLocalNode(expr_pos, temp), 11595 new(Z) LoadLocalNode(expr_pos, temp),
11593 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1)))); 11596 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1))));
11594 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); 11597 AstNode* store =
11598 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true);
11595 ASSERT(store != NULL); 11599 ASSERT(store != NULL);
11596 // The result is a pair of the (side effects of the) store followed by 11600 // The result is a pair of the (side effects of the) store followed by
11597 // the (value of the) initial value temp variable load. 11601 // the (value of the) initial value temp variable load.
11598 let_expr->AddNode(store); 11602 let_expr->AddNode(store);
11599 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp)); 11603 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp));
11600 return let_expr; 11604 return let_expr;
11601 } 11605 }
11602 return expr; 11606 return expr;
11603 } 11607 }
11604 11608
(...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after
14064 void Parser::SkipQualIdent() { 14068 void Parser::SkipQualIdent() {
14065 ASSERT(IsIdentifier()); 14069 ASSERT(IsIdentifier());
14066 ConsumeToken(); 14070 ConsumeToken();
14067 if (CurrentToken() == Token::kPERIOD) { 14071 if (CurrentToken() == Token::kPERIOD) {
14068 ConsumeToken(); // Consume the kPERIOD token. 14072 ConsumeToken(); // Consume the kPERIOD token.
14069 ExpectIdentifier("identifier expected after '.'"); 14073 ExpectIdentifier("identifier expected after '.'");
14070 } 14074 }
14071 } 14075 }
14072 14076
14073 } // namespace dart 14077 } // 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