Report CONFLICTING_CONSTRUCTOR_AND_STATIC_xyz for enums.

Change-Id: Iebd399e6cf0de8e8e50b468815557e683086c6ba
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/233762
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index 38fc6db..7f5aba1 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -106,6 +106,12 @@
       }
     }
 
+    _checkConflictingConstructorAndStatic(
+      classElement: enumElement,
+      staticGetters: staticGetters,
+      staticSetters: staticSetters,
+    );
+
     for (var accessor in enumElement.accessors) {
       var baseName = accessor.displayName;
       if (accessor.isStatic) {
@@ -384,37 +390,17 @@
       }
     }
 
+    _checkConflictingConstructorAndStatic(
+      classElement: element,
+      staticGetters: staticGetters,
+      staticSetters: staticSetters,
+    );
+
     // Check for local static members conflicting with local instance members.
+    // TODO(scheglov) This code is duplicated for enums. But for classes it is
+    // separated also into ErrorVerifier - where we check inherited.
     for (ClassMember member in members) {
-      if (member is ConstructorDeclaration) {
-        var nameNode = member.name;
-        if (nameNode != null) {
-          String name = nameNode.name;
-          var staticMember = staticGetters[name] ?? staticSetters[name];
-          if (staticMember != null) {
-            if (staticMember is PropertyAccessorElement) {
-              CompileTimeErrorCode errorCode;
-              if (staticMember.isSynthetic) {
-                errorCode = CompileTimeErrorCode
-                    .CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD;
-              } else if (staticMember.isGetter) {
-                errorCode = CompileTimeErrorCode
-                    .CONFLICTING_CONSTRUCTOR_AND_STATIC_GETTER;
-              } else {
-                errorCode = CompileTimeErrorCode
-                    .CONFLICTING_CONSTRUCTOR_AND_STATIC_SETTER;
-              }
-              _errorReporter.reportErrorForNode(errorCode, nameNode, [name]);
-            } else {
-              _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
-                nameNode,
-                [name],
-              );
-            }
-          }
-        }
-      } else if (member is FieldDeclaration) {
+      if (member is FieldDeclaration) {
         if (member.isStatic) {
           for (VariableDeclaration field in member.fields.variables) {
             SimpleIdentifier identifier = field.name;
@@ -446,6 +432,37 @@
     }
   }
 
+  void _checkConflictingConstructorAndStatic({
+    required ClassElement classElement,
+    required Map<String, Element> staticGetters,
+    required Map<String, Element> staticSetters,
+  }) {
+    for (var constructor in classElement.constructors) {
+      var name = constructor.name;
+      var staticMember = staticGetters[name] ?? staticSetters[name];
+      if (staticMember is PropertyAccessorElement) {
+        CompileTimeErrorCode errorCode;
+        if (staticMember.isSynthetic) {
+          errorCode =
+              CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD;
+        } else if (staticMember.isGetter) {
+          errorCode =
+              CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_GETTER;
+        } else {
+          errorCode =
+              CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_SETTER;
+        }
+        _errorReporter.reportErrorForElement(errorCode, constructor, [name]);
+      } else if (staticMember is MethodElement) {
+        _errorReporter.reportErrorForElement(
+          CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
+          constructor,
+          [name],
+        );
+      }
+    }
+  }
+
   /// Check whether the given [element] defined by the [identifier] is already
   /// in one of the scopes - [getterScope] or [setterScope], and produce an
   /// error if it is.
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_field_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_field_test.dart
index 4bd1277..2447ef9 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_field_test.dart
@@ -16,7 +16,16 @@
 @reflectiveTest
 class ConflictingConstructorAndStaticFieldTest
     extends PubPackageResolutionTest {
-  test_class_field() async {
+  test_class_instance_field() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  C.foo();
+  int foo = 0;
+}
+''');
+  }
+
+  test_class_static_field() async {
     await assertErrorsInCode(r'''
 class C {
   C.foo();
@@ -28,7 +37,7 @@
     ]);
   }
 
-  test_class_getter() async {
+  test_class_static_getter() async {
     await assertErrorsInCode(r'''
 class C {
   C.foo();
@@ -40,7 +49,7 @@
     ]);
   }
 
-  test_class_OK_notSameClass() async {
+  test_class_static_notSameClass() async {
     await assertNoErrorsInCode(r'''
 class A {
   static int foo = 0;
@@ -51,16 +60,7 @@
 ''');
   }
 
-  test_class_OK_notStatic() async {
-    await assertNoErrorsInCode(r'''
-class C {
-  C.foo();
-  int foo = 0;
-}
-''');
-  }
-
-  test_class_setter() async {
+  test_class_static_setter() async {
     await assertErrorsInCode(r'''
 class C {
   C.foo();
@@ -72,33 +72,64 @@
     ]);
   }
 
-  test_enum_field() async {
+  test_enum_constant() async {
+    await assertErrorsInCode(r'''
+enum E {
+  foo.foo();
+  const E.foo();
+}
+''', [
+      error(
+          CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD, 32, 3),
+    ]);
+  }
+
+  test_enum_instance_field() async {
     await assertNoErrorsInCode(r'''
 enum E {
   v.foo();
-  const E.foo(); // _$foo
+  const E.foo();
+  final int foo = 0;
+}
+''');
+  }
+
+  test_enum_static_field() async {
+    await assertErrorsInCode(r'''
+enum E {
+  v.foo();
+  const E.foo();
   static int foo = 0;
 }
-''');
+''', [
+      error(
+          CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD, 30, 3),
+    ]);
   }
 
-  test_enum_getter() async {
-    await assertNoErrorsInCode(r'''
+  test_enum_static_getter() async {
+    await assertErrorsInCode(r'''
 enum E {
   v.foo();
-  const E.foo(); // _$foo
+  const E.foo();
   static int get foo => 0;
 }
-''');
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_GETTER, 30,
+          3),
+    ]);
   }
 
-  test_enum_setter() async {
-    await assertNoErrorsInCode(r'''
+  test_enum_static_setter() async {
+    await assertErrorsInCode(r'''
 enum E {
   v.foo();
-  const E.foo(); // _$foo
+  const E.foo();
   static void set foo(_) {}
 }
-''');
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_SETTER, 30,
+          3),
+    ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_method_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_method_test.dart
index d962c52..2ce27da 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_constructor_and_static_method_test.dart
@@ -16,7 +16,27 @@
 @reflectiveTest
 class ConflictingConstructorAndStaticMethodTest
     extends PubPackageResolutionTest {
-  test_class() async {
+  test_class_instance() async {
+    await assertNoErrorsInCode(r'''
+class C {
+  C.foo();
+  void foo() {}
+}
+''');
+  }
+
+  test_class_notSameClass() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static void foo() {}
+}
+class B extends A {
+  B.foo();
+}
+''');
+  }
+
+  test_class_static() async {
     await assertErrorsInCode(r'''
 class C {
   C.foo();
@@ -28,33 +48,26 @@
     ]);
   }
 
-  test_class_OK_notSameClass() async {
+  test_enum_instance() async {
     await assertNoErrorsInCode(r'''
-class A {
-  static void foo() {}
-}
-class B extends A {
-  B.foo();
-}
-''');
-  }
-
-  test_class_OK_notStatic() async {
-    await assertNoErrorsInCode(r'''
-class C {
-  C.foo();
+enum E {
+  v.foo();
+  const E.foo();
   void foo() {}
 }
 ''');
   }
 
-  test_enum() async {
-    await assertNoErrorsInCode(r'''
+  test_enum_static() async {
+    await assertErrorsInCode(r'''
 enum E {
   v.foo();
-  const E.foo(); // _$foo
+  const E.foo();
   static void foo() {}
 }
-''');
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD, 30,
+          3),
+    ]);
   }
 }