当前位置: 首页>>代码示例>>C#>>正文


C# BoundBinaryOperator类代码示例

本文整理汇总了C#中BoundBinaryOperator的典型用法代码示例。如果您正苦于以下问题:C# BoundBinaryOperator类的具体用法?C# BoundBinaryOperator怎么用?C# BoundBinaryOperator使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


BoundBinaryOperator类属于命名空间,在下文中一共展示了BoundBinaryOperator类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: RewriteStringConcatenation

        private BoundNode RewriteStringConcatenation(BoundBinaryOperator node)
        {
            // UNDONE: We need to make this more sophisticated. For example, we should
            // UNDONE: be rewriting (M() + "A") + ("B" + N()) as 
            // UNDONE: String.Concat(M(), "AB", N()).
            // UNDONE: We have many overloads of String.Concat to choose from: that
            // UNDONE: take one, two, three, four strings, that take params arrays
            // UNDONE: in strings and objects, and so on. See the native compiler
            // UNDONE: string rewriter for details.
            // UNDONE: For now, just to get this going let's do it the easy way;
            // UNDONE: we'll just generate calls to String.Concat(string, string)
            // UNDONE: or String.Concat(object, object) as appropriate.

            Debug.Assert(node != null);
            Debug.Assert(node.ConstantValueOpt == null);

            SpecialMember member = (node.OperatorKind == BinaryOperatorKind.StringConcatenation) ?
                SpecialMember.System_String__ConcatStringString :
                SpecialMember.System_String__ConcatObjectObject;

            var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member);

            // UNDONE: Handle the bizarre error case where we don't have the expected string concat methods.
            Debug.Assert(method != null);

            return Visit(BoundCall.SynthesizedCall(null, method, node.Left, node.Right));
        }
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:27,代码来源:OperatorRewriter.cs

示例2: EmitBinaryOperatorExpression

        private void EmitBinaryOperatorExpression(BoundBinaryOperator expression, bool used)
        {
            var operatorKind = expression.OperatorKind;

            if (operatorKind.EmitsAsCheckedInstruction())
            {
                EmitBinaryOperator(expression);
            }
            else
            {
                // if operator does not have side-effects itself and is not short-circuiting
                // we can simply emit side-effects from the first operand and then from the second one
                if (!used && !operatorKind.IsLogical() && !OperatorHasSideEffects(operatorKind))
                {
                    EmitExpression(expression.Left, false);
                    EmitExpression(expression.Right, false);
                    return;
                }

                if (IsConditional(operatorKind))
                {
                    EmitBinaryCondOperator(expression, true);
                }
                else
                {
                    EmitBinaryOperator(expression);
                }
            }

            EmitPopIfUnused(used);
        }
开发者ID:xier2012,项目名称:roslyn,代码行数:31,代码来源:EmitOperators.cs

示例3: RewriteDelegateOperation

 private BoundNode RewriteDelegateOperation(BoundBinaryOperator node, SpecialMember member)
 {
     Debug.Assert(node != null);
     var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member);
     // UNDONE: Handle the bizarre error case where we don't have the expected methods.
     Debug.Assert(method != null);
     BoundExpression call = BoundCall.SynthesizedCall(null, method, node.Left, node.Right);
     BoundExpression result = method.ReturnType.SpecialType == SpecialType.System_Delegate ?
         BoundConversion.SynthesizedConversion(call, ConversionKind.ExplicitReference, node.Type) :
         call;
     return Visit(result);
 }
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:12,代码来源:OperatorRewriter.cs

示例4: RewriteStringEquality

        private BoundNode RewriteStringEquality(BoundBinaryOperator node, SpecialMember member)
        {
            Debug.Assert(node != null);
            Debug.Assert(node.ConstantValueOpt == null);

            if (node.Left.ConstantValue == ConstantValue.Null || node.Right.ConstantValue == ConstantValue.Null)
            {
                return base.VisitBinaryOperator(node);
            }

            var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member);
            Debug.Assert(method != null);

            return Visit(BoundCall.SynthesizedCall(null, method, node.Left, node.Right));
        }
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:15,代码来源:OperatorRewriter.cs

