Version 2.13.0-38.0.dev

Merge commit '77da201b19eaf23185465a90492a211bb6a3e978' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
index 18acf3d..af0f47b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_question_mark.dart
@@ -15,17 +15,24 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    if (node is! TypeName) {
-      return;
+    var node = this.node;
+    if (node is VariableDeclaration) {
+      var parent = node.parent;
+      if (parent is VariableDeclarationList) {
+        node = parent.type;
+      } else {
+        return;
+      }
     }
-    var typeName = node as TypeName;
-    var questionMark = typeName.question;
-    if (questionMark == null) {
-      return;
+    if (node is TypeName) {
+      var questionMark = node.question;
+      if (questionMark == null) {
+        return;
+      }
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addDeletion(range.token(questionMark));
+      });
     }
-    await builder.addDartFileEdit(file, (builder) {
-      builder.addDeletion(range.token(questionMark));
-    });
   }
 
   /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index da0af33..6528ff6 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -444,8 +444,9 @@
       'dart.fix.remove.parenthesisInGetterInvocation',
       50,
       'Remove parentheses in getter invocation');
-  static const REMOVE_QUESTION_MARK =
-      FixKind('dart.fix.remove.questionMark', 50, "Remove the '?'");
+  static const REMOVE_QUESTION_MARK = FixKind(
+      'dart.fix.remove.questionMark', 50, "Remove the '?'",
+      appliedTogetherMessage: 'Remove unnecessary question marks in file');
   static const REMOVE_THIS_EXPRESSION = FixKind(
       'dart.fix.remove.thisExpression', 50, 'Remove this expression',
       appliedTogetherMessage:
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 a04b49b..c2753fe 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1004,6 +1004,15 @@
         ],
       )
     ],
+    LintNames.unnecessary_nullable_for_final_variable_declarations: [
+      FixInfo(
+        canBeAppliedToFile: true,
+        canBeBulkApplied: true,
+        generators: [
+          RemoveQuestionMark.newInstance,
+        ],
+      )
+    ],
     LintNames.unnecessary_overrides: [
       FixInfo(
         canBeAppliedToFile: true,
@@ -1278,6 +1287,9 @@
     LintNames.unnecessary_null_in_if_null_operators: [
       RemoveIfNullOperator.newInstance,
     ],
+    LintNames.unnecessary_nullable_for_final_variable_declarations: [
+      RemoveQuestionMark.newInstance,
+    ],
     LintNames.unnecessary_overrides: [
       RemoveMethodDeclaration.newInstance,
     ],
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 46abeb4..60afd1b 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -95,6 +95,8 @@
   static const String unnecessary_new = 'unnecessary_new';
   static const String unnecessary_null_in_if_null_operators =
       'unnecessary_null_in_if_null_operators';
+  static const String unnecessary_nullable_for_final_variable_declarations =
+      'unnecessary_nullable_for_final_variable_declarations';
   static const String unnecessary_overrides = 'unnecessary_overrides';
   static const String unnecessary_parenthesis = 'unnecessary_parenthesis';
   static const String unnecessary_string_interpolations =
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_question_mark_test.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_question_mark_test.dart
new file mode 100644
index 0000000..48706e9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/remove_question_mark_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2021, 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:analysis_server/src/services/linter/lint_names.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bulk_fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveQuestionMarkTest);
+  });
+}
+
+@reflectiveTest
+class RemoveQuestionMarkTest extends BulkFixProcessorTest {
+  @override
+  String get lintCode =>
+      LintNames.unnecessary_nullable_for_final_variable_declarations;
+
+  @override
+  String get testPackageLanguageVersion => latestLanguageVersion;
+
+  Future<void> test_singleFile() async {
+    await resolveTestCode('''
+class C {
+  static final int? x = 0;
+  static final int? y = 0;
+}
+''');
+    await assertHasFix('''
+class C {
+  static final int x = 0;
+  static final int y = 0;
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
index 6a65f3b..6b8bb68 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/bulk/test_all.dart
@@ -51,6 +51,7 @@
 import 'remove_method_declaration_test.dart' as remove_method_declaration;
 import 'remove_non_null_assertion_test.dart' as remove_non_null_assertion;
 import 'remove_operator_test.dart' as remove_operator;
+import 'remove_question_mark_test.dart' as remove_question_mark;
 import 'remove_this_expression_test.dart' as remove_this_expression;
 import 'remove_type_annotation_test.dart' as remove_type_annotation;
 import 'remove_unnecessary_const_test.dart' as remove_unnecessary_const;
@@ -115,6 +116,7 @@
     remove_method_declaration.main();
     remove_non_null_assertion.main();
     remove_operator.main();
+    remove_question_mark.main();
     remove_this_expression.main();
     remove_type_annotation.main();
     remove_unnecessary_const.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_test.dart
index 007b6dc..286b5d3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_question_mark_test.dart
@@ -12,6 +12,7 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(RemoveQuestionMarkTest);
+    defineReflectiveTests(UnnecessaryNullableForFinalVariableDeclarationsTest);
   });
 }
 
@@ -94,3 +95,72 @@
 ''');
   }
 }
+
+@reflectiveTest
+class UnnecessaryNullableForFinalVariableDeclarationsTest
+    extends FixProcessorLintTest with WithNullSafetyMixin {
+  @override
+  FixKind get kind => DartFixKind.REMOVE_QUESTION_MARK;
+
+  @override
+  String get lintCode => 'unnecessary_nullable_for_final_variable_declarations';
+
+  Future<void> test_const_field_static() async {
+    await resolveTestCode('''
+class C {
+  static const int? zero = 0;
+}
+''');
+    await assertHasFix('''
+class C {
+  static const int zero = 0;
+}
+''');
+  }
+
+  Future<void> test_const_topLevelVariable() async {
+    await resolveTestCode('''
+const int? zero = 0;
+''');
+    await assertHasFix('''
+const int zero = 0;
+''');
+  }
+
+  Future<void> test_final_field_static() async {
+    await resolveTestCode('''
+class C {
+  static final int? zero = 0;
+}
+''');
+    await assertHasFix('''
+class C {
+  static final int zero = 0;
+}
+''');
+  }
+
+  Future<void> test_final_localVariable() async {
+    await resolveTestCode('''
+void f() {
+  final int? zero = 0;
+  zero;
+}
+''');
+    await assertHasFix('''
+void f() {
+  final int zero = 0;
+  zero;
+}
+''');
+  }
+
+  Future<void> test_final_topLevelVariable() async {
+    await resolveTestCode('''
+final int? zero = 0;
+''');
+    await assertHasFix('''
+final int zero = 0;
+''');
+  }
+}
diff --git a/tools/VERSION b/tools/VERSION
index 99f3979..9f1a7ac 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 37
+PRERELEASE 38
 PRERELEASE_PATCH 0
\ No newline at end of file