Пример #1
0
            /// <summary>
            /// We only support a sub-class of expressions for now - so we'd better make sure we are protected!
            /// </summary>
            /// <param name="expression"></param>
            /// <returns></returns>
            protected override Expression VisitConditional(ConditionalExpression expression)
            {
                // We can support complex sub-expressions so long as they don't leak out of the
                // comparison.
                if (expression.Type.IsClass &&
                    (
                        CheckForSubQueries.CheckExpression(expression.IfFalse) ||
                        CheckForSubQueries.CheckExpression(expression.IfTrue))
                    )
                {
                    throw new NotSupportedException(string.Format("Complex true/false clauses in a conditional expression are not supported: '{0}'", expression.ToString()));
                }

                // If this is a class as a result, then we can't do much extra processing here. So skip.
                if (expression.Type.IsClass)
                {
                    return(base.VisitConditional(expression));
                }

                // Run the code for the test, and then create the if/then/else that will support it.
                var testExpression           = base.Visit(expression.Test);
                var testExpressionEvaluation = ExpressionToCPP.GetExpression(testExpression, GeneratedCode, CodeContext, MEFContainer);
                var testBoolInCode           = testExpressionEvaluation is DeclarableParameter p ? p : DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool));

                if (testBoolInCode != testExpressionEvaluation)
                {
                    GeneratedCode.Add(testBoolInCode);
                    GeneratedCode.Add(new Statements.StatementAssign(testBoolInCode, testExpressionEvaluation));
                }

                // The result
                var conditionalResult = DeclarableParameter.CreateDeclarableParameterExpression(expression.Type);

                GeneratedCode.Add(conditionalResult);

                // Do the if true statement
                var topScope = GeneratedCode.CurrentScope;

                GeneratedCode.Add(new Statements.StatementFilter(testBoolInCode));
                var iftrueExpression = Visit(expression.IfTrue);

                GeneratedCode.Add(new Statements.StatementAssign(conditionalResult, ExpressionToCPP.GetExpression(iftrueExpression, GeneratedCode, CodeContext, MEFContainer)));
                GeneratedCode.CurrentScope = topScope;

                // Do the if false statement
                GeneratedCode.Add(new Statements.StatementFilter(ExpressionToCPP.GetExpression(Expression.Not(testBoolInCode), GeneratedCode, CodeContext, MEFContainer)));
                var ifFalseExpression = Visit(expression.IfFalse);

                GeneratedCode.Add(new Statements.StatementAssign(conditionalResult, ExpressionToCPP.GetExpression(ifFalseExpression, GeneratedCode, CodeContext, MEFContainer)));
                GeneratedCode.CurrentScope = topScope;

                // Consider this expression now transformed, so return the result, not
                // the conditional expression itself.
                return(conditionalResult);
            }