示例5: VisitBinaryOperator

        public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
        {
            Debug.Assert(node != null);

            BoundExpression left = (BoundExpression)this.Visit(node.Left);
            BoundExpression right = (BoundExpression)this.Visit(node.Right);

            if (node.Type.SpecialType == SpecialType.System_Decimal)
            {
                return RewriteDecimalArithmeticBinaryOperator(node.OperatorKind, node.Syntax, left, right);
            }
            else if (node.Left.Type.SpecialType == SpecialType.System_Decimal && node.Left.Type.SpecialType == SpecialType.System_Decimal)
            {
                return RewriteDecimalComparisonOperator(node.OperatorKind, node.Syntax, left, right);
            }

            return node.Update(node.OperatorKind, left, right, node.ConstantValueOpt, node.MethodOpt, node.ResultKind, node.Type);
        }
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:18,代码来源:DecimalRewriter.cs

示例6: EmitBinaryCondOperator

        //NOTE: The result of this should be a boolean on the stack.
        private void EmitBinaryCondOperator(BoundBinaryOperator binOp, bool sense)
        {
            bool andOrSense = sense;
            int opIdx;

            switch (binOp.OperatorKind.OperatorWithLogical())
            {
                case BinaryOperatorKind.LogicalOr:
                    Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
                    Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);

                    // Rewrite (a || b) as ~(~a && ~b)
                    andOrSense = !andOrSense;
                    // Fall through
                    goto case BinaryOperatorKind.LogicalAnd;

                case BinaryOperatorKind.LogicalAnd:
                    Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
                    Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);

                    // ~(a && b) is equivalent to (~a || ~b)
                    if (!andOrSense)
                    {
                        // generate (~a || ~b)
                        EmitShortCircuitingOperator(binOp, sense, sense, true);
                    }
                    else
                    {
                        // generate (a && b)
                        EmitShortCircuitingOperator(binOp, sense, !sense, false);
                    }
                    return;

                case BinaryOperatorKind.And:
                    Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
                    Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);
                    EmitBinaryCondOperatorHelper(ILOpCode.And, binOp.Left, binOp.Right, sense);
                    return;

                case BinaryOperatorKind.Or:
                    Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
                    Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);
                    EmitBinaryCondOperatorHelper(ILOpCode.Or, binOp.Left, binOp.Right, sense);
                    return;

                case BinaryOperatorKind.Xor:
                    Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
                    Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);

                    // Xor is equivalent to not equal.
                    if (sense)
                        EmitBinaryCondOperatorHelper(ILOpCode.Xor, binOp.Left, binOp.Right, true);
                    else
                        EmitBinaryCondOperatorHelper(ILOpCode.Ceq, binOp.Left, binOp.Right, true);
                    return;

                case BinaryOperatorKind.NotEqual:
                    // neq  is emitted as  !eq
                    sense = !sense;
                    goto case BinaryOperatorKind.Equal;

                case BinaryOperatorKind.Equal:

                    var constant = binOp.Left.ConstantValue;
                    var comparand = binOp.Right;

                    if (constant == null)
                    {
                        constant = comparand.ConstantValue;
                        comparand = binOp.Left;
                    }

                    if (constant != null)
                    {
                        if (constant.IsDefaultValue)
                        {
                            if (!constant.IsFloating)
                            {
                                if (sense)
                                {
                                    EmitIsNullOrZero(comparand, constant);
                                }
                                else
                                {
                                    //  obj != null/0   for pointers and integral numerics is emitted as cgt.un
                                    EmitIsNotNullOrZero(comparand, constant);
                                }
                                return;
                            }
                        }
                        else if (constant.IsBoolean)
                        {
                            // treat  "x = True" ==> "x"
                            EmitExpression(comparand, true);
                            EmitIsSense(sense);
                            return;
                        }
                    }

//.........这里部分代码省略.........
开发者ID:xier2012,项目名称:roslyn,代码行数:101,代码来源:EmitOperators.cs

