コード例 #1
0
        public override BoundNode VisitConditionalOperator(BoundConditionalOperator node)
        {
            BoundSpillSequenceBuilder conditionBuilder = null;
            var condition = VisitExpression(ref conditionBuilder, node.Condition);

            BoundSpillSequenceBuilder consequenceBuilder = null;
            var consequence = VisitExpression(ref consequenceBuilder, node.Consequence);

            BoundSpillSequenceBuilder alternativeBuilder = null;
            var alternative = VisitExpression(ref alternativeBuilder, node.Alternative);

            if (consequenceBuilder == null && alternativeBuilder == null)
            {
                return(UpdateExpression(conditionBuilder, node.Update(node.IsRef, condition, consequence, alternative, node.ConstantValueOpt, node.Type)));
            }

            if (conditionBuilder == null)
            {
                conditionBuilder = new BoundSpillSequenceBuilder();
            }
            if (consequenceBuilder == null)
            {
                consequenceBuilder = new BoundSpillSequenceBuilder();
            }
            if (alternativeBuilder == null)
            {
                alternativeBuilder = new BoundSpillSequenceBuilder();
            }

            if (node.Type.SpecialType == SpecialType.System_Void)
            {
                conditionBuilder.AddStatement(
                    _F.If(condition,
                          UpdateStatement(consequenceBuilder, _F.ExpressionStatement(consequence)),
                          UpdateStatement(alternativeBuilder, _F.ExpressionStatement(alternative))));

                return(conditionBuilder.Update(_F.Default(node.Type)));
            }
            else
            {
                var tmp = _F.SynthesizedLocal(node.Type, kind: SynthesizedLocalKind.Spill, syntax: _F.Syntax);

                conditionBuilder.AddLocal(tmp);
                conditionBuilder.AddStatement(
                    _F.If(condition,
                          UpdateStatement(consequenceBuilder, _F.Assignment(_F.Local(tmp), consequence)),
                          UpdateStatement(alternativeBuilder, _F.Assignment(_F.Local(tmp), alternative))));

                return(conditionBuilder.Update(_F.Local(tmp)));
            }
        }
コード例 #2
0
        /// <summary>
        /// If the condition has a constant value, then just use the selected branch.
        /// e.g. "true ? x : y" becomes "x".
        /// </summary>
        public override BoundNode VisitConditionalOperator(BoundConditionalOperator node)
        {
            // just a fact, not a requirement (VisitExpression would have rewritten otherwise)
            Debug.Assert(node.ConstantValue == null);

            var rewrittenCondition   = VisitExpression(node.Condition);
            var rewrittenConsequence = VisitExpression(node.Consequence);
            var rewrittenAlternative = VisitExpression(node.Alternative);

            if (rewrittenCondition.ConstantValue == null)
            {
                return(node.Update(node.IsRef, rewrittenCondition, rewrittenConsequence, rewrittenAlternative, node.ConstantValueOpt, node.Type));
            }

            return(RewriteConditionalOperator(
                       node.Syntax,
                       rewrittenCondition,
                       rewrittenConsequence,
                       rewrittenAlternative,
                       node.ConstantValueOpt,
                       node.Type,
                       node.IsRef));
        }