Chromium Code Reviews| 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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 3003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3014 // have an initializer expression inlined in the class declaration. | 3014 // have an initializer expression inlined in the class declaration. |
| 3015 // The remaining fields are those initialized by the constructor's | 3015 // The remaining fields are those initialized by the constructor's |
| 3016 // initializing formals and initializer list | 3016 // initializing formals and initializer list |
| 3017 int initializer_idx = 0; | 3017 int initializer_idx = 0; |
| 3018 while (initializer_idx < initialized_fields->length()) { | 3018 while (initializer_idx < initialized_fields->length()) { |
| 3019 Field* initialized_field = (*initialized_fields)[initializer_idx]; | 3019 Field* initialized_field = (*initialized_fields)[initializer_idx]; |
| 3020 initializer_idx++; | 3020 initializer_idx++; |
| 3021 if (initialized_field == NULL) { | 3021 if (initialized_field == NULL) { |
| 3022 break; | 3022 break; |
| 3023 } | 3023 } |
| 3024 | |
| 3025 const String& initialized_name = String::Handle(initialized_field->name()); | |
| 3026 const String& field_name = String::Handle(field->name()); | |
| 3027 if (initialized_name.Equals(field_name) && field->has_initializer()) { | |
| 3028 ReportError(init_pos, "final field '%s' is already initialized.", | |
| 3029 field_name.ToCString()); | |
| 3030 } | |
|
siva
2017/06/16 00:51:10
Pull the handle creation outside the while loop
S
bkonyi
2017/06/16 19:40:44
Done.
| |
| 3031 | |
| 3024 if (initialized_field->raw() == field->raw()) { | 3032 if (initialized_field->raw() == field->raw()) { |
| 3025 // This final field has been initialized by an inlined | 3033 // This final field has been initialized by an inlined |
| 3026 // initializer expression. This is a runtime error. | 3034 // initializer expression. This is a runtime error. |
| 3027 // Throw a NoSuchMethodError for the missing setter. | 3035 // Throw a NoSuchMethodError for the missing setter. |
| 3028 ASSERT(field->is_final()); | 3036 ASSERT(field->is_final()); |
| 3029 | 3037 |
| 3030 // Build a call to NoSuchMethodError::_throwNew( | 3038 // Build a call to NoSuchMethodError::_throwNew( |
| 3031 // Object receiver, | 3039 // Object receiver, |
| 3032 // String memberName, | 3040 // String memberName, |
| 3033 // int invocation_type, | 3041 // int invocation_type, |
| (...skipping 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4488 MemberDesc* existing_member = &members->members()[i]; | 4496 MemberDesc* existing_member = &members->members()[i]; |
| 4489 if (name.Equals(*existing_member->DictName())) { | 4497 if (name.Equals(*existing_member->DictName())) { |
| 4490 ReportError( | 4498 ReportError( |
| 4491 member->name_pos, "%s '%s' conflicts with previously declared %s", | 4499 member->name_pos, "%s '%s' conflicts with previously declared %s", |
| 4492 member->ToCString(), name.ToCString(), existing_member->ToCString()); | 4500 member->ToCString(), name.ToCString(), existing_member->ToCString()); |
| 4493 } | 4501 } |
| 4494 } | 4502 } |
| 4495 } | 4503 } |
| 4496 | 4504 |
| 4497 | 4505 |
| 4506 void Parser::CheckFinalInitializationConflicts(ClassDesc* class_desc) { | |
| 4507 const GrowableArray<const Field*>& fields = class_desc->fields(); | |
| 4508 const GrowableArray<MemberDesc>& members = class_desc->members(); | |
| 4509 for (intptr_t i = 0; i < fields.length(); i++) { | |
| 4510 const Field* current_field = fields.At(i); | |
| 4511 if (!current_field->is_final() || !current_field->has_initializer()) { | |
| 4512 continue; | |
| 4513 } | |
| 4514 const String& field_name = String::Handle(current_field->name()); | |
| 4515 for (intptr_t j = 0; j < members.length(); j++) { | |
| 4516 const MemberDesc current_member = members.At(j); | |
| 4517 if (!current_member.IsConstructor()) { | |
| 4518 continue; | |
| 4519 } | |
| 4520 const ParamList* params = ¤t_member.params; | |
| 4521 if (!params->has_field_initializer) { | |
| 4522 continue; | |
| 4523 } | |
| 4524 const ZoneGrowableArray<ParamDesc>& parameters = *params->parameters; | |
| 4525 for (intptr_t p = 0; p < parameters.length(); p++) { | |
| 4526 const ParamDesc& current_param = parameters[p]; | |
| 4527 if (!current_param.is_field_initializer) { | |
| 4528 continue; | |
| 4529 } | |
| 4530 const String& param_name = *current_param.name; | |
| 4531 if (param_name.Equals(field_name)) { | |
| 4532 ReportError(current_param.name_pos, | |
| 4533 "final field '%s' is already initialized.", | |
| 4534 param_name.ToCString()); | |
| 4535 } | |
| 4536 } | |
| 4537 } | |
| 4538 } | |
| 4539 } | |
|
siva
2017/06/16 00:51:10
If you invert this loop as
for (intptr_t j = 0; j
bkonyi
2017/06/16 19:40:44
Done.
| |
| 4540 | |
| 4541 | |
| 4498 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 4542 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
| 4499 TokenPosition metadata_pos) { | 4543 TokenPosition metadata_pos) { |
| 4500 TRACE_PARSER("ParseClassMemberDefinition"); | 4544 TRACE_PARSER("ParseClassMemberDefinition"); |
| 4501 MemberDesc member; | 4545 MemberDesc member; |
| 4502 current_member_ = &member; | 4546 current_member_ = &member; |
| 4503 member.metadata_pos = metadata_pos; | 4547 member.metadata_pos = metadata_pos; |
| 4504 member.decl_begin_pos = TokenPos(); | 4548 member.decl_begin_pos = TokenPos(); |
| 4505 if ((CurrentToken() == Token::kEXTERNAL) && | 4549 if ((CurrentToken() == Token::kEXTERNAL) && |
| 4506 (LookaheadToken(1) != Token::kLPAREN)) { | 4550 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4507 ConsumeToken(); | 4551 ConsumeToken(); |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4968 ParseClassMemberDefinition(&members, metadata_pos); | 5012 ParseClassMemberDefinition(&members, metadata_pos); |
| 4969 } | 5013 } |
| 4970 ExpectToken(Token::kRBRACE); | 5014 ExpectToken(Token::kRBRACE); |
| 4971 | 5015 |
| 4972 if (cls.LookupTypeParameter(class_name) != TypeParameter::null()) { | 5016 if (cls.LookupTypeParameter(class_name) != TypeParameter::null()) { |
| 4973 ReportError(class_pos, "class name conflicts with type parameter '%s'", | 5017 ReportError(class_pos, "class name conflicts with type parameter '%s'", |
| 4974 class_name.ToCString()); | 5018 class_name.ToCString()); |
| 4975 } | 5019 } |
| 4976 CheckConstructors(&members); | 5020 CheckConstructors(&members); |
| 4977 | 5021 |
| 5022 // Check that our constructors don't try to reinitialize an initialized | |
| 5023 // final variable. | |
| 5024 CheckFinalInitializationConflicts(&members); | |
| 5025 | |
| 4978 // Need to compute this here since MakeArray() will clear the | 5026 // Need to compute this here since MakeArray() will clear the |
| 4979 // functions array in members. | 5027 // functions array in members. |
| 4980 const bool need_implicit_constructor = | 5028 const bool need_implicit_constructor = |
| 4981 !members.has_constructor() && !cls.is_patch(); | 5029 !members.has_constructor() && !cls.is_patch(); |
| 4982 | 5030 |
| 4983 cls.AddFields(members.fields()); | 5031 cls.AddFields(members.fields()); |
| 4984 | 5032 |
| 4985 // Creating a new array for functions marks the class as parsed. | 5033 // Creating a new array for functions marks the class as parsed. |
| 4986 Array& array = Array::Handle(Z, members.MakeFunctionsArray()); | 5034 Array& array = Array::Handle(Z, members.MakeFunctionsArray()); |
| 4987 cls.SetFunctions(array); | 5035 cls.SetFunctions(array); |
| (...skipping 10326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 15314 TokenPosition* start, | 15362 TokenPosition* start, |
| 15315 TokenPosition* end) { | 15363 TokenPosition* end) { |
| 15316 UNREACHABLE(); | 15364 UNREACHABLE(); |
| 15317 return false; | 15365 return false; |
| 15318 } | 15366 } |
| 15319 | 15367 |
| 15320 | 15368 |
| 15321 } // namespace dart | 15369 } // namespace dart |
| 15322 | 15370 |
| 15323 #endif // DART_PRECOMPILED_RUNTIME | 15371 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |