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 "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 parser.SkipFunctionPreamble(func); | |
| 767 node_sequence = parser.ParseFunc(func, default_parameter_values); | 769 node_sequence = parser.ParseFunc(func, default_parameter_values); |
| 768 break; | 770 break; |
| 769 case RawFunction::kImplicitGetter: | 771 case RawFunction::kImplicitGetter: |
| 770 ASSERT(!func.is_static()); | 772 ASSERT(!func.is_static()); |
| 771 node_sequence = parser.ParseInstanceGetter(func); | 773 node_sequence = parser.ParseInstanceGetter(func); |
| 772 break; | 774 break; |
| 773 case RawFunction::kImplicitSetter: | 775 case RawFunction::kImplicitSetter: |
| 774 ASSERT(!func.is_static()); | 776 ASSERT(!func.is_static()); |
| 775 node_sequence = parser.ParseInstanceSetter(func); | 777 node_sequence = parser.ParseInstanceSetter(func); |
| 776 break; | 778 break; |
| (...skipping 2051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2828 } | 2830 } |
| 2829 } | 2831 } |
| 2830 } | 2832 } |
| 2831 } | 2833 } |
| 2832 } | 2834 } |
| 2833 | 2835 |
| 2834 | 2836 |
| 2835 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 2837 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
| 2836 TRACE_PARSER("ParseMethodOrConstructor"); | 2838 TRACE_PARSER("ParseMethodOrConstructor"); |
| 2837 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); | 2839 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); |
| 2838 intptr_t method_pos = this->TokenPos(); | |
| 2839 ASSERT(method->type != NULL); | 2840 ASSERT(method->type != NULL); |
| 2840 ASSERT(method->name_pos > 0); | 2841 ASSERT(method->name_pos > 0); |
| 2841 ASSERT(current_member_ == method); | 2842 ASSERT(current_member_ == method); |
| 2842 | 2843 |
| 2843 if (method->has_var) { | 2844 if (method->has_var) { |
| 2844 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); | 2845 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); |
| 2845 } | 2846 } |
| 2846 if (method->has_final) { | 2847 if (method->has_final) { |
| 2847 ErrorMsg(method->name_pos, "'final' not allowed for methods"); | 2848 ErrorMsg(method->name_pos, "'final' not allowed for methods"); |
| 2848 } | 2849 } |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3082 function_kind = RawFunction::kRegularFunction; | 3083 function_kind = RawFunction::kRegularFunction; |
| 3083 } | 3084 } |
| 3084 Function& func = Function::Handle( | 3085 Function& func = Function::Handle( |
| 3085 Function::New(*method->name, | 3086 Function::New(*method->name, |
| 3086 function_kind, | 3087 function_kind, |
| 3087 method->has_static, | 3088 method->has_static, |
| 3088 method->has_const, | 3089 method->has_const, |
| 3089 method->has_abstract, | 3090 method->has_abstract, |
| 3090 method->has_external, | 3091 method->has_external, |
| 3091 current_class(), | 3092 current_class(), |
| 3092 method_pos)); | 3093 method->decl_begin_pos)); |
| 3093 func.set_result_type(*method->type); | 3094 func.set_result_type(*method->type); |
| 3094 func.set_end_token_pos(method_end_pos); | 3095 func.set_end_token_pos(method_end_pos); |
| 3095 if (method->metadata_pos > 0) { | 3096 if (method->metadata_pos > 0) { |
| 3096 library_.AddFunctionMetadata(func, method->metadata_pos); | 3097 library_.AddFunctionMetadata(func, method->metadata_pos); |
| 3097 } | 3098 } |
| 3098 | 3099 |
| 3099 // If this method is a redirecting factory, set the redirection information. | 3100 // If this method is a redirecting factory, set the redirection information. |
| 3100 if (!redirection_type.IsNull()) { | 3101 if (!redirection_type.IsNull()) { |
| 3101 ASSERT(func.IsFactory()); | 3102 ASSERT(func.IsFactory()); |
| 3102 func.SetRedirectionType(redirection_type); | 3103 func.SetRedirectionType(redirection_type); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3278 } | 3279 } |
| 3279 } | 3280 } |
| 3280 | 3281 |
| 3281 | 3282 |
| 3282 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 3283 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
| 3283 intptr_t metadata_pos) { | 3284 intptr_t metadata_pos) { |
| 3284 TRACE_PARSER("ParseClassMemberDefinition"); | 3285 TRACE_PARSER("ParseClassMemberDefinition"); |
| 3285 MemberDesc member; | 3286 MemberDesc member; |
| 3286 current_member_ = &member; | 3287 current_member_ = &member; |
| 3287 member.metadata_pos = metadata_pos; | 3288 member.metadata_pos = metadata_pos; |
| 3289 member.decl_begin_pos = TokenPos(); | |
| 3288 if ((CurrentToken() == Token::kEXTERNAL) && | 3290 if ((CurrentToken() == Token::kEXTERNAL) && |
| 3289 (LookaheadToken(1) != Token::kLPAREN)) { | 3291 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3290 ConsumeToken(); | 3292 ConsumeToken(); |
| 3291 member.has_external = true; | 3293 member.has_external = true; |
| 3292 } | 3294 } |
| 3293 if ((CurrentToken() == Token::kSTATIC) && | 3295 if ((CurrentToken() == Token::kSTATIC) && |
| 3294 (LookaheadToken(1) != Token::kLPAREN)) { | 3296 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3295 ConsumeToken(); | 3297 ConsumeToken(); |
| 3296 member.has_static = true; | 3298 member.has_static = true; |
| 3297 } | 3299 } |
| (...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4330 } else { | 4332 } else { |
| 4331 ExpectSemicolon(); // Reports error. | 4333 ExpectSemicolon(); // Reports error. |
| 4332 } | 4334 } |
| 4333 } | 4335 } |
| 4334 } | 4336 } |
| 4335 | 4337 |
| 4336 | 4338 |
| 4337 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 4339 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
| 4338 intptr_t metadata_pos) { | 4340 intptr_t metadata_pos) { |
| 4339 TRACE_PARSER("ParseTopLevelFunction"); | 4341 TRACE_PARSER("ParseTopLevelFunction"); |
| 4342 const intptr_t decl_begin_pos = TokenPos(); | |
| 4340 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 4343 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 4341 const bool is_static = true; | 4344 const bool is_static = true; |
| 4342 bool is_external = false; | 4345 bool is_external = false; |
| 4343 bool is_patch = false; | 4346 bool is_patch = false; |
| 4344 if (is_patch_source() && | 4347 if (is_patch_source() && |
| 4345 (CurrentToken() == Token::kIDENT) && | 4348 (CurrentToken() == Token::kIDENT) && |
| 4346 CurrentLiteral()->Equals("patch") && | 4349 CurrentLiteral()->Equals("patch") && |
| 4347 (LookaheadToken(1) != Token::kLPAREN)) { | 4350 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4348 ConsumeToken(); | 4351 ConsumeToken(); |
| 4349 is_patch = true; | 4352 is_patch = true; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4403 ErrorMsg("function block expected"); | 4406 ErrorMsg("function block expected"); |
| 4404 } | 4407 } |
| 4405 Function& func = Function::Handle( | 4408 Function& func = Function::Handle( |
| 4406 Function::New(func_name, | 4409 Function::New(func_name, |
| 4407 RawFunction::kRegularFunction, | 4410 RawFunction::kRegularFunction, |
| 4408 is_static, | 4411 is_static, |
| 4409 /* is_const = */ false, | 4412 /* is_const = */ false, |
| 4410 /* is_abstract = */ false, | 4413 /* is_abstract = */ false, |
| 4411 is_external, | 4414 is_external, |
| 4412 current_class(), | 4415 current_class(), |
| 4413 function_pos)); | 4416 decl_begin_pos)); |
| 4414 func.set_result_type(result_type); | 4417 func.set_result_type(result_type); |
| 4415 func.set_end_token_pos(function_end_pos); | 4418 func.set_end_token_pos(function_end_pos); |
| 4416 AddFormalParamsToFunction(¶ms, func); | 4419 AddFormalParamsToFunction(¶ms, func); |
| 4417 top_level->functions.Add(func); | 4420 top_level->functions.Add(func); |
| 4418 if (!is_patch) { | 4421 if (!is_patch) { |
| 4419 library_.AddObject(func, func_name); | 4422 library_.AddObject(func, func_name); |
| 4420 } else { | 4423 } else { |
| 4421 library_.ReplaceObject(func, func_name); | 4424 library_.ReplaceObject(func, func_name); |
| 4422 } | 4425 } |
| 4423 if (metadata_pos >= 0) { | 4426 if (metadata_pos >= 0) { |
| 4424 library_.AddFunctionMetadata(func, metadata_pos); | 4427 library_.AddFunctionMetadata(func, metadata_pos); |
| 4425 } | 4428 } |
| 4426 } | 4429 } |
| 4427 | 4430 |
| 4428 | 4431 |
| 4429 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 4432 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
| 4430 intptr_t metadata_pos) { | 4433 intptr_t metadata_pos) { |
| 4431 TRACE_PARSER("ParseTopLevelAccessor"); | 4434 TRACE_PARSER("ParseTopLevelAccessor"); |
| 4435 const intptr_t decl_begin_pos = TokenPos(); | |
| 4432 const bool is_static = true; | 4436 const bool is_static = true; |
| 4433 bool is_external = false; | 4437 bool is_external = false; |
| 4434 bool is_patch = false; | 4438 bool is_patch = false; |
| 4435 AbstractType& result_type = AbstractType::Handle(); | 4439 AbstractType& result_type = AbstractType::Handle(); |
| 4436 if (is_patch_source() && | 4440 if (is_patch_source() && |
| 4437 (CurrentToken() == Token::kIDENT) && | 4441 (CurrentToken() == Token::kIDENT) && |
| 4438 CurrentLiteral()->Equals("patch")) { | 4442 CurrentLiteral()->Equals("patch")) { |
| 4439 ConsumeToken(); | 4443 ConsumeToken(); |
| 4440 is_patch = true; | 4444 is_patch = true; |
| 4441 } else if (CurrentToken() == Token::kEXTERNAL) { | 4445 } else if (CurrentToken() == Token::kEXTERNAL) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4528 } | 4532 } |
| 4529 Function& func = Function::Handle( | 4533 Function& func = Function::Handle( |
| 4530 Function::New(accessor_name, | 4534 Function::New(accessor_name, |
| 4531 is_getter? RawFunction::kGetterFunction : | 4535 is_getter? RawFunction::kGetterFunction : |
| 4532 RawFunction::kSetterFunction, | 4536 RawFunction::kSetterFunction, |
| 4533 is_static, | 4537 is_static, |
| 4534 /* is_const = */ false, | 4538 /* is_const = */ false, |
| 4535 /* is_abstract = */ false, | 4539 /* is_abstract = */ false, |
| 4536 is_external, | 4540 is_external, |
| 4537 current_class(), | 4541 current_class(), |
| 4538 accessor_pos)); | 4542 decl_begin_pos)); |
| 4539 func.set_result_type(result_type); | 4543 func.set_result_type(result_type); |
| 4540 func.set_end_token_pos(accessor_end_pos); | 4544 func.set_end_token_pos(accessor_end_pos); |
| 4541 AddFormalParamsToFunction(¶ms, func); | 4545 AddFormalParamsToFunction(¶ms, func); |
| 4542 top_level->functions.Add(func); | 4546 top_level->functions.Add(func); |
| 4543 if (!is_patch) { | 4547 if (!is_patch) { |
| 4544 library_.AddObject(func, accessor_name); | 4548 library_.AddObject(func, accessor_name); |
| 4545 } else { | 4549 } else { |
| 4546 library_.ReplaceObject(func, accessor_name); | 4550 library_.ReplaceObject(func, accessor_name); |
| 4547 } | 4551 } |
| 4548 if (metadata_pos >= 0) { | 4552 if (metadata_pos >= 0) { |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5242 ASSERT(CurrentToken() == Token::kLPAREN); | 5246 ASSERT(CurrentToken() == Token::kLPAREN); |
| 5243 function_name = &Symbols::AnonymousClosure(); | 5247 function_name = &Symbols::AnonymousClosure(); |
| 5244 } else { | 5248 } else { |
| 5245 if (CurrentToken() == Token::kVOID) { | 5249 if (CurrentToken() == Token::kVOID) { |
| 5246 ConsumeToken(); | 5250 ConsumeToken(); |
| 5247 result_type = Type::VoidType(); | 5251 result_type = Type::VoidType(); |
| 5248 } else if ((CurrentToken() == Token::kIDENT) && | 5252 } else if ((CurrentToken() == Token::kIDENT) && |
| 5249 (LookaheadToken(1) != Token::kLPAREN)) { | 5253 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5250 result_type = ParseType(ClassFinalizer::kCanonicalize); | 5254 result_type = ParseType(ClassFinalizer::kCanonicalize); |
| 5251 } | 5255 } |
| 5252 ident_pos = TokenPos(); | |
| 5253 variable_name = ExpectIdentifier("function name expected"); | 5256 variable_name = ExpectIdentifier("function name expected"); |
| 5254 function_name = variable_name; | 5257 function_name = variable_name; |
| 5255 } | 5258 } |
| 5256 | 5259 |
| 5257 if (CurrentToken() != Token::kLPAREN) { | 5260 if (CurrentToken() != Token::kLPAREN) { |
| 5258 ErrorMsg("'(' expected"); | 5261 ErrorMsg("'(' expected"); |
| 5259 } | 5262 } |
| 5260 intptr_t function_pos = TokenPos(); | 5263 intptr_t function_pos = TokenPos(); |
| 5261 | 5264 |
| 5262 // Check whether we have parsed this closure function before, in a previous | 5265 // Check whether we have parsed this closure function before, in a previous |
| 5263 // compilation. If so, reuse the function object, else create a new one | 5266 // compilation. If so, reuse the function object, else create a new one |
| 5264 // and register it in the current class. | 5267 // and register it in the current class. |
| 5265 // Note that we cannot share the same closure function between the closurized | 5268 // Note that we cannot share the same closure function between the closurized |
| 5266 // and non-closurized versions of the same parent function. | 5269 // and non-closurized versions of the same parent function. |
| 5267 Function& function = Function::ZoneHandle(); | 5270 Function& function = Function::ZoneHandle(); |
| 5268 bool is_new_closure = false; | 5271 bool is_new_closure = false; |
| 5269 // TODO(hausner): There could be two different closures at the given | 5272 // TODO(hausner): There could be two different closures at the given |
| 5270 // function_pos, one enclosed in a closurized function and one enclosed in the | 5273 // function_pos, one enclosed in a closurized function and one enclosed in the |
| 5271 // non-closurized version of this same function. | 5274 // non-closurized version of this same function. |
| 5272 function = current_class().LookupClosureFunction(function_pos); | 5275 function = current_class().LookupClosureFunction(function_pos); |
| 5273 if (function.IsNull() || (function.token_pos() != function_pos) || | 5276 if (function.IsNull() || (function.token_pos() != function_pos) || |
| 5274 (function.parent_function() != innermost_function().raw())) { | 5277 (function.parent_function() != innermost_function().raw())) { |
| 5275 is_new_closure = true; | 5278 is_new_closure = true; |
| 5276 function = Function::NewClosureFunction(*function_name, | 5279 function = Function::NewClosureFunction(*function_name, |
| 5277 innermost_function(), | 5280 innermost_function(), |
| 5278 function_pos); | 5281 ident_pos); |
| 5279 function.set_result_type(result_type); | 5282 function.set_result_type(result_type); |
| 5280 current_class().AddClosureFunction(function); | 5283 current_class().AddClosureFunction(function); |
| 5281 } | 5284 } |
| 5282 | 5285 |
| 5283 // The function type needs to be finalized at compile time, since the closure | 5286 // The function type needs to be finalized at compile time, since the closure |
| 5284 // may be type checked at run time when assigned to a function variable, | 5287 // may be type checked at run time when assigned to a function variable, |
| 5285 // passed as a function argument, or returned as a function result. | 5288 // passed as a function argument, or returned as a function result. |
| 5286 | 5289 |
| 5287 LocalVariable* function_variable = NULL; | 5290 LocalVariable* function_variable = NULL; |
| 5288 Type& function_type = Type::ZoneHandle(); | 5291 Type& function_type = Type::ZoneHandle(); |
| (...skipping 4745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10034 } | 10037 } |
| 10035 if (CurrentToken() == Token::kLBRACE) { | 10038 if (CurrentToken() == Token::kLBRACE) { |
| 10036 SkipBlock(); | 10039 SkipBlock(); |
| 10037 } else if (CurrentToken() == Token::kARROW) { | 10040 } else if (CurrentToken() == Token::kARROW) { |
| 10038 ConsumeToken(); | 10041 ConsumeToken(); |
| 10039 SkipExpr(); | 10042 SkipExpr(); |
| 10040 } | 10043 } |
| 10041 } | 10044 } |
| 10042 | 10045 |
| 10043 | 10046 |
| 10047 // Skips function/method/constructor/getter/setter preambles until the formal | |
| 10048 // parameter list. It is enough to skip the tokens, since we have already | |
| 10049 // previously parsed the function. | |
| 10050 void Parser::SkipFunctionPreamble(const Function& func) { | |
| 10051 if (func.IsImplicitConstructor()) return; | |
|
Michael Lippautz (Google)
2013/08/13 18:07:35
Should this be hoisted out of the function and che
hausner
2013/08/13 19:29:52
Either way is fine. I see your point and maybe it
| |
| 10052 while (true) { | |
| 10053 if (CurrentToken() == Token::kLPAREN || | |
| 10054 CurrentToken() == Token::kARROW || | |
| 10055 CurrentToken() == Token::kSEMICOLON || | |
| 10056 CurrentToken() == Token::kLBRACE) { | |
| 10057 return; | |
| 10058 } | |
| 10059 // Case handles "native" keyword, but also return types of form | |
| 10060 // native.SomeType where native is the name of a library. | |
| 10061 if (CurrentToken() == Token::kIDENT && | |
| 10062 LookaheadToken(1) != Token::kPERIOD) { | |
| 10063 if (CurrentLiteral()->raw() == Symbols::Native().raw()) { | |
| 10064 return; | |
| 10065 } | |
| 10066 } | |
| 10067 ConsumeToken(); | |
| 10068 } | |
| 10069 } | |
| 10070 | |
| 10071 | |
| 10044 void Parser::SkipListLiteral() { | 10072 void Parser::SkipListLiteral() { |
| 10045 if (CurrentToken() == Token::kINDEX) { | 10073 if (CurrentToken() == Token::kINDEX) { |
| 10046 // Empty list literal. | 10074 // Empty list literal. |
| 10047 ConsumeToken(); | 10075 ConsumeToken(); |
| 10048 return; | 10076 return; |
| 10049 } | 10077 } |
| 10050 ExpectToken(Token::kLBRACK); | 10078 ExpectToken(Token::kLBRACK); |
| 10051 while (CurrentToken() != Token::kRBRACK) { | 10079 while (CurrentToken() != Token::kRBRACK) { |
| 10052 SkipNestedExpr(); | 10080 SkipNestedExpr(); |
| 10053 if (CurrentToken() == Token::kCOMMA) { | 10081 if (CurrentToken() == Token::kCOMMA) { |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10294 void Parser::SkipQualIdent() { | 10322 void Parser::SkipQualIdent() { |
| 10295 ASSERT(IsIdentifier()); | 10323 ASSERT(IsIdentifier()); |
| 10296 ConsumeToken(); | 10324 ConsumeToken(); |
| 10297 if (CurrentToken() == Token::kPERIOD) { | 10325 if (CurrentToken() == Token::kPERIOD) { |
| 10298 ConsumeToken(); // Consume the kPERIOD token. | 10326 ConsumeToken(); // Consume the kPERIOD token. |
| 10299 ExpectIdentifier("identifier expected after '.'"); | 10327 ExpectIdentifier("identifier expected after '.'"); |
| 10300 } | 10328 } |
| 10301 } | 10329 } |
| 10302 | 10330 |
| 10303 } // namespace dart | 10331 } // namespace dart |
| OLD | NEW |