示例7: EmitShortCircuitingOperator

        private void EmitShortCircuitingOperator(BoundBinaryOperator condition, bool sense, bool stopSense, bool stopValue)
        {
            // we generate:
            //
            // gotoif (a == stopSense) fallThrough
            // b == sense
            // goto labEnd
            // fallThrough:
            // stopValue
            // labEnd:
            //                 AND       OR
            //            +-  ------    -----
            // stopSense  |   !sense    sense
            // stopValue  |     0         1

            object lazyFallThrough = null;

            EmitCondBranch(condition.Left, ref lazyFallThrough, stopSense);
            EmitCondExpr(condition.Right, sense);

            // if fall-through was not initialized, no-one is going to take that branch
            // and we are done with Right on stack
            if (lazyFallThrough == null)
            {
                return;
            }

            var labEnd = new object();
            _builder.EmitBranch(ILOpCode.Br, labEnd);

            // if we get to fallThrough, we should not have Right on stack. Adjust for that.
            _builder.AdjustStack(-1);

            _builder.MarkLabel(lazyFallThrough);
            _builder.EmitBoolConstant(stopValue);
            _builder.MarkLabel(labEnd);
        }
开发者ID:xier2012,项目名称:roslyn,代码行数:37,代码来源:EmitOperators.cs

示例8: CodeForJump

        /// <summary>
        /// Produces opcode for a jump that corresponds to given operation and sense.
        /// Also produces a reverse opcode - opcode for the same condition with inverted sense.
        /// </summary>
        private static ILOpCode CodeForJump(BoundBinaryOperator op, bool sense, out ILOpCode revOpCode)
        {
            int opIdx;

            switch (op.OperatorKind.Operator())
            {
                case BinaryOperatorKind.Equal:
                    revOpCode = !sense ? ILOpCode.Beq : ILOpCode.Bne_un;
                    return sense ? ILOpCode.Beq : ILOpCode.Bne_un;

                case BinaryOperatorKind.NotEqual:
                    revOpCode = !sense ? ILOpCode.Bne_un : ILOpCode.Beq;
                    return sense ? ILOpCode.Bne_un : ILOpCode.Beq;

                case BinaryOperatorKind.LessThan:
                    opIdx = 0;
                    break;

                case BinaryOperatorKind.LessThanOrEqual:
                    opIdx = 1;
                    break;

                case BinaryOperatorKind.GreaterThan:
                    opIdx = 2;
                    break;

                case BinaryOperatorKind.GreaterThanOrEqual:
                    opIdx = 3;
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(op.OperatorKind.Operator());
            }

            if (IsUnsignedBinaryOperator(op))
            {
                opIdx += 2 * IL_OP_CODE_ROW_LENGTH; //unsigned
            }
            else if (IsFloat(op.OperatorKind))
            {
                opIdx += 4 * IL_OP_CODE_ROW_LENGTH;  //float
            }

            int revOpIdx = opIdx;

            if (!sense)
            {
                opIdx += IL_OP_CODE_ROW_LENGTH; //invert op
            }
            else
            {
                revOpIdx += IL_OP_CODE_ROW_LENGTH; //invert rev
            }

            revOpCode = s_condJumpOpCodes[revOpIdx];
            return s_condJumpOpCodes[opIdx];
        }
开发者ID:jkotas,项目名称:roslyn,代码行数:61,代码来源:EmitStatement.cs

示例9: VisitBinaryOperator

        public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
        {
            BoundExpression child = node.Left;

            if (child.Kind != BoundKind.BinaryOperator || child.ConstantValue != null)
            {
                return base.VisitBinaryOperator(node);
            }

            // Do not blow the stack due to a deep recursion on the left.
            var stack = ArrayBuilder<BoundBinaryOperator>.GetInstance();
            stack.Push(node);

            BoundBinaryOperator binary = (BoundBinaryOperator)child;

            while (true)
            {
                stack.Push(binary);
                child = binary.Left;

                if (child.Kind != BoundKind.BinaryOperator || child.ConstantValue != null)
                {
                    break;
                }

                binary = (BoundBinaryOperator)child;
            }

            var left = (BoundExpression)this.Visit(child);

            while (true)
            {
                binary = stack.Pop();
                var right = (BoundExpression)this.Visit(binary.Right);
                var type = this.VisitType(binary.Type);
                left = binary.Update(binary.OperatorKind, left, right, binary.ConstantValueOpt, binary.MethodOpt, binary.ResultKind, type);

                if (stack.Count == 0)
                {
                    break;
                }

                _nodeCounter += 1;
            }

            Debug.Assert((object)binary == node);
            stack.Free();

            return left;
        }
开发者ID:otawfik-ms,项目名称:roslyn,代码行数:50,代码来源:Optimizer.cs

