[analysis_server] `ReplaceFinalWithConst` to handle unnecessary `const`

Fixes #49295

Change-Id: I6974c370e14d16ce5b38471bad7c0d8e86ac6062
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/249581
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
index 832dd64e..9d8bb75 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_const.dart
@@ -6,7 +6,6 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -38,7 +37,7 @@
     Token? constToken;
     if (expression is InstanceCreationExpression) {
       constToken = expression.keyword;
-    } else if (expression is TypedLiteralImpl) {
+    } else if (expression is TypedLiteral) {
       constToken = expression.constKeyword;
     }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
index ac56fdf..af3a2ce 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_final_with_const.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -32,6 +33,31 @@
           builder.addSimpleReplacement(range.token(keyword), 'const');
         });
       }
+
+      for (var variable in node.variables) {
+        var initializer = variable.initializer;
+        if (initializer != null) {
+          Token? constToken;
+          if (initializer is InstanceCreationExpression) {
+            constToken = initializer.keyword;
+          } else if (initializer is TypedLiteral) {
+            constToken = initializer.constKeyword;
+          }
+
+          if (constToken == null) {
+            continue;
+          }
+
+          await builder.addDartFileEdit(file, (builder) {
+            builder.addDeletion(
+              range.startStart(
+                constToken!,
+                constToken.next!,
+              ),
+            );
+          });
+        }
+      }
     }
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
index 7cb0d8d..7c3c8dc 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
@@ -41,7 +41,46 @@
   @override
   String get lintCode => LintNames.prefer_const_declarations;
 
-  Future<void> test_method() async {
+  Future<void> test_const_instanceCreation() async {
+    await resolveTestCode('''
+class A {
+  const A();
+}
+final a = const A();
+''');
+    await assertHasFix('''
+class A {
+  const A();
+}
+const a = A();
+''');
+  }
+
+  Future<void> test_const_instanceCreation_multiple() async {
+    await resolveTestCode('''
+class A {
+  const A();
+}
+final A a1 = const A(), a2 = const A();
+''');
+    await assertHasFix('''
+class A {
+  const A();
+}
+const A a1 = A(), a2 = A();
+''');
+  }
+
+  Future<void> test_const_typedLiteral() async {
+    await resolveTestCode('''
+final b = const [];
+''');
+    await assertHasFix('''
+const b = [];
+''');
+  }
+
+  Future<void> test_variable() async {
     await resolveTestCode('''
 final int a = 1;
 ''');