Index: runtime/vm/parser.cc |
=================================================================== |
--- runtime/vm/parser.cc (revision 40544) |
+++ runtime/vm/parser.cc (working copy) |
@@ -7223,28 +7223,24 @@ |
AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
SourceLabel* label) { |
TRACE_PARSER("ParseForInStatement"); |
- bool is_final = (CurrentToken() == Token::kFINAL); |
+ bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
if (CurrentToken() == Token::kCONST) { |
ReportError("Loop variable cannot be 'const'"); |
} |
const String* loop_var_name = NULL; |
- LocalVariable* loop_var = NULL; |
intptr_t loop_var_pos = 0; |
+ bool new_loop_var = false; |
+ AbstractType& loop_var_type = AbstractType::ZoneHandle(I); |
if (LookaheadToken(1) == Token::kIN) { |
loop_var_pos = TokenPos(); |
loop_var_name = ExpectIdentifier("variable name expected"); |
} else { |
// The case without a type is handled above, so require a type here. |
- const AbstractType& type = |
- AbstractType::ZoneHandle(I, ParseConstFinalVarOrType( |
- FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : |
- ClassFinalizer::kIgnore)); |
- loop_var_pos = TokenPos(); |
+ new_loop_var = true; |
+ loop_var_type = ParseConstFinalVarOrType( |
+ FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : |
+ ClassFinalizer::kIgnore); |
loop_var_name = ExpectIdentifier("variable name expected"); |
- loop_var = new(I) LocalVariable(loop_var_pos, *loop_var_name, type); |
- if (is_final) { |
- loop_var->set_is_final(); |
- } |
} |
ExpectToken(Token::kIN); |
const intptr_t collection_pos = TokenPos(); |
@@ -7286,25 +7282,36 @@ |
// loop body. |
OpenLoopBlock(); |
current_block_->scope->AddLabel(label); |
+ const intptr_t loop_var_assignment_pos = TokenPos(); |
AstNode* iterator_current = new(I) InstanceGetterNode( |
- collection_pos, |
- new(I) LoadLocalNode(collection_pos, iterator_var), |
+ loop_var_assignment_pos, |
+ new(I) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
Symbols::Current()); |
// Generate assignment of next iterator value to loop variable. |
AstNode* loop_var_assignment = NULL; |
- if (loop_var != NULL) { |
- // The for loop declares a new variable. Add it to the loop body scope. |
+ if (new_loop_var) { |
+ // The for loop variable is new for each iteration. |
+ // Create a variable and add it to the loop body scope. |
+ LocalVariable* loop_var = |
+ new(I) LocalVariable(loop_var_assignment_pos, |
+ *loop_var_name, |
+ loop_var_type);; |
+ if (loop_var_is_final) { |
+ loop_var->set_is_final(); |
+ } |
current_block_->scope->AddVariable(loop_var); |
- loop_var_assignment = |
- new(I) StoreLocalNode(loop_var_pos, loop_var, iterator_current); |
+ loop_var_assignment = new(I) StoreLocalNode( |
+ loop_var_assignment_pos, loop_var, iterator_current); |
} else { |
AstNode* loop_var_primary = |
ResolveIdent(loop_var_pos, *loop_var_name, false); |
ASSERT(!loop_var_primary->IsPrimaryNode()); |
- loop_var_assignment = CreateAssignmentNode( |
- loop_var_primary, iterator_current, loop_var_name, loop_var_pos); |
+ loop_var_assignment = CreateAssignmentNode(loop_var_primary, |
+ iterator_current, |
+ loop_var_name, |
+ loop_var_assignment_pos); |
ASSERT(loop_var_assignment != NULL); |
} |
current_block_->statements->Add(loop_var_assignment); |