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 5955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5966 stack_trace_param.token_pos = Scanner::kNoSourcePos; | 5966 stack_trace_param.token_pos = Scanner::kNoSourcePos; |
| 5967 stack_trace_param.type = &dynamic_type; | 5967 stack_trace_param.type = &dynamic_type; |
| 5968 stack_trace_param.name = &Symbols::StackTraceParameter(); | 5968 stack_trace_param.name = &Symbols::StackTraceParameter(); |
| 5969 | 5969 |
| 5970 AddCatchParamsToScope( | 5970 AddCatchParamsToScope( |
| 5971 &exception_param, &stack_trace_param, current_block_->scope); | 5971 &exception_param, &stack_trace_param, current_block_->scope); |
| 5972 | 5972 |
| 5973 LocalVariable* context_var = current_block_->scope->LookupVariable( | 5973 LocalVariable* context_var = current_block_->scope->LookupVariable( |
| 5974 Symbols::SavedTryContextVar(), false); | 5974 Symbols::SavedTryContextVar(), false); |
| 5975 ASSERT(context_var != NULL); | 5975 ASSERT(context_var != NULL); |
| 5976 | |
| 5976 LocalVariable* exception_var = current_block_->scope->LookupVariable( | 5977 LocalVariable* exception_var = current_block_->scope->LookupVariable( |
| 5977 Symbols::ExceptionVar(), false); | 5978 Symbols::ExceptionVar(), false); |
| 5978 if (exception_param.var != NULL) { | 5979 if (exception_param.var != NULL) { |
| 5979 // Generate code to load the exception object (:exception_var) into | 5980 // Generate code to load the exception object (:exception_var) into |
| 5980 // the exception variable specified in this block. | 5981 // the exception variable specified in this block. |
| 5981 ASSERT(exception_var != NULL); | 5982 ASSERT(exception_var != NULL); |
|
hausner
2015/02/24 20:57:31
Maybe it makes sense to pull this assert out of th
regis
2015/02/24 22:05:13
Done. Note that it was asserted in the constructor
| |
| 5982 current_block_->statements->Add(new(Z) StoreLocalNode( | 5983 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 5983 Scanner::kNoSourcePos, | 5984 Scanner::kNoSourcePos, |
| 5984 exception_param.var, | 5985 exception_param.var, |
| 5985 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); | 5986 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); |
| 5986 } | 5987 } |
| 5988 | |
| 5987 LocalVariable* stack_trace_var = | 5989 LocalVariable* stack_trace_var = |
| 5988 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false); | 5990 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false); |
| 5989 if (stack_trace_param.var != NULL) { | 5991 if (stack_trace_param.var != NULL) { |
| 5990 // A stack trace variable is specified in this block, so generate code | 5992 // A stack trace variable is specified in this block, so generate code |
| 5991 // to load the stack trace object (:stack_trace_var) into the stack | 5993 // to load the stack trace object (:stack_trace_var) into the stack |
| 5992 // trace variable specified in this block. | 5994 // trace variable specified in this block. |
| 5993 ASSERT(stack_trace_var != NULL); | 5995 ASSERT(stack_trace_var != NULL); |
| 5994 current_block_->statements->Add(new(Z) StoreLocalNode( | 5996 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 5995 Scanner::kNoSourcePos, | 5997 Scanner::kNoSourcePos, |
| 5996 stack_trace_param.var, | 5998 stack_trace_param.var, |
| 5997 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 5999 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); |
| 5998 } | 6000 } |
| 5999 | 6001 |
| 6002 AddSavedExceptionAndStacktraceToScope( | |
| 6003 exception_var, stack_trace_var, current_block_->scope); | |
| 6004 | |
| 6000 ASSERT(try_blocks_list_ != NULL); | 6005 ASSERT(try_blocks_list_ != NULL); |
| 6001 ASSERT(innermost_function().IsAsyncClosure() || | 6006 ASSERT(innermost_function().IsAsyncClosure() || |
| 6002 innermost_function().IsAsyncFunction()); | 6007 innermost_function().IsAsyncFunction()); |
| 6003 if ((try_blocks_list_->outer_try_block() != NULL) && | 6008 if ((try_blocks_list_->outer_try_block() != NULL) && |
| 6004 (try_blocks_list_->outer_try_block()->try_block() | 6009 (try_blocks_list_->outer_try_block()->try_block() |
| 6005 ->scope->function_level() == | 6010 ->scope->function_level() == |
| 6006 current_block_->scope->function_level())) { | 6011 current_block_->scope->function_level())) { |
| 6007 // We need to unchain three scope levels: catch clause, catch | 6012 // We need to unchain three scope levels: catch clause, catch |
| 6008 // parameters, and the general try block. | 6013 // parameters, and the general try block. |
| 6009 RestoreSavedTryContext( | 6014 RestoreSavedTryContext( |
| (...skipping 2175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8185 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, | 8190 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, |
| 8186 CatchParamDesc* stack_trace_param, | 8191 CatchParamDesc* stack_trace_param, |
| 8187 LocalScope* scope) { | 8192 LocalScope* scope) { |
| 8188 if (exception_param->name != NULL) { | 8193 if (exception_param->name != NULL) { |
| 8189 LocalVariable* var = new(Z) LocalVariable( | 8194 LocalVariable* var = new(Z) LocalVariable( |
| 8190 exception_param->token_pos, | 8195 exception_param->token_pos, |
| 8191 *exception_param->name, | 8196 *exception_param->name, |
| 8192 *exception_param->type); | 8197 *exception_param->type); |
| 8193 var->set_is_final(); | 8198 var->set_is_final(); |
| 8194 bool added_to_scope = scope->AddVariable(var); | 8199 bool added_to_scope = scope->AddVariable(var); |
| 8195 ASSERT(added_to_scope); | 8200 ASSERT(added_to_scope); // TODO(regis): Why do we check below but not here? |
|
hausner
2015/02/24 20:57:31
FWIW, I don't know either.
regis
2015/02/24 22:05:13
I get it now.
The error can only be reported below
| |
| 8196 exception_param->var = var; | 8201 exception_param->var = var; |
| 8197 } | 8202 } |
| 8198 if (stack_trace_param->name != NULL) { | 8203 if (stack_trace_param->name != NULL) { |
| 8199 LocalVariable* var = new(Z) LocalVariable( | 8204 LocalVariable* var = new(Z) LocalVariable( |
| 8200 stack_trace_param->token_pos, | 8205 stack_trace_param->token_pos, |
| 8201 *stack_trace_param->name, | 8206 *stack_trace_param->name, |
| 8202 *stack_trace_param->type); | 8207 *stack_trace_param->type); |
| 8203 var->set_is_final(); | 8208 var->set_is_final(); |
| 8204 bool added_to_scope = scope->AddVariable(var); | 8209 bool added_to_scope = scope->AddVariable(var); |
| 8205 if (!added_to_scope) { | 8210 if (!added_to_scope) { |
| 8206 ReportError(stack_trace_param->token_pos, | 8211 ReportError(stack_trace_param->token_pos, |
| 8207 "name '%s' already exists in scope", | 8212 "name '%s' already exists in scope", |
| 8208 stack_trace_param->name->ToCString()); | 8213 stack_trace_param->name->ToCString()); |
| 8209 } | 8214 } |
| 8210 stack_trace_param->var = var; | 8215 stack_trace_param->var = var; |
| 8211 } | 8216 } |
| 8212 } | 8217 } |
| 8213 | 8218 |
| 8214 | 8219 |
| 8220 // Populate local scope of the catch block with the saved exception and saved | |
| 8221 // stack trace. | |
| 8222 void Parser::AddSavedExceptionAndStacktraceToScope( | |
|
Ivan Posva
2015/02/24 20:52:39
These variables are being added unconditionally he
regis
2015/02/24 22:05:13
Done.
| |
| 8223 LocalVariable* exception_var, | |
| 8224 LocalVariable* stack_trace_var, | |
| 8225 LocalScope* scope) { | |
| 8226 // Add :saved_exception_var and :saved_stack_trace_var to scope. | |
| 8227 LocalVariable* saved_exception_var = new (Z) LocalVariable( | |
| 8228 Scanner::kNoSourcePos, | |
| 8229 Symbols::SavedExceptionVar(), | |
| 8230 Type::ZoneHandle(Z, Type::DynamicType())); | |
| 8231 scope->AddVariable(saved_exception_var); | |
| 8232 saved_exception_var->set_is_captured(); | |
|
Ivan Posva
2015/02/24 20:52:39
These variables should be automatically captured a
hausner
2015/02/24 20:57:31
Capturing explicitly should not be necessary. Afte
regis
2015/02/24 22:05:13
Removed the explicit capturing and marked as final
| |
| 8233 LocalVariable* saved_stack_trace_var = new (Z) LocalVariable( | |
| 8234 Scanner::kNoSourcePos, | |
| 8235 Symbols::SavedStackTraceVar(), | |
| 8236 Type::ZoneHandle(Z, Type::DynamicType())); | |
| 8237 scope->AddVariable(saved_stack_trace_var); | |
| 8238 saved_stack_trace_var->set_is_captured(); | |
| 8239 | |
| 8240 // Generate code to load the exception object (:exception_var) into | |
| 8241 // the saved exception variable (:saved_exception_var) used to rethrow. | |
| 8242 saved_exception_var = current_block_->scope->LookupVariable( | |
| 8243 Symbols::SavedExceptionVar(), false); | |
| 8244 ASSERT(saved_exception_var != NULL); | |
| 8245 ASSERT(exception_var != NULL); | |
| 8246 current_block_->statements->Add(new(Z) StoreLocalNode( | |
| 8247 Scanner::kNoSourcePos, | |
| 8248 saved_exception_var, | |
| 8249 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); | |
| 8250 | |
| 8251 // Generate code to load the stack trace object (:stack_trace_var) into | |
| 8252 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow. | |
| 8253 saved_stack_trace_var = current_block_->scope->LookupVariable( | |
| 8254 Symbols::SavedStackTraceVar(), false); | |
| 8255 ASSERT(saved_stack_trace_var != NULL); | |
| 8256 ASSERT(stack_trace_var != NULL); | |
| 8257 current_block_->statements->Add(new(Z) StoreLocalNode( | |
| 8258 Scanner::kNoSourcePos, | |
| 8259 saved_stack_trace_var, | |
| 8260 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | |
| 8261 } | |
| 8262 | |
| 8263 | |
| 8215 SequenceNode* Parser::ParseFinallyBlock() { | 8264 SequenceNode* Parser::ParseFinallyBlock() { |
| 8216 TRACE_PARSER("ParseFinallyBlock"); | 8265 TRACE_PARSER("ParseFinallyBlock"); |
| 8217 OpenBlock(); | 8266 OpenBlock(); |
| 8218 ExpectToken(Token::kLBRACE); | 8267 ExpectToken(Token::kLBRACE); |
| 8219 | 8268 |
| 8220 // In case of async closures we need to restore the saved try index of an | 8269 // In case of async closures we need to restore the saved try index of an |
| 8221 // outer try block (if it exists). The current try block has already been | 8270 // outer try block (if it exists). The current try block has already been |
| 8222 // removed from the stack of try blocks. | 8271 // removed from the stack of try blocks. |
| 8223 if ((innermost_function().IsAsyncClosure() || | 8272 if ((innermost_function().IsAsyncClosure() || |
| 8224 innermost_function().IsAsyncFunction() || | 8273 innermost_function().IsAsyncFunction() || |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8338 stack_trace_param.token_pos = TokenPos(); | 8387 stack_trace_param.token_pos = TokenPos(); |
| 8339 stack_trace_param.name = ExpectIdentifier("identifier expected"); | 8388 stack_trace_param.name = ExpectIdentifier("identifier expected"); |
| 8340 } | 8389 } |
| 8341 ExpectToken(Token::kRPAREN); | 8390 ExpectToken(Token::kRPAREN); |
| 8342 } | 8391 } |
| 8343 | 8392 |
| 8344 // Create a block containing the catch clause parameters and the | 8393 // Create a block containing the catch clause parameters and the |
| 8345 // following code: | 8394 // following code: |
| 8346 // 1) Store exception object and stack trace object into user-defined | 8395 // 1) Store exception object and stack trace object into user-defined |
| 8347 // variables (as needed). | 8396 // variables (as needed). |
| 8348 // 2) Nested block with source code from catch clause block. | 8397 // 2) In async code, save exception object and stack trace object into |
| 8398 // captured :saved_exception_var and :saved_stack_trace_var. | |
| 8399 // 3) Nested block with source code from catch clause block. | |
| 8349 OpenBlock(); | 8400 OpenBlock(); |
| 8350 AddCatchParamsToScope(&exception_param, &stack_trace_param, | 8401 AddCatchParamsToScope(&exception_param, &stack_trace_param, |
| 8351 current_block_->scope); | 8402 current_block_->scope); |
| 8352 | 8403 |
| 8353 if (exception_param.var != NULL) { | 8404 if (exception_param.var != NULL) { |
| 8354 // Generate code to load the exception object (:exception_var) into | 8405 // Generate code to load the exception object (:exception_var) into |
| 8355 // the exception variable specified in this block. | 8406 // the exception variable specified in this block. |
| 8356 ASSERT(exception_var != NULL); | 8407 ASSERT(exception_var != NULL); |
| 8357 current_block_->statements->Add(new(Z) StoreLocalNode( | 8408 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 8358 catch_pos, exception_param.var, new(Z) LoadLocalNode( | 8409 catch_pos, exception_param.var, new(Z) LoadLocalNode( |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 8386 current_block_->scope->function_level())) { | 8437 current_block_->scope->function_level())) { |
| 8387 // We need to unchain three scope levels: catch clause, catch | 8438 // We need to unchain three scope levels: catch clause, catch |
| 8388 // parameters, and the general try block. | 8439 // parameters, and the general try block. |
| 8389 RestoreSavedTryContext( | 8440 RestoreSavedTryContext( |
| 8390 current_block_->scope->parent()->parent()->parent(), | 8441 current_block_->scope->parent()->parent()->parent(), |
| 8391 try_blocks_list_->outer_try_block()->try_index(), | 8442 try_blocks_list_->outer_try_block()->try_index(), |
| 8392 current_block_->statements); | 8443 current_block_->statements); |
| 8393 } else { | 8444 } else { |
| 8394 parsed_function()->reset_saved_try_ctx_vars(); | 8445 parsed_function()->reset_saved_try_ctx_vars(); |
| 8395 } | 8446 } |
| 8447 AddSavedExceptionAndStacktraceToScope( | |
| 8448 exception_var, stack_trace_var, current_block_->scope); | |
| 8396 } | 8449 } |
| 8397 | 8450 |
| 8398 current_block_->statements->Add(ParseNestedStatement(false, NULL)); | 8451 current_block_->statements->Add(ParseNestedStatement(false, NULL)); |
| 8399 catch_blocks.Add(CloseBlock()); | 8452 catch_blocks.Add(CloseBlock()); |
| 8400 | 8453 |
| 8401 const bool is_bad_type = | 8454 const bool is_bad_type = |
| 8402 exception_param.type->IsMalformed() || | 8455 exception_param.type->IsMalformed() || |
| 8403 exception_param.type->IsMalbounded(); | 8456 exception_param.type->IsMalbounded(); |
| 8404 if (exception_param.type->IsDynamicType() || is_bad_type) { | 8457 if (exception_param.type->IsDynamicType() || is_bad_type) { |
| 8405 // There is no exception type or else it is malformed or malbounded. | 8458 // There is no exception type or else it is malformed or malbounded. |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8530 current_block_->statements->Add(new(Z) StoreLocalNode( | 8583 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 8531 Scanner::kNoSourcePos, | 8584 Scanner::kNoSourcePos, |
| 8532 async_saved_try_ctx, | 8585 async_saved_try_ctx, |
| 8533 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context))); | 8586 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context))); |
| 8534 parsed_function()->set_saved_try_ctx(saved_try_context); | 8587 parsed_function()->set_saved_try_ctx(saved_try_context); |
| 8535 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); | 8588 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); |
| 8536 } | 8589 } |
| 8537 | 8590 |
| 8538 | 8591 |
| 8539 // Restore the currently relevant :saved_try_context_var on the stack | 8592 // Restore the currently relevant :saved_try_context_var on the stack |
| 8540 // from the captured :async_saved_try_cts_var. | 8593 // from the captured :async_saved_try_ctx_var_. |
| 8541 // * Try blocks: Set the context variable for this try block. | 8594 // * Try blocks: Set the context variable for this try block. |
| 8542 // * Catch/finally blocks: Set the context variable for any outer try block (if | 8595 // * Catch/finally blocks: Set the context variable for any outer try block (if |
| 8543 // existent). | 8596 // existent). |
| 8544 // | 8597 // |
| 8545 // Also save the captured variable and the stack variable to be able to set | 8598 // Also save the captured variable and the stack variable to be able to set |
| 8546 // it after a function continues execution (await). | 8599 // it after a function continues execution (await). |
| 8547 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope, | 8600 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope, |
| 8548 int16_t try_index, | 8601 int16_t try_index, |
| 8549 SequenceNode* target) { | 8602 SequenceNode* target) { |
| 8550 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable( | 8603 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable( |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8924 // Empty statement, nothing to do. | 8977 // Empty statement, nothing to do. |
| 8925 ConsumeToken(); | 8978 ConsumeToken(); |
| 8926 } else if (token == Token::kRETHROW) { | 8979 } else if (token == Token::kRETHROW) { |
| 8927 // Rethrow of current exception. | 8980 // Rethrow of current exception. |
| 8928 ConsumeToken(); | 8981 ConsumeToken(); |
| 8929 ExpectSemicolon(); | 8982 ExpectSemicolon(); |
| 8930 // Check if it is ok to do a rethrow. | 8983 // Check if it is ok to do a rethrow. |
| 8931 if ((try_blocks_list_ == NULL) || !try_blocks_list_->inside_catch()) { | 8984 if ((try_blocks_list_ == NULL) || !try_blocks_list_->inside_catch()) { |
| 8932 ReportError(statement_pos, "rethrow of an exception is not valid here"); | 8985 ReportError(statement_pos, "rethrow of an exception is not valid here"); |
| 8933 } | 8986 } |
| 8934 // The exception and stack trace variables are bound in the block | 8987 |
| 8935 // containing the try. | 8988 // If in async code, use :saved_exception_var and :saved_stack_trace_var |
| 8936 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); | 8989 // instead of :exception_var and :stack_trace_var. |
| 8937 ASSERT(scope != NULL); | 8990 LocalVariable* excp_var; |
| 8938 LocalVariable* excp_var = | 8991 LocalVariable* trace_var; |
| 8939 scope->LocalLookupVariable(Symbols::ExceptionVar()); | 8992 if (innermost_function().IsAsyncClosure() || |
| 8993 innermost_function().IsAsyncFunction() || | |
| 8994 innermost_function().IsSyncGenClosure() || | |
| 8995 innermost_function().IsSyncGenerator()) { | |
| 8996 // The saved exception and stack trace variables are bound in the block | |
| 8997 // containing the catch. | |
| 8998 LocalScope* scope = current_block_->scope; | |
| 8999 excp_var = scope->LookupVariable(Symbols::SavedExceptionVar(), false); | |
|
Ivan Posva
2015/02/24 20:52:39
Why is this not LocalLookupVariable?
hausner
2015/02/24 20:57:31
I think Ivan is right, this should only look up in
regis
2015/02/24 22:05:13
As explained by the comments (obviously not clearl
| |
| 9000 trace_var = scope->LookupVariable(Symbols::SavedStackTraceVar(), false); | |
| 9001 } else { | |
| 9002 // The exception and stack trace variables are bound in the block | |
| 9003 // containing the try. | |
| 9004 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); | |
| 9005 ASSERT(scope != NULL); | |
| 9006 excp_var = scope->LocalLookupVariable(Symbols::ExceptionVar()); | |
| 9007 trace_var = scope->LocalLookupVariable(Symbols::StackTraceVar()); | |
| 9008 } | |
| 8940 ASSERT(excp_var != NULL); | 9009 ASSERT(excp_var != NULL); |
| 8941 LocalVariable* trace_var = | |
| 8942 scope->LocalLookupVariable(Symbols::StackTraceVar()); | |
| 8943 ASSERT(trace_var != NULL); | 9010 ASSERT(trace_var != NULL); |
| 9011 | |
| 8944 statement = new(Z) ThrowNode( | 9012 statement = new(Z) ThrowNode( |
| 8945 statement_pos, | 9013 statement_pos, |
| 8946 new(Z) LoadLocalNode(statement_pos, excp_var), | 9014 new(Z) LoadLocalNode(statement_pos, excp_var), |
| 8947 new(Z) LoadLocalNode(statement_pos, trace_var)); | 9015 new(Z) LoadLocalNode(statement_pos, trace_var)); |
| 8948 } else { | 9016 } else { |
| 8949 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9017 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8950 ExpectSemicolon(); | 9018 ExpectSemicolon(); |
| 8951 } | 9019 } |
| 8952 return statement; | 9020 return statement; |
| 8953 } | 9021 } |
| (...skipping 3614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12568 void Parser::SkipQualIdent() { | 12636 void Parser::SkipQualIdent() { |
| 12569 ASSERT(IsIdentifier()); | 12637 ASSERT(IsIdentifier()); |
| 12570 ConsumeToken(); | 12638 ConsumeToken(); |
| 12571 if (CurrentToken() == Token::kPERIOD) { | 12639 if (CurrentToken() == Token::kPERIOD) { |
| 12572 ConsumeToken(); // Consume the kPERIOD token. | 12640 ConsumeToken(); // Consume the kPERIOD token. |
| 12573 ExpectIdentifier("identifier expected after '.'"); | 12641 ExpectIdentifier("identifier expected after '.'"); |
| 12574 } | 12642 } |
| 12575 } | 12643 } |
| 12576 | 12644 |
| 12577 } // namespace dart | 12645 } // namespace dart |
| OLD | NEW |