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",
+];