Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: runtime/vm/parser.cc

Issue 2949943002: Revert "Updated parser to produce error when trying to reinitialize final variables in class constr… (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2988 matching lines...) Expand 10 before | Expand all | Expand 10 after
2999 2999
3000 3000
3001 AstNode* Parser::CheckDuplicateFieldInit( 3001 AstNode* Parser::CheckDuplicateFieldInit(
3002 TokenPosition init_pos, 3002 TokenPosition init_pos,
3003 GrowableArray<Field*>* initialized_fields, 3003 GrowableArray<Field*>* initialized_fields,
3004 AstNode* instance, 3004 AstNode* instance,
3005 Field* field, 3005 Field* field,
3006 AstNode* init_value) { 3006 AstNode* init_value) {
3007 ASSERT(!field->is_static()); 3007 ASSERT(!field->is_static());
3008 AstNode* result = NULL; 3008 AstNode* result = NULL;
3009 const String& field_name = String::Handle(field->name());
3010 String& initialized_name = String::Handle(Z);
3011 3009
3012 // The initializer_list is divided into two sections. The sections 3010 // The initializer_list is divided into two sections. The sections
3013 // are separated by a NULL entry: [f0, ... fn, NULL, fn+1, ...] 3011 // are separated by a NULL entry: [f0, ... fn, NULL, fn+1, ...]
3014 // The first fields f0 .. fn are final fields of the class that 3012 // The first fields f0 .. fn are final fields of the class that
3015 // have an initializer expression inlined in the class declaration. 3013 // have an initializer expression inlined in the class declaration.
3016 // The remaining fields are those initialized by the constructor's 3014 // The remaining fields are those initialized by the constructor's
3017 // initializing formals and initializer list 3015 // initializing formals and initializer list
3018 int initializer_idx = 0; 3016 int initializer_idx = 0;
3019 while (initializer_idx < initialized_fields->length()) { 3017 while (initializer_idx < initialized_fields->length()) {
3020 Field* initialized_field = (*initialized_fields)[initializer_idx]; 3018 Field* initialized_field = (*initialized_fields)[initializer_idx];
3021 initializer_idx++; 3019 initializer_idx++;
3022 if (initialized_field == NULL) { 3020 if (initialized_field == NULL) {
3023 break; 3021 break;
3024 } 3022 }
3025
3026 initialized_name ^= initialized_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 }
3031
3032 if (initialized_field->raw() == field->raw()) { 3023 if (initialized_field->raw() == field->raw()) {
3033 // This final field has been initialized by an inlined 3024 // This final field has been initialized by an inlined
3034 // initializer expression. This is a runtime error. 3025 // initializer expression. This is a runtime error.
3035 // Throw a NoSuchMethodError for the missing setter. 3026 // Throw a NoSuchMethodError for the missing setter.
3036 ASSERT(field->is_final()); 3027 ASSERT(field->is_final());
3037 3028
3038 // Build a call to NoSuchMethodError::_throwNew( 3029 // Build a call to NoSuchMethodError::_throwNew(
3039 // Object receiver, 3030 // Object receiver,
3040 // String memberName, 3031 // String memberName,
3041 // int invocation_type, 3032 // int invocation_type,
(...skipping 2200 matching lines...) Expand 10 before | Expand all | Expand 10 after
5242 AddFormalParamsToFunction(&params, ctor); 5233 AddFormalParamsToFunction(&params, ctor);
5243 ctor.set_result_type(Object::dynamic_type()); 5234 ctor.set_result_type(Object::dynamic_type());
5244 ResolveSignature(ctor); 5235 ResolveSignature(ctor);
5245 // The body of the constructor cannot modify the type of the constructed 5236 // The body of the constructor cannot modify the type of the constructed
5246 // instance, which is passed in as the receiver. 5237 // instance, which is passed in as the receiver.
5247 ctor.set_result_type(*receiver_type); 5238 ctor.set_result_type(*receiver_type);
5248 cls.AddFunction(ctor); 5239 cls.AddFunction(ctor);
5249 } 5240 }
5250 5241
5251 5242
5252 void Parser::CheckFinalInitializationConflicts(const ClassDesc* class_desc,
5253 const MemberDesc* member) {
5254 const ParamList* params = &member->params;
5255 if (!params->has_field_initializer) {
5256 return;
5257 }
5258
5259 const ZoneGrowableArray<ParamDesc>& parameters = *params->parameters;
5260 const GrowableArray<const Field*>& fields = class_desc->fields();
5261 String& field_name = String::Handle(Z);
5262
5263 for (intptr_t p = 0; p < parameters.length(); p++) {
5264 const ParamDesc& current_param = parameters[p];
5265 if (!current_param.is_field_initializer) {
5266 continue;
5267 }
5268
5269 const String& param_name = *current_param.name;
5270 for (intptr_t i = 0; i < fields.length(); i++) {
5271 const Field* current_field = fields.At(i);
5272 if (!current_field->is_final() || !current_field->has_initializer()) {
5273 continue;
5274 }
5275
5276 field_name ^= current_field->name();
5277 if (param_name.Equals(field_name)) {
5278 ReportError(current_param.name_pos,
5279 "final field '%s' is already initialized.",
5280 param_name.ToCString());
5281 }
5282 }
5283 }
5284 }
5285
5286
5287 // Check for cycles in constructor redirection. 5243 // Check for cycles in constructor redirection.
5288 void Parser::CheckConstructors(ClassDesc* class_desc) { 5244 void Parser::CheckConstructors(ClassDesc* class_desc) {
5289 // Check for cycles in constructor redirection. 5245 // Check for cycles in constructor redirection.
5290 const GrowableArray<MemberDesc>& members = class_desc->members(); 5246 const GrowableArray<MemberDesc>& members = class_desc->members();
5291 for (int i = 0; i < members.length(); i++) { 5247 for (int i = 0; i < members.length(); i++) {
5292 MemberDesc* member = &members[i]; 5248 MemberDesc* member = &members[i];
5293 if (member->IsConstructor()) {
5294 // Check that our constructors don't try and reinitialize an initialized
5295 // final variable.
5296 CheckFinalInitializationConflicts(class_desc, member);
5297 }
5298 if (member->redirect_name == NULL) { 5249 if (member->redirect_name == NULL) {
5299 continue; 5250 continue;
5300 } 5251 }
5301 GrowableArray<MemberDesc*> ctors; 5252 GrowableArray<MemberDesc*> ctors;
5302 while ((member != NULL) && (member->redirect_name != NULL)) { 5253 while ((member != NULL) && (member->redirect_name != NULL)) {
5303 ASSERT(member->IsConstructor()); 5254 ASSERT(member->IsConstructor());
5304 // Check whether we have already seen this member. 5255 // Check whether we have already seen this member.
5305 for (int i = 0; i < ctors.length(); i++) { 5256 for (int i = 0; i < ctors.length(); i++) {
5306 if (ctors[i] == member) { 5257 if (ctors[i] == member) {
5307 ReportError(member->name_pos, 5258 ReportError(member->name_pos,
(...skipping 10054 matching lines...) Expand 10 before | Expand all | Expand 10 after
15362 TokenPosition* start, 15313 TokenPosition* start,
15363 TokenPosition* end) { 15314 TokenPosition* end) {
15364 UNREACHABLE(); 15315 UNREACHABLE();
15365 return false; 15316 return false;
15366 } 15317 }
15367 15318
15368 15319
15369 } // namespace dart 15320 } // namespace dart
15370 15321
15371 #endif // DART_PRECOMPILED_RUNTIME 15322 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698