Check for conflict with static members
Change-Id: I7966f2211104b54bfa4f2b026ad8a706d3f2bd6c
Reviewed-on: https://dart-review.googlesource.com/c/88956
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 3712941..3c87fc7 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -7934,6 +7934,26 @@
tip: r"""Try re-ordering the modifiers.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeStaticAndInstanceConflict =
+ messageStaticAndInstanceConflict;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageStaticAndInstanceConflict = const MessageCode(
+ "StaticAndInstanceConflict",
+ analyzerCodes: <String>["CONFLICTING_STATIC_AND_INSTANCE"],
+ message: r"""This static member conflicts with an instance member.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeStaticAndInstanceConflictCause =
+ messageStaticAndInstanceConflictCause;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageStaticAndInstanceConflictCause = const MessageCode(
+ "StaticAndInstanceConflictCause",
+ severity: Severity.context,
+ message: r"""This is the instance member.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeStaticConstructor = messageStaticConstructor;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 4d5c736..a98fb47 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -17,6 +17,8 @@
messageInheritedMembersConflict,
messageInheritedMembersConflictCause1,
messageInheritedMembersConflictCause2,
+ messageStaticAndInstanceConflict,
+ messageStaticAndInstanceConflictCause,
templateDuplicatedDeclaration,
templateDuplicatedDeclarationCause,
templateMissingImplementationCause,
@@ -54,6 +56,7 @@
/// Language Specification](
/// ../../../../../../docs/language/dartLangSpec.tex#classMemberConflicts).
bool isInheritanceConflict(Declaration a, Declaration b) {
+ if (a.isStatic) return true;
if (memberKind(a.target) == memberKind(b.target)) return false;
if (a.isField) return !(b.isField || b.isGetter || b.isSetter);
if (b.isField) return !(a.isField || a.isGetter || a.isSetter);
@@ -145,6 +148,22 @@
b.fileUri, b.charOffset, name.length),
]);
}
+ } else if (a.isStatic != b.isStatic) {
+ Declaration staticMember;
+ Declaration instanceMember;
+ if (a.isStatic) {
+ staticMember = a;
+ instanceMember = b;
+ } else {
+ staticMember = b;
+ instanceMember = a;
+ }
+ cls.library.addProblem(messageStaticAndInstanceConflict,
+ staticMember.charOffset, name.length, staticMember.fileUri,
+ context: <LocatedMessage>[
+ messageStaticAndInstanceConflictCause.withLocation(
+ instanceMember.fileUri, instanceMember.charOffset, name.length)
+ ]);
} else {
// This message can be reported twice (when merging localMembers with
// classSetters, or localSetters with classMembers). By ensuring that
@@ -238,10 +257,6 @@
scope = mixin.scope;
}
}
- // TODO(ahe): Consider if removing static members from [localMembers] and
- // [localSetters] makes sense. It depends on what semantic checks we need
- // to perform with respect to static members and inherited members with the
- // same name.
/// Members (excluding setters) declared in [cls].
List<Declaration> localMembers =
@@ -506,7 +521,7 @@
while (i < aList.length && j < bList.length) {
final Declaration a = aList[i];
final Declaration b = bList[j];
- if (a.isStatic) {
+ if (mergeKind == MergeKind.interfaces && a.isStatic) {
i++;
continue;
}
@@ -531,7 +546,7 @@
}
while (i < aList.length) {
final Declaration a = aList[i];
- if (!a.isStatic) {
+ if (mergeKind != MergeKind.interfaces || !a.isStatic) {
handleOnlyA(a, mergeKind);
result[storeIndex++] = a;
}
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 20e3338..d92d6b8 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -326,6 +326,8 @@
SourceOutlineSummary/example: Fail
StackOverflow/example: Fail
StaticAfterConst/script1: Fail
+StaticAndInstanceConflict/script1: Fail # TODO(ahe): This is fixed when enabling ClassHierarchyBuilder in all modes.
+StaticAndInstanceConflict/script2: Fail # TODO(ahe): This is fixed when enabling ClassHierarchyBuilder in all modes.
SuperAsExpression/example: Fail
SuperAsIdentifier/example: Fail
SuperNullAware/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index a885932..50c5be3 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -3386,3 +3386,22 @@
template: "The class 'Object' can't use mixins."
frontendInternal: true
external: test/fasta/object_supertype_test.dart
+
+StaticAndInstanceConflict:
+ template: "This static member conflicts with an instance member."
+ script:
+ - |
+ class C {
+ set foo(value) {}
+ static get foo => 42;
+ }
+ - |
+ class C {
+ static set foo(value) {}
+ get foo => 42;
+ }
+ analyzerCode: CONFLICTING_STATIC_AND_INSTANCE
+
+StaticAndInstanceConflictCause:
+ template: "This is the instance member."
+ severity: CONTEXT