Skip to content

Commit d291c53

Browse files
chloestefantsovaCommit Bot
authored and
Commit Bot
committed
[cfe] Report errors in inherited restricted members in enums
Part of #47453 Change-Id: I5f80c3507a0264c4516d42967b148f4dc3fd08ad Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/237684 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent 6dfdbee commit d291c53

14 files changed

+2343
-0
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2949,6 +2949,38 @@ const MessageCode messageEnumInClass = const MessageCode("EnumInClass",
29492949
problemMessage: r"""Enums can't be declared inside classes.""",
29502950
correctionMessage: r"""Try moving the enum to the top-level.""");
29512951

2952+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2953+
const Template<Message Function(String name)> templateEnumInheritsRestricted =
2954+
const Template<Message Function(String name)>(
2955+
problemMessageTemplate:
2956+
r"""An enum can't inherit a member named '#name'.""",
2957+
withArguments: _withArgumentsEnumInheritsRestricted);
2958+
2959+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2960+
const Code<Message Function(String name)> codeEnumInheritsRestricted =
2961+
const Code<Message Function(String name)>(
2962+
"EnumInheritsRestricted",
2963+
);
2964+
2965+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2966+
Message _withArgumentsEnumInheritsRestricted(String name) {
2967+
if (name.isEmpty) throw 'No name provided';
2968+
name = demangleMixinApplicationName(name);
2969+
return new Message(codeEnumInheritsRestricted,
2970+
problemMessage: """An enum can't inherit a member named '${name}'.""",
2971+
arguments: {'name': name});
2972+
}
2973+
2974+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2975+
const Code<Null> codeEnumInheritsRestrictedMember =
2976+
messageEnumInheritsRestrictedMember;
2977+
2978+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
2979+
const MessageCode messageEnumInheritsRestrictedMember = const MessageCode(
2980+
"EnumInheritsRestrictedMember",
2981+
severity: Severity.context,
2982+
problemMessage: r"""This is the inherited member""");
2983+
29522984
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
29532985
const Code<Null> codeEnumInstantiation = messageEnumInstantiation;
29542986

pkg/front_end/lib/src/fasta/source/source_loader.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,6 +2134,45 @@ severity: $severity
21342134
}
21352135
ticker.logMs("Checked ${overrideChecks.length} overrides");
21362136

2137+
List<Name> restrictedMemberNames = <Name>[
2138+
new Name("index"),
2139+
new Name("hashCode"),
2140+
new Name("=="),
2141+
new Name("values")
2142+
];
2143+
List<Class?> restrictedMemberDeclarers = <Class?>[
2144+
(target.underscoreEnumType.declaration as ClassBuilder).cls,
2145+
coreTypes.objectClass,
2146+
coreTypes.objectClass,
2147+
null
2148+
];
2149+
for (SourceClassBuilder classBuilder in sourceClasses) {
2150+
if (classBuilder.isEnum) {
2151+
for (int i = 0; i < restrictedMemberNames.length; ++i) {
2152+
Name name = restrictedMemberNames[i];
2153+
Class? declarer = restrictedMemberDeclarers[i];
2154+
2155+
Member? member = hierarchy.getDispatchTarget(classBuilder.cls, name);
2156+
if (member?.enclosingClass != declarer &&
2157+
member?.enclosingClass != classBuilder.cls &&
2158+
member?.isAbstract == false) {
2159+
classBuilder.libraryBuilder.addProblem(
2160+
templateEnumInheritsRestricted.withArguments(name.text),
2161+
classBuilder.charOffset,
2162+
classBuilder.name.length,
2163+
classBuilder.fileUri,
2164+
context: <LocatedMessage>[
2165+
messageEnumInheritsRestrictedMember.withLocation(
2166+
member!.fileUri,
2167+
member.fileOffset,
2168+
member.name.text.length)
2169+
]);
2170+
}
2171+
}
2172+
}
2173+
}
2174+
ticker.logMs("Checked for restricted members inheritance in enums.");
2175+
21372176
typeInferenceEngine.finishTopLevelInitializingFormals();
21382177
ticker.logMs("Finished initializing formals");
21392178
}

pkg/front_end/messages.status

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ EnumImplementerContainsRestrictedInstanceDeclaration/analyzerCode: Fail
233233
EnumImplementerContainsRestrictedInstanceDeclaration/example: Fail
234234
EnumImplementerContainsValuesDeclaration/analyzerCode: Fail
235235
EnumImplementerContainsValuesDeclaration/example: Fail
236+
EnumInheritsRestricted/analyzerCode: Fail
237+
EnumInheritsRestricted/example: Fail
236238
EnumInstantiation/example: Fail
237239
EnumNonConstConstructor/analyzerCode: Fail
238240
EnumNonConstConstructor/example: Fail

pkg/front_end/messages.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5536,6 +5536,13 @@ EnumContainsValuesDeclaration:
55365536
EnumImplementerContainsValuesDeclaration:
55375537
problemMessage: "'#name' has 'Enum' as a superinterface and can't contain non-static member with name 'values'."
55385538

5539+
EnumInheritsRestricted:
5540+
problemMessage: "An enum can't inherit a member named '#name'."
5541+
5542+
EnumInheritsRestrictedMember:
5543+
problemMessage: "This is the inherited member"
5544+
severity: CONTEXT
5545+
55395546
MacroClassNotDeclaredMacro:
55405547
problemMessage: "Non-abstract class '#name' implements 'Macro' but isn't declared as a macro class."
55415548
correctionMessage: "Try adding the 'macro' class modifier."

pkg/front_end/test/spell_checking_list_common.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,8 @@ declaration's
744744
declarations
745745
declare
746746
declared
747+
declarer
748+
declarers
747749
declares
748750
declaring
749751
decode
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
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.
4+
5+
class A1 {
6+
int get hashCode => 42;
7+
}
8+
9+
enum E1 with A1 { // Error.
10+
element
11+
}
12+
13+
class A2 {
14+
int get values => 42;
15+
}
16+
17+
enum E2 with A2 { // Error.
18+
element
19+
}
20+
21+
class A3 {
22+
int get index => 42;
23+
}
24+
25+
enum E3 with A3 { // Error.
26+
element
27+
}
28+
29+
class A4 {
30+
bool operator==(Object other) => true;
31+
}
32+
33+
enum E4 with A4 { // Error.
34+
element
35+
}
36+
37+
mixin M5 {
38+
int get hashCode => 42;
39+
}
40+
41+
enum E5 with M5 { // Error.
42+
element
43+
}
44+
45+
mixin M6 {
46+
int get values => 42;
47+
}
48+
49+
enum E6 with M6 { // Error.
50+
element
51+
}
52+
53+
mixin M7 {
54+
int get index => 42;
55+
}
56+
57+
enum E7 with M7 { // Error.
58+
element
59+
}
60+
61+
mixin M8 {
62+
bool operator==(Object other) => true;
63+
}
64+
65+
enum E8 with M8 { // Error.
66+
element
67+
}
68+
69+
abstract class A9 {
70+
int get index;
71+
int get hashCode;
72+
bool operator==(Object other);
73+
}
74+
75+
enum E9 with A9 { // Ok.
76+
element
77+
}
78+
79+
mixin M10 {
80+
int get index;
81+
int get hashCode;
82+
bool operator==(Object other);
83+
}
84+
85+
enum E10 with M10 { // Ok.
86+
element
87+
}
88+
89+
main() {}

0 commit comments

Comments
 (0)