Version 2.13.0-223.0.dev

Merge commit '8fb98b25c1649fbaa64ce77315d181b16bc92a7f' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index b5a1027..ef6a1ef 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -107,7 +107,7 @@
     ConvertPartOfToUri.newInstance,
     ConvertToDoubleQuotes.newInstance,
     ConvertToFieldParameter.newInstance,
-    ConvertToMutilineString.newInstance,
+    ConvertToMultilineString.newInstance,
     ConvertToNormalParameter.newInstance,
     ConvertToSingleQuotes.newInstance,
     ConvertToExpressionFunctionBody.newInstance,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
index 7665de9..0ca4062 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_contains.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 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';
@@ -29,6 +27,9 @@
     var rightOperand = comparison.rightOperand;
     if (leftOperand is MethodInvocation && _isInteger(rightOperand)) {
       var value = _integerValue(rightOperand);
+      if (value == null) {
+        return;
+      }
       var methodName = leftOperand.methodName;
       var deletionRange = range.endEnd(leftOperand, rightOperand);
       var notOffset = -1;
@@ -48,6 +49,9 @@
       });
     } else if (_isInteger(leftOperand) && rightOperand is MethodInvocation) {
       var value = _integerValue(leftOperand);
+      if (value == null) {
+        return;
+      }
       var methodName = rightOperand.methodName;
       var deletionRange = range.startStart(leftOperand, rightOperand);
       var notOffset = -1;
@@ -71,17 +75,20 @@
 
   /// Return the value of the given [expression], given that [_isInteger]
   /// returned `true`.
-  int _integerValue(Expression expression) {
+  int? _integerValue(Expression expression) {
     if (expression is IntegerLiteral) {
       return expression.value;
     } else if (expression is PrefixExpression &&
         expression.operator.type == TokenType.MINUS) {
       var operand = expression.operand;
       if (operand is IntegerLiteral) {
-        return -operand.value;
+        var value = operand.value;
+        if (value != null) {
+          return -value;
+        }
       }
     }
-    throw StateError('invalid integer value');
+    return null;
   }
 
   TokenType _invertedTokenType(TokenType type) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
index fd38a12..ed84716e 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_expression_function_body.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -31,13 +29,13 @@
       return;
     }
     // prepare return statement
-    List<Statement> statements = (body as BlockFunctionBody).block.statements;
+    List<Statement> statements = body.block.statements;
     if (statements.length != 1) {
       return;
     }
     var onlyStatement = statements.first;
     // prepare returned expression
-    Expression returnExpression;
+    Expression? returnExpression;
     if (onlyStatement is ReturnStatement) {
       returnExpression = onlyStatement.expression;
     } else if (onlyStatement is ExpressionStatement) {
@@ -53,15 +51,17 @@
       return;
     }
 
+    final returnExpression_final = returnExpression;
     await builder.addDartFileEdit(file, (builder) {
       builder.addReplacement(range.node(body), (builder) {
         if (body.isAsynchronous) {
           builder.write('async ');
         }
         builder.write('=> ');
-        builder.write(utils.getNodeText(returnExpression));
-        if (body.parent is! FunctionExpression ||
-            body.parent.parent is FunctionDeclaration) {
+        builder.write(utils.getNodeText(returnExpression_final));
+        var parent = body.parent;
+        if (parent is! FunctionExpression ||
+            parent.parent is FunctionDeclaration) {
           builder.write(';');
         }
       });
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart
index ef999da..447adee 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_field_parameter.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -19,87 +17,128 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    if (node == null) {
-      return;
-    }
-    // prepare ConstructorDeclaration
-    var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
-    if (constructor == null) {
-      return;
-    }
-    var parameterList = constructor.parameters;
-    List<ConstructorInitializer> initializers = constructor.initializers;
     // prepare parameter
-    SimpleFormalParameter parameter;
-    if (node.parent is SimpleFormalParameter &&
-        node.parent.parent is FormalParameterList &&
-        node.parent.parent.parent is ConstructorDeclaration) {
-      parameter = node.parent;
+    var context = _findParameter(node);
+    if (context == null) {
+      return;
     }
-    if (node is SimpleIdentifier &&
-        node.parent is ConstructorFieldInitializer) {
-      var name = (node as SimpleIdentifier).name;
-      ConstructorFieldInitializer initializer = node.parent;
-      if (initializer.expression == node) {
-        for (var formalParameter in parameterList.parameters) {
-          if (formalParameter is SimpleFormalParameter &&
-              formalParameter.identifier.name == name) {
-            parameter = formalParameter;
-          }
-        }
-      }
-    }
-    // analyze parameter
-    if (parameter != null) {
-      var parameterName = parameter.identifier.name;
-      var parameterElement = parameter.declaredElement;
-      // check number of references
-      var visitor = _ReferenceCounter(parameterElement);
-      for (var initializer in initializers) {
-        initializer.accept(visitor);
-      }
-      if (visitor.count != 1) {
-        return;
-      }
-      // find the field initializer
-      ConstructorFieldInitializer parameterInitializer;
-      for (var initializer in initializers) {
-        if (initializer is ConstructorFieldInitializer) {
-          var expression = initializer.expression;
-          if (expression is SimpleIdentifier &&
-              expression.name == parameterName) {
-            parameterInitializer = initializer;
-          }
-        }
-      }
-      if (parameterInitializer == null) {
-        return;
-      }
-      var fieldName = parameterInitializer.fieldName.name;
 
-      await builder.addDartFileEdit(file, (builder) {
-        // replace parameter
-        builder.addSimpleReplacement(range.node(parameter), 'this.$fieldName');
-        // remove initializer
-        var initializerIndex = initializers.indexOf(parameterInitializer);
-        if (initializers.length == 1) {
-          builder
-              .addDeletion(range.endEnd(parameterList, parameterInitializer));
-        } else {
-          if (initializerIndex == 0) {
-            var next = initializers[initializerIndex + 1];
-            builder.addDeletion(range.startStart(parameterInitializer, next));
-          } else {
-            var prev = initializers[initializerIndex - 1];
-            builder.addDeletion(range.endEnd(prev, parameterInitializer));
-          }
-        }
-      });
+    // analyze parameter
+    var parameterName = context.identifier.name;
+    var parameterElement = context.parameter.declaredElement!;
+    var initializers = context.constructor.initializers;
+
+    // check number of references
+    var visitor = _ReferenceCounter(parameterElement);
+    for (var initializer in initializers) {
+      initializer.accept(visitor);
     }
+    if (visitor.count != 1) {
+      return;
+    }
+    // find the field initializer
+    ConstructorFieldInitializer? parameterInitializer;
+    for (var initializer in initializers) {
+      if (initializer is ConstructorFieldInitializer) {
+        var expression = initializer.expression;
+        if (expression is SimpleIdentifier &&
+            expression.name == parameterName) {
+          parameterInitializer = initializer;
+        }
+      }
+    }
+    if (parameterInitializer == null) {
+      return;
+    }
+    var fieldName = parameterInitializer.fieldName.name;
+
+    final context_final = context;
+    final parameterInitializer_final = parameterInitializer;
+    await builder.addDartFileEdit(file, (builder) {
+      // replace parameter
+      builder.addSimpleReplacement(
+        range.node(context_final.parameter),
+        'this.$fieldName',
+      );
+      // remove initializer
+      var initializerIndex = initializers.indexOf(parameterInitializer_final);
+      if (initializers.length == 1) {
+        builder.addDeletion(
+          range.endEnd(
+            context_final.constructor.parameters,
+            parameterInitializer_final,
+          ),
+        );
+      } else {
+        if (initializerIndex == 0) {
+          var next = initializers[initializerIndex + 1];
+          builder.addDeletion(
+            range.startStart(parameterInitializer_final, next),
+          );
+        } else {
+          var prev = initializers[initializerIndex - 1];
+          builder.addDeletion(
+            range.endEnd(prev, parameterInitializer_final),
+          );
+        }
+      }
+    });
   }
 
   /// Return an instance of this class. Used as a tear-off in `AssistProcessor`.
   static ConvertToFieldParameter newInstance() => ConvertToFieldParameter();
+
+  static _Context? _findParameter(AstNode node) {
+    var parent = node.parent;
+    if (parent is SimpleFormalParameter) {
+      var identifier = parent.identifier;
+      if (identifier == null) return null;
+
+      var formalParameterList = parent.parent;
+      if (formalParameterList is! FormalParameterList) return null;
+
+      var constructor = formalParameterList.parent;
+      if (constructor is! ConstructorDeclaration) return null;
+
+      return _Context(
+        parameter: parent,
+        identifier: identifier,
+        constructor: constructor,
+      );
+    }
+
+    if (node is SimpleIdentifier && parent is ConstructorFieldInitializer) {
+      var constructor = parent.parent;
+      if (constructor is! ConstructorDeclaration) return null;
+
+      if (parent.expression == node) {
+        for (var formalParameter in constructor.parameters.parameters) {
+          if (formalParameter is SimpleFormalParameter) {
+            var identifier = formalParameter.identifier;
+            if (identifier != null && identifier.name == node.name) {
+              return _Context(
+                parameter: formalParameter,
+                identifier: identifier,
+                constructor: constructor,
+              );
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+class _Context {
+  final SimpleFormalParameter parameter;
+  final SimpleIdentifier identifier;
+  final ConstructorDeclaration constructor;
+
+  _Context({
+    required this.parameter,
+    required this.identifier,
+    required this.constructor,
+  });
 }
 
 class _ReferenceCounter extends RecursiveAstVisitor<void> {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
index 7b197a4..76b0ad1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_generic_function_syntax.dart
@@ -2,11 +2,10 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/utilities/extensions/ast.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -27,8 +26,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var node = this.node;
-    while (node != null) {
+    for (var node in this.node.withParents) {
       if (node is FunctionTypeAlias) {
         return _convertFunctionTypeAlias(builder, node);
       } else if (node is FunctionTypedFormalParameter) {
@@ -38,7 +36,6 @@
         // when the selection is inside a parameter list.
         return null;
       }
-      node = node.parent;
     }
   }
 
@@ -47,7 +44,7 @@
   bool _allParametersHaveTypes(FormalParameterList parameters) {
     for (var parameter in parameters.parameters) {
       if (parameter is DefaultFormalParameter) {
-        parameter = (parameter as DefaultFormalParameter).parameter;
+        parameter = parameter.parameter;
       }
       if (parameter is SimpleFormalParameter) {
         if (parameter.type == null) {
@@ -65,10 +62,13 @@
     if (!_allParametersHaveTypes(node.parameters)) {
       return;
     }
-    String returnType;
-    if (node.returnType != null) {
-      returnType = utils.getNodeText(node.returnType);
+
+    String? returnType;
+    var returnTypeNode = node.returnType;
+    if (returnTypeNode != null) {
+      returnType = utils.getNodeText(returnTypeNode);
     }
+
     var functionName = utils.getRangeText(
         range.startEnd(node.name, node.typeParameters ?? node.name));
     var parameters = utils.getNodeText(node.parameters);
@@ -81,7 +81,7 @@
     // add change
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleReplacement(
-          range.startStart(node.typedefKeyword.next, node.semicolon),
+          range.startStart(node.typedefKeyword.next!, node.semicolon),
           replacement);
     });
   }
@@ -93,8 +93,9 @@
     }
     var required = node.requiredKeyword != null ? 'required ' : '';
     var covariant = node.covariantKeyword != null ? 'covariant ' : '';
+    var returnTypeNode = node.returnType;
     var returnType =
-        node.returnType != null ? '${utils.getNodeText(node.returnType)} ' : '';
+        returnTypeNode != null ? '${utils.getNodeText(returnTypeNode)} ' : '';
     var functionName = utils.getRangeText(range.startEnd(
         node.identifier, node.typeParameters ?? node.identifier));
     var parameters = utils.getNodeText(node.parameters);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
index 19e52d8..d8ca1d2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_if_null.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 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';
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
index ed675e7..1a9f163 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_int_literal.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -25,16 +23,18 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    if (node is! DoubleLiteral) {
+    var literal = node;
+    if (literal is! DoubleLiteral) {
       return;
     }
-    DoubleLiteral literal = node;
-    int intValue;
+
+    int? intValue;
     try {
-      intValue = literal.value?.truncate();
+      intValue = literal.value.truncate();
     } catch (e) {
       // Double cannot be converted to int
     }
+
     if (intValue == null || intValue != literal.value) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
index ba140fa..45ae0af 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_list_literal.dart
@@ -2,12 +2,11 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.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';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -29,9 +28,14 @@
     // Ensure that this is the default constructor defined on `List`.
     //
     var creation = node.thisOrAncestorOfType<InstanceCreationExpression>();
-    if (creation == null ||
-        node.offset > creation.argumentList.offset ||
-        creation.staticType.element != typeProvider.listElement ||
+    if (creation == null) {
+      return;
+    }
+
+    var type = creation.staticType;
+    if (node.offset > creation.argumentList.offset ||
+        type is! InterfaceType ||
+        type.element != typeProvider.listElement ||
         creation.constructorName.name != null ||
         creation.argumentList.arguments.isNotEmpty) {
       return;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
index 76221ea..5919c43 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_map_literal.dart
@@ -2,13 +2,12 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.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';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -31,11 +30,16 @@
     // `LinkedHashMap`.
     //
     var creation = node.thisOrAncestorOfType<InstanceCreationExpression>();
-    if (creation == null ||
-        node.offset > creation.argumentList.offset ||
+    if (creation == null) {
+      return;
+    }
+
+    var type = creation.staticType;
+    if (node.offset > creation.argumentList.offset ||
         creation.constructorName.name != null ||
         creation.argumentList.arguments.isNotEmpty ||
-        !_isMapClass(creation.staticType.element)) {
+        type is! InterfaceType ||
+        !_isMapClass(type.element)) {
       return;
     }
     //
@@ -57,11 +61,10 @@
 
   /// Return `true` if the [element] represents either the class `Map` or
   /// `LinkedHashMap`.
-  bool _isMapClass(Element element) =>
-      element is ClassElement &&
-      (element == typeProvider.mapElement ||
-          (element.name == 'LinkedHashMap' &&
-              element.library.name == 'dart.collection'));
+  bool _isMapClass(ClassElement element) =>
+      element == typeProvider.mapElement ||
+      (element.name == 'LinkedHashMap' &&
+          element.library.name == 'dart.collection');
 
   /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
   static ConvertToMapLiteral newInstance() => ConvertToMapLiteral();
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_multiline_string.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_multiline_string.dart
index 0dd99aa..51861d9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_multiline_string.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_multiline_string.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -11,7 +9,7 @@
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 
-class ConvertToMutilineString extends CorrectionProducer {
+class ConvertToMultilineString extends CorrectionProducer {
   @override
   AssistKind get assistKind => DartAssistKind.CONVERT_TO_MULTILINE_STRING;
 
@@ -19,7 +17,7 @@
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is InterpolationElement) {
-      node = (node as InterpolationElement).parent;
+      node = node.parent!;
     }
     if (node is SingleStringLiteral) {
       var literal = node;
@@ -42,5 +40,5 @@
   }
 
   /// Return an instance of this class. Used as a tear-off in `AssistProcessor`.
-  static ConvertToMutilineString newInstance() => ConvertToMutilineString();
+  static ConvertToMultilineString newInstance() => ConvertToMultilineString();
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
index a4af1c4..228d9f9 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_named_arguments.dart
@@ -2,13 +2,12 @@
 // 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.
 
-// @dart = 2.9
-
 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/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 
@@ -22,7 +21,7 @@
     var argumentList = node.parent;
     if (argumentList is ArgumentList) {
       // Prepare parameters.
-      List<ParameterElement> parameters;
+      List<ParameterElement>? parameters;
       var parent = argumentList.parent;
       if (parent is FunctionExpressionInvocation) {
         var invokeType = parent.staticInvokeType;
@@ -61,10 +60,10 @@
           argumentList.arguments.skip(numberOfPositionalParameters);
       for (var argument in extraArguments) {
         if (argument is! NamedExpression) {
-          ParameterElement uniqueNamedParameter;
+          ParameterElement? uniqueNamedParameter;
           for (var namedParameter in namedParameters) {
             if (typeSystem.isSubtypeOf(
-                argument.staticType, namedParameter.type)) {
+                argument.typeOrThrow, namedParameter.type)) {
               if (uniqueNamedParameter == null) {
                 uniqueNamedParameter = namedParameter;
               } else {
@@ -84,8 +83,9 @@
       }
 
       await builder.addDartFileEdit(file, (builder) {
-        for (var argument in argumentToParameter.keys) {
-          var parameter = argumentToParameter[argument];
+        for (var entry in argumentToParameter.entries) {
+          var argument = entry.key;
+          var parameter = entry.value;
           builder.addSimpleInsertion(argument.offset, '${parameter.name}: ');
         }
       });
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart
index b220afd..d7a7c65 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_normal_parameter.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -17,38 +15,41 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    if (node is SimpleIdentifier &&
-        node.parent is FieldFormalParameter &&
-        node.parent.parent is FormalParameterList &&
-        node.parent.parent.parent is ConstructorDeclaration) {
-      ConstructorDeclaration constructor = node.parent.parent.parent;
-      FormalParameterList parameterList = node.parent.parent;
-      FieldFormalParameter parameter = node.parent;
-      var parameterElement = parameter.declaredElement;
-      var name = (node as SimpleIdentifier).name;
-      // prepare type
-      var type = parameterElement.type;
+    var identifier = node;
+    if (identifier is! SimpleIdentifier) return;
 
-      await builder.addDartFileEdit(file, (builder) {
-        // replace parameter
-        if (type.isDynamic) {
-          builder.addSimpleReplacement(range.node(parameter), name);
-        } else {
-          builder.addReplacement(range.node(parameter), (builder) {
-            builder.writeType(type);
-            builder.write(' ');
-            builder.write(name);
-          });
-        }
-        // add field initializer
-        List<ConstructorInitializer> initializers = constructor.initializers;
-        if (initializers.isEmpty) {
-          builder.addSimpleInsertion(parameterList.end, ' : $name = $name');
-        } else {
-          builder.addSimpleInsertion(initializers.last.end, ', $name = $name');
-        }
-      });
-    }
+    var parameter = identifier.parent;
+    if (parameter is! FieldFormalParameter) return;
+
+    var parameterList = parameter.parent;
+    if (parameterList is! FormalParameterList) return;
+
+    var constructor = parameterList.parent;
+    if (constructor is! ConstructorDeclaration) return;
+
+    var parameterElement = parameter.declaredElement!;
+    var name = identifier.name;
+    var type = parameterElement.type;
+
+    await builder.addDartFileEdit(file, (builder) {
+      // replace parameter
+      if (type.isDynamic) {
+        builder.addSimpleReplacement(range.node(parameter), name);
+      } else {
+        builder.addReplacement(range.node(parameter), (builder) {
+          builder.writeType(type);
+          builder.write(' ');
+          builder.write(name);
+        });
+      }
+      // add field initializer
+      List<ConstructorInitializer> initializers = constructor.initializers;
+      if (initializers.isEmpty) {
+        builder.addSimpleInsertion(parameterList.end, ' : $name = $name');
+      } else {
+        builder.addSimpleInsertion(initializers.last.end, ', $name = $name');
+      }
+    });
   }
 
   /// Return an instance of this class. Used as a tear-off in `AssistProcessor`.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
index 5307774..013e4fe 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -28,15 +26,17 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
-    if (node.parent is BinaryExpression &&
-        node.parent.parent is ConditionalExpression) {
-      node = node.parent.parent;
+    var parent = node.parent;
+    if (parent is BinaryExpression) {
+      var grandParent = parent.parent;
+      if (grandParent is ConditionalExpression) {
+        node = grandParent;
+      }
     }
     if (node is! ConditionalExpression) {
       return;
     }
-    ConditionalExpression conditional = node;
-    var condition = conditional.condition.unParenthesized;
+    var condition = node.condition.unParenthesized;
     SimpleIdentifier identifier;
     Expression nullExpression;
     Expression nonNullExpression;
@@ -67,21 +67,20 @@
       // is the save variable being compared to `null`.
       //
       if (condition.operator.type == TokenType.EQ_EQ) {
-        nullExpression = conditional.thenExpression;
-        nonNullExpression = conditional.elseExpression;
+        nullExpression = node.thenExpression;
+        nonNullExpression = node.elseExpression;
       } else if (condition.operator.type == TokenType.BANG_EQ) {
-        nonNullExpression = conditional.thenExpression;
-        nullExpression = conditional.elseExpression;
-      }
-      if (nullExpression == null || nonNullExpression == null) {
+        nonNullExpression = node.thenExpression;
+        nullExpression = node.elseExpression;
+      } else {
         return;
       }
       if (nullExpression.unParenthesized is! NullLiteral) {
         return;
       }
       var unwrappedExpression = nonNullExpression.unParenthesized;
-      Expression target;
-      Token operator;
+      Expression? target;
+      Token? operator;
       if (unwrappedExpression is MethodInvocation) {
         target = unwrappedExpression.target;
         operator = unwrappedExpression.operator;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart
index 8f54f38..920b2f2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_spread.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 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';
@@ -16,7 +14,7 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var parent = coveredNode.parent;
+    var parent = coveredNode?.parent;
     if (parent is SpreadElement && !parent.isNullAware) {
       await builder.addDartFileEdit(file, (builder) {
         builder.addSimpleInsertion(parent.spreadOperator.end, '?');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
index 074e90c..a40b1b2 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_package_import.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -27,7 +25,7 @@
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is StringLiteral) {
-      node = node.parent;
+      node = node.parent!;
     }
     if (node is ImportDirective) {
       var importDirective = node;
@@ -45,7 +43,8 @@
 
       // Don't offer to convert a 'package:' URI to itself.
       try {
-        if (Uri.parse(importDirective.uriContent).scheme == 'package') {
+        var uriContent = importDirective.uriContent;
+        if (uriContent == null || Uri.parse(uriContent).scheme == 'package') {
           return;
         }
       } on FormatException {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
index a312a32..48a99d7 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_relative_import.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
@@ -28,16 +26,14 @@
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
     if (node is StringLiteral) {
-      node = node.parent;
+      node = node.parent!;
     }
     if (node is! ImportDirective) {
       return;
     }
 
-    ImportDirective importDirective = node;
-
     // Ignore if invalid URI.
-    if (importDirective.uriSource == null) {
+    if (node.uriSource == null) {
       return;
     }
 
@@ -49,7 +45,11 @@
 
     Uri importUri;
     try {
-      importUri = Uri.parse(importDirective.uriContent);
+      var uriContent = node.uriContent;
+      if (uriContent == null) {
+        return;
+      }
+      importUri = Uri.parse(uriContent);
     } on FormatException {
       return;
     }
@@ -75,9 +75,10 @@
       from: path.dirname(sourceUri.path),
     );
 
+    final node_final = node;
     await builder.addDartFileEdit(file, (builder) {
       builder.addSimpleReplacement(
-        range.node(importDirective.uri).getExpanded(-1),
+        range.node(node_final.uri).getExpanded(-1),
         relativePath,
       );
     });
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
index fb2b42c..8796a16 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_set_literal.dart
@@ -2,12 +2,11 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/assist.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';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/source/source_range.dart';
 import 'package:analyzer_plugin/utilities/assist/assist.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
@@ -62,8 +61,8 @@
       var name = creation.constructorName.name;
       var constructorTypeArguments =
           creation.constructorName.type.typeArguments;
-      TypeArgumentList elementTypeArguments;
-      SourceRange elementsRange;
+      TypeArgumentList? elementTypeArguments;
+      SourceRange? elementsRange;
       if (name == null) {
         // Handle an invocation of the default constructor `Set()`.
       } else if (name.name == 'from' || name.name == 'of') {
@@ -111,7 +110,7 @@
 
   /// Return the invocation of `List.toSet` that is to be converted, or `null`
   /// if the cursor is not inside a invocation of `List.toSet`.
-  MethodInvocation _findInvocationOfToSet() {
+  MethodInvocation? _findInvocationOfToSet() {
     var invocation = node.thisOrAncestorOfType<MethodInvocation>();
     if (invocation == null ||
         node.offset > invocation.argumentList.offset ||
@@ -124,12 +123,23 @@
 
   /// Return the invocation of a `Set` constructor that is to be converted, or
   /// `null` if the cursor is not inside the invocation of a constructor.
-  InstanceCreationExpression _findSetCreation() {
+  InstanceCreationExpression? _findSetCreation() {
     var creation = node.thisOrAncestorOfType<InstanceCreationExpression>();
+    if (creation == null) {
+      return null;
+    }
+
+    if (node.offset > creation.argumentList.offset) {
+      return null;
+    }
+
+    var type = creation.staticType;
+    if (type is! InterfaceType) {
+      return null;
+    }
+
     // TODO(brianwilkerson) Consider also accepting uses of LinkedHashSet.
-    if (creation == null ||
-        node.offset > creation.argumentList.offset ||
-        creation.staticType.element != typeProvider.setElement) {
+    if (type.element != typeProvider.setElement) {
       return null;
     }
     return creation;
@@ -139,7 +149,7 @@
   /// element that would cause a set to be inferred.
   bool _hasUnambiguousElement(InstanceCreationExpression creation) {
     var arguments = creation.argumentList.arguments;
-    if (arguments == null || arguments.isEmpty) {
+    if (arguments.isEmpty) {
       return false;
     }
     return _listHasUnambiguousElement(arguments[0]);
@@ -147,7 +157,7 @@
 
   /// Return `true` if the [element] is sufficient to lexically make the
   /// enclosing literal a set literal rather than a map.
-  bool _isUnambiguousElement(CollectionElement element) {
+  bool _isUnambiguousElement(CollectionElement? element) {
     if (element is ForElement) {
       return _isUnambiguousElement(element.body);
     } else if (element is IfElement) {
@@ -176,7 +186,7 @@
   /// Return `true` if a set would be inferred if the literal replacing the
   /// instance [creation] did not have explicit type arguments.
   bool _setWouldBeInferred(InstanceCreationExpression creation) {
-    var parent = creation.parent;
+    var parent = creation.parent!;
     if (parent is VariableDeclaration) {
       var parent2 = parent.parent;
       if (parent2 is VariableDeclarationList &&
@@ -185,7 +195,7 @@
       }
     } else if (parent.parent is InvocationExpression) {
       var parameterElement = creation.staticParameterElement;
-      if (parameterElement?.type?.element == typeProvider.setElement) {
+      if (parameterElement?.type.element == typeProvider.setElement) {
         return true;
       }
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
index eb508d4..de20ada 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_where_type.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 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';
@@ -20,33 +18,46 @@
 
   @override
   Future<void> compute(ChangeBuilder builder) async {
-    var node = this.node;
-    if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+    var methodName = node;
+    if (methodName is! SimpleIdentifier) {
       return;
     }
-    var methodName = node as SimpleIdentifier;
-    var invocation = node.parent as MethodInvocation;
+
+    var invocation = methodName.parent;
+    if (invocation is! MethodInvocation) {
+      return;
+    }
+
     var arguments = invocation.argumentList.arguments;
-    if (arguments.length != 1 || arguments[0] is! FunctionExpression) {
+    if (arguments.length != 1) {
       return;
     }
-    var body = (arguments[0] as FunctionExpression).body;
-    Expression returnValue;
+
+    var argument = arguments[0];
+    if (argument is! FunctionExpression) {
+      return;
+    }
+
+    Expression? returnValue;
+    var body = argument.body;
     if (body is ExpressionFunctionBody) {
       returnValue = body.expression;
     } else if (body is BlockFunctionBody) {
       var statements = body.block.statements;
-      if (statements.length != 1 || statements[0] is! ReturnStatement) {
+      if (statements.length != 1) {
         return;
       }
-      returnValue = (statements[0] as ReturnStatement).expression;
-    } else {
-      return;
+      var returnStatement = statements[0];
+      if (returnStatement is! ReturnStatement) {
+        return;
+      }
+      returnValue = returnStatement.expression;
     }
+
     if (returnValue is! IsExpression) {
       return;
     }
-    var isExpression = returnValue as IsExpression;
+    var isExpression = returnValue;
     if (isExpression.notOperator != null) {
       return;
     }
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
index 05d4f47..833a8db 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_class.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 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';
@@ -14,7 +12,7 @@
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 
 class CreateClass extends CorrectionProducer {
-  String className;
+  String className = '';
 
   @override
   List<Object> get fixArguments => [className];
@@ -25,14 +23,14 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     var node = this.node;
-    Element prefixElement;
+    Element? prefixElement;
     SimpleIdentifier nameNode;
-    ArgumentList arguments;
+    ArgumentList? arguments;
+
     if (node is Annotation) {
-      var annotation = node as Annotation;
-      var name = annotation.name;
-      arguments = annotation.arguments;
-      if (name == null || name.staticElement != null || arguments == null) {
+      var name = node.name;
+      arguments = node.arguments;
+      if (name.staticElement != null || arguments == null) {
         // TODO(brianwilkerson) Consider supporting creating a class when the
         //  arguments are missing by also adding an empty argument list.
         return;
@@ -59,9 +57,9 @@
     var prefix = '';
     var suffix = '';
     var offset = -1;
-    String filePath;
+    String? filePath;
     if (prefixElement == null) {
-      targetUnit = unit.declaredElement;
+      targetUnit = unit.declaredElement!;
       var enclosingMember = node.thisOrAncestorMatching((node) =>
           node is CompilationUnitMember && node.parent is CompilationUnit);
       if (enclosingMember == null) {
@@ -76,7 +74,7 @@
           var library = import.importedLibrary;
           if (library != null) {
             targetUnit = library.definingCompilationUnit;
-            var targetSource = targetUnit.source;
+            var targetSource = targetUnit.source!;
             try {
               offset = targetSource.contents.data.length;
               filePath = targetSource.fullName;
@@ -91,7 +89,7 @@
         }
       }
     }
-    if (offset < 0) {
+    if (filePath == null || offset < 0) {
       return;
     }
     await builder.addDartFileEdit(filePath, (builder) {
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart
index 6526f89..e9be86a 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor.dart
@@ -2,8 +2,6 @@
 // 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.
 
-// @dart = 2.9
-
 import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
@@ -16,7 +14,8 @@
 
 class CreateConstructor extends CorrectionProducer {
   /// The name of the constructor being created.
-  ConstructorName _constructorName;
+  /// TODO(migration) We set this node when we have the change.
+  late ConstructorName _constructorName;
 
   @override
   List<Object> get fixArguments => [_constructorName];
@@ -27,39 +26,43 @@
   @override
   Future<void> compute(ChangeBuilder builder) async {
     final argumentList = node.parent is ArgumentList ? node.parent : node;
-    if (argumentList is ArgumentList &&
-        argumentList.parent is InstanceCreationExpression) {
-      await _proposeFromInstanceCreation(builder, argumentList.parent);
+    if (argumentList is ArgumentList) {
+      var instanceCreation = argumentList.parent;
+      if (instanceCreation is InstanceCreationExpression) {
+        await _proposeFromInstanceCreation(builder, instanceCreation);
+      }
     } else {
       await _proposeFromConstructorName(builder);
     }
   }
 
   Future<void> _proposeFromConstructorName(ChangeBuilder builder) async {
-    SimpleIdentifier name;
-    InstanceCreationExpression instanceCreation;
-    if (node is SimpleIdentifier) {
-      // name
-      name = node as SimpleIdentifier;
-      if (name.parent is ConstructorName) {
-        _constructorName = name.parent as ConstructorName;
-        if (_constructorName.name == name) {
-          // Type.name
-          if (_constructorName.parent is InstanceCreationExpression) {
-            instanceCreation =
-                _constructorName.parent as InstanceCreationExpression;
-            // new Type.name()
-            if (instanceCreation.constructorName != _constructorName) {
-              return;
-            }
+    var name = node;
+    if (name is! SimpleIdentifier) {
+      return;
+    }
+
+    InstanceCreationExpression? instanceCreation;
+    if (name.parent is ConstructorName) {
+      _constructorName = name.parent as ConstructorName;
+      if (_constructorName.name == name) {
+        // Type.name
+        if (_constructorName.parent is InstanceCreationExpression) {
+          instanceCreation =
+              _constructorName.parent as InstanceCreationExpression;
+          // new Type.name()
+          if (instanceCreation.constructorName != _constructorName) {
+            return;
           }
         }
       }
     }
+
     // do we have enough information?
     if (instanceCreation == null) {
       return;
     }
+
     // prepare target interface type
     var targetType = _constructorName.type.type;
     if (targetType is! InterfaceType) {
@@ -67,23 +70,35 @@
     }
 
     // prepare target ClassDeclaration
-    ClassElement targetElement = targetType.element;
+    var targetElement = targetType.element;
     var targetResult = await sessionHelper.getElementDeclaration(targetElement);
+    if (targetResult == null) {
+      return;
+    }
     var targetNode = targetResult.node;
     if (targetNode is! ClassDeclaration) {
       return;
     }
 
+    var targetUnit = targetResult.resolvedUnit;
+    if (targetUnit == null) {
+      return;
+    }
+
     // prepare location
-    var targetLocation = CorrectionUtils(targetResult.resolvedUnit)
-        .prepareNewConstructorLocation(targetNode);
+    var targetLocation =
+        CorrectionUtils(targetUnit).prepareNewConstructorLocation(targetNode);
+    if (targetLocation == null) {
+      return;
+    }
 
     var targetFile = targetElement.source.fullName;
+    final instanceCreation_final = instanceCreation;
     await builder.addDartFileEdit(targetFile, (builder) {
       builder.addInsertion(targetLocation.offset, (builder) {
         builder.write(targetLocation.prefix);
         builder.writeConstructorDeclaration(targetElement.name,
-            argumentList: instanceCreation.argumentList,
+            argumentList: instanceCreation_final.argumentList,
             constructorName: name,
             constructorNameGroupName: 'NAME');
         builder.write(targetLocation.suffix);
@@ -112,14 +127,25 @@
     // prepare target ClassDeclaration
     var targetElement = constructorElement.enclosingElement;
     var targetResult = await sessionHelper.getElementDeclaration(targetElement);
-    var targetNode = targetResult?.node;
+    if (targetResult == null) {
+      return;
+    }
+    var targetNode = targetResult.node;
     if (targetNode is! ClassDeclaration) {
       return;
     }
 
+    var targetUnit = targetResult.resolvedUnit;
+    if (targetUnit == null) {
+      return;
+    }
+
     // prepare location
-    var targetLocation = CorrectionUtils(targetResult.resolvedUnit)
-        .prepareNewConstructorLocation(targetNode);
+    var targetLocation =
+        CorrectionUtils(targetUnit).prepareNewConstructorLocation(targetNode);
+    if (targetLocation == null) {
+      return;
+    }
 
     var targetSource = targetElement.source;
     var targetFile = targetSource.fullName;
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 e8795a1f..02560a0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1732,15 +1732,15 @@
     return fixes.isNotEmpty ? fixes.first : null;
   }
 
-  void _addFixFromBuilder(ChangeBuilder builder, FixKind kind,
-      {List<Object> args, bool importsOnly = false}) {
+  void _addFixFromBuilder(ChangeBuilder builder, CorrectionProducer producer) {
     if (builder == null) return;
     var change = builder.sourceChange;
-    if (change.edits.isEmpty && !importsOnly) {
+    if (change.edits.isEmpty) {
       return;
     }
+    var kind = producer.fixKind;
     change.id = kind.id;
-    change.message = formatList(kind.message, args);
+    change.message = formatList(kind.message, producer.fixArguments);
     fixes.add(Fix(kind, change));
   }
 
@@ -1764,8 +1764,7 @@
           workspace: context.workspace, eol: context.utils.endOfLine);
       try {
         await producer.compute(builder);
-        _addFixFromBuilder(builder, producer.fixKind,
-            args: producer.fixArguments);
+        _addFixFromBuilder(builder, producer);
       } on ConflictingEditException catch (exception, stackTrace) {
         // Handle the exception by (a) not adding a fix based on the producer
         // and (b) logging the exception.
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 84a6dbf..551ee3a 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -203,6 +203,7 @@
   final Class listClass;
   final Class typeClass;
   final Procedure unsafeCastMethod;
+  final Procedure nativeEffectMethod;
   final Class typedDataClass;
   final Procedure typedDataBufferGetter;
   final Procedure typedDataOffsetInBytesGetter;
@@ -294,6 +295,8 @@
         typeClass = coreTypes.typeClass,
         unsafeCastMethod =
             index.getTopLevelMember('dart:_internal', 'unsafeCast'),
+        nativeEffectMethod =
+            index.getTopLevelMember('dart:_internal', '_nativeEffect'),
         typedDataClass = index.getClass('dart:typed_data', 'TypedData'),
         typedDataBufferGetter =
             index.getMember('dart:typed_data', 'TypedData', 'get:buffer'),
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index 1b69f26..20cfbe8 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -387,29 +387,29 @@
   }
 
   /// Prevents the struct from being tree-shaken in TFA by invoking its
-  /// constructor in a let expression.
-  ///
-  /// TFA does not recognize this as dead code, only the VM does.
-  /// TODO(http://dartbug.com/45607): Wrap with `_nativeEffect` to make the
-  /// intent of this code clear.
+  /// constructor in a `_nativeEffect` expression.
   Expression _invokeStructConstructor(
-      Expression nestedExpression, Class structClass) {
-    final constructor = structClass.constructors
+      Expression nestedExpression, Class compositeClass) {
+    final constructor = compositeClass.constructors
         .firstWhere((c) => c.name == Name("#fromTypedDataBase"));
-    return Let(
-        VariableDeclaration.forValue(
-            ConstructorInvocation(
-                constructor,
-                Arguments([
-                  StaticInvocation(
-                      uint8ListFactory,
-                      Arguments([
-                        ConstantExpression(IntConstant(1)),
-                      ]))
-                    ..fileOffset = nestedExpression.fileOffset,
-                ]))
-              ..fileOffset = nestedExpression.fileOffset,
-            type: InterfaceType(structClass, Nullability.nonNullable)),
+    return BlockExpression(
+        Block([
+          ExpressionStatement(StaticInvocation(
+              nativeEffectMethod,
+              Arguments([
+                ConstructorInvocation(
+                    constructor,
+                    Arguments([
+                      StaticInvocation(
+                          uint8ListFactory,
+                          Arguments([
+                            ConstantExpression(IntConstant(1)),
+                          ]))
+                        ..fileOffset = nestedExpression.fileOffset,
+                    ]))
+                  ..fileOffset = nestedExpression.fileOffset
+              ])))
+        ]),
         nestedExpression)
       ..fileOffset = nestedExpression.fileOffset;
   }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
index 66de23b..3469672 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/ffi_struct_constructors.dart.expect
@@ -65,13 +65,17 @@
 }
 static method testLookupFunctionReturn() → void {
   final ffi::DynamicLibrary* dylib = [@vm.inferred-type.metadata=dart.ffi::DynamicLibrary?] ffi::DynamicLibrary::executable();
-  final () →* self::Struct1* function1 = let final self::Struct1 #t1 = new self::Struct1::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)) in ffi::_asFunctionInternal<() →* self::Struct1*, () →* self::Struct1*>([@vm.direct-call.metadata=dart.ffi::DynamicLibrary.lookup??] [@vm.inferred-type.metadata=dart.ffi::Pointer? (skip check)] dylib.{ffi::DynamicLibrary::lookup}<ffi::NativeFunction<() →* self::Struct1*>*>("function1"));
+  final () →* self::Struct1* function1 = block {
+    _in::_nativeEffect(new self::Struct1::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)));
+  } =>ffi::_asFunctionInternal<() →* self::Struct1*, () →* self::Struct1*>([@vm.direct-call.metadata=dart.ffi::DynamicLibrary.lookup??] [@vm.inferred-type.metadata=dart.ffi::Pointer? (skip check)] dylib.{ffi::DynamicLibrary::lookup}<ffi::NativeFunction<() →* self::Struct1*>*>("function1"));
   final self::Struct1* struct1 = [@vm.call-site-attributes.metadata=receiverType:#lib::Struct1* Function()*] function1.call();
   core::print(struct1);
 }
 static method testAsFunctionReturn() → void {
   final ffi::Pointer<ffi::NativeFunction<() →* self::Struct2*>*>* pointer = [@vm.inferred-type.metadata=dart.ffi::Pointer?] ffi::Pointer::fromAddress<ffi::NativeFunction<() →* self::Struct2*>*>(3735928559);
-  final () →* self::Struct2* function2 = let final self::Struct2 #t2 = new self::Struct2::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)) in ffi::_asFunctionInternal<() →* self::Struct2*, () →* self::Struct2*>(pointer);
+  final () →* self::Struct2* function2 = block {
+    _in::_nativeEffect(new self::Struct2::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)));
+  } =>ffi::_asFunctionInternal<() →* self::Struct2*, () →* self::Struct2*>(pointer);
   final self::Struct2* struct2 = [@vm.call-site-attributes.metadata=receiverType:#lib::Struct2* Function()*] function2.call();
   core::print(struct2);
 }
@@ -79,7 +83,9 @@
   return 42;
 }
 static method testFromFunctionArgument() → void {
-  final ffi::Pointer<ffi::NativeFunction<(self::Struct3*) →* ffi::Int32*>*>* pointer = let final self::Struct3 #t3 = new self::Struct3::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)) in [@vm.inferred-type.metadata=dart.ffi::Pointer?] self::_#ffiCallback0;
+  final ffi::Pointer<ffi::NativeFunction<(self::Struct3*) →* ffi::Int32*>*>* pointer = block {
+    _in::_nativeEffect(new self::Struct3::#fromTypedDataBase([@vm.inferred-type.metadata=dart.typed_data::_Uint8List] typ::Uint8List::•(#C18)));
+  } =>[@vm.inferred-type.metadata=dart.ffi::Pointer?] self::_#ffiCallback0;
   core::print(pointer);
 }
 static method testLookupFunctionArgument() → void {
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 11b7f60..507ce9d 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -279,6 +279,10 @@
   return arguments->NativeArgAt(0);
 }
 
+DEFINE_NATIVE_ENTRY(Internal_nativeEffect, 0, 1) {
+  UNREACHABLE();
+}
+
 DEFINE_NATIVE_ENTRY(Internal_reachabilityFence, 0, 1) {
   UNREACHABLE();
 }
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 3190883..fe0f192 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -333,6 +333,7 @@
   V(GrowableList_setLength, 2)                                                 \
   V(GrowableList_setData, 2)                                                   \
   V(Internal_unsafeCast, 1)                                                    \
+  V(Internal_nativeEffect, 1)                                                  \
   V(Internal_reachabilityFence, 1)                                             \
   V(Internal_collectAllGarbage, 0)                                             \
   V(Internal_makeListFixedLength, 1)                                           \
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index d90c132..9dfcc4e 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -2643,7 +2643,7 @@
 }
 
 Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p) {
-  const intptr_t offset = ReaderOffset() - 1;     // Include the tag.
+  const intptr_t offset = ReaderOffset() - 1;  // Include the tag.
 
   const uint8_t flags = ReadFlags();  // read flags.
   const bool is_invariant = (flags & kMethodInvocationFlagInvariant) != 0;
@@ -3007,7 +3007,9 @@
   }
 
   const auto recognized_kind = target.recognized_kind();
-  if (recognized_kind == MethodRecognizer::kFfiAsFunctionInternal) {
+  if (recognized_kind == MethodRecognizer::kNativeEffect) {
+    return BuildNativeEffect();
+  } else if (recognized_kind == MethodRecognizer::kFfiAsFunctionInternal) {
     return BuildFfiAsFunctionInternal();
   } else if (CompilerState::Current().is_aot() &&
              recognized_kind == MethodRecognizer::kFfiNativeCallbackFunction) {
@@ -5018,20 +5020,42 @@
   return instructions;
 }
 
+Fragment StreamingFlowGraphBuilder::BuildNativeEffect() {
+  const intptr_t argc = ReadUInt();  // Read argument count.
+  ASSERT(argc == 1);                 // Native side effect to ignore.
+  const intptr_t list_length = ReadListLength();  // Read types list length.
+  ASSERT(list_length == 0);
+
+  const intptr_t positional_count =
+      ReadListLength();  // Read positional argument count.
+  ASSERT(positional_count == 1);
+
+  BuildExpression();  // Consume expression but don't save the fragment.
+  Pop();              // Restore the stack.
+
+  const intptr_t named_args_len =
+      ReadListLength();  // Skip empty named arguments.
+  ASSERT(named_args_len == 0);
+
+  Fragment code;
+  code += NullConstant();  // Return type is void.
+  return code;
+}
+
 Fragment StreamingFlowGraphBuilder::BuildFfiAsFunctionInternal() {
-  const intptr_t argc = ReadUInt();               // read argument count.
-  ASSERT(argc == 1);                              // pointer
-  const intptr_t list_length = ReadListLength();  // read types list length.
-  ASSERT(list_length == 2);  // dart signature, then native signature
+  const intptr_t argc = ReadUInt();               // Read argument count.
+  ASSERT(argc == 1);                              // Pointer.
+  const intptr_t list_length = ReadListLength();  // Read types list length.
+  ASSERT(list_length == 2);  // Dart signature, then native signature.
   const TypeArguments& type_arguments =
-      T.BuildTypeArguments(list_length);  // read types.
+      T.BuildTypeArguments(list_length);  // Read types.
   Fragment code;
   const intptr_t positional_count =
-      ReadListLength();  // read positional argument count
+      ReadListLength();  // Read positional argument count.
   ASSERT(positional_count == 1);
-  code += BuildExpression();  // build first positional argument (pointer)
+  code += BuildExpression();  // Build first positional argument (pointer).
   const intptr_t named_args_len =
-      ReadListLength();  // skip (empty) named arguments list
+      ReadListLength();  // Skip empty named arguments list.
   ASSERT(named_args_len == 0);
   code += B->BuildFfiAsFunctionInternalCall(type_arguments);
   return code;
@@ -5044,24 +5068,24 @@
   //
   // The FE also guarantees that all three arguments are constants.
 
-  const intptr_t argc = ReadUInt();  // read argument count
-  ASSERT(argc == 2);                 // target, exceptionalReturn
+  const intptr_t argc = ReadUInt();  // Read argument count.
+  ASSERT(argc == 2);                 // Target, exceptionalReturn.
 
-  const intptr_t list_length = ReadListLength();  // read types list length
-  ASSERT(list_length == 1);                       // native signature
+  const intptr_t list_length = ReadListLength();  // Read types list length.
+  ASSERT(list_length == 1);                       // The native signature.
   const TypeArguments& type_arguments =
-      T.BuildTypeArguments(list_length);  // read types.
+      T.BuildTypeArguments(list_length);  // Read types.
   ASSERT(type_arguments.Length() == 1 && type_arguments.IsInstantiated());
   const FunctionType& native_sig =
       FunctionType::CheckedHandle(Z, type_arguments.TypeAt(0));
 
   Fragment code;
   const intptr_t positional_count =
-      ReadListLength();  // read positional argument count
+      ReadListLength();  // Read positional argument count.
   ASSERT(positional_count == 2);
 
   // Read target expression and extract the target function.
-  code += BuildExpression();  // build first positional argument (target)
+  code += BuildExpression();  // Build first positional argument (target).
   Definition* target_def = B->Peek();
   ASSERT(target_def->IsConstant());
   const Closure& target_closure =
@@ -5081,7 +5105,7 @@
   code += Drop();
 
   const intptr_t named_args_len =
-      ReadListLength();  // skip (empty) named arguments list
+      ReadListLength();  // Skip (empty) named arguments list.
   ASSERT(named_args_len == 0);
 
   const Function& result =
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 7f133f7..47f5bca 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -344,11 +344,14 @@
   Fragment BuildFunctionNode(TokenPosition parent_position,
                              StringIndex name_index);
 
-  // Build build FG for '_asFunctionInternal'. Reads an Arguments from the
+  // Build flow graph for '_nativeEffect'.
+  Fragment BuildNativeEffect();
+
+  // Build FG for '_asFunctionInternal'. Reads an Arguments from the
   // Kernel buffer and pushes the resulting closure.
   Fragment BuildFfiAsFunctionInternal();
 
-  // Build build FG for '_nativeCallbackFunction'. Reads an Arguments from the
+  // Build FG for '_nativeCallbackFunction'. Reads an Arguments from the
   // Kernel buffer and pushes the resulting Function object.
   Fragment BuildFfiNativeCallbackFunction();
 
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 8a2fbbc..02acfb7 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -166,6 +166,7 @@
   V(::, _abi, FfiAbi, 0x7c4ab775)                                              \
   V(::, _asFunctionInternal, FfiAsFunctionInternal, 0xbbcb235a)                \
   V(::, _nativeCallbackFunction, FfiNativeCallbackFunction, 0x3ff5ae9c)        \
+  V(::, _nativeEffect, NativeEffect, 0x61e00b59)                               \
   V(::, _loadInt8, FfiLoadInt8, 0x0f04dfd6)                                    \
   V(::, _loadInt16, FfiLoadInt16, 0xec44312d)                                  \
   V(::, _loadInt32, FfiLoadInt32, 0xee223fc3)                                  \
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index c434ec9..7ee1e6b 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -163,11 +163,16 @@
 T unsafeCast<T>(Object? v) native "Internal_unsafeCast";
 
 // This function can be used to keep an object alive til that point.
-//
 @pragma("vm:recognized", "other")
 @pragma('vm:prefer-inline')
 void reachabilityFence(Object object) native "Internal_reachabilityFence";
 
+// This function can be used to encode native side effects.
+//
+// The function call and it's argument are removed in flow graph construction.
+@pragma("vm:recognized", "other")
+void _nativeEffect(Object object) native "Internal_nativeEffect";
+
 void sendAndExit(SendPort sendPort, var message)
     native "SendPortImpl_sendAndExitInternal_";
 
diff --git a/tests/ffi/native_effect_test.dart b/tests/ffi/native_effect_test.dart
new file mode 100644
index 0000000..41d4aea
--- /dev/null
+++ b/tests/ffi/native_effect_test.dart
@@ -0,0 +1,33 @@
+// 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.
+//
+// SharedObjects=ffi_test_functions
+
+// Tests that the dart:internal _nativeEffect flow graph builder works.
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'dylib_utils.dart';
+
+void main() {
+  testReturnStruct1ByteInt();
+}
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
+    Struct1ByteInt Function(Int8),
+    Struct1ByteInt Function(int)>("ReturnStruct1ByteInt");
+
+void testReturnStruct1ByteInt() {
+  final result = returnStruct1ByteInt(1);
+  Expect.equals(1, result.a0);
+}
+
+class Struct1ByteInt extends Struct {
+  @Int8()
+  external int a0;
+}
diff --git a/tests/ffi_2/native_effect_test.dart b/tests/ffi_2/native_effect_test.dart
new file mode 100644
index 0000000..1b88d14
--- /dev/null
+++ b/tests/ffi_2/native_effect_test.dart
@@ -0,0 +1,33 @@
+// 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.
+//
+// SharedObjects=ffi_test_functions
+
+// Tests that the dart:internal _nativeEffect flow graph builder works.
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'dylib_utils.dart';
+
+void main() {
+  testReturnStruct1ByteInt();
+}
+
+final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+final returnStruct1ByteInt = ffiTestFunctions.lookupFunction<
+    Struct1ByteInt Function(Int8),
+    Struct1ByteInt Function(int)>("ReturnStruct1ByteInt");
+
+void testReturnStruct1ByteInt() {
+  final result = returnStruct1ByteInt(1);
+  Expect.equals(1, result.a0);
+}
+
+class Struct1ByteInt extends Struct {
+  @Int8()
+  int a0;
+}
diff --git a/tools/VERSION b/tools/VERSION
index 148a455..4df21bf 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 222
+PRERELEASE 223
 PRERELEASE_PATCH 0
\ No newline at end of file