Chromium Code Reviews| Index: runtime/vm/parser.cc |
| =================================================================== |
| --- runtime/vm/parser.cc (revision 27495) |
| +++ runtime/vm/parser.cc (working copy) |
| @@ -433,6 +433,7 @@ |
| name(NULL), |
| default_value(NULL), |
| metadata(NULL), |
| + var(NULL), |
| is_final(false), |
| is_field_initializer(false) { } |
| const AbstractType* type; |
| @@ -440,6 +441,7 @@ |
| const String* name; |
| const Object* default_value; // NULL if not an optional parameter. |
| const Object* metadata; // NULL if no metadata or metadata not evaluated. |
| + LocalVariable* var; // Scope variable allocated for this parameter. |
|
regis
2013/09/13 18:38:45
Do not align comment.
hausner
2013/09/13 21:32:16
Done.
|
| bool is_final; |
| bool is_field_initializer; |
| }; |
| @@ -478,6 +480,20 @@ |
| AddFinalParameter(token_pos, &Symbols::This(), receiver_type); |
| } |
| + |
| + // Make the parameter variables visible/invisible. |
| + // Field initializer parameters are always invisible. |
| + void SetInvisible(bool invisible) { |
| + const intptr_t num_params = parameters->length(); |
| + for (int i = 0; i < num_params; i++) { |
| + ParamDesc& param = (*parameters)[i]; |
| + ASSERT(param.var != NULL); |
| + if (!param.is_field_initializer) { |
| + param.var->set_invisible(invisible); |
| + } |
| + } |
| + } |
| + |
| void SetImplicitlyFinal() { |
| implicitly_final = true; |
| } |
| @@ -2483,16 +2499,6 @@ |
| } |
| -// Helper function to make the first num_variables variables in the |
| -// given scope visible/invisible. |
| -static void SetInvisible(LocalScope* scope, int num_variables, bool invisible) { |
| - ASSERT(num_variables <= scope->num_variables()); |
| - for (int i = 0; i < num_variables; i++) { |
| - scope->VariableAt(i)->set_invisible(invisible); |
| - } |
| -} |
| - |
| - |
| void Parser::CheckRecursiveInvocation() { |
| const GrowableObjectArray& pending_functions = |
| GrowableObjectArray::Handle( |
| @@ -2568,14 +2574,13 @@ |
| // the scope so the expressions use the correct offsets for 'this' when |
| // storing values. We make the formal parameters temporarily invisible |
| // while parsing the instance field initializer expressions. |
| - SetInvisible(current_block_->scope, params.parameters->length(), true); |
| + params.SetInvisible(true); |
| GrowableArray<Field*> initialized_fields; |
| LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| OpenBlock(); |
| ParseInitializedInstanceFields(cls, receiver, &initialized_fields); |
| // Make the parameters (which are in the outer scope) visible again. |
| - SetInvisible(current_block_->scope->parent(), |
| - params.parameters->length(), false); |
| + params.SetInvisible(false); |
| // Turn formal field parameters into field initializers or report error |
| // if the function is not a constructor. |
| @@ -2592,13 +2597,12 @@ |
| } |
| CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); |
| AstNode* instance = new LoadLocalNode(param.name_pos, receiver); |
| - LocalVariable* p = |
| - current_block_->scope->LookupVariable(*param.name, false); |
| - ASSERT(p != NULL); |
| // Initializing formals cannot be used in the explicit initializer |
| // list, nor can they be used in the constructor body. |
| - // Thus, make the parameter invisible. |
| - p->set_invisible(true); |
| + // Thus, they are set to be invisible when added to the scope. |
| + LocalVariable* p = param.var; |
| + ASSERT(p != NULL); |
| + ASSERT(p->is_invisible()); |
| AstNode* value = new LoadLocalNode(param.name_pos, p); |
| EnsureExpressionTemp(); |
| AstNode* initializer = new StoreInstanceFieldNode( |
| @@ -5171,9 +5175,13 @@ |
| "name '%s' already exists in scope", |
| param_desc.name->ToCString()); |
| } |
| + param_desc.var = parameter; |
| if (param_desc.is_final) { |
| parameter->set_is_final(); |
| } |
| + if (param_desc.is_field_initializer) { |
| + parameter->set_invisible(true); |
| + } |
| } |
| } |