| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 bool has_final; | 519 bool has_final; |
| 520 bool has_const; | 520 bool has_const; |
| 521 bool has_static; | 521 bool has_static; |
| 522 bool has_var; | 522 bool has_var; |
| 523 bool has_factory; | 523 bool has_factory; |
| 524 bool has_operator; | 524 bool has_operator; |
| 525 intptr_t metadata_pos; | 525 intptr_t metadata_pos; |
| 526 Token::Kind operator_token; | 526 Token::Kind operator_token; |
| 527 const AbstractType* type; | 527 const AbstractType* type; |
| 528 intptr_t name_pos; | 528 intptr_t name_pos; |
| 529 intptr_t decl_begin_pos; |
| 529 String* name; | 530 String* name; |
| 530 // For constructors: NULL or name of redirected to constructor. | 531 // For constructors: NULL or name of redirected to constructor. |
| 531 String* redirect_name; | 532 String* redirect_name; |
| 532 // For constructors: NULL for unnamed constructor, | 533 // For constructors: NULL for unnamed constructor, |
| 533 // identifier after classname for named constructors. | 534 // identifier after classname for named constructors. |
| 534 String* constructor_name; | 535 String* constructor_name; |
| 535 ParamList params; | 536 ParamList params; |
| 536 RawFunction::Kind kind; | 537 RawFunction::Kind kind; |
| 537 }; | 538 }; |
| 538 | 539 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 SequenceNode* node_sequence = NULL; | 758 SequenceNode* node_sequence = NULL; |
| 758 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); | 759 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); |
| 759 switch (func.kind()) { | 760 switch (func.kind()) { |
| 760 case RawFunction::kRegularFunction: | 761 case RawFunction::kRegularFunction: |
| 761 case RawFunction::kClosureFunction: | 762 case RawFunction::kClosureFunction: |
| 762 case RawFunction::kGetterFunction: | 763 case RawFunction::kGetterFunction: |
| 763 case RawFunction::kSetterFunction: | 764 case RawFunction::kSetterFunction: |
| 764 case RawFunction::kConstructor: | 765 case RawFunction::kConstructor: |
| 765 // The call to a redirecting factory is redirected. | 766 // The call to a redirecting factory is redirected. |
| 766 ASSERT(!func.IsRedirectingFactory()); | 767 ASSERT(!func.IsRedirectingFactory()); |
| 768 if (!func.IsImplicitConstructor()) { |
| 769 parser.SkipFunctionPreamble(); |
| 770 } |
| 767 node_sequence = parser.ParseFunc(func, default_parameter_values); | 771 node_sequence = parser.ParseFunc(func, default_parameter_values); |
| 768 break; | 772 break; |
| 769 case RawFunction::kImplicitGetter: | 773 case RawFunction::kImplicitGetter: |
| 770 ASSERT(!func.is_static()); | 774 ASSERT(!func.is_static()); |
| 771 node_sequence = parser.ParseInstanceGetter(func); | 775 node_sequence = parser.ParseInstanceGetter(func); |
| 772 break; | 776 break; |
| 773 case RawFunction::kImplicitSetter: | 777 case RawFunction::kImplicitSetter: |
| 774 ASSERT(!func.is_static()); | 778 ASSERT(!func.is_static()); |
| 775 node_sequence = parser.ParseInstanceSetter(func); | 779 node_sequence = parser.ParseInstanceSetter(func); |
| 776 break; | 780 break; |
| (...skipping 2048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2825 } | 2829 } |
| 2826 } | 2830 } |
| 2827 } | 2831 } |
| 2828 } | 2832 } |
| 2829 } | 2833 } |
| 2830 | 2834 |
| 2831 | 2835 |
| 2832 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 2836 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
| 2833 TRACE_PARSER("ParseMethodOrConstructor"); | 2837 TRACE_PARSER("ParseMethodOrConstructor"); |
| 2834 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); | 2838 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); |
| 2835 intptr_t method_pos = this->TokenPos(); | |
| 2836 ASSERT(method->type != NULL); | 2839 ASSERT(method->type != NULL); |
| 2837 ASSERT(method->name_pos > 0); | 2840 ASSERT(method->name_pos > 0); |
| 2838 ASSERT(current_member_ == method); | 2841 ASSERT(current_member_ == method); |
| 2839 | 2842 |
| 2840 if (method->has_var) { | 2843 if (method->has_var) { |
| 2841 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); | 2844 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); |
| 2842 } | 2845 } |
| 2843 if (method->has_final) { | 2846 if (method->has_final) { |
| 2844 ErrorMsg(method->name_pos, "'final' not allowed for methods"); | 2847 ErrorMsg(method->name_pos, "'final' not allowed for methods"); |
| 2845 } | 2848 } |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3079 function_kind = RawFunction::kRegularFunction; | 3082 function_kind = RawFunction::kRegularFunction; |
| 3080 } | 3083 } |
| 3081 Function& func = Function::Handle( | 3084 Function& func = Function::Handle( |
| 3082 Function::New(*method->name, | 3085 Function::New(*method->name, |
| 3083 function_kind, | 3086 function_kind, |
| 3084 method->has_static, | 3087 method->has_static, |
| 3085 method->has_const, | 3088 method->has_const, |
| 3086 method->has_abstract, | 3089 method->has_abstract, |
| 3087 method->has_external, | 3090 method->has_external, |
| 3088 current_class(), | 3091 current_class(), |
| 3089 method_pos)); | 3092 method->decl_begin_pos)); |
| 3090 func.set_result_type(*method->type); | 3093 func.set_result_type(*method->type); |
| 3091 func.set_end_token_pos(method_end_pos); | 3094 func.set_end_token_pos(method_end_pos); |
| 3092 if (method->metadata_pos > 0) { | 3095 if (method->metadata_pos > 0) { |
| 3093 library_.AddFunctionMetadata(func, method->metadata_pos); | 3096 library_.AddFunctionMetadata(func, method->metadata_pos); |
| 3094 } | 3097 } |
| 3095 | 3098 |
| 3096 // If this method is a redirecting factory, set the redirection information. | 3099 // If this method is a redirecting factory, set the redirection information. |
| 3097 if (!redirection_type.IsNull()) { | 3100 if (!redirection_type.IsNull()) { |
| 3098 ASSERT(func.IsFactory()); | 3101 ASSERT(func.IsFactory()); |
| 3099 func.SetRedirectionType(redirection_type); | 3102 func.SetRedirectionType(redirection_type); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3275 } | 3278 } |
| 3276 } | 3279 } |
| 3277 | 3280 |
| 3278 | 3281 |
| 3279 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 3282 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
| 3280 intptr_t metadata_pos) { | 3283 intptr_t metadata_pos) { |
| 3281 TRACE_PARSER("ParseClassMemberDefinition"); | 3284 TRACE_PARSER("ParseClassMemberDefinition"); |
| 3282 MemberDesc member; | 3285 MemberDesc member; |
| 3283 current_member_ = &member; | 3286 current_member_ = &member; |
| 3284 member.metadata_pos = metadata_pos; | 3287 member.metadata_pos = metadata_pos; |
| 3288 member.decl_begin_pos = TokenPos(); |
| 3285 if ((CurrentToken() == Token::kEXTERNAL) && | 3289 if ((CurrentToken() == Token::kEXTERNAL) && |
| 3286 (LookaheadToken(1) != Token::kLPAREN)) { | 3290 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3287 ConsumeToken(); | 3291 ConsumeToken(); |
| 3288 member.has_external = true; | 3292 member.has_external = true; |
| 3289 } | 3293 } |
| 3290 if ((CurrentToken() == Token::kSTATIC) && | 3294 if ((CurrentToken() == Token::kSTATIC) && |
| 3291 (LookaheadToken(1) != Token::kLPAREN)) { | 3295 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3292 ConsumeToken(); | 3296 ConsumeToken(); |
| 3293 member.has_static = true; | 3297 member.has_static = true; |
| 3294 } | 3298 } |
| (...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4321 } else { | 4325 } else { |
| 4322 ExpectSemicolon(); // Reports error. | 4326 ExpectSemicolon(); // Reports error. |
| 4323 } | 4327 } |
| 4324 } | 4328 } |
| 4325 } | 4329 } |
| 4326 | 4330 |
| 4327 | 4331 |
| 4328 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 4332 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
| 4329 intptr_t metadata_pos) { | 4333 intptr_t metadata_pos) { |
| 4330 TRACE_PARSER("ParseTopLevelFunction"); | 4334 TRACE_PARSER("ParseTopLevelFunction"); |
| 4335 const intptr_t decl_begin_pos = TokenPos(); |
| 4331 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 4336 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 4332 const bool is_static = true; | 4337 const bool is_static = true; |
| 4333 bool is_external = false; | 4338 bool is_external = false; |
| 4334 bool is_patch = false; | 4339 bool is_patch = false; |
| 4335 if (is_patch_source() && | 4340 if (is_patch_source() && |
| 4336 (CurrentToken() == Token::kIDENT) && | 4341 (CurrentToken() == Token::kIDENT) && |
| 4337 CurrentLiteral()->Equals("patch") && | 4342 CurrentLiteral()->Equals("patch") && |
| 4338 (LookaheadToken(1) != Token::kLPAREN)) { | 4343 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4339 ConsumeToken(); | 4344 ConsumeToken(); |
| 4340 is_patch = true; | 4345 is_patch = true; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4394 ErrorMsg("function block expected"); | 4399 ErrorMsg("function block expected"); |
| 4395 } | 4400 } |
| 4396 Function& func = Function::Handle( | 4401 Function& func = Function::Handle( |
| 4397 Function::New(func_name, | 4402 Function::New(func_name, |
| 4398 RawFunction::kRegularFunction, | 4403 RawFunction::kRegularFunction, |
| 4399 is_static, | 4404 is_static, |
| 4400 /* is_const = */ false, | 4405 /* is_const = */ false, |
| 4401 /* is_abstract = */ false, | 4406 /* is_abstract = */ false, |
| 4402 is_external, | 4407 is_external, |
| 4403 current_class(), | 4408 current_class(), |
| 4404 function_pos)); | 4409 decl_begin_pos)); |
| 4405 func.set_result_type(result_type); | 4410 func.set_result_type(result_type); |
| 4406 func.set_end_token_pos(function_end_pos); | 4411 func.set_end_token_pos(function_end_pos); |
| 4407 AddFormalParamsToFunction(¶ms, func); | 4412 AddFormalParamsToFunction(¶ms, func); |
| 4408 top_level->functions.Add(func); | 4413 top_level->functions.Add(func); |
| 4409 if (!is_patch) { | 4414 if (!is_patch) { |
| 4410 library_.AddObject(func, func_name); | 4415 library_.AddObject(func, func_name); |
| 4411 } else { | 4416 } else { |
| 4412 library_.ReplaceObject(func, func_name); | 4417 library_.ReplaceObject(func, func_name); |
| 4413 } | 4418 } |
| 4414 if (metadata_pos >= 0) { | 4419 if (metadata_pos >= 0) { |
| 4415 library_.AddFunctionMetadata(func, metadata_pos); | 4420 library_.AddFunctionMetadata(func, metadata_pos); |
| 4416 } | 4421 } |
| 4417 } | 4422 } |
| 4418 | 4423 |
| 4419 | 4424 |
| 4420 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 4425 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
| 4421 intptr_t metadata_pos) { | 4426 intptr_t metadata_pos) { |
| 4422 TRACE_PARSER("ParseTopLevelAccessor"); | 4427 TRACE_PARSER("ParseTopLevelAccessor"); |
| 4428 const intptr_t decl_begin_pos = TokenPos(); |
| 4423 const bool is_static = true; | 4429 const bool is_static = true; |
| 4424 bool is_external = false; | 4430 bool is_external = false; |
| 4425 bool is_patch = false; | 4431 bool is_patch = false; |
| 4426 AbstractType& result_type = AbstractType::Handle(); | 4432 AbstractType& result_type = AbstractType::Handle(); |
| 4427 if (is_patch_source() && | 4433 if (is_patch_source() && |
| 4428 (CurrentToken() == Token::kIDENT) && | 4434 (CurrentToken() == Token::kIDENT) && |
| 4429 CurrentLiteral()->Equals("patch")) { | 4435 CurrentLiteral()->Equals("patch")) { |
| 4430 ConsumeToken(); | 4436 ConsumeToken(); |
| 4431 is_patch = true; | 4437 is_patch = true; |
| 4432 } else if (CurrentToken() == Token::kEXTERNAL) { | 4438 } else if (CurrentToken() == Token::kEXTERNAL) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4519 } | 4525 } |
| 4520 Function& func = Function::Handle( | 4526 Function& func = Function::Handle( |
| 4521 Function::New(accessor_name, | 4527 Function::New(accessor_name, |
| 4522 is_getter? RawFunction::kGetterFunction : | 4528 is_getter? RawFunction::kGetterFunction : |
| 4523 RawFunction::kSetterFunction, | 4529 RawFunction::kSetterFunction, |
| 4524 is_static, | 4530 is_static, |
| 4525 /* is_const = */ false, | 4531 /* is_const = */ false, |
| 4526 /* is_abstract = */ false, | 4532 /* is_abstract = */ false, |
| 4527 is_external, | 4533 is_external, |
| 4528 current_class(), | 4534 current_class(), |
| 4529 accessor_pos)); | 4535 decl_begin_pos)); |
| 4530 func.set_result_type(result_type); | 4536 func.set_result_type(result_type); |
| 4531 func.set_end_token_pos(accessor_end_pos); | 4537 func.set_end_token_pos(accessor_end_pos); |
| 4532 AddFormalParamsToFunction(¶ms, func); | 4538 AddFormalParamsToFunction(¶ms, func); |
| 4533 top_level->functions.Add(func); | 4539 top_level->functions.Add(func); |
| 4534 if (!is_patch) { | 4540 if (!is_patch) { |
| 4535 library_.AddObject(func, accessor_name); | 4541 library_.AddObject(func, accessor_name); |
| 4536 } else { | 4542 } else { |
| 4537 library_.ReplaceObject(func, accessor_name); | 4543 library_.ReplaceObject(func, accessor_name); |
| 4538 } | 4544 } |
| 4539 if (metadata_pos >= 0) { | 4545 if (metadata_pos >= 0) { |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5235 ASSERT(CurrentToken() == Token::kLPAREN); | 5241 ASSERT(CurrentToken() == Token::kLPAREN); |
| 5236 function_name = &Symbols::AnonymousClosure(); | 5242 function_name = &Symbols::AnonymousClosure(); |
| 5237 } else { | 5243 } else { |
| 5238 if (CurrentToken() == Token::kVOID) { | 5244 if (CurrentToken() == Token::kVOID) { |
| 5239 ConsumeToken(); | 5245 ConsumeToken(); |
| 5240 result_type = Type::VoidType(); | 5246 result_type = Type::VoidType(); |
| 5241 } else if ((CurrentToken() == Token::kIDENT) && | 5247 } else if ((CurrentToken() == Token::kIDENT) && |
| 5242 (LookaheadToken(1) != Token::kLPAREN)) { | 5248 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5243 result_type = ParseType(ClassFinalizer::kCanonicalize); | 5249 result_type = ParseType(ClassFinalizer::kCanonicalize); |
| 5244 } | 5250 } |
| 5245 ident_pos = TokenPos(); | |
| 5246 variable_name = ExpectIdentifier("function name expected"); | 5251 variable_name = ExpectIdentifier("function name expected"); |
| 5247 function_name = variable_name; | 5252 function_name = variable_name; |
| 5248 } | 5253 } |
| 5249 | 5254 |
| 5250 if (CurrentToken() != Token::kLPAREN) { | 5255 if (CurrentToken() != Token::kLPAREN) { |
| 5251 ErrorMsg("'(' expected"); | 5256 ErrorMsg("'(' expected"); |
| 5252 } | 5257 } |
| 5253 intptr_t function_pos = TokenPos(); | 5258 intptr_t function_pos = TokenPos(); |
| 5254 | 5259 |
| 5255 // Check whether we have parsed this closure function before, in a previous | 5260 // Check whether we have parsed this closure function before, in a previous |
| 5256 // compilation. If so, reuse the function object, else create a new one | 5261 // compilation. If so, reuse the function object, else create a new one |
| 5257 // and register it in the current class. | 5262 // and register it in the current class. |
| 5258 // Note that we cannot share the same closure function between the closurized | 5263 // Note that we cannot share the same closure function between the closurized |
| 5259 // and non-closurized versions of the same parent function. | 5264 // and non-closurized versions of the same parent function. |
| 5260 Function& function = Function::ZoneHandle(); | 5265 Function& function = Function::ZoneHandle(); |
| 5261 bool is_new_closure = false; | 5266 bool is_new_closure = false; |
| 5262 // TODO(hausner): There could be two different closures at the given | 5267 // TODO(hausner): There could be two different closures at the given |
| 5263 // function_pos, one enclosed in a closurized function and one enclosed in the | 5268 // function_pos, one enclosed in a closurized function and one enclosed in the |
| 5264 // non-closurized version of this same function. | 5269 // non-closurized version of this same function. |
| 5265 function = current_class().LookupClosureFunction(function_pos); | 5270 function = current_class().LookupClosureFunction(function_pos); |
| 5266 if (function.IsNull() || (function.token_pos() != function_pos) || | 5271 if (function.IsNull() || (function.token_pos() != function_pos) || |
| 5267 (function.parent_function() != innermost_function().raw())) { | 5272 (function.parent_function() != innermost_function().raw())) { |
| 5268 is_new_closure = true; | 5273 is_new_closure = true; |
| 5269 function = Function::NewClosureFunction(*function_name, | 5274 function = Function::NewClosureFunction(*function_name, |
| 5270 innermost_function(), | 5275 innermost_function(), |
| 5271 function_pos); | 5276 ident_pos); |
| 5272 function.set_result_type(result_type); | 5277 function.set_result_type(result_type); |
| 5273 current_class().AddClosureFunction(function); | 5278 current_class().AddClosureFunction(function); |
| 5274 } | 5279 } |
| 5275 | 5280 |
| 5276 // The function type needs to be finalized at compile time, since the closure | 5281 // The function type needs to be finalized at compile time, since the closure |
| 5277 // may be type checked at run time when assigned to a function variable, | 5282 // may be type checked at run time when assigned to a function variable, |
| 5278 // passed as a function argument, or returned as a function result. | 5283 // passed as a function argument, or returned as a function result. |
| 5279 | 5284 |
| 5280 LocalVariable* function_variable = NULL; | 5285 LocalVariable* function_variable = NULL; |
| 5281 Type& function_type = Type::ZoneHandle(); | 5286 Type& function_type = Type::ZoneHandle(); |
| (...skipping 4746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10028 } | 10033 } |
| 10029 if (CurrentToken() == Token::kLBRACE) { | 10034 if (CurrentToken() == Token::kLBRACE) { |
| 10030 SkipBlock(); | 10035 SkipBlock(); |
| 10031 } else if (CurrentToken() == Token::kARROW) { | 10036 } else if (CurrentToken() == Token::kARROW) { |
| 10032 ConsumeToken(); | 10037 ConsumeToken(); |
| 10033 SkipExpr(); | 10038 SkipExpr(); |
| 10034 } | 10039 } |
| 10035 } | 10040 } |
| 10036 | 10041 |
| 10037 | 10042 |
| 10043 // Skips function/method/constructor/getter/setter preambles until the formal |
| 10044 // parameter list. It is enough to skip the tokens, since we have already |
| 10045 // previously parsed the function. |
| 10046 void Parser::SkipFunctionPreamble() { |
| 10047 while (true) { |
| 10048 if (CurrentToken() == Token::kLPAREN || |
| 10049 CurrentToken() == Token::kARROW || |
| 10050 CurrentToken() == Token::kSEMICOLON || |
| 10051 CurrentToken() == Token::kLBRACE) { |
| 10052 return; |
| 10053 } |
| 10054 // Case handles "native" keyword, but also return types of form |
| 10055 // native.SomeType where native is the name of a library. |
| 10056 if (CurrentToken() == Token::kIDENT && |
| 10057 LookaheadToken(1) != Token::kPERIOD) { |
| 10058 if (CurrentLiteral()->raw() == Symbols::Native().raw()) { |
| 10059 return; |
| 10060 } |
| 10061 } |
| 10062 ConsumeToken(); |
| 10063 } |
| 10064 } |
| 10065 |
| 10066 |
| 10038 void Parser::SkipListLiteral() { | 10067 void Parser::SkipListLiteral() { |
| 10039 if (CurrentToken() == Token::kINDEX) { | 10068 if (CurrentToken() == Token::kINDEX) { |
| 10040 // Empty list literal. | 10069 // Empty list literal. |
| 10041 ConsumeToken(); | 10070 ConsumeToken(); |
| 10042 return; | 10071 return; |
| 10043 } | 10072 } |
| 10044 ExpectToken(Token::kLBRACK); | 10073 ExpectToken(Token::kLBRACK); |
| 10045 while (CurrentToken() != Token::kRBRACK) { | 10074 while (CurrentToken() != Token::kRBRACK) { |
| 10046 SkipNestedExpr(); | 10075 SkipNestedExpr(); |
| 10047 if (CurrentToken() == Token::kCOMMA) { | 10076 if (CurrentToken() == Token::kCOMMA) { |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10288 void Parser::SkipQualIdent() { | 10317 void Parser::SkipQualIdent() { |
| 10289 ASSERT(IsIdentifier()); | 10318 ASSERT(IsIdentifier()); |
| 10290 ConsumeToken(); | 10319 ConsumeToken(); |
| 10291 if (CurrentToken() == Token::kPERIOD) { | 10320 if (CurrentToken() == Token::kPERIOD) { |
| 10292 ConsumeToken(); // Consume the kPERIOD token. | 10321 ConsumeToken(); // Consume the kPERIOD token. |
| 10293 ExpectIdentifier("identifier expected after '.'"); | 10322 ExpectIdentifier("identifier expected after '.'"); |
| 10294 } | 10323 } |
| 10295 } | 10324 } |
| 10296 | 10325 |
| 10297 } // namespace dart | 10326 } // namespace dart |
| OLD | NEW |