public override Expression VisitBinaryExpression(BinaryExpression binaryExpression)
{
if (binaryExpression == null) return null;
Expression opnd1 = binaryExpression.Operand1 = this.VisitExpression(binaryExpression.Operand1);
Expression opnd2 = binaryExpression.Operand2 = this.VisitExpression(binaryExpression.Operand2);
if (opnd1 == null || opnd2 == null)
return null;
Set opnd1TypeAsSet = opnd1.Type as Set;
Set opnd2TypeAsSet = opnd2.Type as Set;
Literal lit1 = opnd1 as Literal;
Literal lit2 = opnd2 as Literal;
if ((opnd1TypeAsSet != null || opnd2TypeAsSet != null) &&
!this.validSetOperations.Contains(binaryExpression) &&
binaryExpression.NodeType != (NodeType)ZingNodeType.In)
{
this.HandleError(binaryExpression, Error.InvalidSetExpression);
return null;
}
switch (binaryExpression.NodeType)
{
case NodeType.Add:
case NodeType.Sub:
if (opnd1TypeAsSet != null)
{
if (opnd1TypeAsSet.SetType != opnd2.Type && opnd1.Type != opnd2.Type)
{
if (opnd2TypeAsSet != null)
this.HandleError(opnd1, Error.IncompatibleSetTypes);
else
this.HandleError(opnd2, Error.IncompatibleSetOperand);
return null;
}
return binaryExpression;
}
break;
case NodeType.LogicalAnd:
{
if (lit1 != null && lit1.Value is bool)
{
if (((bool)lit1.Value) == true)
return opnd2;
else
return opnd1;
}
if (lit2 != null && lit2.Value is bool)
{
if (((bool)lit2.Value) == true)
return opnd1;
else
return opnd2;
}
}
break;
case NodeType.LogicalOr:
{
if (lit1 != null && lit1.Value is bool)
{
if (((bool)lit1.Value) == false)
return opnd2;
else
return opnd1;
}
if (lit2 != null && lit2.Value is bool)
{
if (((bool)lit2.Value) == false)
return opnd1;
else
return opnd2;
}
}
break;
case (NodeType)ZingNodeType.In:
if (opnd2TypeAsSet == null)
{
this.HandleError(opnd2, Error.ExpectedSetType);
return null;
}
if (opnd2TypeAsSet.SetType != opnd1.Type)
{
this.HandleError(opnd1, Error.IncompatibleSetOperand);
return null;
}
return binaryExpression;
default:
break;
}
return base.CoerceBinaryExpressionOperands(binaryExpression, opnd1, opnd2);
}