De-duplicate recordStaticType methods

Change-Id: I4f94acd553b0b76610bc58972d608fda207016b6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/229360
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index 901f6f8..e2d6df6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -274,8 +274,6 @@
   ///
   /// @param expression the node whose type is to be recorded
   /// @param type the static type of the node
-  ///
-  /// TODO(scheglov) this is duplication
   void recordStaticType(ExpressionImpl expression, DartType type) {
     var hooks = _migrationResolutionHooks;
     if (hooks != null) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index ab438c7..2c26796 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -195,24 +195,6 @@
     return type is InterfaceType && type.isDartCoreFunction;
   }
 
-  /// Record that the static type of the given node is the given type.
-  ///
-  /// @param expression the node whose type is to be recorded
-  /// @param type the static type of the node
-  ///
-  /// TODO(scheglov) this is duplicate
-  void _recordStaticType(ExpressionImpl expression, DartType type) {
-    var hooks = _resolver.migrationResolutionHooks;
-    if (hooks != null) {
-      type = hooks.modifyExpressionType(expression, type);
-    }
-
-    expression.staticType = type;
-    if (_resolver.typeSystem.isBottom(type)) {
-      _resolver.flowAnalysis.flow?.handleExit();
-    }
-  }
-
   void _reportInstanceAccessToStaticMember(
     SimpleIdentifier nameNode,
     ExecutableElement element,
@@ -842,7 +824,7 @@
     DartType getterReturnType,
   ) {
     var targetType = _resolveTypeParameter(getterReturnType);
-    _recordStaticType(node.methodName, targetType);
+    _inferenceHelper.recordStaticType(node.methodName, targetType);
 
     ExpressionImpl functionExpression;
     var target = node.target;
diff --git a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
index e4476e7..a108a8b 100644
--- a/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/prefix_expression_resolver.dart
@@ -125,16 +125,6 @@
     }
   }
 
-  /// Record that the static type of the given node is the given type.
-  ///
-  /// @param expression the node whose type is to be recorded
-  /// @param type the static type of the node
-  ///
-  /// TODO(scheglov) this is duplicate
-  void _recordStaticType(ExpressionImpl expression, DartType type) {
-    _inferenceHelper.recordStaticType(expression, type);
-  }
-
   void _resolve1(PrefixExpressionImpl node) {
     Token operator = node.operator;
     TokenType operatorType = operator.type;
@@ -195,7 +185,7 @@
   void _resolve2(PrefixExpressionImpl node) {
     TokenType operator = node.operator.type;
     if (identical(node.readType, NeverTypeImpl.instance)) {
-      _recordStaticType(node, NeverTypeImpl.instance);
+      _inferenceHelper.recordStaticType(node, NeverTypeImpl.instance);
     } else {
       // The other cases are equivalent to invoking a method.
       var staticMethodElement = node.staticElement;
@@ -216,7 +206,7 @@
           }
         }
       }
-      _recordStaticType(node, staticType);
+      _inferenceHelper.recordStaticType(node, staticType);
     }
     _resolver.nullShortingTermination(node);
   }
@@ -232,7 +222,7 @@
     _resolver.boolExpressionVerifier.checkForNonBoolNegationExpression(operand,
         whyNotPromoted: whyNotPromoted);
 
-    _recordStaticType(node, _typeProvider.boolType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
 
     _resolver.flowAnalysis.flow?.logicalNot_end(node, operand);
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
index eb97c1f..4a1e23d 100644
--- a/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
@@ -44,8 +44,8 @@
     }
 
     if (identical(node.prefix.staticType, NeverTypeImpl.instance)) {
-      _recordStaticType(identifier, NeverTypeImpl.instance);
-      _recordStaticType(node, NeverTypeImpl.instance);
+      _inferenceHelper.recordStaticType(identifier, NeverTypeImpl.instance);
+      _inferenceHelper.recordStaticType(node, NeverTypeImpl.instance);
       return;
     }
 
