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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 }; | 426 }; |
427 | 427 |
428 | 428 |
429 struct ParamDesc { | 429 struct ParamDesc { |
430 ParamDesc() | 430 ParamDesc() |
431 : type(NULL), | 431 : type(NULL), |
432 name_pos(0), | 432 name_pos(0), |
433 name(NULL), | 433 name(NULL), |
434 default_value(NULL), | 434 default_value(NULL), |
435 metadata(NULL), | 435 metadata(NULL), |
| 436 var(NULL), |
436 is_final(false), | 437 is_final(false), |
437 is_field_initializer(false) { } | 438 is_field_initializer(false) { } |
438 const AbstractType* type; | 439 const AbstractType* type; |
439 intptr_t name_pos; | 440 intptr_t name_pos; |
440 const String* name; | 441 const String* name; |
441 const Object* default_value; // NULL if not an optional parameter. | 442 const Object* default_value; // NULL if not an optional parameter. |
442 const Object* metadata; // NULL if no metadata or metadata not evaluated. | 443 const Object* metadata; // NULL if no metadata or metadata not evaluated. |
| 444 LocalVariable* var; // Scope variable allocated for this parameter. |
443 bool is_final; | 445 bool is_final; |
444 bool is_field_initializer; | 446 bool is_field_initializer; |
445 }; | 447 }; |
446 | 448 |
447 | 449 |
448 struct ParamList { | 450 struct ParamList { |
449 ParamList() { | 451 ParamList() { |
450 Clear(); | 452 Clear(); |
451 } | 453 } |
452 | 454 |
(...skipping 18 matching lines...) Expand all Loading... |
471 param.is_final = true; | 473 param.is_final = true; |
472 param.type = type; | 474 param.type = type; |
473 this->parameters->Add(param); | 475 this->parameters->Add(param); |
474 } | 476 } |
475 | 477 |
476 void AddReceiver(const AbstractType* receiver_type, intptr_t token_pos) { | 478 void AddReceiver(const AbstractType* receiver_type, intptr_t token_pos) { |
477 ASSERT(this->parameters->is_empty()); | 479 ASSERT(this->parameters->is_empty()); |
478 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); | 480 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); |
479 } | 481 } |
480 | 482 |
| 483 |
| 484 // Make the parameter variables visible/invisible. |
| 485 // Field initializer parameters are always invisible. |
| 486 void SetInvisible(bool invisible) { |
| 487 const intptr_t num_params = parameters->length(); |
| 488 for (int i = 0; i < num_params; i++) { |
| 489 ParamDesc& param = (*parameters)[i]; |
| 490 ASSERT(param.var != NULL); |
| 491 if (!param.is_field_initializer) { |
| 492 param.var->set_invisible(invisible); |
| 493 } |
| 494 } |
| 495 } |
| 496 |
481 void SetImplicitlyFinal() { | 497 void SetImplicitlyFinal() { |
482 implicitly_final = true; | 498 implicitly_final = true; |
483 } | 499 } |
484 | 500 |
485 int num_fixed_parameters; | 501 int num_fixed_parameters; |
486 int num_optional_parameters; | 502 int num_optional_parameters; |
487 bool has_optional_positional_parameters; | 503 bool has_optional_positional_parameters; |
488 bool has_optional_named_parameters; | 504 bool has_optional_named_parameters; |
489 bool has_field_initializer; | 505 bool has_field_initializer; |
490 bool implicitly_final; | 506 bool implicitly_final; |
(...skipping 1985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2476 | 2492 |
2477 GenerateSuperConstructorCall(current_class(), receiver, forwarding_args); | 2493 GenerateSuperConstructorCall(current_class(), receiver, forwarding_args); |
2478 CheckConstFieldsInitialized(current_class()); | 2494 CheckConstFieldsInitialized(current_class()); |
2479 | 2495 |
2480 // Empty constructor body. | 2496 // Empty constructor body. |
2481 SequenceNode* statements = CloseBlock(); | 2497 SequenceNode* statements = CloseBlock(); |
2482 return statements; | 2498 return statements; |
2483 } | 2499 } |
2484 | 2500 |
2485 | 2501 |
2486 // Helper function to make the first num_variables variables in the | |
2487 // given scope visible/invisible. | |
2488 static void SetInvisible(LocalScope* scope, int num_variables, bool invisible) { | |
2489 ASSERT(num_variables <= scope->num_variables()); | |
2490 for (int i = 0; i < num_variables; i++) { | |
2491 scope->VariableAt(i)->set_invisible(invisible); | |
2492 } | |
2493 } | |
2494 | |
2495 | |
2496 void Parser::CheckRecursiveInvocation() { | 2502 void Parser::CheckRecursiveInvocation() { |
2497 const GrowableObjectArray& pending_functions = | 2503 const GrowableObjectArray& pending_functions = |
2498 GrowableObjectArray::Handle( | 2504 GrowableObjectArray::Handle( |
2499 isolate()->object_store()->pending_functions()); | 2505 isolate()->object_store()->pending_functions()); |
2500 for (int i = 0; i < pending_functions.Length(); i++) { | 2506 for (int i = 0; i < pending_functions.Length(); i++) { |
2501 if (pending_functions.At(i) == current_function().raw()) { | 2507 if (pending_functions.At(i) == current_function().raw()) { |
2502 const String& fname = | 2508 const String& fname = |
2503 String::Handle(current_function().UserVisibleName()); | 2509 String::Handle(current_function().UserVisibleName()); |
2504 ErrorMsg("circular dependency for function %s", fname.ToCString()); | 2510 ErrorMsg("circular dependency for function %s", fname.ToCString()); |
2505 } | 2511 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2561 | 2567 |
2562 // Now populate function scope with the formal parameters. | 2568 // Now populate function scope with the formal parameters. |
2563 AddFormalParamsToScope(¶ms, current_block_->scope); | 2569 AddFormalParamsToScope(¶ms, current_block_->scope); |
2564 | 2570 |
2565 // Initialize instance fields that have an explicit initializer expression. | 2571 // Initialize instance fields that have an explicit initializer expression. |
2566 // The formal parameter names must not be visible to the instance | 2572 // The formal parameter names must not be visible to the instance |
2567 // field initializer expressions, yet the parameters must be added to | 2573 // field initializer expressions, yet the parameters must be added to |
2568 // the scope so the expressions use the correct offsets for 'this' when | 2574 // the scope so the expressions use the correct offsets for 'this' when |
2569 // storing values. We make the formal parameters temporarily invisible | 2575 // storing values. We make the formal parameters temporarily invisible |
2570 // while parsing the instance field initializer expressions. | 2576 // while parsing the instance field initializer expressions. |
2571 SetInvisible(current_block_->scope, params.parameters->length(), true); | 2577 params.SetInvisible(true); |
2572 GrowableArray<Field*> initialized_fields; | 2578 GrowableArray<Field*> initialized_fields; |
2573 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 2579 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
2574 OpenBlock(); | 2580 OpenBlock(); |
2575 ParseInitializedInstanceFields(cls, receiver, &initialized_fields); | 2581 ParseInitializedInstanceFields(cls, receiver, &initialized_fields); |
2576 // Make the parameters (which are in the outer scope) visible again. | 2582 // Make the parameters (which are in the outer scope) visible again. |
2577 SetInvisible(current_block_->scope->parent(), | 2583 params.SetInvisible(false); |
2578 params.parameters->length(), false); | |
2579 | 2584 |
2580 // Turn formal field parameters into field initializers or report error | 2585 // Turn formal field parameters into field initializers or report error |
2581 // if the function is not a constructor. | 2586 // if the function is not a constructor. |
2582 if (params.has_field_initializer) { | 2587 if (params.has_field_initializer) { |
2583 for (int i = 0; i < params.parameters->length(); i++) { | 2588 for (int i = 0; i < params.parameters->length(); i++) { |
2584 ParamDesc& param = (*params.parameters)[i]; | 2589 ParamDesc& param = (*params.parameters)[i]; |
2585 if (param.is_field_initializer) { | 2590 if (param.is_field_initializer) { |
2586 const String& field_name = *param.name; | 2591 const String& field_name = *param.name; |
2587 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); | 2592 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); |
2588 if (field.IsNull()) { | 2593 if (field.IsNull()) { |
2589 ErrorMsg(param.name_pos, | 2594 ErrorMsg(param.name_pos, |
2590 "unresolved reference to instance field '%s'", | 2595 "unresolved reference to instance field '%s'", |
2591 field_name.ToCString()); | 2596 field_name.ToCString()); |
2592 } | 2597 } |
2593 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); | 2598 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); |
2594 AstNode* instance = new LoadLocalNode(param.name_pos, receiver); | 2599 AstNode* instance = new LoadLocalNode(param.name_pos, receiver); |
2595 LocalVariable* p = | |
2596 current_block_->scope->LookupVariable(*param.name, false); | |
2597 ASSERT(p != NULL); | |
2598 // Initializing formals cannot be used in the explicit initializer | 2600 // Initializing formals cannot be used in the explicit initializer |
2599 // list, nor can they be used in the constructor body. | 2601 // list, nor can they be used in the constructor body. |
2600 // Thus, make the parameter invisible. | 2602 // Thus, they are set to be invisible when added to the scope. |
2601 p->set_invisible(true); | 2603 LocalVariable* p = param.var; |
| 2604 ASSERT(p != NULL); |
| 2605 ASSERT(p->is_invisible()); |
2602 AstNode* value = new LoadLocalNode(param.name_pos, p); | 2606 AstNode* value = new LoadLocalNode(param.name_pos, p); |
2603 EnsureExpressionTemp(); | 2607 EnsureExpressionTemp(); |
2604 AstNode* initializer = new StoreInstanceFieldNode( | 2608 AstNode* initializer = new StoreInstanceFieldNode( |
2605 param.name_pos, instance, field, value); | 2609 param.name_pos, instance, field, value); |
2606 current_block_->statements->Add(initializer); | 2610 current_block_->statements->Add(initializer); |
2607 } | 2611 } |
2608 } | 2612 } |
2609 } | 2613 } |
2610 | 2614 |
2611 // Now parse the explicit initializer list or constructor redirection. | 2615 // Now parse the explicit initializer list or constructor redirection. |
(...skipping 2552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5164 ParamDesc& param_desc = (*params->parameters)[i]; | 5168 ParamDesc& param_desc = (*params->parameters)[i]; |
5165 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); | 5169 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); |
5166 const String* name = param_desc.name; | 5170 const String* name = param_desc.name; |
5167 LocalVariable* parameter = new LocalVariable( | 5171 LocalVariable* parameter = new LocalVariable( |
5168 param_desc.name_pos, *name, *param_desc.type); | 5172 param_desc.name_pos, *name, *param_desc.type); |
5169 if (!scope->AddVariable(parameter)) { | 5173 if (!scope->AddVariable(parameter)) { |
5170 ErrorMsg(param_desc.name_pos, | 5174 ErrorMsg(param_desc.name_pos, |
5171 "name '%s' already exists in scope", | 5175 "name '%s' already exists in scope", |
5172 param_desc.name->ToCString()); | 5176 param_desc.name->ToCString()); |
5173 } | 5177 } |
| 5178 param_desc.var = parameter; |
5174 if (param_desc.is_final) { | 5179 if (param_desc.is_final) { |
5175 parameter->set_is_final(); | 5180 parameter->set_is_final(); |
5176 } | 5181 } |
| 5182 if (param_desc.is_field_initializer) { |
| 5183 parameter->set_invisible(true); |
| 5184 } |
5177 } | 5185 } |
5178 } | 5186 } |
5179 | 5187 |
5180 | 5188 |
5181 // Builds ReturnNode/NativeBodyNode for a native function. | 5189 // Builds ReturnNode/NativeBodyNode for a native function. |
5182 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 5190 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
5183 const Function& func) { | 5191 const Function& func) { |
5184 func.set_is_native(true); | 5192 func.set_is_native(true); |
5185 TRACE_PARSER("ParseNativeFunctionBlock"); | 5193 TRACE_PARSER("ParseNativeFunctionBlock"); |
5186 const Class& cls = Class::Handle(func.Owner()); | 5194 const Class& cls = Class::Handle(func.Owner()); |
(...skipping 5227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10414 void Parser::SkipQualIdent() { | 10422 void Parser::SkipQualIdent() { |
10415 ASSERT(IsIdentifier()); | 10423 ASSERT(IsIdentifier()); |
10416 ConsumeToken(); | 10424 ConsumeToken(); |
10417 if (CurrentToken() == Token::kPERIOD) { | 10425 if (CurrentToken() == Token::kPERIOD) { |
10418 ConsumeToken(); // Consume the kPERIOD token. | 10426 ConsumeToken(); // Consume the kPERIOD token. |
10419 ExpectIdentifier("identifier expected after '.'"); | 10427 ExpectIdentifier("identifier expected after '.'"); |
10420 } | 10428 } |
10421 } | 10429 } |
10422 | 10430 |
10423 } // namespace dart | 10431 } // namespace dart |
OLD | NEW |