示例10: EmitBinaryOperator

        private void EmitBinaryOperator(BoundBinaryOperator expression)
        {
            BoundExpression child = expression.Left;

            if (child.Kind != BoundKind.BinaryOperator || child.ConstantValue != null)
            {
                EmitBinaryOperatorSimple(expression);
                return;
            }

            BoundBinaryOperator binary = (BoundBinaryOperator)child;
            var operatorKind = binary.OperatorKind;

            if (!operatorKind.EmitsAsCheckedInstruction() && IsConditional(operatorKind))
            {
                EmitBinaryOperatorSimple(expression);
                return;
            }

            // Do not blow the stack due to a deep recursion on the left.
            var stack = ArrayBuilder<BoundBinaryOperator>.GetInstance();
            stack.Push(expression);

            while (true)
            {
                stack.Push(binary);
                child = binary.Left;

                if (child.Kind != BoundKind.BinaryOperator || child.ConstantValue != null)
                {
                    break;
                }

                binary = (BoundBinaryOperator)child;
                operatorKind = binary.OperatorKind;

                if (!operatorKind.EmitsAsCheckedInstruction() && IsConditional(operatorKind))
                {
                    break;
                }
            }

            EmitExpression(child, true);

            do
            {
                binary = stack.Pop();

                EmitExpression(binary.Right, true);
                bool isChecked = binary.OperatorKind.EmitsAsCheckedInstruction();
                if (isChecked)
                {
                    EmitBinaryCheckedOperatorInstruction(binary);
                }
                else
                {
                    EmitBinaryOperatorInstruction(binary);
                }

                EmitConversionToEnumUnderlyingType(binary, @checked: isChecked);
            }
            while (stack.Count > 0);

            Debug.Assert((object)binary == expression);
            stack.Free();
        }
开发者ID:xier2012,项目名称:roslyn,代码行数:66,代码来源:EmitOperators.cs

示例11: EmitBinaryCheckedOperatorInstruction

        private void EmitBinaryCheckedOperatorInstruction(BoundBinaryOperator expression)
        {
            var unsigned = IsUnsignedBinaryOperator(expression);

            switch (expression.OperatorKind.Operator())
            {
                case BinaryOperatorKind.Multiplication:
                    if (unsigned)
                    {
                        _builder.EmitOpCode(ILOpCode.Mul_ovf_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Mul_ovf);
                    }
                    break;

                case BinaryOperatorKind.Addition:
                    if (unsigned)
                    {
                        _builder.EmitOpCode(ILOpCode.Add_ovf_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Add_ovf);
                    }
                    break;

                case BinaryOperatorKind.Subtraction:
                    if (unsigned)
                    {
                        _builder.EmitOpCode(ILOpCode.Sub_ovf_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Sub_ovf);
                    }
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(expression.OperatorKind.Operator());
            }
        }
开发者ID:xier2012,项目名称:roslyn,代码行数:43,代码来源:EmitOperators.cs

示例12: EmitBinaryArithOperator

        private void EmitBinaryArithOperator(BoundBinaryOperator expression)
        {
            EmitExpression(expression.Left, true);
            EmitExpression(expression.Right, true);

            switch (expression.OperatorKind.Operator())
            {
                case BinaryOperatorKind.Multiplication:
                    _builder.EmitOpCode(ILOpCode.Mul);
                    break;

                case BinaryOperatorKind.Addition:
                    _builder.EmitOpCode(ILOpCode.Add);
                    break;

                case BinaryOperatorKind.Subtraction:
                    _builder.EmitOpCode(ILOpCode.Sub);
                    break;

                case BinaryOperatorKind.Division:
                    if (IsUnsignedBinaryOperator(expression))
                    {
                        _builder.EmitOpCode(ILOpCode.Div_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Div);
                    }
                    break;

                case BinaryOperatorKind.Remainder:
                    if (IsUnsignedBinaryOperator(expression))
                    {
                        _builder.EmitOpCode(ILOpCode.Rem_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Rem);
                    }
                    break;

                case BinaryOperatorKind.LeftShift:
                    _builder.EmitOpCode(ILOpCode.Shl);
                    break;

                case BinaryOperatorKind.RightShift:
                    if (IsUnsignedBinaryOperator(expression))
                    {
                        _builder.EmitOpCode(ILOpCode.Shr_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Shr);
                    }
                    break;

                case BinaryOperatorKind.And:
                    _builder.EmitOpCode(ILOpCode.And);
                    break;

                case BinaryOperatorKind.Xor:
                    _builder.EmitOpCode(ILOpCode.Xor);
                    break;

                case BinaryOperatorKind.Or:
                    _builder.EmitOpCode(ILOpCode.Or);
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(expression.OperatorKind.Operator());
            }

            EmitConversionToEnumUnderlyingType(expression, @checked: false);
        }
