Version 2.17.0-48.0.dev

Merge commit '43206b1d9a1fd3b019d6da1638d7651eb642339a' into 'dev'
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 e2d6df6..765d3d5 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -277,7 +277,8 @@
   void recordStaticType(ExpressionImpl expression, DartType type) {
     var hooks = _migrationResolutionHooks;
     if (hooks != null) {
-      type = hooks.modifyExpressionType(expression, type);
+      type = hooks.modifyExpressionType(
+          expression, type, InferenceContext.getContext(expression));
     }
 
     expression.staticType = type;
diff --git a/pkg/analyzer/lib/src/generated/migration.dart b/pkg/analyzer/lib/src/generated/migration.dart
index 6bd94fa..0da672d 100644
--- a/pkg/analyzer/lib/src/generated/migration.dart
+++ b/pkg/analyzer/lib/src/generated/migration.dart
@@ -23,7 +23,8 @@
   /// Called after the resolver has determined the type of an expression node.
   /// Should return the type that the expression has after migrations have been
   /// applied.
-  DartType modifyExpressionType(Expression expression, DartType dartType);
+  DartType modifyExpressionType(
+      Expression expression, DartType dartType, DartType? contextType);
 
   /// Called after the resolver has inferred the type of a function literal
   /// parameter.  Should return the type that the parameter has after migrations
@@ -31,6 +32,11 @@
   DartType modifyInferredParameterType(
       ParameterElement parameter, DartType type);
 
+  /// Called at the beginning of visiting a binary expression, to report the
+  /// context type of the binary expression.
+  void reportBinaryExpressionContext(
+      BinaryExpression node, DartType? contextType);
+
   /// Called after the resolver has determined the read and write types
   /// of the assignment expression.
   void setCompoundAssignmentExpressionTypes(CompoundAssignmentExpression node);
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 046824e..ee635b2 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1214,6 +1214,11 @@
 
   @override
   void visitBinaryExpression(BinaryExpression node) {
+    var migrationResolutionHooks = this.migrationResolutionHooks;
+    if (migrationResolutionHooks != null) {
+      migrationResolutionHooks.reportBinaryExpressionContext(
+          node, InferenceContext.getContext(node));
+    }
     _binaryExpressionResolver.resolve(node as BinaryExpressionImpl);
     insertGenericFunctionInstantiation(node);
   }
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 0caee26..8da2940 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -331,6 +331,8 @@
   final Map<MethodInvocation, DartType Function(DartType)>
       _deferredMethodInvocationProcessing = {};
 
+  final Map<Expression, DartType?> _contextTypes = {};
+
   TypeProvider get typeProvider => _fixBuilder!.typeProvider;
 
   @override
@@ -514,8 +516,10 @@
   }
 
   @override
-  DartType modifyExpressionType(Expression node, DartType type) =>
+  DartType modifyExpressionType(
+          Expression node, DartType type, DartType? contextType) =>
       _wrapExceptions(node, () => type, () {
+        _contextTypes[node] = contextType;
         if (node is NamedExpression) {
           // Do not attempt to modify named expressions.  We should already have
           // been called for [node.expression], and we should have made the
@@ -554,6 +558,12 @@
   }
 
   @override
+  void reportBinaryExpressionContext(
+      BinaryExpression node, DartType? contextType) {
+    _contextTypes[node] = contextType;
+  }
+
+  @override
   void setCompoundAssignmentExpressionTypes(CompoundAssignmentExpression node) {
     assert(_assignmentLikeExpressionHandlers[node] == null);
     if (node is AssignmentExpression) {
@@ -720,8 +730,7 @@
     }
     if (type.isDynamic) return type;
     var ancestor = _findNullabilityContextAncestor(node);
-    context ??=
-        InferenceContext.getContext(ancestor) ?? DynamicTypeImpl.instance;
+    context ??= _contextTypes[ancestor] ?? DynamicTypeImpl.instance;
     if (!_isSubtypeOrCoercible(type, context)) {
       var transformationInfo =
           _fixBuilder!._whereOrNullTransformer.tryTransformOrElseArgument(node);
diff --git a/tools/VERSION b/tools/VERSION
index d842f12..3aaae4e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 47
+PRERELEASE 48
 PRERELEASE_PATCH 0
\ No newline at end of file