本文整理汇总了C#中Microsoft.CodeAnalysis.CSharp.BoundBinaryOperator类的典型用法代码示例。如果您正苦于以下问题:C# BoundBinaryOperator类的具体用法?C# BoundBinaryOperator怎么用?C# BoundBinaryOperator使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
BoundBinaryOperator类属于Microsoft.CodeAnalysis.CSharp命名空间,在下文中一共展示了BoundBinaryOperator类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: VisitBinaryOperator
public BoundExpression VisitBinaryOperator(BoundBinaryOperator node, BoundUnaryOperator applyParentUnaryOperator = null)
{
// In machine-generated code we frequently end up with binary operator trees that are deep on the left,
// such as a + b + c + d ...
// To avoid blowing the call stack, we make an explicit stack of the binary operators to the left,
// and then lower by traversing the explicit stack.
var stack = ArrayBuilder<BoundBinaryOperator>.GetInstance();
for (BoundBinaryOperator current = node; current != null; current = current.Left as BoundBinaryOperator)
{
stack.Push(current);
}
BoundExpression loweredLeft = VisitExpression(stack.Peek().Left);
while (stack.Count > 0)
{
BoundBinaryOperator original = stack.Pop();
BoundExpression loweredRight = VisitExpression(original.Right);
loweredLeft = MakeBinaryOperator(original, original.Syntax, original.OperatorKind, loweredLeft, loweredRight, original.Type, original.MethodOpt,
applyParentUnaryOperator: (stack.Count == 0) ? applyParentUnaryOperator : null);
}
stack.Free();
return loweredLeft;
}
示例2: TryFoldWithConditionalAccess
private BoundExpression TryFoldWithConditionalAccess(BoundBinaryOperator node)
{
var syntax = node.Syntax;
var left = node.Left;
var right = node.Right;
BoundConditionalAccess conditionalAccess;
if (!node.OperatorKind.IsLifted())
{
var operatorKind = node.OperatorKind;
if (operatorKind == BinaryOperatorKind.NullableNullEqual || operatorKind == BinaryOperatorKind.NullableNullNotEqual)
{
var leftAlwaysNull = NullableNeverHasValue(left);
var rightAlwaysNull = NullableNeverHasValue(right);
if (leftAlwaysNull || rightAlwaysNull)
{
BoundExpression maybeNull = leftAlwaysNull ? right : left;
if (TryGetOptimizableNullableConditionalAccess(maybeNull, out conditionalAccess))
{
BoundExpression accessExpression = conditionalAccess.AccessExpression;
accessExpression = _factory.Sequence(accessExpression, MakeBooleanConstant(syntax, operatorKind == BinaryOperatorKind.NullableNullNotEqual));
conditionalAccess = conditionalAccess.Update(conditionalAccess.Receiver, accessExpression, accessExpression.Type);
var whenNull = operatorKind == BinaryOperatorKind.NullableNullEqual ? MakeBooleanConstant(syntax, true) : null;
return RewriteConditionalAccess(conditionalAccess, used: true, rewrittenWhenNull: whenNull);
}
}
}
}
else
{
var unliftedOperatorKind = node.OperatorKind.Unlifted();
if (unliftedOperatorKind.IsComparison() && TryGetOptimizableNullableConditionalAccess(left, out conditionalAccess))
{
var rightAlwaysHasValue = NullableAlwaysHasValue(VisitExpression(right));
// reading rightAlwaysHasValue should not have sideeffects here
// otherwise we would need to read it even when we knew that LHS is null
if (rightAlwaysHasValue != null && !IntroducingReadCanBeObservable(rightAlwaysHasValue))
{
BoundExpression accessExpression = conditionalAccess.AccessExpression;
accessExpression = node.Update(unliftedOperatorKind, accessExpression, rightAlwaysHasValue, null, node.MethodOpt, node.ResultKind, node.Type);
conditionalAccess = conditionalAccess.Update(conditionalAccess.Receiver, accessExpression, accessExpression.Type);
var whenNull = unliftedOperatorKind.Operator() == BinaryOperatorKind.NotEqual ? MakeBooleanConstant(syntax, true) : null;
return RewriteConditionalAccess(conditionalAccess, used: true, rewrittenWhenNull: whenNull);
}
}
}
return null;
}
示例3: VisitBinaryOperator
public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
{
// check for common trivial cases like arr?.Length > 0
// in such situations we can fuse two operations and thus
// avoid doing lifting.
// In the given example if "arr" is null then the result is false,
// otherwise we can do unlifted ">" directly on arr.Length
if (node.OperatorKind.IsLifted() ||
node.OperatorKind == BinaryOperatorKind.NullableNullEqual ||
node.OperatorKind == BinaryOperatorKind.NullableNullNotEqual)
{
BoundExpression foldedWithConditionalAccess = TryFoldWithConditionalAccess(node);
if (foldedWithConditionalAccess != null)
{
return foldedWithConditionalAccess;
}
}
return VisitBinaryOperator(node, null);
}
示例4: MakeCall
private BoundExpression MakeCall(
BoundCall node,
SyntaxNode syntax,
BoundExpression rewrittenReceiver,
MethodSymbol method,
ImmutableArray<BoundExpression> rewrittenArguments,
ImmutableArray<RefKind> argumentRefKinds,
bool invokedAsExtensionMethod,
LookupResultKind resultKind,
TypeSymbol type,
ImmutableArray<LocalSymbol> temps = default(ImmutableArray<LocalSymbol>))
{
BoundExpression rewrittenBoundCall;
if (method.IsStatic &&
method.ContainingType.IsObjectType() &&
!_inExpressionLambda &&
(object)method == (object)_compilation.GetSpecialTypeMember(SpecialMember.System_Object__ReferenceEquals))
{
Debug.Assert(rewrittenArguments.Length == 2);
// ECMA - 335
// I.8.2.5.1 Identity
// ...
// Identity is implemented on System.Object via the ReferenceEquals method.
rewrittenBoundCall = new BoundBinaryOperator(
syntax,
BinaryOperatorKind.ObjectEqual,
rewrittenArguments[0],
rewrittenArguments[1],
null,
null,
resultKind,
type);
}
else if (node == null)
{
rewrittenBoundCall = new BoundCall(
syntax,
rewrittenReceiver,
method,
rewrittenArguments,
default(ImmutableArray<string>),
argumentRefKinds,
isDelegateCall: false,
expanded: false,
invokedAsExtensionMethod: invokedAsExtensionMethod,
argsToParamsOpt: default(ImmutableArray<int>),
resultKind: resultKind,
type: type);
}
else
{
rewrittenBoundCall = node.Update(
rewrittenReceiver,
method,
rewrittenArguments,
default(ImmutableArray<string>),
argumentRefKinds,
node.IsDelegateCall,
false,
node.InvokedAsExtensionMethod,
default(ImmutableArray<int>),
node.ResultKind,
node.Type);
}
if (!temps.IsDefaultOrEmpty)
{
return new BoundSequence(
syntax,
locals: temps,
sideEffects: ImmutableArray<BoundExpression>.Empty,
value: rewrittenBoundCall,
type: type);
}
return rewrittenBoundCall;
}
示例5: RewriteStringEquality
private BoundExpression RewriteStringEquality(BoundBinaryOperator oldNode, CSharpSyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression loweredLeft, BoundExpression loweredRight, TypeSymbol type, SpecialMember member)
{
if (oldNode != null && (loweredLeft.ConstantValue == ConstantValue.Null || loweredRight.ConstantValue == ConstantValue.Null))
{
return oldNode.Update(operatorKind, loweredLeft, loweredRight, oldNode.ConstantValueOpt, oldNode.MethodOpt, oldNode.ResultKind, type);
}
var method = GetSpecialTypeMethod(syntax, member);
Debug.Assert((object)method != null);
return BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight);
}
示例6: 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;
//.........这里部分代码省略.........
示例7: MakeBinary
private BoundExpression MakeBinary(BoundBinaryOperator node, bool isLifted, bool requiresLifted, string opname, BoundExpression loweredLeft, BoundExpression loweredRight)
{
return
((object)node.MethodOpt == null) ? ExprFactory(opname, loweredLeft, loweredRight) :
requiresLifted ? ExprFactory(opname, loweredLeft, loweredRight, Bound.Literal(isLifted && node.MethodOpt.ReturnType != node.Type), Bound.MethodInfo(node.MethodOpt)) :
ExprFactory(opname, loweredLeft, loweredRight, Bound.MethodInfo(node.MethodOpt));
}
示例8: VisitBinaryOperator
public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
{
throw ExceptionUtilities.Unreachable;
}
示例9: CheckDynamic
private void CheckDynamic(BoundBinaryOperator node)
{
if (_inExpressionLambda && node.OperatorKind.IsDynamic())
{
Error(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, node);
}
}
示例10: CheckOr
private void CheckOr(BoundBinaryOperator node)
{
// We wish to give a warning for situations where an unexpected sign extension wipes
// out some bits. For example:
//
// int x = 0x0ABC0000;
// short y = -2; // 0xFFFE
// int z = x | y;
//
// The user might naively expect the result to be 0x0ABCFFFE. But the short is sign-extended
// when it is converted to int before the bitwise or, so this is in fact the same as:
//
// int x = 0x0ABC0000;
// short y = -2; // 0xFFFE
// int ytemp = y; // 0xFFFFFFFE
// int z = x | ytemp;
//
// Which gives 0xFFFFFFFE, not 0x0ABCFFFE.
//
// However, we wish to suppress the warning if:
//
// * The sign extension is "expected" -- for instance, because there was an explicit cast
// from short to int: "int z = x | (int)y;" should not produce the warning.
// Note that "uint z = (uint)x | (uint)y;" should still produce the warning because
// the user might not realize that converting y to uint does a sign extension.
//
// * There is the same amount of sign extension on both sides. For example, when
// doing "short | sbyte", both sides are sign extended. The left creates two FF bytes
// and the right creates three, so we are potentially wiping out information from the
// left side. But "short | short" adds two FF bytes on both sides, so no information is lost.
//
// The native compiler also suppresses this warning in a bizarre and inconsistent way. If
// the side whose bits are going to be wiped out by sign extension is a *constant*, then the
// warning is suppressed *if the constant, when converted to a signed long, fits into the
// range of the type that is being sign-extended.*
//
// Consider the effects of this rule:
//
// (uint)0xFFFF0000 | y -- gives the warning because 0xFFFF0000 as a long is not in the range of a short,
// *even though the result will not be affected by the sign extension*.
// (ulong)0xFFFFFFFFFFFFFFFF | y -- suppresses the warning, because 0xFFFFFFFFFFFFFFFF as a signed long fits into a short.
// (int)0x0000ABCD | y -- suppresses the warning, even though the 0000 is going to be wiped out by the sign extension.
//
// It seems clear that the intention of the heuristic is to *suppress the warning when the bits being hammered
// on are either all zero, or all one.* Therefore that is the heuristic we will *actually* implement here.
//
switch (node.OperatorKind)
{
case BinaryOperatorKind.LiftedUIntOr:
case BinaryOperatorKind.LiftedIntOr:
case BinaryOperatorKind.LiftedULongOr:
case BinaryOperatorKind.LiftedLongOr:
case BinaryOperatorKind.UIntOr:
case BinaryOperatorKind.IntOr:
case BinaryOperatorKind.ULongOr:
case BinaryOperatorKind.LongOr:
break;
default:
return;
}
// The native compiler skips this warning if both sides of the operator are constants.
//
// CONSIDER: Is that sensible? It seems reasonable that if we would warn on int | short
// when they are non-constants, or when one is a constant, that we would similarly warn
// when both are constants.
if (node.ConstantValue != null)
{
return;
}
// Start by determining *which bits on each side are going to be unexpectedly turned on*.
ulong left = FindSurprisingSignExtensionBits(node.Left);
ulong right = FindSurprisingSignExtensionBits(node.Right);
// If they are all the same then there's no warning to give.
if (left == right)
{
return;
}
// Suppress the warning if one side is a constant, and either all the unexpected
// bits are already off, or all the unexpected bits are already on.
ConstantValue constVal = GetConstantValueForBitwiseOrCheck(node.Left);
if (constVal != null)
{
ulong val = constVal.UInt64Value;
if ((val & right) == right || (~val & right) == right)
{
return;
}
}
constVal = GetConstantValueForBitwiseOrCheck(node.Right);
if (constVal != null)
//.........这里部分代码省略.........
示例11: CheckVacuousComparisons
private void CheckVacuousComparisons(BoundBinaryOperator tree, ConstantValue constantValue, BoundNode operand)
{
Debug.Assert(tree != null);
Debug.Assert(constantValue != null);
Debug.Assert(operand != null);
// We wish to detect comparisons between integers and constants which are likely to be wrong
// because we know at compile time whether they will be true or false. For example:
//
// const short s = 1000;
// byte b = whatever;
// if (b < s)
//
// We know that this will always be true because when b and s are both converted to int for
// the comparison, the left side will always be less than the right side.
//
// We only give the warning if there is no explicit conversion involved on the operand.
// For example, if we had:
//
// const uint s = 1000;
// sbyte b = whatever;
// if ((byte)b < s)
//
// Then we do not give a warning.
//
// Note that the native compiler has what looks to be some dead code. It checks to see
// if the conversion on the operand is from an enum type. But this is unnecessary if
// we are rejecting cases with explicit conversions. The only possible cases are:
//
// enum == enumConstant -- enum types must be the same, so it must be in range.
// enum == integralConstant -- not legal unless the constant is zero, which is in range.
// enum == (ENUM)anyConstant -- if the constant is out of range then this is not legal in the first place
// unless we're in an unchecked context, in which case, the user probably does
// not want the warning.
// integral == enumConstant -- never legal in the first place
//
// Since it seems pointless to try to check enums, we simply look for vacuous comparisons of
// integral types here.
for (BoundConversion conversion = operand as BoundConversion;
conversion != null;
conversion = conversion.Operand as BoundConversion)
{
if (conversion.ConversionKind != ConversionKind.ImplicitNumeric &&
conversion.ConversionKind != ConversionKind.ImplicitConstant)
{
return;
}
// As in dev11, we don't dig through explicit casts (see ExpressionBinder::WarnAboutBadRelationals).
if (conversion.ExplicitCastInCode)
{
return;
}
if (!conversion.Operand.Type.SpecialType.IsIntegralType() || !conversion.Type.SpecialType.IsIntegralType())
{
return;
}
if (!Binder.CheckConstantBounds(conversion.Operand.Type.SpecialType, constantValue))
{
Error(ErrorCode.WRN_VacuousIntegralComp, tree, conversion.Operand.Type);
return;
}
}
}
示例12: CheckSelfComparisons
private void CheckSelfComparisons(BoundBinaryOperator node)
{
Debug.Assert(node != null);
Debug.Assert(node.OperatorKind.IsComparison());
if (!node.HasAnyErrors && IsSameLocalOrField(node.Left, node.Right))
{
Error(ErrorCode.WRN_ComparisonToSelf, node);
}
}
示例13: CheckRelationals
private void CheckRelationals(BoundBinaryOperator node)
{
Debug.Assert(node != null);
if (!node.OperatorKind.IsComparison())
{
return;
}
// Don't bother to check vacuous comparisons where both sides are constant, eg, where someone
// is doing something like "if (0xFFFFFFFFU == 0)" -- these are likely to be machine-
// generated code.
if (node.Left.ConstantValue != null && node.Right.ConstantValue == null && node.Right.Kind == BoundKind.Conversion)
{
CheckVacuousComparisons(node, node.Left.ConstantValue, node.Right);
}
if (node.Right.ConstantValue != null && node.Left.ConstantValue == null && node.Left.Kind == BoundKind.Conversion)
{
CheckVacuousComparisons(node, node.Right.ConstantValue, node.Left);
}
if (node.OperatorKind == BinaryOperatorKind.ObjectEqual || node.OperatorKind == BinaryOperatorKind.ObjectNotEqual)
{
TypeSymbol t;
if (node.Left.Type.SpecialType == SpecialType.System_Object && !IsExplicitCast(node.Left) && !(node.Left.ConstantValue != null && node.Left.ConstantValue.IsNull) && ConvertedHasEqual(node.OperatorKind, node.Right, out t))
{
// Possible unintended reference comparison; to get a value comparison, cast the left hand side to type '{0}'
_diagnostics.Add(ErrorCode.WRN_BadRefCompareLeft, node.Syntax.Location, t);
}
else if (node.Right.Type.SpecialType == SpecialType.System_Object && !IsExplicitCast(node.Right) && !(node.Right.ConstantValue != null && node.Right.ConstantValue.IsNull) && ConvertedHasEqual(node.OperatorKind, node.Left, out t))
{
// Possible unintended reference comparison; to get a value comparison, cast the right hand side to type '{0}'
_diagnostics.Add(ErrorCode.WRN_BadRefCompareRight, node.Syntax.Location, t);
}
}
CheckSelfComparisons(node);
}
示例14: CheckBinaryOperator
private void CheckBinaryOperator(BoundBinaryOperator node)
{
if ((object)node.MethodOpt == null)
{
CheckUnsafeType(node.Left);
CheckUnsafeType(node.Right);
}
CheckOr(node);
CheckNullableNullBinOp(node);
CheckLiftedBinOp(node);
CheckRelationals(node);
CheckDynamic(node);
}
示例15: CheckBinaryOperator
private void CheckBinaryOperator(BoundBinaryOperator node)
{
if ((object)node.MethodOpt == null)
{
CheckUnsafeType(node.Left);
CheckUnsafeType(node.Right);
}
CheckForBitwiseOrSignExtend(node, node.OperatorKind, node.Left, node.Right);
CheckNullableNullBinOp(node);
CheckLiftedBinOp(node);
CheckRelationals(node);
CheckDynamic(node);
}