Add a fix for invalid_inside_unary_pattern

Closes 51915

Change-Id: I378f66d70c083dd5852a9c8a04e3ddf59aff66d7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292981
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/surround_with_parentheses.dart b/pkg/analysis_server/lib/src/services/correction/dart/surround_with_parentheses.dart
new file mode 100644
index 0000000..4bb15a6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/surround_with_parentheses.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2023, 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/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class SurroundWithParentheses extends CorrectionProducer {
+  @override
+  bool get canBeAppliedInBulk => false;
+
+  @override
+  bool get canBeAppliedToFile => false;
+
+  @override
+  FixKind get fixKind => DartFixKind.SURROUND_WITH_PARENTHESES;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    await builder.addDartFileEdit(file, (builder) {
+      builder.addSimpleInsertion(node.offset, '(');
+      builder.addSimpleInsertion(node.end, ')');
+    });
+  }
+}
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 be82584..ade6354 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
@@ -2500,7 +2500,7 @@
 ParserErrorCode.INVALID_INITIALIZER:
   status: needsEvaluation
 ParserErrorCode.INVALID_INSIDE_UNARY_PATTERN:
-  status: needsEvaluation
+  status: hasFix
 ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION:
   status: needsEvaluation
 ParserErrorCode.INVALID_OPERATOR:
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 98597c7..474e5e4 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -1760,6 +1760,11 @@
     DartFixKindPriority.DEFAULT,
     'Move all unnamed constructors before named constructors',
   );
+  static const SURROUND_WITH_PARENTHESES = FixKind(
+    'dart.fix.surround.parentheses',
+    DartFixKindPriority.DEFAULT,
+    'Surround with parentheses',
+  );
   static const UPDATE_SDK_CONSTRAINTS = FixKind(
     'dart.fix.updateSdkConstraints',
     DartFixKindPriority.DEFAULT,
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 bb88fff..20084a2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -207,6 +207,7 @@
 import 'package:analysis_server/src/services/correction/dart/sort_combinators.dart';
 import 'package:analysis_server/src/services/correction/dart/sort_constructor_first.dart';
 import 'package:analysis_server/src/services/correction/dart/sort_unnamed_constructor_first.dart';
+import 'package:analysis_server/src/services/correction/dart/surround_with_parentheses.dart';
 import 'package:analysis_server/src/services/correction/dart/update_sdk_constraints.dart';
 import 'package:analysis_server/src/services/correction/dart/use_curly_braces.dart';
 import 'package:analysis_server/src/services/correction/dart/use_effective_integer_division.dart';
@@ -1414,6 +1415,9 @@
     ParserErrorCode.INVALID_CONSTANT_PATTERN_NEGATION: [
       AddConst.new,
     ],
+    ParserErrorCode.INVALID_INSIDE_UNARY_PATTERN: [
+      SurroundWithParentheses.new,
+    ],
     ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE: [
       AddTypeAnnotation.new,
     ],
diff --git a/pkg/analysis_server/test/src/services/correction/fix/surround_with_parentheses_test.dart b/pkg/analysis_server/test/src/services/correction/fix/surround_with_parentheses_test.dart
new file mode 100644
index 0000000..6f7bae8
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/surround_with_parentheses_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2023, 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/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SurroundWithParenthesesTest);
+  });
+}
+
+@reflectiveTest
+class SurroundWithParenthesesTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.SURROUND_WITH_PARENTHESES;
+
+  Future<void> test_cast_cast() async {
+    await resolveTestCode('''
+void f(x) {
+  switch (x) {
+    case 0 as int as num:
+      break;
+  }
+}
+''');
+    await assertHasFix('''
+void f(x) {
+  switch (x) {
+    case (0 as int) as num:
+      break;
+  }
+}
+''');
+  }
+
+  Future<void> test_cast_nullCheck() async {
+    await resolveTestCode('''
+void f(x) {
+  switch (x) {
+    case 0 as int? ?:
+      break;
+  }
+}
+''');
+    await assertHasFix('''
+void f(x) {
+  switch (x) {
+    case (0 as int?) ?:
+      break;
+  }
+}
+''');
+  }
+
+  Future<void> test_relationalNullCheck() async {
+    await resolveTestCode('''
+void f(x) {
+  switch (x) {
+    case > 1?:
+      break;
+  }
+}
+''');
+    await assertHasFix('''
+void f(x) {
+  switch (x) {
+    case (> 1)?:
+      break;
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 00a2963..629e1e2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -251,6 +251,7 @@
 import 'sort_constructor_first_test.dart' as sort_constructor_first_test;
 import 'sort_unnamed_constructor_first_test.dart'
     as sort_unnamed_constructor_first_test;
+import 'surround_with_parentheses_test.dart' as surround_with_parentheses;
 import 'type_literal_in_constant_pattern_test.dart'
     as type_literal_in_constant_pattern;
 import 'update_sdk_constraints_test.dart' as update_sdk_constraints;
@@ -480,6 +481,7 @@
     sort_constructor_first_test.main();
     sort_combinators_test.main();
     sort_unnamed_constructor_first_test.main();
+    surround_with_parentheses.main();
     type_literal_in_constant_pattern.main();
     update_sdk_constraints.main();
     use_curly_braces.main();