Add support for patterns to replace null assert with cast fix

Bug: 51880
Change-Id: I3b4bebefdb1122531ec9070ed70a15933d06dd70
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292100
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Keerti Parthasarathy <keertip@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_null_check_with_cast.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_null_check_with_cast.dart
index 0be2ee8..68dac13 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/replace_null_check_with_cast.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_null_check_with_cast.dart
@@ -2,6 +2,7 @@
 // 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:_fe_analyzer_shared/src/scanner/token.dart';
 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';
@@ -26,13 +27,21 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     final node = this.node;
-    if (node is! PostfixExpression) {
-      return;
+    Token? operator;
+    DartType? operandType;
+    if (node is NullAssertPattern) {
+      operator = node.operator;
+      operandType = node.matchedValueType;
     }
-    var operand = node.operand;
-    var operator = node.operator;
-    var operandType = operand.staticType;
-    if (operandType is! TypeParameterType) {
+    if (node is PostfixExpression) {
+      var operand = node.operand;
+      operator = node.operator;
+      if (operand.staticType is! TypeParameterType) {
+        return;
+      }
+      operandType = operand.staticType;
+    }
+    if (operator == null || operandType == null) {
       return;
     }
     // It is possible that there are cases of precedence and syntax which would
@@ -42,8 +51,8 @@
     // TODO(srawlins): Follow up on
     // https://github.com/dart-lang/linter/issues/3256.
     await builder.addDartFileEdit(file, (builder) {
-      builder.addSimpleReplacement(range.token(operator),
-          ' as ${operandType.getDisplayString(withNullability: false)}');
+      builder.addSimpleReplacement(range.token(operator!),
+          ' as ${operandType!.getDisplayString(withNullability: false)}');
     });
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_null_check_with_cast_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_null_check_with_cast_test.dart
index d99e73f..ca887e8 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_null_check_with_cast_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_null_check_with_cast_test.dart
@@ -51,6 +51,23 @@
   @override
   String get lintCode => LintNames.null_check_on_nullable_type_parameter;
 
+  Future<void> test_pattern() async {
+    await resolveTestCode('''
+void f<T>((T?, T?) p){
+  var (x!, y) = p;
+  print(x);
+  print(y);
+}
+''');
+    await assertHasFix('''
+void f<T>((T?, T?) p){
+  var (x as T, y) = p;
+  print(x);
+  print(y);
+}
+''');
+  }
+
   Future<void> test_simpleIdentifier() async {
     await resolveTestCode('''
 T run<T>(T? result) {