Exemple #1
0
 protected IEnumerable <Type> GetSubTypes(ExpressionBuilderParameters parameters)
 {
     using (IEnumerator <IExpressionBuilder> children = GetEnumerator())
         while (children.MoveNext())
         {
             yield return(children.Current.GetExpressionStaticType(parameters));
         }
 }
Exemple #2
0
        protected IEnumerable <object> GetConstants(ExpressionBuilderParameters parameters)
        {
            using (IEnumerator <IExpressionBuilder> children = GetEnumerator())
                while (children.MoveNext())
                {
                    object ret = null;

                    Expression exp = children.Current.CreateExpression(parameters, null, null);
                    if ((exp != null) && (exp.NodeType == LinqExpressionType.Constant))
                    {
                        ret = ((ConstantExpression)exp).Value;
                    }

                    yield return(ret);
                }
        }
Exemple #3
0
        public virtual Expression CreateExpression(ExpressionBuilderParameters parameters)
        {
            Expression ret = null;

            List <Type> subTypes = GetSubTypes(parameters).ToList <Type>();
            Type        subtype  = subTypes.FirstOrDefault <Type>(t => t != null);

            subTypes = subTypes.Select <Type, Type>(t => t == null ? subtype : t).ToList <Type>();

            // Custom implementation
            if (parameters.OperatorImplementationProvider != null)
            {
                List <object> paramValues = GetConstants(parameters).ToList <object>();
                string        opname      = GetCustomImplementationName(subTypes, paramValues, parameters);

                Type[]     types  = subTypes.ToArray();
                object[]   values = paramValues.ToArray();
                object     instance;
                MethodInfo method = parameters.OperatorImplementationProvider.GetImplementation(opname, ref types, ref values, out instance);
                if (method != null)
                {
                    Debug.Assert(types.Length == values.Length);
                    using (IEnumerator <IExpressionBuilder> children = GetEnumerator())
                    {
                        IEnumerator             v       = values.GetEnumerator();
                        IEnumerator             t       = types.GetEnumerator();
                        LinkedList <Expression> subexpr = new LinkedList <Expression>();

                        while (v.MoveNext() && t.MoveNext())
                        {
                            children.MoveNext();
                            if (v.Current == null)
                            {
                                subexpr.AddLast(
                                    children.Current.CreateExpression(parameters, (Type)t.Current, (e, p) => CustomCallback(children, subexpr, t, v, e, p, method, instance, parameters))
                                    );
                            }
                            else
                            {
                                subexpr.AddLast(Expression.Constant(v.Current, (Type)t.Current));
                            }
                        }

                        if (subexpr.First != subexpr.Last)
                        {
                            ret = CreateCustomExpression(method, instance, subexpr, parameters, subtype);
                        }
                        else
                        {
                            ret = subexpr.First.Value;
                        }
                    }
                }
            }

            // Standard implementation
            if (ret == null)
            {
                using (IEnumerator <IExpressionBuilder> children = GetEnumerator())
                {
                    LinkedList <Expression> subexpr = new LinkedList <Expression>();

                    while (children.MoveNext())
                    {
                        subexpr.AddLast(
                            children.Current.CreateExpression(parameters, subtype, (e, p) => StandardCallback(children, subexpr, e, p, parameters, subtype))
                            );
                    }

                    if (subexpr.First != subexpr.Last)
                    {
                        ret = CreateStandardExpression(subexpr, parameters, subtype);
                    }
                    else
                    {
                        ret = subexpr.First.Value;
                    }
                }
            }

            return(ret);
        }
Exemple #4
0
        private Expression StandardCallback(IEnumerator <IExpressionBuilder> children, LinkedList <Expression> subexpr, Expression basexp, ParameterExpression pexp, ExpressionBuilderParameters parameters, Type expectedStaticType)
        {
            Expression ret = basexp;

            if (pexp != null)
            {
                Expression sub     = null;
                bool       hasNext = children.MoveNext();
                if (hasNext)
                {
                    sub = children.Current.CreateExpression(parameters, expectedStaticType, (e, p) => StandardCallback(children, subexpr, e, p, parameters, expectedStaticType));
                }
                else
                {
                    sub = subexpr.Last.Value;
                    subexpr.RemoveLast();
                }
                ret = CreateStandardExpression(new Expression[] { ret, sub }, parameters, expectedStaticType);
                if (!hasNext)
                {
                    subexpr.AddLast(ret);
                }
            }

            return(ret);
        }
Exemple #5
0
        private Expression CustomCallback(IEnumerator <IExpressionBuilder> children, LinkedList <Expression> subexpr, IEnumerator types, IEnumerator vals, Expression basexp, ParameterExpression pexp, MethodInfo method, object instance, ExpressionBuilderParameters parameters)
        {
            Expression ret = basexp;

            if (pexp != null)
            {
                Expression sub     = null;
                bool       hasNext = vals.MoveNext() && types.MoveNext();
                if (hasNext)
                {
                    children.MoveNext();
                    if (vals.Current == null)
                    {
                        sub = children.Current.CreateExpression(parameters, (Type)types.Current, (e, p) => CustomCallback(children, subexpr, types, vals, e, p, method, instance, parameters));
                    }
                    else
                    {
                        sub = CustomCallback(children, subexpr, types, vals, Expression.Constant(vals.Current, (Type)types.Current), null, method, instance, parameters);
                    }
                }
                else
                {
                    sub = subexpr.Last.Value;
                    subexpr.RemoveLast();
                }
                ret = CreateCustomExpression(method, instance, new Expression[] { ret, sub }, parameters, (Type)types.Current);
                if (!hasNext)
                {
                    subexpr.AddLast(ret);
                }
            }

            return(ret);
        }
Exemple #6
0
        protected virtual Expression CreateCustomExpression(MethodInfo method, object instance, IEnumerable <Expression> subexpr, ExpressionBuilderParameters parameters, Type subType)
        {
            Expression op = null;

            if (instance != null)
            {
                op = Expression.Call(
                    Expression.Constant(instance),
                    method,
                    subexpr
                    );
            }
            else
            {
                op = Expression.Call(
                    method,
                    subexpr
                    );
            }
            return(op);
        }
Exemple #7
0
 protected abstract string GetCustomImplementationName(List <Type> paramTypes, List <object> paramValues, ExpressionBuilderParameters parameters);
Exemple #8
0
 protected abstract Expression CreateStandardExpression(IEnumerable <Expression> subexpr, ExpressionBuilderParameters parameters, Type subType);