Chromium Code Reviews| 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 "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 2960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2971 // is the "super call" and is implicitly at the end of the | 2971 // is the "super call" and is implicitly at the end of the |
| 2972 // initializer list. | 2972 // initializer list. |
| 2973 ASSERT(!is_redirecting_constructor); | 2973 ASSERT(!is_redirecting_constructor); |
| 2974 ArgumentListNode* ctor_args = super_call->arguments(); | 2974 ArgumentListNode* ctor_args = super_call->arguments(); |
| 2975 // The super initializer call has at least 2 arguments: the | 2975 // The super initializer call has at least 2 arguments: the |
| 2976 // implicit receiver, and the hidden construction phase. | 2976 // implicit receiver, and the hidden construction phase. |
| 2977 ASSERT(ctor_args->length() >= 2); | 2977 ASSERT(ctor_args->length() >= 2); |
| 2978 for (int i = 2; i < ctor_args->length(); i++) { | 2978 for (int i = 2; i < ctor_args->length(); i++) { |
| 2979 AstNode* arg = ctor_args->NodeAt(i); | 2979 AstNode* arg = ctor_args->NodeAt(i); |
| 2980 if (!IsSimpleLocalOrLiteralNode(arg)) { | 2980 if (!IsSimpleLocalOrLiteralNode(arg)) { |
| 2981 LocalVariable* temp = | 2981 LocalVariable* temp = CreateTempConstVariable(arg->token_pos(), "sca"); |
| 2982 CreateTempConstVariable(arg->token_pos(), "sca"); | |
| 2983 AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg); | 2982 AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg); |
| 2984 ctor_args->SetNodeAt(i, save_temp); | 2983 ctor_args->SetNodeAt(i, save_temp); |
| 2985 } | 2984 } |
| 2986 } | 2985 } |
| 2987 } | 2986 } |
| 2988 OpenBlock(); // Block to collect constructor body nodes. | 2987 OpenBlock(); // Block to collect constructor body nodes. |
| 2989 intptr_t body_pos = TokenPos(); | 2988 intptr_t body_pos = TokenPos(); |
| 2990 | 2989 |
| 2991 // Insert the implicit super call to the super constructor body. | 2990 // Insert the implicit super call to the super constructor body. |
| 2992 if (super_call != NULL) { | 2991 if (super_call != NULL) { |
| (...skipping 4129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7122 // outermost enclosing function. | 7121 // outermost enclosing function. |
| 7123 const bool kTestOnly = false; | 7122 const bool kTestOnly = false; |
| 7124 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 7123 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| 7125 if (receiver == NULL) { | 7124 if (receiver == NULL) { |
| 7126 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 7125 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
| 7127 } | 7126 } |
| 7128 return new(Z) LoadLocalNode(TokenPos(), receiver); | 7127 return new(Z) LoadLocalNode(TokenPos(), receiver); |
| 7129 } | 7128 } |
| 7130 | 7129 |
| 7131 | 7130 |
| 7132 AstNode* Parser::CallGetter(intptr_t token_pos, | 7131 InstanceGetterNode* Parser::CallGetter(intptr_t token_pos, |
| 7133 AstNode* object, | 7132 AstNode* object, |
| 7134 const String& name) { | 7133 const String& name) { |
|
srdjan
2015/06/17 18:15:36
Fix indentation.
hausner
2015/06/17 22:24:57
Done.
| |
| 7135 return new(Z) InstanceGetterNode(token_pos, object, name); | 7134 return new(Z) InstanceGetterNode(token_pos, object, name); |
| 7136 } | 7135 } |
| 7137 | 7136 |
| 7138 | 7137 |
| 7139 // Returns ast nodes of the variable initialization. | 7138 // Returns ast nodes of the variable initialization. |
| 7140 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 7139 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
| 7141 bool is_final, | 7140 bool is_final, |
| 7142 bool is_const, | 7141 bool is_const, |
| 7143 SequenceNode** await_preamble) { | 7142 SequenceNode** await_preamble) { |
| 7144 TRACE_PARSER("ParseVariableDeclaration"); | 7143 TRACE_PARSER("ParseVariableDeclaration"); |
| (...skipping 2982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10127 arguments->Add(new(Z) LiteralNode(call_pos, array)); | 10126 arguments->Add(new(Z) LiteralNode(call_pos, array)); |
| 10128 | 10127 |
| 10129 return MakeStaticCall(Symbols::NoSuchMethodError(), | 10128 return MakeStaticCall(Symbols::NoSuchMethodError(), |
| 10130 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 10129 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 10131 arguments); | 10130 arguments); |
| 10132 } | 10131 } |
| 10133 | 10132 |
| 10134 | 10133 |
| 10135 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 10134 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
| 10136 TRACE_PARSER("ParseBinaryExpr"); | 10135 TRACE_PARSER("ParseBinaryExpr"); |
| 10137 ASSERT(min_preced >= Token::Precedence(Token::kOR)); | 10136 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
| 10138 AstNode* left_operand = ParseUnaryExpr(); | 10137 AstNode* left_operand = ParseUnaryExpr(); |
| 10139 if (left_operand->IsPrimaryNode() && | 10138 if (left_operand->IsPrimaryNode() && |
| 10140 (left_operand->AsPrimaryNode()->IsSuper())) { | 10139 (left_operand->AsPrimaryNode()->IsSuper())) { |
| 10141 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10140 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
| 10142 } | 10141 } |
| 10143 int current_preced = Token::Precedence(CurrentToken()); | 10142 int current_preced = Token::Precedence(CurrentToken()); |
| 10144 while (current_preced >= min_preced) { | 10143 while (current_preced >= min_preced) { |
| 10145 while (Token::Precedence(CurrentToken()) == current_preced) { | 10144 while (Token::Precedence(CurrentToken()) == current_preced) { |
| 10146 Token::Kind op_kind = CurrentToken(); | 10145 Token::Kind op_kind = CurrentToken(); |
| 10147 const intptr_t op_pos = TokenPos(); | 10146 const intptr_t op_pos = TokenPos(); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 10177 let->AddNode(left_operand); | 10176 let->AddNode(left_operand); |
| 10178 let->AddNode(ThrowTypeError(type_pos, type)); | 10177 let->AddNode(ThrowTypeError(type_pos, type)); |
| 10179 left_operand = let; | 10178 left_operand = let; |
| 10180 break; // Type checks and casts can't be chained. | 10179 break; // Type checks and casts can't be chained. |
| 10181 } | 10180 } |
| 10182 } | 10181 } |
| 10183 if (Token::IsRelationalOperator(op_kind) | 10182 if (Token::IsRelationalOperator(op_kind) |
| 10184 || Token::IsTypeTestOperator(op_kind) | 10183 || Token::IsTypeTestOperator(op_kind) |
| 10185 || Token::IsTypeCastOperator(op_kind) | 10184 || Token::IsTypeCastOperator(op_kind) |
| 10186 || Token::IsEqualityOperator(op_kind)) { | 10185 || Token::IsEqualityOperator(op_kind)) { |
| 10187 if (Token::IsTypeTestOperator(op_kind) || | |
| 10188 Token::IsTypeCastOperator(op_kind)) { | |
| 10189 if (!right_operand->AsTypeNode()->type().IsInstantiated()) { | |
| 10190 EnsureExpressionTemp(); | |
| 10191 } | |
| 10192 } | |
| 10193 left_operand = new(Z) ComparisonNode( | 10186 left_operand = new(Z) ComparisonNode( |
| 10194 op_pos, op_kind, left_operand, right_operand); | 10187 op_pos, op_kind, left_operand, right_operand); |
| 10195 break; // Equality and relational operators cannot be chained. | 10188 break; // Equality and relational operators cannot be chained. |
| 10196 } else { | 10189 } else { |
| 10197 left_operand = OptimizeBinaryOpNode( | 10190 left_operand = OptimizeBinaryOpNode( |
| 10198 op_pos, op_kind, left_operand, right_operand); | 10191 op_pos, op_kind, left_operand, right_operand); |
| 10199 } | 10192 } |
| 10200 } | 10193 } |
| 10201 current_preced--; | 10194 current_preced--; |
| 10202 } | 10195 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10265 rhs_literal->literal().IsDouble()) { | 10258 rhs_literal->literal().IsDouble()) { |
| 10266 double left_double = Double::Cast(lhs_literal->literal()).value(); | 10259 double left_double = Double::Cast(lhs_literal->literal()).value(); |
| 10267 double right_double = Double::Cast(rhs_literal->literal()).value(); | 10260 double right_double = Double::Cast(rhs_literal->literal()).value(); |
| 10268 if (binary_op == Token::kDIV) { | 10261 if (binary_op == Token::kDIV) { |
| 10269 const Double& dbl_obj = Double::ZoneHandle(Z, | 10262 const Double& dbl_obj = Double::ZoneHandle(Z, |
| 10270 Double::NewCanonical((left_double / right_double))); | 10263 Double::NewCanonical((left_double / right_double))); |
| 10271 return new(Z) LiteralNode(op_pos, dbl_obj); | 10264 return new(Z) LiteralNode(op_pos, dbl_obj); |
| 10272 } | 10265 } |
| 10273 } | 10266 } |
| 10274 } | 10267 } |
| 10275 if ((binary_op == Token::kAND) || (binary_op == Token::kOR)) { | |
| 10276 EnsureExpressionTemp(); | |
| 10277 } | |
| 10278 if (binary_op == Token::kBIT_AND) { | 10268 if (binary_op == Token::kBIT_AND) { |
| 10279 // Normalize so that rhs is a literal if any is. | 10269 // Normalize so that rhs is a literal if any is. |
| 10280 if ((rhs_literal == NULL) && (lhs_literal != NULL)) { | 10270 if ((rhs_literal == NULL) && (lhs_literal != NULL)) { |
| 10281 // Swap. | 10271 // Swap. |
| 10282 LiteralNode* temp = rhs_literal; | 10272 LiteralNode* temp = rhs_literal; |
| 10283 rhs_literal = lhs_literal; | 10273 rhs_literal = lhs_literal; |
| 10284 lhs_literal = temp; | 10274 lhs_literal = temp; |
| 10285 } | 10275 } |
| 10286 if ((rhs_literal != NULL) && | 10276 if ((rhs_literal != NULL) && |
| 10287 (rhs_literal->literal().IsSmi() || rhs_literal->literal().IsMint())) { | 10277 (rhs_literal->literal().IsSmi() || rhs_literal->literal().IsMint())) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10325 case Token::kASSIGN_SHR: | 10315 case Token::kASSIGN_SHR: |
| 10326 return new(Z) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); | 10316 return new(Z) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); |
| 10327 case Token::kASSIGN_SHL: | 10317 case Token::kASSIGN_SHL: |
| 10328 return new(Z) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); | 10318 return new(Z) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); |
| 10329 case Token::kASSIGN_OR: | 10319 case Token::kASSIGN_OR: |
| 10330 return new(Z) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); | 10320 return new(Z) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); |
| 10331 case Token::kASSIGN_AND: | 10321 case Token::kASSIGN_AND: |
| 10332 return new(Z) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); | 10322 return new(Z) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); |
| 10333 case Token::kASSIGN_XOR: | 10323 case Token::kASSIGN_XOR: |
| 10334 return new(Z) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); | 10324 return new(Z) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); |
| 10325 case Token::kASSIGN_COND: | |
| 10326 return new(Z) BinaryOpNode(op_pos, Token::kIFNULL, lhs, rhs); | |
| 10335 default: | 10327 default: |
| 10336 ReportError(op_pos, | 10328 ReportError(op_pos, |
| 10337 "internal error: ExpandAssignableOp '%s' unimplemented", | 10329 "internal error: ExpandAssignableOp '%s' unimplemented", |
| 10338 Token::Name(assignment_op)); | 10330 Token::Name(assignment_op)); |
| 10339 UNIMPLEMENTED(); | 10331 UNIMPLEMENTED(); |
| 10340 return NULL; | 10332 return NULL; |
| 10341 } | 10333 } |
| 10342 } | 10334 } |
| 10343 | 10335 |
| 10344 | 10336 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10380 return result; | 10372 return result; |
| 10381 } | 10373 } |
| 10382 if (node->IsInstanceGetterNode()) { | 10374 if (node->IsInstanceGetterNode()) { |
| 10383 InstanceGetterNode* getter = node->AsInstanceGetterNode(); | 10375 InstanceGetterNode* getter = node->AsInstanceGetterNode(); |
| 10384 AstNode* receiver = getter->receiver(); | 10376 AstNode* receiver = getter->receiver(); |
| 10385 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { | 10377 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { |
| 10386 LocalVariable* t0 = result->AddInitializer(getter->receiver()); | 10378 LocalVariable* t0 = result->AddInitializer(getter->receiver()); |
| 10387 receiver = new(Z) LoadLocalNode(token_pos, t0); | 10379 receiver = new(Z) LoadLocalNode(token_pos, t0); |
| 10388 } | 10380 } |
| 10389 *expr = new(Z) InstanceGetterNode( | 10381 *expr = new(Z) InstanceGetterNode( |
| 10390 token_pos, receiver, getter->field_name()); | 10382 token_pos, receiver, getter->field_name(), getter->is_conditional()); |
| 10391 return result; | 10383 return result; |
| 10392 } | 10384 } |
| 10393 return result; | 10385 return result; |
| 10394 } | 10386 } |
| 10395 | 10387 |
| 10396 | 10388 |
| 10397 // Check whether the syntax of expression expr is a grammatically legal | 10389 // Check whether the syntax of expression expr is a grammatically legal |
| 10398 // assignable expression. This check is used to detect situations where | 10390 // assignable expression. This check is used to detect situations where |
| 10399 // the expression itself is assignable, but the source is grammatically | 10391 // the expression itself is assignable, but the source is grammatically |
| 10400 // wrong. The AST representation of an expression cannot distinguish | 10392 // wrong. The AST representation of an expression cannot distinguish |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10443 let_node->AddNode(ThrowNoSuchMethodError( | 10435 let_node->AddNode(ThrowNoSuchMethodError( |
| 10444 original->token_pos(), | 10436 original->token_pos(), |
| 10445 *target_cls, | 10437 *target_cls, |
| 10446 String::Handle(Z, Field::SetterName(name)), | 10438 String::Handle(Z, Field::SetterName(name)), |
| 10447 NULL, // No arguments. | 10439 NULL, // No arguments. |
| 10448 InvocationMirror::kStatic, | 10440 InvocationMirror::kStatic, |
| 10449 original->IsLoadLocalNode() ? | 10441 original->IsLoadLocalNode() ? |
| 10450 InvocationMirror::kLocalVar : InvocationMirror::kSetter, | 10442 InvocationMirror::kLocalVar : InvocationMirror::kSetter, |
| 10451 NULL)); // No existing function. | 10443 NULL)); // No existing function. |
| 10452 result = let_node; | 10444 result = let_node; |
| 10453 } else if (result->IsStoreIndexedNode() || | 10445 } |
| 10454 result->IsInstanceSetterNode() || | 10446 // The compound assignment operator a ??= b is different from other |
| 10455 result->IsStaticSetterNode() || | 10447 // a op= b assignments. If a is non-null, the assignment to a must be |
| 10456 result->IsStoreStaticFieldNode() || | 10448 // dropped: |
| 10457 result->IsStoreLocalNode()) { | 10449 // normally: a op= b ==> a = a op b |
| 10458 // Ensure that the expression temp is allocated for nodes that may need it. | 10450 // however: a ??= b ==> a ?? (a = b) |
| 10459 EnsureExpressionTemp(); | 10451 // Therefore, we need to transform a = (a ?? b) into a ?? (a = b) |
| 10452 if (rhs->IsBinaryOpNode() && | |
| 10453 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { | |
| 10454 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); | |
| 10455 AstNode* modified_assign = | |
| 10456 CreateAssignmentNode(ifnull->left(), | |
| 10457 ifnull->right(), | |
| 10458 left_ident, | |
| 10459 left_pos); | |
| 10460 result = new BinaryOpNode(rhs->token_pos(), | |
|
srdjan
2015/06/17 18:15:36
new (Z)
hausner
2015/06/17 22:24:57
Done.
| |
| 10461 Token::kIFNULL, | |
| 10462 original, | |
| 10463 modified_assign); | |
| 10460 } | 10464 } |
| 10461 return result; | 10465 return result; |
| 10462 } | 10466 } |
| 10463 | 10467 |
| 10464 | 10468 |
| 10465 AstNode* Parser::ParseCascades(AstNode* expr) { | 10469 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 10466 intptr_t cascade_pos = TokenPos(); | 10470 intptr_t cascade_pos = TokenPos(); |
| 10467 LetNode* cascade = new(Z) LetNode(cascade_pos); | 10471 LetNode* cascade = new(Z) LetNode(cascade_pos); |
| 10468 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 10472 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
| 10469 while (CurrentToken() == Token::kCASCADE) { | 10473 while (CurrentToken() == Token::kCASCADE) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10631 if (!expr->IsLiteralNode()) { | 10635 if (!expr->IsLiteralNode()) { |
| 10632 ReportError(expr_pos, "expression must be a compile-time constant"); | 10636 ReportError(expr_pos, "expression must be a compile-time constant"); |
| 10633 } | 10637 } |
| 10634 return expr->AsLiteralNode(); | 10638 return expr->AsLiteralNode(); |
| 10635 } | 10639 } |
| 10636 | 10640 |
| 10637 | 10641 |
| 10638 AstNode* Parser::ParseConditionalExpr() { | 10642 AstNode* Parser::ParseConditionalExpr() { |
| 10639 TRACE_PARSER("ParseConditionalExpr"); | 10643 TRACE_PARSER("ParseConditionalExpr"); |
| 10640 const intptr_t expr_pos = TokenPos(); | 10644 const intptr_t expr_pos = TokenPos(); |
| 10641 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); | 10645 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); |
| 10642 if (CurrentToken() == Token::kCONDITIONAL) { | 10646 if (CurrentToken() == Token::kCONDITIONAL) { |
| 10643 EnsureExpressionTemp(); | 10647 EnsureExpressionTemp(); |
| 10644 ConsumeToken(); | 10648 ConsumeToken(); |
| 10645 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 10649 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
| 10646 ExpectToken(Token::kCOLON); | 10650 ExpectToken(Token::kCOLON); |
| 10647 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 10651 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
| 10648 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 10652 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
| 10649 } | 10653 } |
| 10650 return expr; | 10654 return expr; |
| 10651 } | 10655 } |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10838 arguments->NodeAt(0), | 10842 arguments->NodeAt(0), |
| 10839 arguments->NodeAt(1)); | 10843 arguments->NodeAt(1)); |
| 10840 } | 10844 } |
| 10841 } | 10845 } |
| 10842 return new(Z) StaticCallNode(ident_pos, func, arguments); | 10846 return new(Z) StaticCallNode(ident_pos, func, arguments); |
| 10843 } | 10847 } |
| 10844 | 10848 |
| 10845 | 10849 |
| 10846 AstNode* Parser::ParseInstanceCall(AstNode* receiver, | 10850 AstNode* Parser::ParseInstanceCall(AstNode* receiver, |
| 10847 const String& func_name, | 10851 const String& func_name, |
| 10848 intptr_t ident_pos) { | 10852 intptr_t ident_pos, |
| 10853 bool is_conditional) { | |
| 10849 TRACE_PARSER("ParseInstanceCall"); | 10854 TRACE_PARSER("ParseInstanceCall"); |
| 10850 CheckToken(Token::kLPAREN); | 10855 CheckToken(Token::kLPAREN); |
| 10851 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 10856 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 10852 return new(Z) InstanceCallNode(ident_pos, receiver, func_name, arguments); | 10857 return new(Z) InstanceCallNode(ident_pos, |
| 10858 receiver, | |
| 10859 func_name, | |
| 10860 arguments, | |
| 10861 is_conditional); | |
| 10853 } | 10862 } |
| 10854 | 10863 |
| 10855 | 10864 |
| 10856 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 10865 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
| 10857 TRACE_PARSER("ParseClosureCall"); | 10866 TRACE_PARSER("ParseClosureCall"); |
| 10858 const intptr_t call_pos = TokenPos(); | 10867 const intptr_t call_pos = TokenPos(); |
| 10859 ASSERT(CurrentToken() == Token::kLPAREN); | 10868 ASSERT(CurrentToken() == Token::kLPAREN); |
| 10860 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 10869 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 10861 return BuildClosureCall(call_pos, closure, arguments); | 10870 return BuildClosureCall(call_pos, closure, arguments); |
| 10862 } | 10871 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10988 } | 10997 } |
| 10989 UNREACHABLE(); | 10998 UNREACHABLE(); |
| 10990 return NULL; | 10999 return NULL; |
| 10991 } | 11000 } |
| 10992 | 11001 |
| 10993 | 11002 |
| 10994 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 11003 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
| 10995 AstNode* left = primary; | 11004 AstNode* left = primary; |
| 10996 while (true) { | 11005 while (true) { |
| 10997 AstNode* selector = NULL; | 11006 AstNode* selector = NULL; |
| 10998 if (CurrentToken() == Token::kPERIOD) { | 11007 if ((CurrentToken() == Token::kPERIOD) || |
| 11008 (CurrentToken() == Token::kQM_PERIOD)) { | |
| 11009 // Unconditional or conditional property extraction or method call. | |
| 11010 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; | |
| 10999 ConsumeToken(); | 11011 ConsumeToken(); |
| 11000 if (left->IsPrimaryNode()) { | 11012 if (left->IsPrimaryNode()) { |
| 11001 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11013 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 11002 const intptr_t primary_pos = primary_node->token_pos(); | 11014 const intptr_t primary_pos = primary_node->token_pos(); |
| 11003 if (primary_node->primary().IsFunction()) { | 11015 if (primary_node->primary().IsFunction()) { |
| 11004 left = LoadClosure(primary_node); | 11016 left = LoadClosure(primary_node); |
| 11005 } else if (primary_node->primary().IsTypeParameter()) { | 11017 } else if (primary_node->primary().IsTypeParameter()) { |
| 11006 if (ParsingStaticMember()) { | 11018 if (ParsingStaticMember()) { |
| 11007 const String& name = String::ZoneHandle(Z, | 11019 const String& name = String::Handle(Z, |
| 11008 TypeParameter::Cast(primary_node->primary()).name()); | 11020 TypeParameter::Cast(primary_node->primary()).name()); |
| 11009 ReportError(primary_pos, | 11021 ReportError(primary_pos, |
| 11010 "cannot access type parameter '%s' " | 11022 "cannot access type parameter '%s' " |
| 11011 "from static function", | 11023 "from static function", |
| 11012 name.ToCString()); | 11024 name.ToCString()); |
| 11013 } | 11025 } |
| 11014 if (current_block_->scope->function_level() > 0) { | 11026 if (current_block_->scope->function_level() > 0) { |
| 11015 // Make sure that the instantiator is captured. | 11027 // Make sure that the instantiator is captured. |
| 11016 CaptureInstantiator(); | 11028 CaptureInstantiator(); |
| 11017 } | 11029 } |
| 11018 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | 11030 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
| 11019 type_parameter ^= ClassFinalizer::FinalizeType( | 11031 type_parameter ^= ClassFinalizer::FinalizeType( |
| 11020 current_class(), | 11032 current_class(), |
| 11021 TypeParameter::Cast(primary_node->primary()), | 11033 TypeParameter::Cast(primary_node->primary()), |
| 11022 ClassFinalizer::kCanonicalize); | 11034 ClassFinalizer::kCanonicalize); |
| 11023 ASSERT(!type_parameter.IsMalformed()); | 11035 ASSERT(!type_parameter.IsMalformed()); |
| 11024 left = new(Z) TypeNode(primary->token_pos(), type_parameter); | 11036 left = new(Z) TypeNode(primary->token_pos(), type_parameter); |
| 11037 } else if (is_conditional && primary_node->primary().IsClass()) { | |
| 11038 // The left-hand side of ?. is interpreted as an expression | |
| 11039 // of type Type, not as a class literal. | |
| 11040 const Class& type_class = Class::Cast(primary_node->primary()); | |
| 11041 AbstractType& type = Type::ZoneHandle(Z, | |
| 11042 Type::New(type_class, TypeArguments::Handle(Z), | |
| 11043 primary_pos, Heap::kOld)); | |
| 11044 type ^= ClassFinalizer::FinalizeType( | |
| 11045 current_class(), type, ClassFinalizer::kCanonicalize); | |
| 11046 // Type may be malbounded, but not malformed. | |
| 11047 ASSERT(!type.IsMalformed()); | |
| 11048 left = new(Z) TypeNode(primary_pos, type); | |
| 11025 } else { | 11049 } else { |
| 11026 // Super field access handled in ParseSuperFieldAccess(), | 11050 // Super field access handled in ParseSuperFieldAccess(), |
| 11027 // super calls handled in ParseSuperCall(). | 11051 // super calls handled in ParseSuperCall(). |
| 11028 ASSERT(!primary_node->IsSuper()); | 11052 ASSERT(!primary_node->IsSuper()); |
| 11029 left = LoadFieldIfUnresolved(left); | 11053 left = LoadFieldIfUnresolved(left); |
| 11030 } | 11054 } |
| 11031 } | 11055 } |
| 11032 const intptr_t ident_pos = TokenPos(); | 11056 const intptr_t ident_pos = TokenPos(); |
| 11033 String* ident = ExpectIdentifier("identifier expected"); | 11057 String* ident = ExpectIdentifier("identifier expected"); |
| 11034 if (CurrentToken() == Token::kLPAREN) { | 11058 if (CurrentToken() == Token::kLPAREN) { |
| 11035 // Identifier followed by a opening paren: method call. | 11059 // Identifier followed by a opening paren: method call. |
| 11036 if (left->IsPrimaryNode() && | 11060 if (left->IsPrimaryNode() && |
| 11037 left->AsPrimaryNode()->primary().IsClass()) { | 11061 left->AsPrimaryNode()->primary().IsClass()) { |
| 11038 // Static method call prefixed with class name. | 11062 // Static method call prefixed with class name. |
| 11063 ASSERT(!is_conditional); | |
| 11039 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); | 11064 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); |
| 11040 selector = ParseStaticCall(cls, *ident, ident_pos); | 11065 selector = ParseStaticCall(cls, *ident, ident_pos); |
| 11041 } else { | 11066 } else { |
| 11042 selector = ParseInstanceCall(left, *ident, ident_pos); | 11067 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); |
| 11043 } | 11068 } |
| 11044 } else { | 11069 } else { |
| 11045 // Field access. | 11070 // Field access. |
| 11046 Class& cls = Class::Handle(Z); | 11071 Class& cls = Class::Handle(Z); |
| 11047 bool is_deferred = false; | 11072 bool is_deferred = false; |
| 11048 if (left->IsPrimaryNode()) { | 11073 if (left->IsPrimaryNode()) { |
| 11049 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11074 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 11050 if (primary_node->primary().IsClass()) { | 11075 if (primary_node->primary().IsClass()) { |
| 11051 // If the primary node referred to a class we are loading a | 11076 // If the primary node referred to a class we are loading a |
| 11052 // qualified static field. | 11077 // qualified static field. |
| 11053 cls ^= primary_node->primary().raw(); | 11078 cls ^= primary_node->primary().raw(); |
| 11054 is_deferred = primary_node->is_deferred_reference(); | 11079 is_deferred = primary_node->is_deferred_reference(); |
| 11055 } | 11080 } |
| 11056 } | 11081 } |
| 11057 if (cls.IsNull()) { | 11082 if (cls.IsNull()) { |
| 11058 // Instance field access. | 11083 // Instance field access. |
| 11059 selector = CallGetter(ident_pos, left, *ident); | 11084 selector = new(Z) InstanceGetterNode(ident_pos, |
| 11085 left, | |
| 11086 *ident, | |
| 11087 is_conditional); | |
| 11060 } else { | 11088 } else { |
| 11061 // Static field access. | 11089 // Static field access. |
| 11090 ASSERT(!is_conditional); | |
| 11062 selector = GenerateStaticFieldAccess(cls, *ident, ident_pos); | 11091 selector = GenerateStaticFieldAccess(cls, *ident, ident_pos); |
| 11063 ASSERT(selector != NULL); | 11092 ASSERT(selector != NULL); |
| 11064 if (selector->IsLoadStaticFieldNode()) { | 11093 if (selector->IsLoadStaticFieldNode()) { |
| 11065 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); | 11094 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
| 11066 } else if (selector->IsStaticGetterNode()) { | 11095 } else if (selector->IsStaticGetterNode()) { |
| 11067 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); | 11096 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); |
| 11068 } | 11097 } |
| 11069 } | 11098 } |
| 11070 } | 11099 } |
| 11071 } else if (CurrentToken() == Token::kLBRACK) { | 11100 } else if (CurrentToken() == Token::kLBRACK) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11135 } else { | 11164 } else { |
| 11136 // Dynamic function call on implicit "this" parameter. | 11165 // Dynamic function call on implicit "this" parameter. |
| 11137 if (current_function().is_static()) { | 11166 if (current_function().is_static()) { |
| 11138 ReportError(primary_pos, | 11167 ReportError(primary_pos, |
| 11139 "cannot access instance method '%s' " | 11168 "cannot access instance method '%s' " |
| 11140 "from static function", | 11169 "from static function", |
| 11141 func_name.ToCString()); | 11170 func_name.ToCString()); |
| 11142 } | 11171 } |
| 11143 selector = ParseInstanceCall(LoadReceiver(primary_pos), | 11172 selector = ParseInstanceCall(LoadReceiver(primary_pos), |
| 11144 func_name, | 11173 func_name, |
| 11145 primary_pos); | 11174 primary_pos, |
| 11175 false); | |
|
srdjan
2015/06/17 18:15:36
Add comment what 'false' means:
false /* is_c
hausner
2015/06/17 22:24:57
Done.
| |
| 11146 } | 11176 } |
| 11147 } else if (primary_node->primary().IsString()) { | 11177 } else if (primary_node->primary().IsString()) { |
| 11148 // Primary is an unresolved name. | 11178 // Primary is an unresolved name. |
| 11149 if (primary_node->IsSuper()) { | 11179 if (primary_node->IsSuper()) { |
| 11150 ReportError(primary_pos, "illegal use of super"); | 11180 ReportError(primary_pos, "illegal use of super"); |
| 11151 } | 11181 } |
| 11152 String& name = | 11182 String& name = |
| 11153 String::CheckedZoneHandle(primary_node->primary().raw()); | 11183 String::CheckedZoneHandle(primary_node->primary().raw()); |
| 11154 if (current_function().is_static()) { | 11184 if (current_function().is_static()) { |
| 11155 // The static call will be converted to throwing a NSM error. | 11185 // The static call will be converted to throwing a NSM error. |
| 11156 selector = ParseStaticCall(current_class(), name, primary_pos); | 11186 selector = ParseStaticCall(current_class(), name, primary_pos); |
| 11157 } else { | 11187 } else { |
| 11158 // Treat as call to unresolved (instance) method. | 11188 // Treat as call to unresolved (instance) method. |
| 11159 selector = ParseInstanceCall(LoadReceiver(primary_pos), | 11189 selector = ParseInstanceCall(LoadReceiver(primary_pos), |
| 11160 name, | 11190 name, |
| 11161 primary_pos); | 11191 primary_pos, |
| 11192 false); | |
| 11162 } | 11193 } |
| 11163 } else if (primary_node->primary().IsTypeParameter()) { | 11194 } else if (primary_node->primary().IsTypeParameter()) { |
| 11164 const String& name = String::ZoneHandle(Z, | 11195 const String& name = String::ZoneHandle(Z, |
| 11165 TypeParameter::Cast(primary_node->primary()).name()); | 11196 TypeParameter::Cast(primary_node->primary()).name()); |
| 11166 if (ParsingStaticMember()) { | 11197 if (ParsingStaticMember()) { |
| 11167 // Treat as this.T(), because T is in scope. | 11198 // Treat as this.T(), because T is in scope. |
| 11168 ReportError(primary_pos, | 11199 ReportError(primary_pos, |
| 11169 "cannot access type parameter '%s' " | 11200 "cannot access type parameter '%s' " |
| 11170 "from static function", | 11201 "from static function", |
| 11171 name.ToCString()); | 11202 name.ToCString()); |
| 11172 } else { | 11203 } else { |
| 11173 // Treat as call to unresolved (instance) method. | 11204 // Treat as call to unresolved (instance) method. |
| 11174 selector = ParseInstanceCall(LoadReceiver(primary_pos), | 11205 selector = ParseInstanceCall(LoadReceiver(primary_pos), |
| 11175 name, | 11206 name, |
| 11176 primary_pos); | 11207 primary_pos, |
| 11208 false); | |
| 11177 } | 11209 } |
| 11178 } else if (primary_node->primary().IsClass()) { | 11210 } else if (primary_node->primary().IsClass()) { |
| 11179 const Class& type_class = Class::Cast(primary_node->primary()); | 11211 const Class& type_class = Class::Cast(primary_node->primary()); |
| 11180 AbstractType& type = Type::ZoneHandle(Z, Type::New( | 11212 AbstractType& type = Type::ZoneHandle(Z, Type::New( |
| 11181 type_class, TypeArguments::Handle(Z), primary_pos)); | 11213 type_class, TypeArguments::Handle(Z), primary_pos)); |
| 11182 type ^= ClassFinalizer::FinalizeType( | 11214 type ^= ClassFinalizer::FinalizeType( |
| 11183 current_class(), type, ClassFinalizer::kCanonicalize); | 11215 current_class(), type, ClassFinalizer::kCanonicalize); |
| 11184 // Type may be malbounded, but not malformed. | 11216 // Type may be malbounded, but not malformed. |
| 11185 ASSERT(!type.IsMalformed()); | 11217 ASSERT(!type.IsMalformed()); |
| 11186 selector = new(Z) TypeNode(primary_pos, type); | 11218 selector = new(Z) TypeNode(primary_pos, type); |
| (...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13088 const String& ident = *ExpectIdentifier("identifier expected"); | 13120 const String& ident = *ExpectIdentifier("identifier expected"); |
| 13089 if (CurrentToken() == Token::kLPAREN) { | 13121 if (CurrentToken() == Token::kLPAREN) { |
| 13090 primary = ParseSuperCall(ident); | 13122 primary = ParseSuperCall(ident); |
| 13091 } else { | 13123 } else { |
| 13092 primary = ParseSuperFieldAccess(ident, ident_pos); | 13124 primary = ParseSuperFieldAccess(ident, ident_pos); |
| 13093 } | 13125 } |
| 13094 } else if ((CurrentToken() == Token::kLBRACK) || | 13126 } else if ((CurrentToken() == Token::kLBRACK) || |
| 13095 Token::CanBeOverloaded(CurrentToken()) || | 13127 Token::CanBeOverloaded(CurrentToken()) || |
| 13096 (CurrentToken() == Token::kNE)) { | 13128 (CurrentToken() == Token::kNE)) { |
| 13097 primary = ParseSuperOperator(); | 13129 primary = ParseSuperOperator(); |
| 13130 } else if (CurrentToken() == Token::kQM_PERIOD) { | |
| 13131 ReportError("super call or super getter may not use ?."); | |
| 13098 } else { | 13132 } else { |
| 13099 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); | 13133 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); |
| 13100 } | 13134 } |
| 13101 } else { | 13135 } else { |
| 13102 UnexpectedToken(); | 13136 UnexpectedToken(); |
| 13103 } | 13137 } |
| 13104 return primary; | 13138 return primary; |
| 13105 } | 13139 } |
| 13106 | 13140 |
| 13107 | 13141 |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13412 ConsumeToken(); | 13446 ConsumeToken(); |
| 13413 SkipUnaryExpr(); | 13447 SkipUnaryExpr(); |
| 13414 } else { | 13448 } else { |
| 13415 SkipPostfixExpr(); | 13449 SkipPostfixExpr(); |
| 13416 } | 13450 } |
| 13417 } | 13451 } |
| 13418 | 13452 |
| 13419 | 13453 |
| 13420 void Parser::SkipBinaryExpr() { | 13454 void Parser::SkipBinaryExpr() { |
| 13421 SkipUnaryExpr(); | 13455 SkipUnaryExpr(); |
| 13422 const int min_prec = Token::Precedence(Token::kOR); | 13456 const int min_prec = Token::Precedence(Token::kIFNULL); |
| 13423 const int max_prec = Token::Precedence(Token::kMUL); | 13457 const int max_prec = Token::Precedence(Token::kMUL); |
| 13424 while (((min_prec <= Token::Precedence(CurrentToken())) && | 13458 while (((min_prec <= Token::Precedence(CurrentToken())) && |
| 13425 (Token::Precedence(CurrentToken()) <= max_prec))) { | 13459 (Token::Precedence(CurrentToken()) <= max_prec))) { |
| 13426 if (CurrentToken() == Token::kIS) { | 13460 if (CurrentToken() == Token::kIS) { |
| 13427 ConsumeToken(); | 13461 ConsumeToken(); |
| 13428 if (CurrentToken() == Token::kNOT) { | 13462 if (CurrentToken() == Token::kNOT) { |
| 13429 ConsumeToken(); | 13463 ConsumeToken(); |
| 13430 } | 13464 } |
| 13431 SkipType(false); | 13465 SkipType(false); |
| 13432 } else if (CurrentToken() == Token::kAS) { | 13466 } else if (CurrentToken() == Token::kAS) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13476 void Parser::SkipQualIdent() { | 13510 void Parser::SkipQualIdent() { |
| 13477 ASSERT(IsIdentifier()); | 13511 ASSERT(IsIdentifier()); |
| 13478 ConsumeToken(); | 13512 ConsumeToken(); |
| 13479 if (CurrentToken() == Token::kPERIOD) { | 13513 if (CurrentToken() == Token::kPERIOD) { |
| 13480 ConsumeToken(); // Consume the kPERIOD token. | 13514 ConsumeToken(); // Consume the kPERIOD token. |
| 13481 ExpectIdentifier("identifier expected after '.'"); | 13515 ExpectIdentifier("identifier expected after '.'"); |
| 13482 } | 13516 } |
| 13483 } | 13517 } |
| 13484 | 13518 |
| 13485 } // namespace dart | 13519 } // namespace dart |
| OLD | NEW |