protected override Expression VisitTry(TryExpression node)
        {
            var res = default(Expression);

            if (node.Finally != null || node.Fault != null)
            {
                var body     = Visit(node.Body);
                var handlers = Visit(node.Handlers, VisitCatchBlock);

                if (node.Finally != null)
                {
                    Debug.Assert(node.Fault == null);


                    if (VisitAndFindAwait(node.Finally, out Expression @finally))
                    {
                        if (handlers.Count != 0)
                        {
                            body = Expression.TryCatch(body, handlers.ToArray());
                        }

                        res = RewriteHandler(body, @finally, isFault: false);
                    }
                    else
                    {
                        res = node.Update(body, handlers, @finally, null);
                    }
                }
                else
                {
                    Debug.Assert(node.Finally == null);


                    if (VisitAndFindAwait(node.Fault, out Expression fault))
                    {
                        Debug.Assert(handlers.Count == 0);

                        res = RewriteHandler(body, fault, isFault: true);
                    }
                    else
                    {
                        res = node.Update(body, handlers, null, fault);
                    }
                }
            }
            else
            {
                res = base.VisitTry(node);
            }

            return(res);
        }
        private static Expression GetCheckedTryCatch(
            TryExpression tryCatchValue,
            Expression keyedAccess,
            Expression checkedAccess,
            ParameterExpression existingValue)
        {
            var existingValueOrDefault = Expression.Condition(
                checkedAccess,
                existingValue,
                existingValue.Type.ToDefaultExpression());

            var replacements = new ExpressionReplacementDictionary(1)
            {
                [keyedAccess] = existingValueOrDefault
            };

            var updatedCatchHandlers = tryCatchValue
                                       .Handlers
                                       .ProjectToArray(handler => handler.Update(
                                                           handler.Variable,
                                                           handler.Filter.Replace(replacements),
                                                           handler.Body.Replace(replacements)));

            var updatedTryCatch = tryCatchValue.Update(
                tryCatchValue.Body,
                updatedCatchHandlers,
                tryCatchValue.Finally,
                tryCatchValue.Fault);

            return(Expression.Block(new[] { existingValue }, updatedTryCatch));
        }
Example #3
0
        private Expression TransformX(TryExpression e)
        {
            var b = Transform(e.Body);
            var c = Transform(e.Handlers, TransformCatchBlock);
            var f = Transform(e.Finally);
            var t = Transform(e.Fault);

            return(e.Update(b, c, f, t));
        }
Example #4
0
 /// <summary>
 /// Visits the children of the <see cref="TryExpression" />.
 /// </summary>
 /// <param name="node">The expression to visit.</param>
 /// <returns>The modified expression, if it or any subexpression was modified;
 /// otherwise, returns the original expression.</returns>
 protected internal virtual Expression VisitTry(TryExpression node)
 {
     return(node.Update(
                Visit(node.Body),
                Visit(node.Handlers, VisitCatchBlock),
                Visit(node.Finally),
                Visit(node.Fault)
                ));
 }