@@ -92,8 +92,8 @@
       // breaking change release.
       type = _inferenceHelper.inferTearOff(node, identifier, type);
     }
-    _recordStaticType(identifier, type);
-    _recordStaticType(node, type);
+    _inferenceHelper.recordStaticType(identifier, type);
+    _inferenceHelper.recordStaticType(node, type);
   }
 
   /// Return the type that should be recorded for a node that resolved to the given accessor.
@@ -142,16 +142,6 @@
     return true;
   }
 
-  /// Record that the static type of the given node is the given type.
-  ///
-  /// @param expression the node whose type is to be recorded
-  /// @param type the static type of the node
-  ///
-  /// TODO(scheglov) this is duplicate
-  void _recordStaticType(ExpressionImpl expression, DartType type) {
-    _inferenceHelper.recordStaticType(expression, type);
-  }
-
   /// TODO(scheglov) this is duplicate
   void _setExtensionIdentifierType(IdentifierImpl node) {
     if (node is SimpleIdentifierImpl && node.inDeclarationContext()) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
index 01d2337..16c0251 100644
--- a/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/simple_identifier_resolver.dart
@@ -11,16 +11,18 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_provider.dart';
-import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
+import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
 import 'package:analyzer/src/dart/resolver/property_element_resolver.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 
 class SimpleIdentifierResolver {
   final ResolverVisitor _resolver;
-  final FlowAnalysisHelper? _flowAnalysis;
 
-  SimpleIdentifierResolver(this._resolver, this._flowAnalysis);
+  final InvocationInferenceHelper _inferenceHelper;
+
+  SimpleIdentifierResolver(this._resolver)
+      : _inferenceHelper = _resolver.inferenceHelper;
 
   ErrorReporter get _errorReporter => _resolver.errorReporter;
 
@@ -101,24 +103,6 @@
     return false;
   }
 
-  /// Record that the static type of the given node is the given type.
-  ///
-  /// @param expression the node whose type is to be recorded
-  /// @param type the static type of the node
-  ///
-  /// TODO(scheglov) this is duplicate
-  void _recordStaticType(ExpressionImpl expression, DartType type) {
-    var hooks = _resolver.migrationResolutionHooks;
-    if (hooks != null) {
-      type = hooks.modifyExpressionType(expression, type);
-    }
-
-    expression.staticType = type;
-    if (_resolver.typeSystem.isBottom(type)) {
-      _flowAnalysis?.flow?.handleExit();
-    }
-  }
-
   void _resolve1(SimpleIdentifierImpl node) {
     //
     // Synthetic identifiers have been already reported during parsing.
@@ -261,7 +245,7 @@
       staticType =
           _resolver.inferenceHelper.inferTearOff(node, node, staticType);
     }
-    _recordStaticType(node, staticType);
+    _inferenceHelper.recordStaticType(node, staticType);
   }
 
   /// TODO(scheglov) this is duplicate
diff --git a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
index a9fce6a..bb7a033 100644
--- a/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/typed_literal_resolver.dart
@@ -676,24 +676,6 @@
     }
   }
 
