Version 2.18.0-9.0.dev

Merge commit 'f2b5ba82ab156b11ad4d2467b72c09b0eac8fa8f' into 'dev'
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 a83ddc1..447bb63 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
@@ -1417,6 +1417,8 @@
   status: needsEvaluation
 HintCode.UNNECESSARY_CAST:
   status: hasFix
+HintCode.UNNECESSARY_FINAL:
+  status: needsEvaluation
 HintCode.UNNECESSARY_IGNORE:
   status: needsEvaluation
 HintCode.UNNECESSARY_IMPORT:
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 6477d49..15c5a05 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -655,6 +655,7 @@
   HintCode.UNDEFINED_SHOWN_NAME,
   HintCode.UNIGNORABLE_IGNORE,
   HintCode.UNNECESSARY_CAST,
+  HintCode.UNNECESSARY_FINAL,
   HintCode.UNNECESSARY_IGNORE,
   HintCode.UNNECESSARY_IMPORT,
   HintCode.UNNECESSARY_NO_SUCH_METHOD,
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 aa8d8df..27a6074 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -3778,6 +3778,16 @@
   );
 
   /**
+   * No parameters.
+   */
+  static const HintCode UNNECESSARY_FINAL = HintCode(
+    'UNNECESSARY_FINAL',
+    "The keyword 'final' isn't necessary because the parameter is implicitly "
+        "'final'.",
+    correctionMessage: "Try removing the 'final'.",
+  );
+
+  /**
    * Parameters:
    * 0: the name of the diagnostic being ignored
    */
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index d2e352f..4f5dc3e 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -488,6 +488,12 @@
   }
 
   @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    _checkFinalParameter(node, node.keyword);
+    super.visitFieldFormalParameter(node);
+  }
+
+  @override
   void visitFormalParameterList(FormalParameterList node) {
     _checkRequiredParameter(node);
     super.visitFormalParameterList(node);
@@ -776,6 +782,12 @@
   }
 
   @override
+  void visitSuperFormalParameter(SuperFormalParameter node) {
+    _checkFinalParameter(node, node.keyword);
+    super.visitSuperFormalParameter(node);
+  }
+
+  @override
   void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
     _deprecatedVerifier.pushInDeprecatedMetadata(node.metadata);
 
@@ -856,6 +868,15 @@
     return false;
   }
 
+  void _checkFinalParameter(FormalParameter node, Token? keyword) {
+    if (node.isFinal) {
+      _errorReporter.reportErrorForToken(
+        HintCode.UNNECESSARY_FINAL,
+        keyword!,
+      );
+    }
+  }
+
   void _checkForAssignmentOfDoNotStore(Expression? expression) {
     var expressionMap = _getSubExpressionsMarkedDoNotStore(expression);
     for (var entry in expressionMap.entries) {
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index dbddb54..925a70d 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -20414,6 +20414,11 @@
         }
       }
       ```
+  UNNECESSARY_FINAL:
+    problemMessage: The keyword 'final' isn't necessary because the parameter is implicitly 'final'.
+    correctionMessage: Try removing the 'final'.
+    hasPublishedDocs: false
+    comment: No parameters.
   UNNECESSARY_IGNORE:
     problemMessage: "The diagnostic '{0}' isn't produced at this location so it doesn't need to be ignored."
     correctionMessage: Try removing the name from the list, or removing the whole comment if this is the only name in the list.
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 8bfc4e8..4e8864f 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -751,6 +751,7 @@
 import 'undefined_super_setter_test.dart' as undefined_super_setter;
 import 'unignorable_ignore_test.dart' as unignorable_ignore;
 import 'unnecessary_cast_test.dart' as unnecessary_cast;
+import 'unnecessary_final_test.dart' as unnecessary_final;
 import 'unnecessary_ignore_test.dart' as unnecessary_ignore;
 import 'unnecessary_import_test.dart' as unnecessary_import;
 import 'unnecessary_no_such_method_test.dart' as unnecessary_no_such_method;
@@ -1294,6 +1295,7 @@
     unignorable_ignore.main();
     unnecessary_import.main();
     unnecessary_cast.main();
+    unnecessary_final.main();
     unnecessary_ignore.main();
     unnecessary_no_such_method.main();
     unnecessary_non_null_assertion.main();
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_final_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_final_test.dart
new file mode 100644
index 0000000..8d586e9
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_final_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2022, 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(UnnecessaryFinalTest);
+  });
+}
+
+@reflectiveTest
+class UnnecessaryFinalTest extends PubPackageResolutionTest {
+  test_final() async {
+    await assertNoErrorsInCode('''
+class C {
+  C(final int value);
+}
+''');
+  }
+
+  test_positional() async {
+    await assertErrorsInCode('''
+class C {
+  C([final this.value = 0]);
+  int value;
+}
+''', [
+      error(HintCode.UNNECESSARY_FINAL, 15, 5),
+    ]);
+  }
+
+  test_super() async {
+    await assertErrorsInCode('''
+class A {
+  A(this.value);
+  int value;
+}
+
+class B extends A {
+  B(final super.value);
+}
+''', [
+      error(HintCode.UNNECESSARY_FINAL, 67, 5),
+    ]);
+  }
+
+  test_this() async {
+    await assertErrorsInCode('''
+class C {
+  C(final this.value);
+  int value;
+}
+''', [
+      error(HintCode.UNNECESSARY_FINAL, 14, 5),
+    ]);
+  }
+}
diff --git a/pkg/nnbd_migration/test/fix_aggregator_test.dart b/pkg/nnbd_migration/test/fix_aggregator_test.dart
index f32f6be..b028031 100644
--- a/pkg/nnbd_migration/test/fix_aggregator_test.dart
+++ b/pkg/nnbd_migration/test/fix_aggregator_test.dart
@@ -1413,6 +1413,7 @@
 
   Future<void>
       test_parameter_field_formal_addExplicitType_declared_with_final() async {
+    verifyNoTestUnitErrors = false;
     await analyze('''
 class C {
   int x;
diff --git a/tools/VERSION b/tools/VERSION
index 562e238..8a50ded 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 8
+PRERELEASE 9
 PRERELEASE_PATCH 0
\ No newline at end of file