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 |