Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Unified Diff: runtime/vm/parser.cc

Issue 577423005: Fix context handling in for-in loops (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/debugger.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « runtime/vm/debugger.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698