-  /// Record that the static type of the given node is the given type.
-  ///
-  /// @param expression the node whose type is to be recorded
-  /// @param type the static type of the node
-  ///
-  /// TODO(scheglov) Inline this.
-  void _recordStaticType(ExpressionImpl expression, DartType type) {
-    expression.staticType = type;
-//    if (type == null) {
-//      expression.staticType = _dynamicType;
-//    } else {
-//      expression.staticType = type;
-//      if (identical(type, NeverTypeImpl.instance)) {
-//        _flowAnalysis?.flow?.handleExit();
-//      }
-//    }
-  }
-
   void _resolveListLiteral2(ListLiteralImpl node) {
     var typeArguments = node.typeArguments?.arguments;
 
@@ -703,12 +685,9 @@
       if (typeArguments.length == 1) {
         elementType = typeArguments[0].typeOrThrow;
       }
-      _recordStaticType(
-        node,
-        _typeProvider.listElement.instantiate(
-          typeArguments: [elementType],
-          nullabilitySuffix: _noneOrStarSuffix,
-        ),
+      node.staticType = _typeProvider.listElement.instantiate(
+        typeArguments: [elementType],
+        nullabilitySuffix: _noneOrStarSuffix,
       );
       return;
     }
@@ -721,12 +700,12 @@
     if (inferred != listDynamicType) {
       // TODO(brianwilkerson) Determine whether we need to make the inferred
       //  type non-nullable here or whether it will already be non-nullable.
-      _recordStaticType(node, inferred!);
+      node.staticType = inferred!;
       return;
     }
 
     // If we have no type arguments and couldn't infer any, use dynamic.
-    _recordStaticType(node, listDynamicType);
+    node.staticType = listDynamicType;
   }
 
   void _resolveSetOrMapLiteral2(SetOrMapLiteralImpl node) {
@@ -739,24 +718,18 @@
       if (typeArguments.length == 1) {
         node.becomeSet();
         var elementType = typeArguments[0].typeOrThrow;
-        _recordStaticType(
-          node,
-          _typeProvider.setElement.instantiate(
-            typeArguments: [elementType],
-            nullabilitySuffix: _noneOrStarSuffix,
-          ),
+        node.staticType = _typeProvider.setElement.instantiate(
+          typeArguments: [elementType],
+          nullabilitySuffix: _noneOrStarSuffix,
         );
         return;
       } else if (typeArguments.length == 2) {
         node.becomeMap();
         var keyType = typeArguments[0].typeOrThrow;
         var valueType = typeArguments[1].typeOrThrow;
-        _recordStaticType(
-          node,
-          _typeProvider.mapElement.instantiate(
-            typeArguments: [keyType, valueType],
-            nullabilitySuffix: _noneOrStarSuffix,
-          ),
+        node.staticType = _typeProvider.mapElement.instantiate(
+          typeArguments: [keyType, valueType],
+          nullabilitySuffix: _noneOrStarSuffix,
         );
         return;
       }
@@ -787,7 +760,7 @@
     // TODO(brianwilkerson) Decide whether the literalType needs to be made
     //  non-nullable here or whether that will have happened in
     //  _inferSetOrMapLiteralType.
-    _recordStaticType(node, literalType);
+    node.staticType = literalType;
   }
 
   DartType _toMapType(SetOrMapLiteral node, DartType? contextType,
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index dfeb521..046824e 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -292,7 +292,7 @@
       InstanceCreationExpressionResolver(this);
 
   late final SimpleIdentifierResolver _simpleIdentifierResolver =
-      SimpleIdentifierResolver(this, flowAnalysis);
+      SimpleIdentifierResolver(this);
 
   late final PropertyElementResolver _propertyElementResolver =
       PropertyElementResolver(this);
@@ -412,7 +412,7 @@
     elementResolver = ElementResolver(this,
         migratableAstInfoProvider: _migratableAstInfoProvider);
     inferenceContext = InferenceContext._(this);
-    typeAnalyzer = StaticTypeAnalyzer(this, migrationResolutionHooks);
+    typeAnalyzer = StaticTypeAnalyzer(this);
     _functionReferenceResolver =
         FunctionReferenceResolver(this, _isNonNullableByDefault);
   }
@@ -2473,7 +2473,7 @@
       var subexpressionToKeep =
           conditionalKnownValue ? node.thenExpression : node.elseExpression;
       subexpressionToKeep.accept(this);
-      typeAnalyzer.recordStaticType(node, subexpressionToKeep.typeOrThrow);
+      inferenceHelper.recordStaticType(node, subexpressionToKeep.typeOrThrow);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 11579a3..734711d 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -10,7 +10,7 @@
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/generated/migration.dart';
+import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 
 /// Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
@@ -24,7 +24,7 @@
   /// The resolver driving the resolution and type analysis.
   final ResolverVisitor _resolver;
 
-  final MigrationResolutionHooks? _migrationResolutionHooks;
+  final InvocationInferenceHelper _inferenceHelper;
 
   /// The object providing access to the types defined by the language.
   late TypeProviderImpl _typeProvider;
@@ -39,35 +39,18 @@
   /// [_resolver] based on the
   ///
   /// @param resolver the resolver driving this participant
-  StaticTypeAnalyzer(this._resolver, this._migrationResolutionHooks) {
+  StaticTypeAnalyzer(this._resolver)
+      : _inferenceHelper = _resolver.inferenceHelper {
     _typeProvider = _resolver.typeProvider;
     _typeSystem = _resolver.typeSystem;
     _dynamicType = _typeProvider.dynamicType;
   }
 
-  /// Record that the static type of the given node is the given type.
-  ///
-  /// @param expression the node whose type is to be recorded
-  /// @param type the static type of the node
-  ///
-  /// TODO(scheglov) this is duplication
-  void recordStaticType(ExpressionImpl expression, DartType type) {
-    var hooks = _migrationResolutionHooks;
-    if (hooks != null) {
-      type = hooks.modifyExpressionType(expression, type);
-    }
-
-    expression.staticType = type;
-    if (_typeSystem.isBottom(type)) {
-      _resolver.flowAnalysis.flow?.handleExit();
-    }
-  }
-
   /// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
   /// `String`.</blockquote>
   @override
   void visitAdjacentStrings(covariant AdjacentStringsImpl node) {
-    recordStaticType(node, _typeProvider.stringType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.stringType);
   }
 
   /// The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
@@ -78,7 +61,7 @@
   /// The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
   @override
   void visitAsExpression(covariant AsExpressionImpl node) {
-    recordStaticType(node, _getType(node.type));
+    _inferenceHelper.recordStaticType(node, _getType(node.type));
   }
 
   /// The Dart Language Specification, 16.29 (Await Expressions):
@@ -89,14 +72,14 @@
   void visitAwaitExpression(covariant AwaitExpressionImpl node) {
     var resultType = node.expression.typeOrThrow;
     resultType = _typeSystem.flatten(resultType);
-    recordStaticType(node, resultType);
+    _inferenceHelper.recordStaticType(node, resultType);
   }
 
   /// The Dart Language Specification, 12.4: <blockquote>The static type of a boolean literal is
   /// bool.</blockquote>
   @override
   void visitBooleanLiteral(covariant BooleanLiteralImpl node) {
-    recordStaticType(node, _typeProvider.boolType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
   }
 
   /// The Dart Language Specification, 12.15.2: <blockquote>A cascaded method invocation expression
@@ -104,7 +87,7 @@
   /// t;}(e)</i>.</blockquote>
   @override
   void visitCascadeExpression(covariant CascadeExpressionImpl node) {
-    recordStaticType(node, node.target.typeOrThrow);
+    _inferenceHelper.recordStaticType(node, node.target.typeOrThrow);
   }
 
   /// The Dart Language Specification, 12.19: <blockquote> ... a conditional expression <i>c</i> of
@@ -123,7 +106,7 @@
   /// double.</blockquote>
   @override
   void visitDoubleLiteral(covariant DoubleLiteralImpl node) {
-    recordStaticType(node, _typeProvider.doubleType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.doubleType);
   }
 
   @override
@@ -180,7 +163,8 @@
   void visitInstanceCreationExpression(
       covariant InstanceCreationExpressionImpl node) {
     _inferInstanceCreationExpression(node);
-    recordStaticType(node, node.constructorName.type2.typeOrThrow);
+    _inferenceHelper.recordStaticType(
+        node, node.constructorName.type2.typeOrThrow);
   }
 
   /// <blockquote>
@@ -206,9 +190,9 @@
     if (context == null ||
         _typeSystem.isAssignableTo(_typeProvider.intType, context) ||
         !_typeSystem.isAssignableTo(_typeProvider.doubleType, context)) {
-      recordStaticType(node, _typeProvider.intType);
+      _inferenceHelper.recordStaticType(node, _typeProvider.intType);
     } else {
-      recordStaticType(node, _typeProvider.doubleType);
+      _inferenceHelper.recordStaticType(node, _typeProvider.doubleType);
     }
   }
 
@@ -218,7 +202,7 @@
   /// The static type of an is-expression is `bool`.</blockquote>
   @override
   void visitIsExpression(covariant IsExpressionImpl node) {
-    recordStaticType(node, _typeProvider.boolType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.boolType);
   }
 
   @override
@@ -229,42 +213,42 @@
   @override
   void visitNamedExpression(covariant NamedExpressionImpl node) {
     Expression expression = node.expression;
-    recordStaticType(node, expression.typeOrThrow);
+    _inferenceHelper.recordStaticType(node, expression.typeOrThrow);
   }
 
   /// The Dart Language Specification, 12.2: <blockquote>The static type of `null` is bottom.
   /// </blockquote>
   @override
   void visitNullLiteral(covariant NullLiteralImpl node) {
-    recordStaticType(node, _typeProvider.nullType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.nullType);
   }
 
   @override
   void visitParenthesizedExpression(
       covariant ParenthesizedExpressionImpl node) {
     Expression expression = node.expression;
-    recordStaticType(node, expression.typeOrThrow);
+    _inferenceHelper.recordStaticType(node, expression.typeOrThrow);
   }
 
   /// The Dart Language Specification, 12.9: <blockquote>The static type of a rethrow expression is
   /// bottom.</blockquote>
   @override
   void visitRethrowExpression(covariant RethrowExpressionImpl node) {
-    recordStaticType(node, _typeProvider.bottomType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.bottomType);
   }
 
   /// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
   /// `String`.</blockquote>
   @override
   void visitSimpleStringLiteral(covariant SimpleStringLiteralImpl node) {
-    recordStaticType(node, _typeProvider.stringType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.stringType);
   }
 
   /// The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
   /// `String`.</blockquote>
   @override
   void visitStringInterpolation(covariant StringInterpolationImpl node) {
-    recordStaticType(node, _typeProvider.stringType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.stringType);
   }
 
   @override
@@ -275,15 +259,15 @@
         node.thisOrAncestorOfType<ExtensionDeclaration>() != null) {
       // TODO(brianwilkerson) Report this error if it hasn't already been
       // reported.
-      recordStaticType(node, _dynamicType);
+      _inferenceHelper.recordStaticType(node, _dynamicType);
     } else {
-      recordStaticType(node, thisType);
+      _inferenceHelper.recordStaticType(node, thisType);
     }
   }
 
   @override
   void visitSymbolLiteral(covariant SymbolLiteralImpl node) {
-    recordStaticType(node, _typeProvider.symbolType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.symbolType);
   }
 
   /// The Dart Language Specification, 12.10: <blockquote>The static type of `this` is the
@@ -295,9 +279,9 @@
     if (thisType == null) {
       // TODO(brianwilkerson) Report this error if it hasn't already been
       // reported.
-      recordStaticType(node, _dynamicType);
+      _inferenceHelper.recordStaticType(node, _dynamicType);
     } else {
-      recordStaticType(node, thisType);
+      _inferenceHelper.recordStaticType(node, thisType);
     }
   }
 
@@ -305,7 +289,7 @@
   /// bottom.</blockquote>
   @override
   void visitThrowExpression(covariant ThrowExpressionImpl node) {
-    recordStaticType(node, _typeProvider.bottomType);
+    _inferenceHelper.recordStaticType(node, _typeProvider.bottomType);
   }
 
   /// Set the static type of [node] to be the least upper bound of the static
@@ -327,7 +311,7 @@
 
     staticType = _resolver.toLegacyTypeIfOptOut(staticType);
 
-    recordStaticType(node, staticType);
+    _inferenceHelper.recordStaticType(node, staticType);
   }
 
   /// Return the type represented by the given type [annotation].