Example #5
0
 /// <summary>
 /// Visits the children of the <see cref="TryExpression"/>.
 /// </summary>
 /// <param name="node">The expression to visit.</param>
 /// <returns>The modified expression, if it or any subexpression was modified;
 /// otherwise, returns the original expression.</returns>
 protected override Expression VisitTry(TryExpression node)
 {
     return(node.Update(
                Visit(node.Body),
                Visit(node.Handlers, VisitCatchBlock),
                Visit(node.Finally),
                Visit(node.Fault)
                ));
 }
        public T?Simplify <T>(T?expression) where T : Expression
        {
            if (expression is null)
            {
                return(null);
            }
            Expression expr = expression.Reduce() switch
            {
                UnaryExpression unaryExpr => unaryExpr.Update(Simplify(unaryExpr.Operand)),
                BinaryExpression binaryExpr => binaryExpr.Update(Simplify(binaryExpr.Left), binaryExpr.Conversion, Simplify(binaryExpr.Right)),
                LambdaExpression lambdaExpr => Expression.Lambda(Simplify(lambdaExpr.Body), lambdaExpr.Name, lambdaExpr.TailCall, Simplify(lambdaExpr.Parameters)),
                TryExpression tryExpr => tryExpr.Update(Simplify(tryExpr.Body), Simplify(tryExpr.Handlers), Simplify(tryExpr.Finally), Simplify(tryExpr.Fault)),
                NewExpression newExpr => newExpr.Update(Simplify(newExpr.Arguments)),
                GotoExpression gotoExpr => gotoExpr.Update(gotoExpr.Target, Simplify(gotoExpr.Value)),
                LoopExpression loopExpr => loopExpr.Update(loopExpr.BreakLabel, loopExpr.ContinueLabel, Simplify(loopExpr.Body)),
                BlockExpression blockExpr => blockExpr.Update(Simplify(blockExpr.Variables), Simplify(blockExpr.Expressions)),
                IndexExpression indexExpr => indexExpr.Update(Simplify(indexExpr.Object) !, Simplify(indexExpr.Arguments)),
                LabelExpression labelExpr => labelExpr.Update(labelExpr.Target, Simplify(labelExpr.DefaultValue)),
                MemberExpression memberExpr => memberExpr.Update(Simplify(memberExpr.Expression)),
                SwitchExpression switchExpr => switchExpr.Update(Simplify(switchExpr.SwitchValue), Simplify(switchExpr.Cases), Simplify(switchExpr.DefaultBody)),
                DynamicExpression dynamicExpr => dynamicExpr.Update(Simplify(dynamicExpr.Arguments)),
                ListInitExpression listInitExpr => listInitExpr.Update(Simplify(listInitExpr.NewExpression), Simplify(listInitExpr.Initializers)),
                NewArrayExpression newArrayExpr => newArrayExpr.Update(Simplify(newArrayExpr.Expressions)),
                InvocationExpression invokeExpr => invokeExpr.Update(Simplify(invokeExpr.Expression), Simplify(invokeExpr.Arguments)),
                MemberInitExpression memberInitExpr => memberInitExpr.Update(Simplify(memberInitExpr.NewExpression), memberInitExpr.Bindings),
                MethodCallExpression methodCallExpr => methodCallExpr.Update(Simplify(methodCallExpr.Object), Simplify(methodCallExpr.Arguments)),
                TypeBinaryExpression typeBinaryExpr => typeBinaryExpr.Update(Simplify(typeBinaryExpr.Expression)),
                ConditionalExpression condExpr => condExpr.Update(Simplify(condExpr.Test), Simplify(condExpr.IfTrue), Simplify(condExpr.IfFalse)),
                RuntimeVariablesExpression runtimeVarExpr => runtimeVarExpr.Update(Simplify(runtimeVarExpr.Variables)),
                _ => expression
            };

            foreach (var transform in transformers)
            {
                expr = transform.Transform(expr, this);
            }

            return((T)expr);
        }
Example #7
0
        public void UpdateTryDiffFaultDiffNode()
        {
            TryExpression tryExp = Expression.TryFault(Expression.Empty(), Expression.Empty());

            Assert.NotSame(tryExp, tryExp.Update(tryExp.Body, tryExp.Handlers, tryExp.Finally, Expression.Empty()));
        }
Example #8
0
        public void UpdateTryDiffFinallyDiffNode()
        {
            TryExpression tryExp = Expression.TryCatchFinally(Expression.Empty(), Expression.Empty(), Expression.Catch(typeof(Exception), Expression.Empty()));

            Assert.NotSame(tryExp, tryExp.Update(tryExp.Body, tryExp.Handlers, Expression.Empty(), null));
        }
Example #9
0
        TryExpression Convert(TryExpression expr)
        {
            var handlers = expr.Handlers.Select(h => h.Update(Process(h.Variable), Process(h.Filter), Process(h.Body)));

            return(expr.Update(Process(expr.Body), handlers, Process(expr.Finally), Process(expr.Fault)));
        }
 protected virtual Expression VisitTry(TryExpression node, Type expectedType)
 => node.Update(Visit(node.Body, expectedType), Visit(node.Handlers, _ => null, VisitCatchBlock), Visit(node.Finally, null), Visit(node.Fault, null));