| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 return new LocalVariable(token_pos, | 106 return new LocalVariable(token_pos, |
| 107 String::ZoneHandle(Symbols::ExprTemp()), | 107 String::ZoneHandle(Symbols::ExprTemp()), |
| 108 Type::ZoneHandle(Type::DynamicType())); | 108 Type::ZoneHandle(Type::DynamicType())); |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 112 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
| 113 ASSERT(node_sequence_ == NULL); | 113 ASSERT(node_sequence_ == NULL); |
| 114 ASSERT(node_sequence != NULL); | 114 ASSERT(node_sequence != NULL); |
| 115 node_sequence_ = node_sequence; | 115 node_sequence_ = node_sequence; |
| 116 const int num_fixed_params = function().num_fixed_parameters(); | |
| 117 const int num_opt_params = function().num_optional_parameters(); | |
| 118 // Allocated ids for parameters. | |
| 119 intptr_t parameter_id = AstNode::kNoId; | |
| 120 for (intptr_t i = 0; i < num_fixed_params + num_opt_params; i++) { | |
| 121 parameter_id = AstNode::GetNextId(); | |
| 122 if (i == 0) { | |
| 123 node_sequence_->set_first_parameter_id(parameter_id); | |
| 124 } | |
| 125 } | |
| 126 node_sequence_->set_last_parameter_id(parameter_id); | |
| 127 } | 116 } |
| 128 | 117 |
| 129 | 118 |
| 130 void ParsedFunction::AllocateVariables() { | 119 void ParsedFunction::AllocateVariables() { |
| 131 LocalScope* scope = node_sequence()->scope(); | 120 LocalScope* scope = node_sequence()->scope(); |
| 132 const int fixed_parameter_count = function().num_fixed_parameters(); | 121 const int fixed_parameter_count = function().num_fixed_parameters(); |
| 133 const int optional_parameter_count = function().num_optional_parameters(); | 122 const int optional_parameter_count = function().num_optional_parameters(); |
| 134 const int parameter_count = fixed_parameter_count + optional_parameter_count; | 123 const int parameter_count = fixed_parameter_count + optional_parameter_count; |
| 135 const bool is_native_instance_closure = | 124 const bool is_native_instance_closure = |
| 136 function().is_native() && function().IsImplicitInstanceClosureFunction(); | 125 function().is_native() && function().IsImplicitInstanceClosureFunction(); |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 } else { | 644 } else { |
| 656 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); | 645 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); |
| 657 } | 646 } |
| 658 } | 647 } |
| 659 | 648 |
| 660 | 649 |
| 661 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 650 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
| 662 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 651 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 663 Isolate* isolate = Isolate::Current(); | 652 Isolate* isolate = Isolate::Current(); |
| 664 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 653 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 665 // Compilation can be nested, preserve the ast node id. | |
| 666 const intptr_t prev_ast_node_id = isolate->ast_node_id(); | |
| 667 isolate->set_ast_node_id(0); | |
| 668 ASSERT(parsed_function != NULL); | 654 ASSERT(parsed_function != NULL); |
| 669 const Function& func = parsed_function->function(); | 655 const Function& func = parsed_function->function(); |
| 670 const Class& cls = Class::Handle(isolate, func.owner()); | 656 const Class& cls = Class::Handle(isolate, func.owner()); |
| 671 const Script& script = Script::Handle(isolate, cls.script()); | 657 const Script& script = Script::Handle(isolate, cls.script()); |
| 672 Parser parser(script, func, func.token_pos()); | 658 Parser parser(script, func, func.token_pos()); |
| 673 SequenceNode* node_sequence = NULL; | 659 SequenceNode* node_sequence = NULL; |
| 674 Array& default_parameter_values = Array::Handle(isolate, Array::null()); | 660 Array& default_parameter_values = Array::Handle(isolate, Array::null()); |
| 675 switch (func.kind()) { | 661 switch (func.kind()) { |
| 676 case RawFunction::kRegularFunction: | 662 case RawFunction::kRegularFunction: |
| 677 case RawFunction::kClosureFunction: | 663 case RawFunction::kClosureFunction: |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 instantiator = parser.LookupReceiver(node_sequence->scope(), kTestOnly); | 707 instantiator = parser.LookupReceiver(node_sequence->scope(), kTestOnly); |
| 722 } | 708 } |
| 723 if (!parser.current_function().IsLocalFunction() || | 709 if (!parser.current_function().IsLocalFunction() || |
| 724 ((instantiator != NULL) && instantiator->is_captured())) { | 710 ((instantiator != NULL) && instantiator->is_captured())) { |
| 725 parsed_function->set_instantiator( | 711 parsed_function->set_instantiator( |
| 726 new LoadLocalNode(node_sequence->token_pos(), *instantiator)); | 712 new LoadLocalNode(node_sequence->token_pos(), *instantiator)); |
| 727 } | 713 } |
| 728 } | 714 } |
| 729 | 715 |
| 730 parsed_function->set_default_parameter_values(default_parameter_values); | 716 parsed_function->set_default_parameter_values(default_parameter_values); |
| 731 isolate->set_ast_node_id(prev_ast_node_id); | |
| 732 } | 717 } |
| 733 | 718 |
| 734 | 719 |
| 735 // TODO(regis): Implement support for non-const final static fields (currently | 720 // TODO(regis): Implement support for non-const final static fields (currently |
| 736 // supported "final" fields are actually const fields). | 721 // supported "final" fields are actually const fields). |
| 737 // TODO(regis): Since a const variable is implicitly final, | 722 // TODO(regis): Since a const variable is implicitly final, |
| 738 // rename ParseStaticConstGetter to ParseStaticFinalGetter and | 723 // rename ParseStaticConstGetter to ParseStaticFinalGetter and |
| 739 // rename kConstImplicitGetter to kImplicitFinalGetter. | 724 // rename kConstImplicitGetter to kImplicitFinalGetter. |
| 740 SequenceNode* Parser::ParseStaticConstGetter(const Function& func) { | 725 SequenceNode* Parser::ParseStaticConstGetter(const Function& func) { |
| 741 TRACE_PARSER("ParseStaticConstGetter"); | 726 TRACE_PARSER("ParseStaticConstGetter"); |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 1318 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1334 ExpectToken(Token::kRBRACK); | 1319 ExpectToken(Token::kRBRACK); |
| 1335 | 1320 |
| 1336 if (Token::IsAssignmentOperator(CurrentToken()) && | 1321 if (Token::IsAssignmentOperator(CurrentToken()) && |
| 1337 (CurrentToken() != Token::kASSIGN)) { | 1322 (CurrentToken() != Token::kASSIGN)) { |
| 1338 // Compound assignment. Ensure side effects in index expression | 1323 // Compound assignment. Ensure side effects in index expression |
| 1339 // only execute once. If the index is not a local variable or an | 1324 // only execute once. If the index is not a local variable or an |
| 1340 // literal, evaluate and save in a temporary local. | 1325 // literal, evaluate and save in a temporary local. |
| 1341 if (!IsSimpleLocalOrLiteralNode(index_expr)) { | 1326 if (!IsSimpleLocalOrLiteralNode(index_expr)) { |
| 1342 LocalVariable* temp = | 1327 LocalVariable* temp = |
| 1343 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); | 1328 CreateTempConstVariable(operator_pos, "lix"); |
| 1344 AstNode* save = | 1329 AstNode* save = |
| 1345 new StoreLocalNode(operator_pos, *temp, index_expr); | 1330 new StoreLocalNode(operator_pos, *temp, index_expr); |
| 1346 current_block_->statements->Add(save); | 1331 current_block_->statements->Add(save); |
| 1347 index_expr = new LoadLocalNode(operator_pos, *temp); | 1332 index_expr = new LoadLocalNode(operator_pos, *temp); |
| 1348 } | 1333 } |
| 1349 } | 1334 } |
| 1350 | 1335 |
| 1351 // Resolve the [] operator function in the superclass. | 1336 // Resolve the [] operator function in the superclass. |
| 1352 const String& index_operator_name = | 1337 const String& index_operator_name = |
| 1353 String::ZoneHandle(Symbols::IndexToken()); | 1338 String::ZoneHandle(Symbols::IndexToken()); |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2030 // The temporary variables are necessary so that the argument | 2015 // The temporary variables are necessary so that the argument |
| 2031 // expressions are not evaluated twice. | 2016 // expressions are not evaluated twice. |
| 2032 ArgumentListNode* ctor_args = super_call->arguments(); | 2017 ArgumentListNode* ctor_args = super_call->arguments(); |
| 2033 // The super initializer call has at least 2 arguments: the | 2018 // The super initializer call has at least 2 arguments: the |
| 2034 // implicit receiver, and the hidden construction phase. | 2019 // implicit receiver, and the hidden construction phase. |
| 2035 ASSERT(ctor_args->length() >= 2); | 2020 ASSERT(ctor_args->length() >= 2); |
| 2036 for (int i = 2; i < ctor_args->length(); i++) { | 2021 for (int i = 2; i < ctor_args->length(); i++) { |
| 2037 AstNode* arg = ctor_args->NodeAt(i); | 2022 AstNode* arg = ctor_args->NodeAt(i); |
| 2038 if (!IsSimpleLocalOrLiteralNode(arg)) { | 2023 if (!IsSimpleLocalOrLiteralNode(arg)) { |
| 2039 LocalVariable* temp = | 2024 LocalVariable* temp = |
| 2040 CreateTempConstVariable(arg->token_pos(), arg->id(), "sca"); | 2025 CreateTempConstVariable(arg->token_pos(), "sca"); |
| 2041 AstNode* save_temp = | 2026 AstNode* save_temp = |
| 2042 new StoreLocalNode(arg->token_pos(), *temp, arg); | 2027 new StoreLocalNode(arg->token_pos(), *temp, arg); |
| 2043 ctor_args->SetNodeAt(i, save_temp); | 2028 ctor_args->SetNodeAt(i, save_temp); |
| 2044 } | 2029 } |
| 2045 } | 2030 } |
| 2046 } | 2031 } |
| 2047 OpenBlock(); // Block to collect constructor body nodes. | 2032 OpenBlock(); // Block to collect constructor body nodes. |
| 2048 | 2033 |
| 2049 // Insert the implicit super call to the super constructor body. | 2034 // Insert the implicit super call to the super constructor body. |
| 2050 if (super_call != NULL) { | 2035 if (super_call != NULL) { |
| (...skipping 4251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6302 } | 6287 } |
| 6303 | 6288 |
| 6304 | 6289 |
| 6305 void Parser::EnsureExpressionTemp() { | 6290 void Parser::EnsureExpressionTemp() { |
| 6306 // Temporary used later by the flow_graph_builder. | 6291 // Temporary used later by the flow_graph_builder. |
| 6307 GetIncrementTempLocal(); | 6292 GetIncrementTempLocal(); |
| 6308 } | 6293 } |
| 6309 | 6294 |
| 6310 | 6295 |
| 6311 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 6296 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, |
| 6312 intptr_t token_id, | |
| 6313 const char* s) { | 6297 const char* s) { |
| 6314 char name[64]; | 6298 char name[64]; |
| 6315 OS::SNPrint(name, 64, ":%s%d", s, token_id); | 6299 OS::SNPrint(name, 64, ":%s%d", s, token_pos); |
| 6316 LocalVariable* temp = | 6300 LocalVariable* temp = |
| 6317 new LocalVariable(token_pos, | 6301 new LocalVariable(token_pos, |
| 6318 String::ZoneHandle(Symbols::New(name)), | 6302 String::ZoneHandle(Symbols::New(name)), |
| 6319 Type::ZoneHandle(Type::DynamicType())); | 6303 Type::ZoneHandle(Type::DynamicType())); |
| 6320 temp->set_is_final(); | 6304 temp->set_is_final(); |
| 6321 current_block_->scope->AddVariable(temp); | 6305 current_block_->scope->AddVariable(temp); |
| 6322 return temp; | 6306 return temp; |
| 6323 } | 6307 } |
| 6324 | 6308 |
| 6325 | 6309 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6405 // to control inputs with potential side effects, the store part stores any | 6389 // to control inputs with potential side effects, the store part stores any |
| 6406 // side effect creating inputs into locals. The load part reads then from | 6390 // side effect creating inputs into locals. The load part reads then from |
| 6407 // those locals. If expr may have side effects, it will be split into two new | 6391 // those locals. If expr may have side effects, it will be split into two new |
| 6408 // left and right nodes. 'expr' becomes the right node, left node is returned as | 6392 // left and right nodes. 'expr' becomes the right node, left node is returned as |
| 6409 // result. | 6393 // result. |
| 6410 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 6394 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
| 6411 AstNode* node = *expr; | 6395 AstNode* node = *expr; |
| 6412 if (node->IsLoadIndexedNode()) { | 6396 if (node->IsLoadIndexedNode()) { |
| 6413 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); | 6397 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); |
| 6414 LoadIndexedNode* right_node = left_node; | 6398 LoadIndexedNode* right_node = left_node; |
| 6415 intptr_t node_id = node->id(); | |
| 6416 intptr_t token_pos = node->token_pos(); | 6399 intptr_t token_pos = node->token_pos(); |
| 6417 node = NULL; // Do not use it. | 6400 node = NULL; // Do not use it. |
| 6418 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { | 6401 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { |
| 6419 LocalVariable* temp = | 6402 LocalVariable* temp = |
| 6420 CreateTempConstVariable(token_pos, node_id, "lia"); | 6403 CreateTempConstVariable(token_pos, "lia"); |
| 6421 StoreLocalNode* save = | 6404 StoreLocalNode* save = |
| 6422 new StoreLocalNode(token_pos, *temp, left_node->array()); | 6405 new StoreLocalNode(token_pos, *temp, left_node->array()); |
| 6423 left_node = | 6406 left_node = |
| 6424 new LoadIndexedNode(token_pos, save, left_node->index_expr()); | 6407 new LoadIndexedNode(token_pos, save, left_node->index_expr()); |
| 6425 right_node = new LoadIndexedNode(token_pos, | 6408 right_node = new LoadIndexedNode(token_pos, |
| 6426 new LoadLocalNode(token_pos, *temp), | 6409 new LoadLocalNode(token_pos, *temp), |
| 6427 right_node->index_expr()); | 6410 right_node->index_expr()); |
| 6428 } | 6411 } |
| 6429 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { | 6412 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { |
| 6430 LocalVariable* temp = | 6413 LocalVariable* temp = |
| 6431 CreateTempConstVariable(token_pos, node_id, "lix"); | 6414 CreateTempConstVariable(token_pos, "lix"); |
| 6432 StoreLocalNode* save = | 6415 StoreLocalNode* save = |
| 6433 new StoreLocalNode(token_pos, *temp, left_node->index_expr()); | 6416 new StoreLocalNode(token_pos, *temp, left_node->index_expr()); |
| 6434 left_node = new LoadIndexedNode(token_pos, | 6417 left_node = new LoadIndexedNode(token_pos, |
| 6435 left_node->array(), | 6418 left_node->array(), |
| 6436 save); | 6419 save); |
| 6437 right_node = new LoadIndexedNode(token_pos, | 6420 right_node = new LoadIndexedNode(token_pos, |
| 6438 right_node->array(), | 6421 right_node->array(), |
| 6439 new LoadLocalNode(token_pos, *temp)); | 6422 new LoadLocalNode(token_pos, *temp)); |
| 6440 } | 6423 } |
| 6441 *expr = right_node; | 6424 *expr = right_node; |
| 6442 return left_node; | 6425 return left_node; |
| 6443 } | 6426 } |
| 6444 if (node->IsInstanceGetterNode()) { | 6427 if (node->IsInstanceGetterNode()) { |
| 6445 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); | 6428 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); |
| 6446 InstanceGetterNode* right_node = left_node; | 6429 InstanceGetterNode* right_node = left_node; |
| 6447 intptr_t node_id = node->id(); | |
| 6448 intptr_t token_pos = node->token_pos(); | 6430 intptr_t token_pos = node->token_pos(); |
| 6449 node = NULL; // Do not use it. | 6431 node = NULL; // Do not use it. |
| 6450 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { | 6432 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { |
| 6451 LocalVariable* temp = | 6433 LocalVariable* temp = |
| 6452 CreateTempConstVariable(token_pos, node_id, "igr"); | 6434 CreateTempConstVariable(token_pos, "igr"); |
| 6453 StoreLocalNode* save = | 6435 StoreLocalNode* save = |
| 6454 new StoreLocalNode(token_pos, *temp, left_node->receiver()); | 6436 new StoreLocalNode(token_pos, *temp, left_node->receiver()); |
| 6455 left_node = new InstanceGetterNode(token_pos, | 6437 left_node = new InstanceGetterNode(token_pos, |
| 6456 save, | 6438 save, |
| 6457 left_node->field_name()); | 6439 left_node->field_name()); |
| 6458 right_node = new InstanceGetterNode(token_pos, | 6440 right_node = new InstanceGetterNode(token_pos, |
| 6459 new LoadLocalNode(token_pos, *temp), | 6441 new LoadLocalNode(token_pos, *temp), |
| 6460 right_node->field_name()); | 6442 right_node->field_name()); |
| 6461 } | 6443 } |
| 6462 *expr = right_node; | 6444 *expr = right_node; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6475 result->IsStaticSetterNode())) { | 6457 result->IsStaticSetterNode())) { |
| 6476 EnsureExpressionTemp(); | 6458 EnsureExpressionTemp(); |
| 6477 } | 6459 } |
| 6478 return result; | 6460 return result; |
| 6479 } | 6461 } |
| 6480 | 6462 |
| 6481 | 6463 |
| 6482 AstNode* Parser::ParseCascades(AstNode* expr) { | 6464 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 6483 intptr_t cascade_pos = TokenPos(); | 6465 intptr_t cascade_pos = TokenPos(); |
| 6484 LocalVariable* cascade_receiver_var = | 6466 LocalVariable* cascade_receiver_var = |
| 6485 CreateTempConstVariable(cascade_pos, expr->id(), "casc"); | 6467 CreateTempConstVariable(cascade_pos, "casc"); |
| 6486 StoreLocalNode* save_cascade = | 6468 StoreLocalNode* save_cascade = |
| 6487 new StoreLocalNode(cascade_pos, *cascade_receiver_var, expr); | 6469 new StoreLocalNode(cascade_pos, *cascade_receiver_var, expr); |
| 6488 current_block_->statements->Add(save_cascade); | 6470 current_block_->statements->Add(save_cascade); |
| 6489 while (CurrentToken() == Token::kCASCADE) { | 6471 while (CurrentToken() == Token::kCASCADE) { |
| 6490 cascade_pos = TokenPos(); | 6472 cascade_pos = TokenPos(); |
| 6491 LoadLocalNode* load_cascade_receiver = | 6473 LoadLocalNode* load_cascade_receiver = |
| 6492 new LoadLocalNode(cascade_pos, *cascade_receiver_var); | 6474 new LoadLocalNode(cascade_pos, *cascade_receiver_var); |
| 6493 if (Token::IsIdentifier(LookaheadToken(1))) { | 6475 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 6494 // Replace .. with . for ParseSelectors(). | 6476 // Replace .. with . for ParseSelectors(). |
| 6495 token_kind_ = Token::kPERIOD; | 6477 token_kind_ = Token::kPERIOD; |
| (...skipping 1394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7890 | 7872 |
| 7891 ConstructorCallNode* Parser::CreateConstructorCallNode( | 7873 ConstructorCallNode* Parser::CreateConstructorCallNode( |
| 7892 intptr_t token_pos, | 7874 intptr_t token_pos, |
| 7893 const AbstractTypeArguments& type_arguments, | 7875 const AbstractTypeArguments& type_arguments, |
| 7894 const Function& constructor, | 7876 const Function& constructor, |
| 7895 ArgumentListNode* arguments) { | 7877 ArgumentListNode* arguments) { |
| 7896 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 7878 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
| 7897 EnsureExpressionTemp(); | 7879 EnsureExpressionTemp(); |
| 7898 } | 7880 } |
| 7899 LocalVariable* allocated = | 7881 LocalVariable* allocated = |
| 7900 CreateTempConstVariable(token_pos, token_pos, "alloc"); | 7882 CreateTempConstVariable(token_pos, "alloc"); |
| 7901 return new ConstructorCallNode(token_pos, | 7883 return new ConstructorCallNode(token_pos, |
| 7902 type_arguments, | 7884 type_arguments, |
| 7903 constructor, | 7885 constructor, |
| 7904 arguments, | 7886 arguments, |
| 7905 *allocated); | 7887 *allocated); |
| 7906 } | 7888 } |
| 7907 | 7889 |
| 7908 | 7890 |
| 7909 static void AddKeyValuePair(ArrayNode* pairs, | 7891 static void AddKeyValuePair(ArrayNode* pairs, |
| 7910 bool is_const, | 7892 bool is_const, |
| (...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8962 void Parser::SkipQualIdent() { | 8944 void Parser::SkipQualIdent() { |
| 8963 ASSERT(IsIdentifier()); | 8945 ASSERT(IsIdentifier()); |
| 8964 ConsumeToken(); | 8946 ConsumeToken(); |
| 8965 if (CurrentToken() == Token::kPERIOD) { | 8947 if (CurrentToken() == Token::kPERIOD) { |
| 8966 ConsumeToken(); // Consume the kPERIOD token. | 8948 ConsumeToken(); // Consume the kPERIOD token. |
| 8967 ExpectIdentifier("identifier expected after '.'"); | 8949 ExpectIdentifier("identifier expected after '.'"); |
| 8968 } | 8950 } |
| 8969 } | 8951 } |
| 8970 | 8952 |
| 8971 } // namespace dart | 8953 } // namespace dart |
| OLD | NEW |