analyzer: Remove DIVISION_OPTIMIZATION hint

This is replaced by the use_truncating_division lint rule.

Work towards https://github.com/dart-lang/sdk/issues/50796

Cq-Include-Trybots: luci.dart.try:flutter-analyze-try,analyzer-win-release-try,pkg-win-release-try
Change-Id: Ied034267f4f8e5ea70ed0b4a21c39e88c88240ec
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/378574
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index 75d0d24..95142b4 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -1836,8 +1836,6 @@
     Should probably be able to use `DataDriven`.
 HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE:
   status: hasFix
-HintCode.DIVISION_OPTIMIZATION:
-  status: hasFix
 HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION:
   status: noFix
 HintCode.MACRO_INFO:
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 1184fae..bd08bdd 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1552,9 +1552,6 @@
   HintCode.DEPRECATED_COLON_FOR_DEFAULT_VALUE: [
     ReplaceColonWithEquals.new,
   ],
-  HintCode.DIVISION_OPTIMIZATION: [
-    UseEffectiveIntegerDivision.new,
-  ],
   HintCode.UNNECESSARY_IMPORT: [
     RemoveUnusedImport.new,
   ],
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index 8acb555..1d4125a 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -207,4 +207,5 @@
   static const String use_string_in_part_of_directives =
       'use_string_in_part_of_directives';
   static const String use_super_parameters = 'use_super_parameters';
+  static const String use_truncating_division = 'use_truncating_division';
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart
index b169998..833e0da 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -17,6 +18,9 @@
 
 @reflectiveTest
 class UseEffectiveIntegerDivisionMultiTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode => LintNames.use_truncating_division;
