Const fields doesn't introduce setters; look for setter
Fixes #28268.
Change-Id: I43ccc4072be2fba3ee9273d451fc767876191e16
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100964
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index cbd139f..d780212 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1843,8 +1843,12 @@
setter = declaration;
} else if (declaration.isGetter) {
setter = scope.lookupSetter(name, charOffset, uri);
- } else if (declaration.isField && !declaration.isFinal) {
- setter = declaration;
+ } else if (declaration.isField) {
+ if (declaration.isFinal || declaration.isConst) {
+ setter = scope.lookupSetter(name, charOffset, uri);
+ } else {
+ setter = declaration;
+ }
}
StaticAccessGenerator generator = new StaticAccessGenerator.fromBuilder(
this, declaration, token, setter);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
index c2ca617..212281c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
@@ -1350,8 +1350,14 @@
setter = declaration.findStaticBuilder(
name.name, offsetForToken(token), uri, helper.library,
isSetter: true);
- } else if (member.isField && !member.isFinal) {
- setter = member;
+ } else if (member.isField) {
+ if (member.isFinal || member.isConst) {
+ setter = declaration.findStaticBuilder(
+ name.name, offsetForToken(token), uri, helper.library,
+ isSetter: true);
+ } else {
+ setter = member;
+ }
}
generator = new StaticAccessGenerator.fromBuilder(
helper, member, send.token, setter);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index be97aab..e2a7840 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -202,9 +202,10 @@
scope.setters.forEach((String name, Declaration setter) {
Declaration member = scopeBuilder[name];
if (member == null ||
- !(member.isField && !member.isFinal ||
- member.isRegularMethod && member.isStatic && setter.isStatic))
+ !(member.isField && !member.isFinal && !member.isConst ||
+ member.isRegularMethod && member.isStatic && setter.isStatic)) {
return;
+ }
if (member.isInstanceMember == setter.isInstanceMember) {
addProblem(templateConflictsWithMember.withArguments(name),
setter.charOffset, noLength);
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 07d9eb6..ede5fec 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -618,7 +618,12 @@
scope.setters.forEach((String name, Declaration setter) {
Declaration member = scopeBuilder[name];
- if (member == null || !member.isField || member.isFinal) return;
+ if (member == null ||
+ !member.isField ||
+ member.isFinal ||
+ member.isConst) {
+ return;
+ }
addProblem(templateConflictsWithMember.withArguments(name),
setter.charOffset, noLength, fileUri);
// TODO(ahe): Context to previous message?
diff --git a/tests/language_2/regress_28268_test.dart b/tests/language_2/regress_28268_test.dart
new file mode 100644
index 0000000..a2a0bd5
--- /dev/null
+++ b/tests/language_2/regress_28268_test.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+class E {
+ static final String a = "get a";
+ static void set a(String o) {
+ printx("set a: $o");
+ }
+
+ static const String b = "get b";
+ static void set b(String o) {
+ printx("set b: $o");
+ }
+
+ static void set c(String o) {
+ printx("set c: $o");
+ }
+
+ final String d = "get d";
+ void set d(String o) {
+ printx("set d: $o");
+ }
+
+ final String e = "get e";
+
+ static const String f = "get f";
+
+ set g(v) {
+ printx("set g: $v");
+ }
+
+ set h(v) {
+ printx("set h: $v");
+ }
+
+ foo() {
+ printx(e);
+ e = "set e"; // //# 01: compile-time error
+ printx(e);
+
+ printx(f);
+ f = "set f"; // //# 02: compile-time error
+ printx(f);
+
+ printx(g); // //# 03: compile-time error
+ g = "set g";
+ printx(g); // //# 04: compile-time error
+
+ printx(h); // //# 05: compile-time error
+ h = "set h";
+ printx(h); // //# 06: compile-time error
+ }
+}
+
+set e(v) {
+ printx("Setting top-level e: $v");
+}
+
+set f(v) {
+ printx("Setting top-level f: $v");
+}
+
+final String g = "get g";
+
+const String h = "get h";
+
+const x = 42;
+final y = 42;
+
+set x(v) {
+ printx("Setting top-level x: $v");
+}
+
+set y(v) {
+ printx("Setting top-level y: $v");
+}
+
+main() {
+ printx(E.a);
+ E.a = "set E";
+ printx(E.a);
+
+ printx(E.b);
+ E.b = "set E";
+ printx(E.b);
+
+ E.c = "set E";
+
+ E eInstance = new E();
+ printx(eInstance.d);
+ eInstance.d = "set eInstance";
+ printx(eInstance.d);
+ eInstance.foo();
+
+ printx(e); // //# 07: compile-time error
+ e = "set e";
+ printx(e); // //# 08: compile-time error
+
+ printx(f); // //# 09: compile-time error
+ f = "set f";
+ printx(f); // //# 10: compile-time error
+
+ printx(g);
+ g = "set g"; // //# 11: compile-time error
+ printx(g);
+
+ printx(h);
+ h = "set h"; // //# 12: compile-time error
+ printx(h);
+
+ printx(x);
+ x = "Hello world!";
+ printx(x);
+
+ printx(y);
+ y = "Hello world!";
+ printx(y);
+
+ Expect.listEquals(expected, actual);
+}
+
+List<String> actual = <String>[];
+void printx(Object x) {
+ actual.add(x.toString());
+}
+
+List<String> expected = <String>[
+ "get a",
+ "set a: set E",
+ "get a",
+ "get b",
+ "set b: set E",
+ "get b",
+ "set c: set E",
+ "get d",
+ "set d: set eInstance",
+ "get d",
+ "get e",
+ "get e",
+ "get f",
+ "get f",
+ "set g: set g",
+ "set h: set h",
+ "Setting top-level e: set e",
+ "Setting top-level f: set f",
+ "get g",
+ "get g",
+ "get h",
+ "get h",
+ "42",
+ "Setting top-level x: Hello world!",
+ "42",
+ "42",
+ "Setting top-level y: Hello world!",
+ "42",
+];