[analysis_server] Exclude parameter information when hovering over binary operator RHS argument

Similar to the previous Hover change that excluded parameter for expressions passed to setters, this does the same for binary operators (where hovering the expression on the right side would also show the parameter info).

Change-Id: I6a2eb0d60ddcc64912b09e7c69bfc44cc700c619
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/392940
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index 8460408..5097276 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -212,10 +212,15 @@
       return null;
     }
     var parameter = node.correspondingParameter;
-    if (parameter?.enclosingElement2 is SetterElement) {
-      return null;
-    }
-    return _elementDisplayString(node, parameter);
+    return switch (parameter?.enclosingElement2) {
+      // Expressions passed as arguments to setters and binary expressions
+      // will have parameters here but we don't want them to show as such in
+      // hovers because information about those functions are already available
+      // by hovering over the function name or the operator.
+      SetterElement() => null,
+      MethodElement2 method when method.isOperator => null,
+      _ => _elementDisplayString(node, parameter),
+    };
   }
 
   /// Adjusts the target node for constructors.
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index 22ee3cf..8c6eeda 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -77,6 +77,62 @@
     await setRoots(included: [workspaceRootPath], excluded: []);
   }
 
+  Future<void> test_binaryOperator() async {
+    newFile(testFilePath, '''
+class A {
+  /// doc op
+  A operator +(A other) => this;
+}
+
+var a = A() + A();
+''');
+    var hover = await prepareHover('+ A()');
+    // element
+    expect(hover.containingLibraryName, 'package:test/test.dart');
+    expect(hover.containingLibraryPath, testFile.path);
+    expect(hover.dartdoc, 'doc op');
+    expect(hover.elementDescription, 'A +(A other)');
+    expect(hover.elementKind, 'method');
+    // types
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+    // no parameter.
+    expect(hover.parameter, isNull);
+  }
+
+  Future<void> test_binaryOperator_leftHandSide() async {
+    newFile(testFilePath, '''
+class A {
+  /// doc aaa
+  A();
+  A operator +(int other) => this;
+}
+
+var a = A() + A();
+''');
+    var hover = await prepareHover('A() +');
+    // element
+    expect(hover.elementDescription, '(new) A A()');
+    // don't show parameter information for binary operators
+    expect(hover.parameter, isNull);
+  }
+
+  Future<void> test_binaryOperator_rightHandSide() async {
+    newFile(testFilePath, '''
+class A {
+  A();
+  A operator +(int other) => this;
+}
+
+var a = A() + A(); // 1
+''');
+    var hover = await prepareHover('A(); // 1');
+    // element
+    expect(hover.elementDescription, '(new) A A()');
+    // don't show parameter information for binary operators
+    expect(hover.parameter, isNull);
+  }
+
   Future<void> test_class_constructor_named() async {
     newFile(testFilePath, '''
 class A {