+
   Future<void> test_singleFile() async {
     await resolveTestCode('''
 void f() {
@@ -53,10 +57,13 @@
 }
 
 @reflectiveTest
-class UseEffectiveIntegerDivisionTest extends FixProcessorTest {
+class UseEffectiveIntegerDivisionTest extends FixProcessorLintTest {
   @override
   FixKind get kind => DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION;
 
+  @override
+  String get lintCode => LintNames.use_truncating_division;
+
   Future<void> test_normalDivision() async {
     await resolveTestCode('''
 void f() {
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
index 9a7f281..7bd3b50 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -86,15 +86,6 @@
   );
 
   ///  No parameters.
-  static const HintCode DIVISION_OPTIMIZATION = HintCode(
-    'DIVISION_OPTIMIZATION',
-    "The operator x ~/ y is more efficient than (x / y).toInt().",
-    correctionMessage:
-        "Try re-writing the expression to use the '~/' operator.",
-    hasPublishedDocs: true,
-  );
-
-  ///  No parameters.
   static const HintCode IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION = HintCode(
     'IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION',
     "The imported library defines a top-level function named 'loadLibrary' "
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 738b9cd..a4a425a 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -159,7 +159,6 @@
 
   @override
   void visitBinaryExpression(BinaryExpression node) {
-    _checkForDivisionOptimizationHint(node);
     _deprecatedVerifier.binaryExpression(node);
     _checkForInvariantNanComparison(node);
     _checkForInvariantNullComparison(node);
@@ -849,47 +848,6 @@
     }
   }
 
-  /// Checks the passed binary expression for [HintCode.DIVISION_OPTIMIZATION].
-  ///
-  /// Returns whether a hint code is generated.
-  // TODO(srawlins): Remove this ASAP, as it is being replaced by the
-  // 'use_truncating_division' lint rule, to avoid double reporting.
-  bool _checkForDivisionOptimizationHint(BinaryExpression node) {
-    if (node.operator.type != TokenType.SLASH) return false;
-
-    // Return if the two operands are not each `int`.
-    var leftType = node.leftOperand.staticType;
-    if (leftType == null || !leftType.isDartCoreInt) return false;
-
-    var rightType = node.rightOperand.staticType;
-    if (rightType == null || !rightType.isDartCoreInt) return false;
-
-    // Return if the '/' operator is not defined in core, or if we don't know
-    // its static type.
-    var methodElement = node.staticElement;
-    if (methodElement == null) return false;
-
-    var libraryElement = methodElement.library;
-    if (!libraryElement.isDartCore) return false;
-
-    var parent = node.parent;
-    if (parent is! ParenthesizedExpression) return false;
-
-    var outermostParentheses = parent.thisOrAncestorMatching(
-        (e) => e.parent is! ParenthesizedExpression) as ParenthesizedExpression;
-    var grandParent = outermostParentheses.parent;
-    if (grandParent is! MethodInvocation) return false;
-
-    // Report an error if the `(x / y)` expression has `toInt()` invoked on it.
-    if (grandParent.methodName.name == 'toInt' &&
-        grandParent.argumentList.arguments.isEmpty) {
-      _errorReporter.atNode(grandParent, HintCode.DIVISION_OPTIMIZATION);
-      return true;
-    }
-
-    return false;
-  }
-
   /// Generate hints related to duplicate elements (keys) in sets (maps).
   void _checkForDuplications(SetOrMapLiteral node) {
     // This only checks for top-level elements. If, for, and spread elements
diff --git a/pkg/analyzer/lib/src/error/error_code_values.g.dart b/pkg/analyzer/lib/src/error/error_code_values.g.dart
index 2bb4ebb..50e992f 100644
--- a/pkg/analyzer/lib/src/error/error_code_values.g.dart
+++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart
@@ -649,7 +649,6 @@
   HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE,
   HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE,
   HintCode.DEPRECATED_MEMBER_USE_WITH_MESSAGE,
-  HintCode.DIVISION_OPTIMIZATION,
   HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
   HintCode.MACRO_INFO,
   HintCode.UNNECESSARY_IMPORT,
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 262d208..c7bb24f 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -20977,6 +20977,7 @@
       This code is deprecated in favor of the
       'deprecated_member_from_same_package' lint rule, and will be removed.
   DIVISION_OPTIMIZATION:
+    removedIn: "3.5"
     problemMessage: The operator x ~/ y is more efficient than (x / y).toInt().
     correctionMessage: "Try re-writing the expression to use the '~/' operator."
     hasPublishedDocs: true
diff --git a/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart b/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart
deleted file mode 100644
index d011743..0000000
--- a/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/error/codes.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../dart/resolution/context_collection_resolution.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(DivisionOptimizationTest);
-  });
-}
-
-@reflectiveTest
-class DivisionOptimizationTest extends PubPackageResolutionTest {
-  test_divisionOptimization() async {
-    await assertNoErrorsInCode(r'''
-void f(int x, int y) {
-  x / y.toInt();
-}
-''');
-  }
-
-  test_double() async {
-    await assertNoErrorsInCode(r'''
-void f(double x, double y) {
-  (x / y).toInt();
-}
-''');
-  }
-
-  test_dynamic() async {
-    await assertNoErrorsInCode(r'''
-void f(x, y) {
-  (x / y).toInt();
-}
-''');
-  }
-
-  test_int() async {
-    await assertErrorsInCode(r'''
-void f(int x, int y) {
-  (x / y).toInt();
-}
-''', [
-      error(HintCode.DIVISION_OPTIMIZATION, 25, 15),
-    ]);
-  }
-
-  test_nonNumeric() async {
-    await assertNoErrorsInCode(r'''
-class A {
-  A operator /(A x) { return x; }
-
-  void toInt() {}
-}
-void f(A x, A y) {
-  (x / y).toInt();
-}
-''');
-  }
-
-  test_wrappedInParentheses() async {
-    await assertErrorsInCode(r'''
-void f(int x, int y) {
-  (((x / y))).toInt();
-}
-''', [
-      error(HintCode.DIVISION_OPTIMIZATION, 25, 19),
-    ]);
-  }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 2d6bfbd..ccf6acb 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -185,7 +185,6 @@
     as deprecated_implements_function;
 import 'deprecated_member_use_test.dart' as deprecated_member_use;
 import 'deprecated_mixin_function_test.dart' as deprecated_mixin_function;
-import 'division_optimization_test.dart' as division_optimization;
 import 'doc_directive_argument_wrong_format_test.dart'
     as doc_directive_argument_wrong_format;
 import 'doc_directive_has_extra_arguments_test.dart'
@@ -1049,7 +1048,6 @@
     deprecated_implements_function.main();
     deprecated_member_use.main();
     deprecated_mixin_function.main();
-    division_optimization.main();
     doc_directive_argument_wrong_format.main();
     doc_directive_has_extra_arguments.main();
     doc_directive_has_unexpected_named_argument.main();
diff --git a/pkg/linter/test/rules/all.dart b/pkg/linter/test/rules/all.dart
index bcd8e8f..86bb541 100644
--- a/pkg/linter/test/rules/all.dart
+++ b/pkg/linter/test/rules/all.dart
@@ -293,6 +293,7 @@
 import 'use_super_parameters_test.dart' as use_super_parameters;
 import 'use_test_throws_matchers_test.dart' as use_test_throws_matchers;
 import 'use_to_and_as_if_applicable_test.dart' as use_to_and_as_if_applicable;
+import 'use_truncating_division_test.dart' as use_truncating_division;
 import 'valid_regexps_test.dart' as valid_regexps;
 import 'void_checks_test.dart' as void_checks;
 
@@ -507,6 +508,7 @@
   use_super_parameters.main();
   use_test_throws_matchers.main();
   use_to_and_as_if_applicable.main();
+  use_truncating_division.main();
   valid_regexps.main();
   void_checks.main();
 }
diff --git a/pkg/linter/test/rules/use_truncating_division_test.dart b/pkg/linter/test/rules/use_truncating_division_test.dart
index 5d62584..d05582b 100644
--- a/pkg/linter/test/rules/use_truncating_division_test.dart
+++ b/pkg/linter/test/rules/use_truncating_division_test.dart
@@ -31,8 +31,6 @@
   (x / y).toInt();
 }
 ''', [
-      // TODO(srawlins): ASAP, remove this Hint.
-      error(HintCode.DIVISION_OPTIMIZATION, 25, 15),
       lint(25, 15),
     ]);
   }
@@ -43,8 +41,6 @@
   (((x / y))).toInt();
 }
 ''', [
-      // TODO(srawlins): ASAP, remove this Hint.
-      error(HintCode.DIVISION_OPTIMIZATION, 25, 19),
       lint(25, 19),
     ]);
   }
@@ -55,8 +51,6 @@
   ((x + 1) / (y - 1)).toInt();
 }
 ''', [
-      // TODO(srawlins): ASAP, remove this Hint.
-      error(HintCode.DIVISION_OPTIMIZATION, 25, 27),
       lint(25, 27),
     ]);
   }