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 cbd139f04f2..d7802122846 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 @@ abstract class BodyBuilder extends ScopeListener 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 c2ca617618d..212281c0cf1 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 @@ class KernelTypeUseGenerator extends KernelReadOnlyAccessGenerator 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 be97aabb48f..e2a78401932 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 @@ class SourceClassBuilder extends KernelClassBuilder 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 07d9eb6c815..ede5fecff55 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 @@ abstract class SourceLibraryBuilder 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 00000000000..a2a0bd510dd --- /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 actual = []; +void printx(Object x) { + actual.add(x.toString()); +} + +List expected = [ + "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", +];