本文整理汇总了C#中BinaryOperatorKind.Operator方法的典型用法代码示例。如果您正苦于以下问题:C# BinaryOperatorKind.Operator方法的具体用法?C# BinaryOperatorKind.Operator怎么用?C# BinaryOperatorKind.Operator使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BinaryOperatorKind
的用法示例。
在下文中一共展示了BinaryOperatorKind.Operator方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: LowerLiftedBuiltInComparisonOperator
private BoundExpression LowerLiftedBuiltInComparisonOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression loweredLeft,
BoundExpression loweredRight)
{
// SPEC: For the equality operators == != :
// SPEC: The lifted operator considers two null values equal and a null value unequal to
// SPEC: any non-null value. If both operands are non-null the lifted operator unwraps
// SPEC: the operands and applies the underlying operator to produce the bool result.
// SPEC:
// SPEC: For the relational operators < > <= >= :
// SPEC: The lifted operator produces the value false if one or both operands
// SPEC: are null. Otherwise the lifted operator unwraps the operands and
// SPEC: applies the underlying operator to produce the bool result.
// Note that this means that x == y is true but x <= y is false if both are null.
// x <= y is not the same as (x < y) || (x == y).
// Start with some simple optimizations for cases like one side being null.
BoundExpression optimized = TrivialLiftedComparisonOperatorOptimizations(syntax, kind, loweredLeft, loweredRight, null);
if (optimized != null)
{
return optimized;
}
// We rewrite x == y as
//
// tempx = x;
// tempy = y;
// result = tempx.GetValueOrDefault() == tempy.GetValueOrDefault() ?
// tempx.HasValue == tempy.HasValue :
// false;
//
// and x != y as
//
// tempx = x;
// tempy = y;
// result = tempx.GetValueOrDefault() == tempy.GetValueOrDefault() ?
// tempx.HasValue != tempy.HasValue :
// true;
//
// Otherwise, we rewrite x OP y as
//
// tempx = x;
// tempy = y;
// result = tempx.GetValueOrDefault() OP tempy.GetValueOrDefault() ?
// tempx.HasValue & tempy.HasValue :
// false;
//
// Note that there is no reason to generate "&&" over "&"; the cost of
// the added code for the conditional branch would be about the same as simply doing
// the bitwise & in the first place.
//
// We have not yet optimized the case where we have a known-not-null value on one side,
// and an unknown value on the other. In those cases we will still generate a temp, but
// we will not generate the call to the unnecessary nullable ctor or to GetValueOrDefault.
// Rather, we will generate the value's temp instead of a call to GetValueOrDefault, and generate
// literal true for HasValue. The tree construction methods we call will use those constants
// to eliminate unnecessary branches.
BoundExpression xNonNull = NullableAlwaysHasValue(loweredLeft);
BoundExpression yNonNull = NullableAlwaysHasValue(loweredRight);
BoundAssignmentOperator tempAssignmentX;
BoundLocal boundTempX = _factory.StoreToTemp(xNonNull ?? loweredLeft, out tempAssignmentX);
BoundAssignmentOperator tempAssignmentY;
BoundLocal boundTempY = _factory.StoreToTemp(yNonNull ?? loweredRight, out tempAssignmentY);
BoundExpression callX_GetValueOrDefault = MakeOptimizedGetValueOrDefault(syntax, boundTempX);
BoundExpression callY_GetValueOrDefault = MakeOptimizedGetValueOrDefault(syntax, boundTempY);
BoundExpression callX_HasValue = MakeOptimizedHasValue(syntax, boundTempX);
BoundExpression callY_HasValue = MakeOptimizedHasValue(syntax, boundTempY);
// tempx.GetValueOrDefault() == tempy.GetValueOrDefault()
BinaryOperatorKind operatorKind = kind.Operator();
BinaryOperatorKind conditionOperator = operatorKind == BinaryOperatorKind.NotEqual ?
BinaryOperatorKind.Equal :
operatorKind;
TypeSymbol boolType = _compilation.GetSpecialType(SpecialType.System_Boolean);
BoundExpression condition = MakeBinaryOperator(
syntax: syntax,
operatorKind: conditionOperator.WithType(kind.OperandTypes()),
loweredLeft: callX_GetValueOrDefault,
loweredRight: callY_GetValueOrDefault,
type: boolType,
method: null);
BinaryOperatorKind consequenceOperator;
switch (operatorKind)
{
case BinaryOperatorKind.Equal:
consequenceOperator = BinaryOperatorKind.BoolEqual;
break;
case BinaryOperatorKind.NotEqual:
consequenceOperator = BinaryOperatorKind.BoolNotEqual;
break;
default:
consequenceOperator = BinaryOperatorKind.BoolAnd;
//.........这里部分代码省略.........
示例2: LowerLiftedUserDefinedComparisonOperator
private BoundExpression LowerLiftedUserDefinedComparisonOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression loweredLeft,
BoundExpression loweredRight,
MethodSymbol method)
{
// If both sides are null, or neither side is null, then we can do some simple optimizations.
BoundExpression optimized = TrivialLiftedComparisonOperatorOptimizations(syntax, kind, loweredLeft, loweredRight, method);
if (optimized != null)
{
return optimized;
}
// Otherwise, the expression
//
// x == y
//
// becomes
//
// tempX = x;
// tempY = y;
// result = tempX.HasValue == tempY.HasValue ?
// (tempX.HasValue ?
// tempX.GetValueOrDefault() == tempY.GetValueOrDefault() :
// true) :
// false;
//
//
// the expression
//
// x != y
//
// becomes
//
// tempX = x;
// tempY = y;
// result = tempX.HasValue == tempY.HasValue ?
// (tempX.HasValue ?
// tempX.GetValueOrDefault() != tempY.GetValueOrDefault() :
// false) :
// true;
//
//
// For the other comparison operators <, <=, >, >=,
//
// x OP y
//
// becomes
//
// tempX = x;
// tempY = y;
// result = tempX.HasValue & tempY.HasValue ?
// tempX.GetValueOrDefault() OP tempY.GetValueOrDefault() :
// false;
//
// We have not yet optimized the case where we have a known-not-null value on one side,
// and an unknown value on the other. In those cases we will still generate a temp, but
// we will not generate the call to the unnecessary nullable ctor or to GetValueOrDefault.
// Rather, we will generate the value's temp instead of a call to GetValueOrDefault, and generate
// literal true for HasValue. The tree construction methods we call will use those constants
// to eliminate unnecessary branches.
BoundExpression xNonNull = NullableAlwaysHasValue(loweredLeft);
BoundExpression yNonNull = NullableAlwaysHasValue(loweredRight);
// TODO: (This TODO applies throughout this file, not just to this method.)
// TODO: We might be storing a constant to this temporary that we could simply inline.
// TODO: (There are other expressions that can be safely moved around other than constants
// TODO: as well -- for example a boxing conversion of a constant int to object.)
// TODO: Build a better temporary-storage management system that decides whether or not
// TODO: to store a temporary.
BoundAssignmentOperator tempAssignmentX;
BoundLocal boundTempX = _factory.StoreToTemp(xNonNull ?? loweredLeft, out tempAssignmentX);
BoundAssignmentOperator tempAssignmentY;
BoundLocal boundTempY = _factory.StoreToTemp(yNonNull ?? loweredRight, out tempAssignmentY);
BoundExpression callX_GetValueOrDefault = MakeOptimizedGetValueOrDefault(syntax, boundTempX);
BoundExpression callY_GetValueOrDefault = MakeOptimizedGetValueOrDefault(syntax, boundTempY);
BoundExpression callX_HasValue = MakeOptimizedHasValue(syntax, boundTempX);
BoundExpression callY_HasValue = MakeOptimizedHasValue(syntax, boundTempY);
// tempx.HasValue == tempy.HasValue
BinaryOperatorKind conditionOperator;
BinaryOperatorKind operatorKind = kind.Operator();
switch (operatorKind)
{
case BinaryOperatorKind.Equal:
case BinaryOperatorKind.NotEqual:
conditionOperator = BinaryOperatorKind.BoolEqual;
break;
default:
conditionOperator = BinaryOperatorKind.BoolAnd;
break;
}
TypeSymbol boolType = _compilation.GetSpecialType(SpecialType.System_Boolean);
//.........这里部分代码省略.........
示例3: MakeDynamicLogicalBinaryOperator
private BoundExpression MakeDynamicLogicalBinaryOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind operatorKind,
BoundExpression loweredLeft,
BoundExpression loweredRight,
MethodSymbol leftTruthOperator,
TypeSymbol type,
bool isCompoundAssignment,
BoundUnaryOperator applyParentUnaryOperator)
{
Debug.Assert(operatorKind.Operator() == BinaryOperatorKind.And || operatorKind.Operator() == BinaryOperatorKind.Or);
// Dynamic logical && and || operators are lowered as follows:
// left && right -> IsFalse(left) ? left : And(left, right)
// left || right -> IsTrue(left) ? left : Or(left, right)
//
// Optimization: If the binary AND/OR is directly contained in IsFalse/IsTrue operator (parentUnaryOperator != null)
// we can avoid calling IsFalse/IsTrue twice on the same object.
// IsFalse(left && right) -> IsFalse(left) || IsFalse(And(left, right))
// IsTrue(left || right) -> IsTrue(left) || IsTrue(Or(left, right))
bool isAnd = operatorKind.Operator() == BinaryOperatorKind.And;
// Operator to be used to test the left operand:
var testOperator = isAnd ? UnaryOperatorKind.DynamicFalse : UnaryOperatorKind.DynamicTrue;
// VisitUnaryOperator ensures we are never called with parentUnaryOperator != null when we can't perform the optimization.
Debug.Assert(applyParentUnaryOperator == null || applyParentUnaryOperator.OperatorKind == testOperator);
ConstantValue constantLeft = loweredLeft.ConstantValue ?? UnboxConstant(loweredLeft);
if (testOperator == UnaryOperatorKind.DynamicFalse && constantLeft == ConstantValue.False ||
testOperator == UnaryOperatorKind.DynamicTrue && constantLeft == ConstantValue.True)
{
Debug.Assert(leftTruthOperator == null);
if (applyParentUnaryOperator != null)
{
// IsFalse(false && right) -> true
// IsTrue(true || right) -> true
return _factory.Literal(true);
}
else
{
// false && right -> box(false)
// true || right -> box(true)
return MakeConversionNode(loweredLeft, type, @checked: false);
}
}
BoundExpression result;
var boolean = _compilation.GetSpecialType(SpecialType.System_Boolean);
// Store left to local if needed. If constant or already local we don't need a temp
// since the value of left can't change until right is evaluated.
BoundAssignmentOperator tempAssignment;
BoundLocal temp;
if (constantLeft == null && loweredLeft.Kind != BoundKind.Local && loweredLeft.Kind != BoundKind.Parameter)
{
BoundAssignmentOperator assignment;
var local = _factory.StoreToTemp(loweredLeft, out assignment);
loweredLeft = local;
tempAssignment = assignment;
temp = local;
}
else
{
tempAssignment = null;
temp = null;
}
var op = _dynamicFactory.MakeDynamicBinaryOperator(operatorKind, loweredLeft, loweredRight, isCompoundAssignment, type).ToExpression();
// IsFalse(true) or IsTrue(false) are always false:
bool leftTestIsConstantFalse = testOperator == UnaryOperatorKind.DynamicFalse && constantLeft == ConstantValue.True ||
testOperator == UnaryOperatorKind.DynamicTrue && constantLeft == ConstantValue.False;
if (applyParentUnaryOperator != null)
{
// IsFalse(left && right) -> IsFalse(left) || IsFalse(And(left, right))
// IsTrue(left || right) -> IsTrue(left) || IsTrue(Or(left, right))
result = _dynamicFactory.MakeDynamicUnaryOperator(testOperator, op, boolean).ToExpression();
if (!leftTestIsConstantFalse)
{
BoundExpression leftTest = MakeTruthTestForDynamicLogicalOperator(syntax, loweredLeft, boolean, leftTruthOperator, negative: isAnd);
result = _factory.Binary(BinaryOperatorKind.LogicalOr, boolean, leftTest, result);
}
}
else
{
// left && right -> IsFalse(left) ? left : And(left, right)
// left || right -> IsTrue(left) ? left : Or(left, right)
if (leftTestIsConstantFalse)
{
result = op;
}
else
{
// We might need to box.
//.........这里部分代码省略.........
示例4: TrivialLiftedComparisonOperatorOptimizations
private BoundExpression TrivialLiftedComparisonOperatorOptimizations(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression left,
BoundExpression right,
MethodSymbol method)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
// Optimization #1: if both sides are null then the result
// is either true (for equality) or false (for everything else.)
bool leftAlwaysNull = NullableNeverHasValue(left);
bool rightAlwaysNull = NullableNeverHasValue(right);
TypeSymbol boolType = _compilation.GetSpecialType(SpecialType.System_Boolean);
if (leftAlwaysNull && rightAlwaysNull)
{
return MakeLiteral(syntax, ConstantValue.Create(kind.Operator() == BinaryOperatorKind.Equal), boolType);
}
// Optimization #2: If both sides are non-null then we can again eliminate the lifting entirely.
BoundExpression leftNonNull = NullableAlwaysHasValue(left);
BoundExpression rightNonNull = NullableAlwaysHasValue(right);
if (leftNonNull != null && rightNonNull != null)
{
return MakeBinaryOperator(
syntax: syntax,
operatorKind: kind.Unlifted(),
loweredLeft: leftNonNull,
loweredRight: rightNonNull,
type: boolType,
method: method);
}
// Optimization #3: If one side is null and the other is definitely not, then we generate the side effects
// of the non-null side and result in true (for not-equals) or false (for everything else.)
BinaryOperatorKind operatorKind = kind.Operator();
if (leftAlwaysNull && rightNonNull != null || rightAlwaysNull && leftNonNull != null)
{
BoundExpression result = MakeLiteral(syntax, ConstantValue.Create(operatorKind == BinaryOperatorKind.NotEqual), boolType);
BoundExpression nonNull = leftAlwaysNull ? rightNonNull : leftNonNull;
if (ReadIsSideeffecting(nonNull))
{
result = new BoundSequence(
syntax: syntax,
locals: ImmutableArray<LocalSymbol>.Empty,
sideEffects: ImmutableArray.Create<BoundExpression>(nonNull),
value: result,
type: boolType);
}
return result;
}
// Optimization #4: If one side is null and the other is unknown, then we have three cases:
// #4a: If we have x == null then that becomes !x.HasValue.
// #4b: If we have x != null then that becomes x.HasValue.
// #4c: If we have x OP null then that becomes side effects of x, result in false.
if (leftAlwaysNull || rightAlwaysNull)
{
BoundExpression maybeNull = leftAlwaysNull ? right : left;
if (operatorKind == BinaryOperatorKind.Equal || operatorKind == BinaryOperatorKind.NotEqual)
{
BoundExpression callHasValue = MakeNullableHasValue(syntax, maybeNull);
BoundExpression result = operatorKind == BinaryOperatorKind.Equal ?
MakeUnaryOperator(UnaryOperatorKind.BoolLogicalNegation, syntax, null, callHasValue, boolType) :
callHasValue;
return result;
}
else
{
BoundExpression falseExpr = MakeBooleanConstant(syntax, operatorKind == BinaryOperatorKind.NotEqual);
return _factory.Sequence(maybeNull, falseExpr);
}
}
return null;
}
示例5: RewritePointerNumericOperator
private BoundExpression RewritePointerNumericOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression loweredLeft,
BoundExpression loweredRight,
TypeSymbol returnType,
bool isPointerElementAccess,
bool isLeftPointer)
{
if (isLeftPointer)
{
loweredRight = MakeSizeOfMultiplication(loweredRight, (PointerTypeSymbol)loweredLeft.Type, kind.IsChecked());
}
else
{
loweredLeft = MakeSizeOfMultiplication(loweredLeft, (PointerTypeSymbol)loweredRight.Type, kind.IsChecked());
}
if (isPointerElementAccess)
{
Debug.Assert(kind.Operator() == BinaryOperatorKind.Addition);
// NOTE: This is here to persist a bug in Dev10. checked(p[n]) should be equivalent to checked(*(p + n)),
// but Dev10 omits the check on the addition (though it retains the check on the multiplication of n by
// the size).
kind = kind & ~BinaryOperatorKind.Checked;
}
return new BoundBinaryOperator(
syntax,
kind,
loweredLeft,
loweredRight,
ConstantValue.NotAvailable,
null,
LookupResultKind.Viable,
returnType);
}
示例6: RewriteLiftedBinaryOperator
private BoundExpression RewriteLiftedBinaryOperator(CSharpSyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression loweredLeft, BoundExpression loweredRight, TypeSymbol type, MethodSymbol method)
{
var conditionalLeft = loweredLeft as BoundLoweredConditionalAccess;
// NOTE: we could in theory handle side-effecting loweredRight here too
// by including it as a part of whenNull, but there is a concern
// that it can lead to code duplication
var optimize = conditionalLeft != null &&
!ReadIsSideeffecting(loweredRight) &&
(conditionalLeft.WhenNullOpt == null || conditionalLeft.WhenNullOpt.IsDefaultValue());
if (optimize)
{
loweredLeft = conditionalLeft.WhenNotNull;
}
var result = operatorKind.IsComparison() ?
operatorKind.IsUserDefined() ?
LowerLiftedUserDefinedComparisonOperator(syntax, operatorKind, loweredLeft, loweredRight, method) :
LowerLiftedBuiltInComparisonOperator(syntax, operatorKind, loweredLeft, loweredRight) :
LowerLiftedBinaryArithmeticOperator(syntax, operatorKind, loweredLeft, loweredRight, type, method);
if (optimize)
{
BoundExpression whenNullOpt = null;
// for all operators null-in means null-out
// except for the Equal/NotEqual since null == null ==> true
if (operatorKind.Operator() == BinaryOperatorKind.NotEqual ||
operatorKind.Operator() == BinaryOperatorKind.Equal)
{
whenNullOpt = RewriteLiftedBinaryOperator(syntax, operatorKind, _factory.Default(loweredLeft.Type), loweredRight, type, method);
}
result = conditionalLeft.Update(
conditionalLeft.Receiver,
conditionalLeft.HasValueMethodOpt,
whenNotNull: result,
whenNullOpt: whenNullOpt,
id: conditionalLeft.Id,
type: result.Type
);
}
return result;
}
示例7: GetBinaryOperatorName
private string GetBinaryOperatorName(BinaryOperatorKind opKind, out bool isChecked, out bool isLifted, out bool requiresLifted)
{
isChecked = opKind.IsChecked();
isLifted = opKind.IsLifted();
requiresLifted = opKind.IsComparison();
switch (opKind.Operator())
{
case BinaryOperatorKind.Addition: return isChecked ? "AddChecked" : "Add";
case BinaryOperatorKind.Multiplication: return isChecked ? "MultiplyChecked" : "Multiply";
case BinaryOperatorKind.Subtraction: return isChecked ? "SubtractChecked" : "Subtract";
case BinaryOperatorKind.Division: return "Divide";
case BinaryOperatorKind.Remainder: return "Modulo";
case BinaryOperatorKind.And: return opKind.IsLogical() ? "AndAlso" : "And";
case BinaryOperatorKind.Xor: return "ExclusiveOr";
case BinaryOperatorKind.Or: return opKind.IsLogical() ? "OrElse" : "Or";
case BinaryOperatorKind.LeftShift: return "LeftShift";
case BinaryOperatorKind.RightShift: return "RightShift";
case BinaryOperatorKind.Equal: return "Equal";
case BinaryOperatorKind.NotEqual: return "NotEqual";
case BinaryOperatorKind.LessThan: return "LessThan";
case BinaryOperatorKind.LessThanOrEqual: return "LessThanOrEqual";
case BinaryOperatorKind.GreaterThan: return "GreaterThan";
case BinaryOperatorKind.GreaterThanOrEqual: return "GreaterThanOrEqual";
default:
throw ExceptionUtilities.UnexpectedValue(opKind.Operator());
}
}
示例8: MakeBinaryOperator
private BoundExpression MakeBinaryOperator(
BoundBinaryOperator oldNode,
CSharpSyntaxNode syntax,
BinaryOperatorKind operatorKind,
BoundExpression loweredLeft,
BoundExpression loweredRight,
TypeSymbol type,
MethodSymbol method,
bool isPointerElementAccess = false,
bool isCompoundAssignment = false,
BoundUnaryOperator applyParentUnaryOperator = null)
{
Debug.Assert(oldNode == null || (oldNode.Syntax == syntax));
if (_inExpressionLambda)
{
switch (operatorKind.Operator() | operatorKind.OperandTypes())
{
case BinaryOperatorKind.ObjectAndStringConcatenation:
case BinaryOperatorKind.StringAndObjectConcatenation:
case BinaryOperatorKind.StringConcatenation:
return RewriteStringConcatenation(syntax, operatorKind, loweredLeft, loweredRight, type);
case BinaryOperatorKind.DelegateCombination:
return RewriteDelegateOperation(syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_Delegate__Combine);
case BinaryOperatorKind.DelegateRemoval:
return RewriteDelegateOperation(syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_Delegate__Remove);
case BinaryOperatorKind.DelegateEqual:
return RewriteDelegateOperation(syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_Delegate__op_Equality);
case BinaryOperatorKind.DelegateNotEqual:
return RewriteDelegateOperation(syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_Delegate__op_Inequality);
}
}
else
// try to lower the expression.
{
if (operatorKind.IsDynamic())
{
Debug.Assert(!isPointerElementAccess);
if (operatorKind.IsLogical())
{
return MakeDynamicLogicalBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, method, type, isCompoundAssignment, applyParentUnaryOperator);
}
else
{
Debug.Assert((object)method == null);
return _dynamicFactory.MakeDynamicBinaryOperator(operatorKind, loweredLeft, loweredRight, isCompoundAssignment, type).ToExpression();
}
}
if (operatorKind.IsLifted())
{
return RewriteLiftedBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, type, method);
}
if (operatorKind.IsUserDefined())
{
return LowerUserDefinedBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, type, method);
}
switch (operatorKind.OperatorWithLogical() | operatorKind.OperandTypes())
{
case BinaryOperatorKind.NullableNullEqual:
case BinaryOperatorKind.NullableNullNotEqual:
return RewriteNullableNullEquality(syntax, operatorKind, loweredLeft, loweredRight, type);
case BinaryOperatorKind.ObjectAndStringConcatenation:
case BinaryOperatorKind.StringAndObjectConcatenation:
case BinaryOperatorKind.StringConcatenation:
return RewriteStringConcatenation(syntax, operatorKind, loweredLeft, loweredRight, type);
case BinaryOperatorKind.StringEqual:
return RewriteStringEquality(oldNode, syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_String__op_Equality);
case BinaryOperatorKind.StringNotEqual:
return RewriteStringEquality(oldNode, syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_String__op_Inequality);
case BinaryOperatorKind.DelegateCombination:
return RewriteDelegateOperation(syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_Delegate__Combine);
case BinaryOperatorKind.DelegateRemoval:
return RewriteDelegateOperation(syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_Delegate__Remove);
case BinaryOperatorKind.DelegateEqual:
return RewriteDelegateOperation(syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_Delegate__op_Equality);
case BinaryOperatorKind.DelegateNotEqual:
return RewriteDelegateOperation(syntax, operatorKind, loweredLeft, loweredRight, type, SpecialMember.System_Delegate__op_Inequality);
case BinaryOperatorKind.LogicalBoolAnd:
if (loweredRight.ConstantValue == ConstantValue.True) return loweredLeft;
if (loweredLeft.ConstantValue == ConstantValue.True) return loweredRight;
if (loweredLeft.ConstantValue == ConstantValue.False) return loweredLeft;
if (loweredRight.Kind == BoundKind.Local || loweredRight.Kind == BoundKind.Parameter)
{
operatorKind &= ~BinaryOperatorKind.Logical;
}
goto default;
//.........这里部分代码省略.........
示例9: FoldEnumBinaryOperator
private ConstantValue FoldEnumBinaryOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression left,
BoundExpression right,
DiagnosticBag diagnostics)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
Debug.Assert(kind.IsEnum());
Debug.Assert(!kind.IsLifted());
// A built-in binary operation on constant enum operands is evaluated into an operation on
// constants of the underlying type U of the enum type E. Comparison operators are lowered as
// simply computing U<U. All other operators are computed as (E)(U op U) or in the case of
// E-E, (U)(U-U).
TypeSymbol enumType = GetEnumType(kind, left, right);
TypeSymbol underlyingType = enumType.GetEnumUnderlyingType();
BoundExpression newLeftOperand = CreateConversion(left, underlyingType, diagnostics);
BoundExpression newRightOperand = CreateConversion(right, underlyingType, diagnostics);
// If the underlying type is byte, sbyte, short, ushort or nullables of those then we'll need
// to convert it up to int or int? because there are no + - * & | ^ < > <= >= == != operators
// on byte, sbyte, short or ushort. They all convert to int.
SpecialType operandSpecialType = GetEnumPromotedType(underlyingType.SpecialType);
TypeSymbol operandType = (operandSpecialType == underlyingType.SpecialType) ?
underlyingType :
GetSpecialType(operandSpecialType, diagnostics, syntax);
newLeftOperand = CreateConversion(newLeftOperand, operandType, diagnostics);
newRightOperand = CreateConversion(newRightOperand, operandType, diagnostics);
BinaryOperatorKind newKind = kind.Operator().WithType(newLeftOperand.Type.SpecialType);
SpecialType operatorType = SpecialType.None;
switch (newKind.Operator())
{
case BinaryOperatorKind.Addition:
case BinaryOperatorKind.Subtraction:
case BinaryOperatorKind.And:
case BinaryOperatorKind.Or:
case BinaryOperatorKind.Xor:
operatorType = operandType.SpecialType;
break;
case BinaryOperatorKind.LessThan:
case BinaryOperatorKind.LessThanOrEqual:
case BinaryOperatorKind.GreaterThan:
case BinaryOperatorKind.GreaterThanOrEqual:
case BinaryOperatorKind.Equal:
case BinaryOperatorKind.NotEqual:
operatorType = SpecialType.System_Boolean;
break;
default:
throw ExceptionUtilities.UnexpectedValue(newKind.Operator());
}
var constantValue = FoldBinaryOperator(syntax, newKind, newLeftOperand, newRightOperand, operatorType, diagnostics);
if (operatorType != SpecialType.System_Boolean && constantValue != null && !constantValue.IsBad)
{
TypeSymbol resultType = kind == BinaryOperatorKind.EnumSubtraction ? underlyingType : enumType;
// We might need to convert back to the underlying type.
return FoldConstantNumericConversion(syntax, constantValue, resultType, diagnostics);
}
return constantValue;
}
示例10: TryFoldingNullableEquality
/// <summary>
/// If one of the (unconverted) operands has constant value null and the other has
/// a null constant value other than null, then they are definitely not equal
/// and we can give a constant value for either == or !=. This is a spec violation
/// that we retain from Dev10.
/// </summary>
/// <param name="kind">The operator kind. Nothing will happen if it is not a lifted equality operator.</param>
/// <param name="left">The left-hand operand of the operation (possibly wrapped in a conversion).</param>
/// <param name="right">The right-hand operand of the operation (possibly wrapped in a conversion).</param>
/// <returns>
/// If the operator represents lifted equality, then constant value true if both arguments have constant
/// value null, constant value false if exactly one argument has constant value null, and null otherwise.
/// If the operator represents lifted inequality, then constant value false if both arguments have constant
/// value null, constant value true if exactly one argument has constant value null, and null otherwise.
/// </returns>
/// <remarks>
/// SPEC VIOLATION: according to the spec (section 7.19) constant expressions cannot
/// include implicit nullable conversions or nullable subexpressions. However, Dev10
/// specifically folds over lifted == and != (see ExpressionBinder::TryFoldingNullableEquality).
/// Dev 10 does do compile-time evaluation of simple lifted operators, but it does so
/// in a rewriting pass (see NullableRewriter) - they are not treated as constant values.
/// </remarks>
private static ConstantValue TryFoldingNullableEquality(BinaryOperatorKind kind, BoundExpression left, BoundExpression right)
{
if (kind.IsLifted())
{
BinaryOperatorKind op = kind.Operator();
if (op == BinaryOperatorKind.Equal || op == BinaryOperatorKind.NotEqual)
{
if (left.Kind == BoundKind.Conversion && right.Kind == BoundKind.Conversion)
{
BoundConversion leftConv = (BoundConversion)left;
BoundConversion rightConv = (BoundConversion)right;
ConstantValue leftConstant = leftConv.Operand.ConstantValue;
ConstantValue rightConstant = rightConv.Operand.ConstantValue;
if (leftConstant != null && rightConstant != null)
{
bool leftIsNull = leftConstant.IsNull;
bool rightIsNull = rightConstant.IsNull;
if (leftIsNull || rightIsNull)
{
// IMPL CHANGE: Dev10 raises WRN_NubExprIsConstBool in some cases, but that really doesn't
// make sense (why warn that a constant has a constant value?).
return (leftIsNull == rightIsNull) == (op == BinaryOperatorKind.Equal) ? ConstantValue.True : ConstantValue.False;
}
}
}
}
}
return null;
}
示例11: GetDecimalIncDecOperator
private MethodSymbol GetDecimalIncDecOperator(BinaryOperatorKind oper)
{
SpecialMember member;
switch (oper.Operator())
{
case BinaryOperatorKind.Addition: member = SpecialMember.System_Decimal__op_Increment; break;
case BinaryOperatorKind.Subtraction: member = SpecialMember.System_Decimal__op_Decrement; break;
default:
throw ExceptionUtilities.UnexpectedValue(oper.Operator());
}
var method = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(member);
Debug.Assert((object)method != null); // Should have been checked during Warnings pass
return method;
}
示例12: GetSignature
internal BinaryOperatorSignature GetSignature(BinaryOperatorKind kind)
{
var left = LeftType(kind);
switch (kind.Operator())
{
case BinaryOperatorKind.Multiplication:
case BinaryOperatorKind.Division:
case BinaryOperatorKind.Subtraction:
case BinaryOperatorKind.Remainder:
case BinaryOperatorKind.And:
case BinaryOperatorKind.Or:
case BinaryOperatorKind.Xor:
return new BinaryOperatorSignature(kind, left, left, left);
case BinaryOperatorKind.Addition:
return new BinaryOperatorSignature(kind, LeftType(kind), RightType(kind), ReturnType(kind));
case BinaryOperatorKind.LeftShift:
case BinaryOperatorKind.RightShift:
TypeSymbol returnType = Compilation.GetSpecialType(SpecialType.System_Int32);
if (kind.IsLifted())
{
returnType = Compilation.GetSpecialType(SpecialType.System_Nullable_T).Construct(returnType);
}
return new BinaryOperatorSignature(kind, left, returnType, left);
case BinaryOperatorKind.Equal:
case BinaryOperatorKind.NotEqual:
case BinaryOperatorKind.GreaterThan:
case BinaryOperatorKind.LessThan:
case BinaryOperatorKind.GreaterThanOrEqual:
case BinaryOperatorKind.LessThanOrEqual:
return new BinaryOperatorSignature(kind, left, left, Compilation.GetSpecialType(SpecialType.System_Boolean));
}
return new BinaryOperatorSignature(kind, LeftType(kind), RightType(kind), ReturnType(kind));
}
示例13: LowerUserDefinedLogicalOperator
private BoundExpression LowerUserDefinedLogicalOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind operatorKind,
BoundExpression loweredLeft,
BoundExpression loweredRight,
TypeSymbol type,
MethodSymbol method)
{
Debug.Assert((object)method != null);
// See comments in method IsValidUserDefinedConditionalLogicalOperator for information
// on some subtle aspects of this lowering.
// We generate one of:
//
// x || y --> temp = x; T.true(temp) ? temp : T.|(temp, y);
// x && y --> temp = x; T.false(temp) ? temp : T.&(temp, y);
//
// For the ease of naming locals, we'll assume we're doing an &&.
// TODO: We generate every one of these as "temp = x; T.false(temp) ? temp : T.&(temp, y)" even
// TODO: when x has no side effects. We can optimize away the temporary if there are no side effects.
BoundAssignmentOperator tempAssignment;
var boundTemp = factory.StoreToTemp(loweredLeft, out tempAssignment);
// T.false(temp)
var falseOperatorCall = BoundCall.Synthesized(syntax, null, GetTruthOperator(type, negative: operatorKind.Operator() == BinaryOperatorKind.And), boundTemp);
// T.&(temp, y)
var andOperatorCall = LowerUserDefinedBinaryOperator(syntax, operatorKind & ~BinaryOperatorKind.Logical, boundTemp, loweredRight, type, method);
// T.false(temp) ? temp : T.&(temp, y)
BoundExpression conditionalExpression = RewriteConditionalOperator(
syntax: syntax,
rewrittenCondition: falseOperatorCall,
rewrittenConsequence: boundTemp,
rewrittenAlternative: andOperatorCall,
constantValueOpt: null,
rewrittenType: type);
// temp = x; T.false(temp) ? temp : T.&(temp, y)
return new BoundSequence(
syntax: syntax,
locals: ImmutableArray.Create(boundTemp.LocalSymbol),
sideEffects: ImmutableArray.Create<BoundExpression>(tempAssignment),
value: conditionalExpression,
type: type);
}
示例14: OperatorHasSideEffects
private static bool OperatorHasSideEffects(BinaryOperatorKind kind)
{
switch (kind.Operator())
{
case BinaryOperatorKind.Division:
case BinaryOperatorKind.Remainder:
return true;
default:
return kind.IsChecked();
}
}
示例15: GetDecimalIncDecOperator
private MethodSymbol GetDecimalIncDecOperator(BinaryOperatorKind oper)
{
SpecialMember member;
switch (oper.Operator())
{
case BinaryOperatorKind.Addition: member = SpecialMember.System_Decimal__op_Increment; break;
case BinaryOperatorKind.Subtraction: member = SpecialMember.System_Decimal__op_Decrement; break;
default:
Debug.Assert(false); // Cannot reach here
return null;
}
var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member);
Debug.Assert((object)method != null); // Should have been checked during Warnings pass
return method;
}