开发者ID:noahstein,项目名称:roslyn,代码行数:74,代码来源:EmitOperators.cs

示例13: EmitBinaryCheckedOperatorExpression

        private void EmitBinaryCheckedOperatorExpression(BoundBinaryOperator expression, bool used)
        {
            EmitExpression(expression.Left, true);
            EmitExpression(expression.Right, true);

            var unsigned = IsUnsignedBinaryOperator(expression);

            switch (expression.OperatorKind.Operator())
            {
                case BinaryOperatorKind.Multiplication:
                    if (unsigned)
                    {
                        _builder.EmitOpCode(ILOpCode.Mul_ovf_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Mul_ovf);
                    }
                    break;

                case BinaryOperatorKind.Addition:
                    if (unsigned)
                    {
                        _builder.EmitOpCode(ILOpCode.Add_ovf_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Add_ovf);
                    }
                    break;

                case BinaryOperatorKind.Subtraction:
                    if (unsigned)
                    {
                        _builder.EmitOpCode(ILOpCode.Sub_ovf_un);
                    }
                    else
                    {
                        _builder.EmitOpCode(ILOpCode.Sub_ovf);
                    }
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(expression.OperatorKind.Operator());
            }

            EmitConversionToEnumUnderlyingType(expression, @checked: true);

            EmitPopIfUnused(used);
        }
开发者ID:noahstein,项目名称:roslyn,代码行数:50,代码来源:EmitOperators.cs

示例14: VisitBinaryOperator

        public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
        {
            if (node.ConstantValueOpt != null)
            {
                return node;
            }

            switch (node.OperatorKind)
            {
                case BinaryOperatorKind.ObjectAndStringConcatenation:
                case BinaryOperatorKind.StringAndObjectConcatenation:
                case BinaryOperatorKind.StringConcatenation:
                    return RewriteStringConcatenation(node);
                case BinaryOperatorKind.StringEqual:
                    return RewriteStringEquality(node, SpecialMember.System_String__op_Equality);
                case BinaryOperatorKind.StringNotEqual:
                    return RewriteStringEquality(node, SpecialMember.System_String__op_Inequality);
                case BinaryOperatorKind.DelegateCombination:
                    return RewriteDelegateOperation(node, SpecialMember.System_Delegate__Combine);
                case BinaryOperatorKind.DelegateRemoval:
                    return RewriteDelegateOperation(node, SpecialMember.System_Delegate__Remove);
                case BinaryOperatorKind.DelegateEqual:
                    return RewriteDelegateOperation(node, SpecialMember.System_Delegate__op_Equality);
                case BinaryOperatorKind.DelegateNotEqual:
                    return RewriteDelegateOperation(node, SpecialMember.System_Delegate__op_Inequality);
            }
            return base.VisitBinaryOperator(node);
        }
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:28,代码来源:OperatorRewriter.cs

示例15: VisitCompoundAssignmentOperator


