public override BoundNode VisitCompoundAssignmentOperator(BoundCompoundAssignmentOperator node)
{
VisitLvalue(node.Left); // PROTOTYPE(NullableReferenceTypes): Method should be called VisitValue rather than VisitLvalue.
TypeSymbolWithAnnotations leftType = _resultType;
TypeSymbolWithAnnotations resultType;
Debug.Assert(!IsConditionalState);
//if (this.State.Reachable) // Consider reachability: see https://github.com/dotnet/roslyn/issues/28798
{
TypeSymbolWithAnnotations leftOnRightType = GetAdjustedResult(leftType, MakeSlot(node.Left));
// PROTOTYPE(NullableReferenceTypes): Update operator based on inferred argument types.
if ((object)node.Operator.LeftType != null)
{
// PROTOTYPE(NullableReferenceTypes): Ignoring top-level nullability of operator left parameter.
leftOnRightType = ApplyConversion(
node.Left,
node.Left,
node.LeftConversion,
TypeSymbolWithAnnotations.Create(node.Operator.LeftType),
leftOnRightType,
checkConversion: true,
fromExplicitCast: false,
useLegacyWarnings: false,
AssignmentKind.Assignment,
reportTopLevelWarnings: false,
reportNestedWarnings: false);
}
else
{
leftOnRightType = default;
}
VisitRvalue(node.Right);
TypeSymbolWithAnnotations rightType = _resultType;
if ((object)node.Operator.ReturnType != null)
{
if (node.Operator.Kind.IsUserDefined() && (object)node.Operator.Method != null && node.Operator.Method.ParameterCount == 2)
{
ReportArgumentWarnings(node.Left, leftOnRightType, node.Operator.Method.Parameters[0]);
ReportArgumentWarnings(node.Right, rightType, node.Operator.Method.Parameters[1]);
}
resultType = InferResultNullability(node.Operator.Kind, node.Operator.Method, node.Operator.ReturnType, leftOnRightType, rightType);
resultType = ApplyConversion(
node,
node,
node.FinalConversion,
leftType,
resultType,
checkConversion: true,
fromExplicitCast: false,
useLegacyWarnings: false,
AssignmentKind.Assignment);
}
else
{
resultType = TypeSymbolWithAnnotations.Create(node.Type);
}
TrackNullableStateForAssignment(node, leftType, MakeSlot(node.Left), resultType);
_resultType = resultType;
}
//else
//{
// VisitRvalue(node.Right);
// AfterRightHasBeenVisited(node);
// resultType = null;
//}
return null;
}