| 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 |