本文整理汇总了C#中BinaryOperatorKind.IsLifted方法的典型用法代码示例。如果您正苦于以下问题:C# BinaryOperatorKind.IsLifted方法的具体用法?C# BinaryOperatorKind.IsLifted怎么用?C# BinaryOperatorKind.IsLifted使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BinaryOperatorKind
的用法示例。
在下文中一共展示了BinaryOperatorKind.IsLifted方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: 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;
//.........这里部分代码省略.........
示例2: LowerUserDefinedBinaryOperator
private BoundExpression LowerUserDefinedBinaryOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind operatorKind,
BoundExpression loweredLeft,
BoundExpression loweredRight,
TypeSymbol type,
MethodSymbol method)
{
Debug.Assert(!operatorKind.IsLogical());
if (operatorKind.IsLifted())
{
return RewriteLiftedBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, type, method);
}
// Otherwise, nothing special here.
Debug.Assert((object)method != null);
Debug.Assert(method.ReturnType == type);
return BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight);
}
示例3: 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());
}
}
示例4: VisitBinaryOperator
private BoundExpression VisitBinaryOperator(BinaryOperatorKind opKind, MethodSymbol methodOpt, TypeSymbol type, BoundExpression left, BoundExpression right)
{
bool isChecked, isLifted, requiresLifted;
string opName = GetBinaryOperatorName(opKind, out isChecked, out isLifted, out requiresLifted);
// Fix up the null value for a nullable comparison vs null
if ((object)left.Type == null && left.IsLiteralNull())
{
left = _bound.Default(right.Type);
}
if ((object)right.Type == null && right.IsLiteralNull())
{
right = _bound.Default(left.Type);
}
var loweredLeft = Visit(left);
var loweredRight = Visit(right);
// Enums are handled as per their promoted underlying type
switch (opKind.OperandTypes())
{
case BinaryOperatorKind.Enum:
case BinaryOperatorKind.EnumAndUnderlying:
case BinaryOperatorKind.UnderlyingAndEnum:
{
var enumOperand = (opKind.OperandTypes() == BinaryOperatorKind.UnderlyingAndEnum) ? right : left;
var promotedType = PromotedType(enumOperand.Type.StrippedType().GetEnumUnderlyingType());
if (opKind.IsLifted())
{
promotedType = _nullableType.Construct(promotedType);
}
loweredLeft = PromoteEnumOperand(left, loweredLeft, promotedType, isChecked);
loweredRight = PromoteEnumOperand(right, loweredRight, promotedType, isChecked);
var result = MakeBinary(methodOpt, type, isLifted, requiresLifted, opName, loweredLeft, loweredRight);
return Demote(result, type, isChecked);
}
default:
return MakeBinary(methodOpt, type, isLifted, requiresLifted, opName, loweredLeft, loweredRight);
}
}
示例5: FoldBinaryOperator
// Returns null if the operator can't be evaluated at compile time.
private ConstantValue FoldBinaryOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind kind,
BoundExpression left,
BoundExpression right,
SpecialType resultType,
DiagnosticBag diagnostics,
ref int compoundStringLength)
{
Debug.Assert(left != null);
Debug.Assert(right != null);
if (left.HasAnyErrors || right.HasAnyErrors)
{
return null;
}
// SPEC VIOLATION: see method definition for details
ConstantValue nullableEqualityResult = TryFoldingNullableEquality(kind, left, right);
if (nullableEqualityResult != null)
{
return nullableEqualityResult;
}
var valueLeft = left.ConstantValue;
var valueRight = right.ConstantValue;
if (valueLeft == null || valueRight == null)
{
return null;
}
if (valueLeft.IsBad || valueRight.IsBad)
{
return ConstantValue.Bad;
}
if (kind.IsEnum() && !kind.IsLifted())
{
return FoldEnumBinaryOperator(syntax, kind, left, right, diagnostics);
}
// Divisions by zero on integral types and decimal always fail even in an unchecked context.
if (IsDivisionByZero(kind, valueRight))
{
Error(diagnostics, ErrorCode.ERR_IntDivByZero, syntax);
return ConstantValue.Bad;
}
object newValue = null;
// Certain binary operations never fail; bool & bool, for example. If we are in one of those
// cases, simply fold the operation and return.
//
// Although remainder and division always overflow at runtime with arguments int.MinValue/long.MinValue and -1
// (regardless of checked context) the constant folding behavior is different.
// Remainder never overflows at compile time while division does.
newValue = FoldNeverOverflowBinaryOperators(kind, valueLeft, valueRight);
if (newValue != null)
{
return ConstantValue.Create(newValue, resultType);
}
ConstantValue concatResult = FoldStringConcatenation(kind, valueLeft, valueRight, ref compoundStringLength);
if (concatResult != null)
{
if (concatResult.IsBad)
{
Error(diagnostics, ErrorCode.ERR_ConstantStringTooLong, syntax);
}
return concatResult;
}
// Certain binary operations always fail if they overflow even when in an unchecked context;
// decimal + decimal, for example. If we are in one of those cases, make the attempt. If it
// succeeds, return the result. If not, give a compile-time error regardless of context.
try
{
newValue = FoldDecimalBinaryOperators(kind, valueLeft, valueRight);
}
catch (OverflowException)
{
Error(diagnostics, ErrorCode.ERR_DecConstError, syntax);
return ConstantValue.Bad;
}
if (newValue != null)
{
return ConstantValue.Create(newValue, resultType);
}
if (CheckOverflowAtCompileTime)
{
try
{
newValue = FoldCheckedIntegralBinaryOperator(kind, valueLeft, valueRight);
}
catch (OverflowException)
{
//.........这里部分代码省略.........
示例6: 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;
}
示例7: 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;
}
示例8: LiftedType
private TypeSymbol LiftedType(BinaryOperatorKind kind)
{
Debug.Assert(kind.IsLifted());
var nullable = Compilation.GetSpecialType(SpecialType.System_Nullable_T);
switch (kind.OperandTypes())
{
case BinaryOperatorKind.Int: return nullable.Construct(Compilation.GetSpecialType(SpecialType.System_Int32));
case BinaryOperatorKind.UInt: return nullable.Construct(Compilation.GetSpecialType(SpecialType.System_UInt32));
case BinaryOperatorKind.Long: return nullable.Construct(Compilation.GetSpecialType(SpecialType.System_Int64));
case BinaryOperatorKind.ULong: return nullable.Construct(Compilation.GetSpecialType(SpecialType.System_UInt64));
case BinaryOperatorKind.Float: return nullable.Construct(Compilation.GetSpecialType(SpecialType.System_Single));
case BinaryOperatorKind.Double: return nullable.Construct(Compilation.GetSpecialType(SpecialType.System_Double));
case BinaryOperatorKind.Decimal: return nullable.Construct(Compilation.GetSpecialType(SpecialType.System_Decimal));
case BinaryOperatorKind.Bool: return nullable.Construct(Compilation.GetSpecialType(SpecialType.System_Boolean));
}
Debug.Assert(false, "Bad operator kind in lifted type");
return null;
}
示例9: ReturnType
private TypeSymbol ReturnType(BinaryOperatorKind kind)
{
if (kind.IsLifted())
{
return LiftedType(kind);
}
else
{
switch (kind.OperandTypes())
{
case BinaryOperatorKind.Int: return Compilation.GetSpecialType(SpecialType.System_Int32);
case BinaryOperatorKind.UInt: return Compilation.GetSpecialType(SpecialType.System_UInt32);
case BinaryOperatorKind.Long: return Compilation.GetSpecialType(SpecialType.System_Int64);
case BinaryOperatorKind.ULong: return Compilation.GetSpecialType(SpecialType.System_UInt64);
case BinaryOperatorKind.Float: return Compilation.GetSpecialType(SpecialType.System_Single);
case BinaryOperatorKind.Double: return Compilation.GetSpecialType(SpecialType.System_Double);
case BinaryOperatorKind.Decimal: return Compilation.GetSpecialType(SpecialType.System_Decimal);
case BinaryOperatorKind.Bool: return Compilation.GetSpecialType(SpecialType.System_Boolean);
case BinaryOperatorKind.Object: return Compilation.GetSpecialType(SpecialType.System_Object);
case BinaryOperatorKind.ObjectAndString:
case BinaryOperatorKind.StringAndObject:
case BinaryOperatorKind.String:
return Compilation.GetSpecialType(SpecialType.System_String);
}
}
Debug.Assert(false, "Bad operator kind in return type");
return null;
}
示例10: 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));
}
示例11: LowerUserDefinedBinaryOperator
private BoundExpression LowerUserDefinedBinaryOperator(
CSharpSyntaxNode syntax,
BinaryOperatorKind operatorKind,
BoundExpression loweredLeft,
BoundExpression loweredRight,
TypeSymbol type,
MethodSymbol method)
{
if (operatorKind.IsLogical())
{
// Yes, we could have a lifted, logical, user-defined operator:
//
// struct C {
// public static C operator &(C x, C y) {...}
// public static bool operator true(C? c) { ... }
// public static bool operator false(C? c) { ... }
// }
//
// If we have C? q, r and we say q && r then this gets bound as
// C? tempQ = q ;
// C.false(tempQ) ?
// tempQ :
// (
// C? tempR = r ;
// tempQ.HasValue & tempR.HasValue ?
// new C?(C.&(tempQ.GetValueOrDefault(), tempR.GetValueOrDefault())) :
// default C?()
// )
//
// Note that the native compiler does not allow q && r. However, the native compiler
// *does* allow q && r if C is defined as:
//
// struct C {
// public static C? operator &(C? x, C? y) {...}
// public static bool operator true(C? c) { ... }
// public static bool operator false(C? c) { ... }
// }
//
// It seems unusual and wrong that an & operator should be allowed to become
// a && operator if there is a "manually lifted" operator in source, but not
// if there is a "synthesized" lifted operator. Roslyn fixes this bug.
//
// Anyway, in this case we must lower this to its non-logical form, and then
// lower the interior of that to its non-lifted form.
return LowerUserDefinedLogicalOperator(syntax, operatorKind, loweredLeft, loweredRight, type, method);
}
else if (operatorKind.IsLifted())
{
if (operatorKind.IsComparison())
{
return LowerLiftedUserDefinedComparisonOperator(syntax, operatorKind, loweredLeft, loweredRight, method);
}
else
{
return LowerLiftedBinaryArithmeticOperator(syntax, operatorKind, loweredLeft, loweredRight, type, method);
}
}
// Otherwise, nothing special here.
Debug.Assert((object)method != null);
Debug.Assert(method.ReturnType == type);
return BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight);
}