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

Unified Diff: runtime/vm/parser.cc

Issue 2939553005: Updated parser to produce error when trying to reinitialize final variables in class constructors. … (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index f96c1a3ec17e9fb14636824aff397baba1ee81ab..f191c8574d8bbf01d0fbc271a667cbda6b66e839 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -3021,6 +3021,15 @@ AstNode* Parser::CheckDuplicateFieldInit(
if (initialized_field == NULL) {
break;
}
+
+ const String& initialized_name =
+ String::ZoneHandle(initialized_field->name());
+ const String& field_name = String::ZoneHandle(field->name());
siva 2017/06/13 22:20:08 Why do these have to be zone handles and not just
+ if (initialized_name.Equals(field_name) && field->IsFinalAndInitialized()) {
+ ReportError(init_pos, "'%s' is initialized already, and final.",
zra 2017/06/13 20:19:41 How about "final field '%s' is already initialized
bkonyi 2017/06/13 22:16:47 Done.
+ field_name.ToCString());
+ }
+
if (initialized_field->raw() == field->raw()) {
// This final field has been initialized by an inlined
// initializer expression. This is a runtime error.
@@ -4495,6 +4504,37 @@ void Parser::CheckMemberNameConflict(ClassDesc* members, MemberDesc* member) {
}
+void Parser::CheckMemberAlreadyInitializedConflicts(ClassDesc* members,
+ MemberDesc* member) {
+ if (!member->IsConstructor()) {
+ return;
+ }
+ ParamList* params = &member->params;
+ if (!params->has_field_initializer) {
+ return;
+ }
+ const ZoneGrowableArray<ParamDesc>& parameters = *params->parameters;
+ for (int p = 0; p < parameters.length(); p++) {
zra 2017/06/13 20:19:41 intptr_t p
bkonyi 2017/06/13 22:16:47 Done.
+ const ParamDesc& current_param = parameters[p];
+ if (!current_param.is_field_initializer) {
+ continue;
+ }
+ const String& name = *current_param.name;
+ for (int i = 0; i < members->members().length(); i++) {
zra 2017/06/13 20:19:42 intptr_t i
bkonyi 2017/06/13 22:16:47 Done.
+ MemberDesc* existing_member = &members->members()[i];
+ if (existing_member->has_final &&
+ name.Equals(*existing_member->DictName()) &&
+ existing_member->field_ != NULL &&
zra 2017/06/13 20:19:42 parens around != clause
bkonyi 2017/06/13 22:16:47 Done.
+ existing_member->field_->IsFinalAndInitialized()) {
+ ReportError(current_param.name_pos,
+ "'%s' is initialized already, and final.",
zra 2017/06/13 20:19:41 "final field %s is already initialized"
bkonyi 2017/06/13 22:16:47 Done.
+ existing_member->DictName()->ToCString());
+ }
+ }
+ }
+}
+
+
void Parser::ParseClassMemberDefinition(ClassDesc* members,
TokenPosition metadata_pos) {
TRACE_PARSER("ParseClassMemberDefinition");
@@ -4707,6 +4747,7 @@ void Parser::ParseClassMemberDefinition(ClassDesc* members,
}
current_member_ = NULL;
CheckMemberNameConflict(members, &member);
+ CheckMemberAlreadyInitializedConflicts(members, &member);
members->AddMember(member);
}
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698