Hint `INVALID_USE_OF_VISIBLE_FOR_OVERRIDING_MEMBER` with operators

Fixes #48729

Change-Id: I6402a8a24419073b0659c7db89d2f1da1d740c87
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239671
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index ffe0eb4..d2e352f 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -341,6 +341,7 @@
     _checkForDivisionOptimizationHint(node);
     _deprecatedVerifier.binaryExpression(node);
     _checkForInvariantNullComparison(node);
+    _invalidAccessVerifier.verifyBinary(node);
     super.visitBinaryExpression(node);
   }
 
@@ -1849,6 +1850,25 @@
     _checkForOtherInvalidAccess(identifier, element);
   }
 
+  void verifyBinary(BinaryExpression node) {
+    var element = node.staticElement;
+    if (element != null && _hasVisibleForOverriding(element)) {
+      var operator = node.operator;
+
+      if (node.leftOperand is SuperExpression) {
+        var methodDeclaration = node.thisOrAncestorOfType<MethodDeclaration>();
+        if (methodDeclaration?.name.name == operator.lexeme) {
+          return;
+        }
+      }
+
+      _errorReporter.reportErrorForToken(
+          HintCode.INVALID_USE_OF_VISIBLE_FOR_OVERRIDING_MEMBER,
+          operator,
+          [operator.type.lexeme]);
+    }
+  }
+
   void verifyImport(ImportDirective node) {
     var element = node.uriElement;
     if (_hasInternal(element) &&
@@ -1968,7 +1988,7 @@
           parent is PropertyAccess && parent.target is SuperExpression) {
         var methodDeclaration =
             grandparent?.thisOrAncestorOfType<MethodDeclaration>();
-        if (methodDeclaration?.name.token.value() == identifier.token.value()) {
+        if (methodDeclaration?.name.name == identifier.name) {
           validOverride = true;
         }
       }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_overriding_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_overriding_member_test.dart
index d4e5892..04c59dd 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_overriding_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_overriding_member_test.dart
@@ -111,6 +111,27 @@
     ]);
   }
 
+  test_operator() async {
+    newFile2('$testPackageLibPath/a.dart', '''
+import 'package:meta/meta.dart';
+
+class A {
+  @visibleForOverriding
+  operator >(A other) => true;
+}
+''');
+
+    await assertErrorsInCode('''
+import 'a.dart';
+
+class B {
+  void m(A a) => a > A();
+}
+''', [
+      error(HintCode.INVALID_USE_OF_VISIBLE_FOR_OVERRIDING_MEMBER, 47, 1),
+    ]);
+  }
+
   test_overriding_getter() async {
     newFile2('$testPackageLibPath/a.dart', '''
 import 'package:meta/meta.dart';
@@ -169,14 +190,18 @@
 }
 ''');
 
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 import 'a.dart';
 
 class B extends A {
   @override
   operator >(A other) => super > other;
+
+  void m() => super > A();
 }
-''');
+''', [
+      error(HintCode.INVALID_USE_OF_VISIBLE_FOR_OVERRIDING_MEMBER, 111, 1),
+    ]);
   }
 
   test_overriding_setter() async {