-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Open
Labels
Milestone
Description
public override BoundNode VisitIncrementOperator(BoundIncrementOperator node)
{
Debug.Assert(!IsConditionalState);
VisitRvalue(node.Operand);
var operandType = _resultType;
bool setResult = false;
if (this.State.Reachable)
{
// PROTOTYPE(NullableReferenceTypes): Update increment method based on operand type.
MethodSymbol incrementOperator = (node.OperatorKind.IsUserDefined() && (object)node.MethodOpt != null && node.MethodOpt.ParameterCount == 1) ? node.MethodOpt : null;
TypeSymbolWithAnnotations targetTypeOfOperandConversion;
AssignmentKind assignmentKind = AssignmentKind.Assignment;
ParameterSymbol target = null;
// PROTOTYPE(NullableReferenceTypes): Update conversion method based on operand type.
if (node.OperandConversion.IsUserDefined && (object)node.OperandConversion.Method != null && node.OperandConversion.Method.ParameterCount == 1)
{
targetTypeOfOperandConversion = node.OperandConversion.Method.ReturnType;
}
else if ((object)incrementOperator != null)
{
targetTypeOfOperandConversion = incrementOperator.Parameters[0].Type;
assignmentKind = AssignmentKind.Argument;
target = incrementOperator.Parameters[0];
}
else
{
// Either a built-in increment, or an error case.
targetTypeOfOperandConversion = default;
}
TypeSymbolWithAnnotations resultOfOperandConversionType;
if (!targetTypeOfOperandConversion.IsNull)
{
// PROTOTYPE(NullableReferenceTypes): Should something special be done for targetTypeOfOperandConversion for lifted case?
resultOfOperandConversionType = ApplyConversion(
node.Operand,
node.Operand,
node.OperandConversion,
targetTypeOfOperandConversion,
operandType,
checkConversion: true,
fromExplicitCast: false,
useLegacyWarnings: false,
assignmentKind,
target,
reportTopLevelWarnings: true,
reportNestedWarnings: true);
}
else
{
resultOfOperandConversionType = operandType;
}
TypeSymbolWithAnnotations resultOfIncrementType;
if ((object)incrementOperator == null)
{
resultOfIncrementType = resultOfOperandConversionType;
}
else
{
resultOfIncrementType = incrementOperator.ReturnType;
}
resultOfIncrementType = ApplyConversion(
node,
node,
node.ResultConversion,
operandType,
resultOfIncrementType,
checkConversion: true,
fromExplicitCast: false,
useLegacyWarnings: false,
AssignmentKind.Assignment);
// PROTOTYPE(NullableReferenceTypes): Check node.Type.IsErrorType() instead?
if (!node.HasErrors)
{
var op = node.OperatorKind.Operator();
_resultType = (op == UnaryOperatorKind.PrefixIncrement || op == UnaryOperatorKind.PrefixDecrement) ? resultOfIncrementType : operandType;
setResult = true;
TrackNullableStateForAssignment(node, operandType, MakeSlot(node.Operand), valueType: resultOfIncrementType);
}
}
if (!setResult)
{
this.SetResult(node);
}
return null;
}