//.........这里部分代码省略.........
                // UNDONE:
                // UNDONE: For now, we'll punt on both problems, as indexers are not implemented yet anyway.
                // UNDONE: We'll just generate one temporary for each argument. This will work, but in the
                // UNDONE: subsequent rewritings will generate more unnecessary temporaries. 

                var transformedArguments = ArrayBuilder<BoundExpression>.GetInstance();
                foreach (var argument in indexer.Arguments)
                {
                    var rewrittenArgument = (BoundExpression)Visit(argument);
                    var argumentTemp = TempHelpers.StoreToTemp(rewrittenArgument, RefKind.None, containingSymbol);
                    transformedArguments.Add(argumentTemp.Item2);
                    stores.Add(argumentTemp.Item1);
                    temps.Add(argumentTemp.Item2.LocalSymbol);
                }

                transformedLHS = new BoundIndexerAccess(indexer.Syntax, indexer.SyntaxTree, transformedArguments.ToReadOnlyAndFree(), transformedReceiver,
                    indexer.IndexerSymbol, indexer.Type);
            }
            else if (node.Left.Kind == BoundKind.Local || node.Left.Kind == BoundKind.Parameter)
            {
                // No temporaries are needed. Just generate local = local + value
                transformedLHS = node.Left;
            }
            else if (node.Left.Kind == BoundKind.FieldAccess)
            {
                // * If the field is static then no temporaries are needed. 
                // * If the field is not static and the receiver is of reference type then generate t = r; t.f = t.f + value
                // * If the field is not static and the receiver is a variable of value type then we'll fall into the
                //   general variable case below.

                var fieldAccess = (BoundFieldAccess)node.Left;
                if (fieldAccess.ReceiverOpt == null)
                {
                    transformedLHS = fieldAccess;
                }
                else if (!fieldAccess.ReceiverOpt.Type.IsValueType)
                {
                    var rewrittenReceiver = (BoundExpression)Visit(fieldAccess.ReceiverOpt);
                    var receiverTemp = TempHelpers.StoreToTemp(rewrittenReceiver, RefKind.None, containingSymbol);
                    stores.Add(receiverTemp.Item1);
                    temps.Add(receiverTemp.Item2.LocalSymbol);
                    transformedLHS = new BoundFieldAccess(fieldAccess.Syntax, fieldAccess.SyntaxTree, receiverTemp.Item2, fieldAccess.FieldSymbol, null);
                }
            }

            if (transformedLHS == null)
            {
                // We made no transformation above. Either we have array[index] += value or 
                // structVariable.field += value; either way we have a potentially complicated variable-
                // producing expression on the left. Generate
                // ref temp = ref variable; temp = temp + value
                var rewrittenVariable = (BoundExpression)Visit(node.Left);
                var variableTemp = TempHelpers.StoreToTemp(rewrittenVariable, RefKind.Ref, containingSymbol);
                stores.Add(variableTemp.Item1);
                temps.Add(variableTemp.Item2.LocalSymbol);
                transformedLHS = variableTemp.Item2;
            }

            // OK, we now have the temporary declarations, the temporary stores, and the transformed left hand side.
            // We need to generate 
            //
            // xlhs = (FINAL)((LEFT)xlhs op rhs)
            //
            // And then wrap it up with the generated temporaries.
            //
            // (The right hand side has already been converted to the type expected by the operator.)

            BoundExpression opLHS = BoundConversion.SynthesizedConversion(transformedLHS, node.LeftConversion, node.Operator.LeftType);
            Debug.Assert(node.Right.Type == node.Operator.RightType);
            BoundExpression op = new BoundBinaryOperator(null, null, node.Operator.Kind, opLHS, node.Right, null, node.Operator.ReturnType);
            BoundExpression opFinal = BoundConversion.SynthesizedConversion(op, node.FinalConversion, node.Left.Type);
            BoundExpression assignment = new BoundAssignmentOperator(null, null, transformedLHS, opFinal, node.Left.Type);

            // OK, at this point we have:
            //
            // * temps evaluating and storing portions of the LHS that must be evaluated only once.
            // * the "transformed" left hand side, rebuilt to use temps where necessary
            // * the assignment "xlhs = (FINAL)((LEFT)xlhs op (RIGHT)rhs)"
            // 
            // Notice that we have recursively rewritten the bound nodes that are things stored in
            // the temps, but we might have more rewriting to do on the assignment. There are three
            // conversions in there that might be lowered to method calls, an operator that might
            // be lowered to delegate combine, string concat, and so on, and don't forget, we 
            // haven't lowered the right hand side at all! Let's rewrite all these things at once.

            BoundExpression rewrittenAssignment = (BoundExpression)Visit(assignment);

            BoundExpression result = (temps.Count == 0) ?
                rewrittenAssignment :
                new BoundSequence(null,
                    null,
                    temps.ToReadOnly(),
                    stores.ToReadOnly(),
                    rewrittenAssignment,
                    rewrittenAssignment.Type);

            temps.Free();
            stores.Free();
            return result;
        }
开发者ID:modulexcite,项目名称:pattern-matching-csharp,代码行数:101,代码来源:OperatorRewriter.cs


注:本文中的BoundBinaryOperator类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。