Exemple #1
0
        private static void PrepareNestedLambdaTypes(TreeAnalyzer analyzer, Type capturedArgumentType)
        {
            var length = analyzer.NestedLambdas.Length;

            for (var i = 0; i < length; i++)
            {
                var lambda = analyzer.NestedLambdas[i];
                if (capturedArgumentType != null)
                {
                    var type = Utils.MapDelegateType(capturedArgumentType
                                                     .Append(lambda.Key.Parameters.GetTypes())
                                                     .Append(lambda.Key.ReturnType));
                    analyzer.AddStoredItem(lambda.Key, type);
                }
                else
                {
                    analyzer.AddStoredItem(lambda.Key, lambda.Key.Type);
                }
            }
        }
Exemple #2
0
        public bool Analyze(Expression expression, params ParameterExpression[] parameters)
        {
            switch (expression.NodeType)
            {
            case ExpressionType.Parameter:

                if (parameters.ContainsElement(expression) || this.DefinedVariables.ContainsElement(expression))
                {
                    return(true);
                }
                this.AddCapturedParameter((ParameterExpression)expression);
                return(true);

            case ExpressionType.Lambda:
                var lambda = (LambdaExpression)expression;

                var analyzer = new TreeAnalyzer();
                if (!analyzer.Analyze(lambda.Body, lambda.Parameters.CastToArray()))
                {
                    return(false);
                }

                this.AddNestedLambda(new KeyValue <LambdaExpression, Expression[]>(lambda, analyzer.DefinedVariables));

                var length = analyzer.StoredExpressions.Length;
                for (var i = 0; i < length; i++)
                {
                    this.AddStoredItem(analyzer.StoredExpressions[i], analyzer.StoredExpressions[i].Type, analyzer.StoredObjects[i]);
                }

                var lambdaLength = analyzer.NestedLambdas.Length;
                for (var i = 0; i < lambdaLength; i++)
                {
                    this.AddNestedLambda(analyzer.NestedLambdas[i]);
                }

                var capturedLength = analyzer.CapturedParameters.Length;
                for (var i = 0; i < capturedLength; i++)
                {
                    this.AddCapturedParameter(analyzer.CapturedParameters[i]);
                }

                return(true);

            case ExpressionType.MemberAccess:
                return(this.Analyze(((MemberExpression)expression).Expression, parameters));

            case ExpressionType.Constant:
                var constant = (ConstantExpression)expression;
                if (constant.Value == null || IsInPlaceEmittableConstant(constant.Type, constant.Value))
                {
                    return(true);
                }
                this.AddStoredItem(constant, constant.Type, constant.Value);
                return(true);

            case ExpressionType.New:
                return(this.Analyze(((NewExpression)expression).Arguments, parameters));

            case ExpressionType.MemberInit:
                var memberInit = (MemberInitExpression)expression;
                if (!this.Analyze(memberInit.NewExpression, parameters))
                {
                    return(false);
                }

                return(this.Analyze(memberInit.Bindings, parameters));

            case ExpressionType.Block:
                var block = (BlockExpression)expression;
                for (var i = 0; i < block.Variables.Count; i++)
                {
                    this.AddDefinedVariable(block.Variables[i]);
                }

                return(this.Analyze(block.Expressions, parameters));

            case ExpressionType.Conditional:
                var condition = (ConditionalExpression)expression;
                return(this.Analyze(condition.Test, parameters) &&
                       this.Analyze(condition.IfTrue, parameters) &&
                       this.Analyze(condition.IfFalse, parameters));

            case ExpressionType.Default:
                return(true);

            case ExpressionType.Call:
                var call = (MethodCallExpression)expression;
                return((call.Object == null || this.Analyze(call.Object, parameters)) &&
                       this.Analyze(call.Arguments, parameters));

            case ExpressionType.Invoke:
                var invoke = (InvocationExpression)expression;
                return(this.Analyze(invoke.Expression, parameters) &&
                       this.Analyze(invoke.Arguments, parameters));

            case ExpressionType.NewArrayInit:
                return(this.Analyze(((NewArrayExpression)expression).Expressions, parameters));

            default:
                if (expression is UnaryExpression unaryExpression)
                {
                    return(this.Analyze(unaryExpression.Operand, parameters));
                }

                if (expression is BinaryExpression binaryExpression)
                {
                    return(this.Analyze(binaryExpression.Left, parameters) &&
                           this.Analyze(binaryExpression.Right, parameters));
                }

                break;
            }

            return(false);
        }