コード例 #1
0
 public static bool Contains(ParameterExpression param, Expression expr)
 {
     FreeParameters freeParams = new FreeParameters();
     freeParams.Visit(expr);
     return freeParams.Parameters.Contains(param);
 }
コード例 #2
0
        public static LambdaExpression Rewrite(LambdaExpression expr, LambdaExpression selector, Substitution pSubst)
        {
            if (expr != null)
            {
                Type resultType = selector.Body.Type;
                ParameterExpression resultParam = Expression.Parameter(resultType, "key_1");

                // Perform substitutions
                ExpressionSubst subst = new ExpressionSubst(pSubst);
                subst.AddSubst(selector.Body, resultParam);
                if (selector.Body is NewExpression)
                {
                    NewExpression newBody = (NewExpression)selector.Body;
                    if (newBody.Constructor != null)
                    {
                        resultType = newBody.Constructor.DeclaringType;
                    }
                    if (TypeSystem.IsAnonymousType(resultType))
                    {
                        PropertyInfo[] props = resultType.GetProperties();

                        //the following test is never expected to occur, and an assert would most likely suffice.
                        if (props.Length != newBody.Arguments.Count)
                        {
                            throw new DryadLinqException(DryadLinqErrorCode.Internal, SR.BugInHandlingAnonymousClass);
                        }

                        for (int i = 0; i < props.Length; i++)
                        {
                            Expression leftExpr = newBody.Arguments[i];
                            Expression rightExpr = CreateMemberAccess(resultParam, props[i].Name);
                            subst.AddSubst(leftExpr, rightExpr);
                        }
                    }
                }
                if (selector.Body is MemberInitExpression)
                {
                    ReadOnlyCollection<MemberBinding> bindings = ((MemberInitExpression)selector.Body).Bindings;
                    for (int i = 0; i < bindings.Count; i++)
                    {
                        if (bindings[i] is MemberAssignment)
                        {
                            Expression leftExpr = ((MemberAssignment)bindings[i]).Expression;
                            Expression rightExpr = CreateMemberAccess(resultParam, ((MemberAssignment)bindings[i]).Member.Name);
                            subst.AddSubst(leftExpr, rightExpr);
                        }
                    }
                }
                else
                {
                    FieldMappingAttribute[] attribs = AttributeSystem.GetFieldMappingAttribs(selector);
                    if (attribs != null)
                    {
                        foreach (FieldMappingAttribute attrib in attribs)
                        {
                            string[] srcFieldNames = attrib.Source.Split('.');
                            string paramName = srcFieldNames[0];

                            ParameterInfo[] paramInfos = null;
                            if (selector.Body is MethodCallExpression)
                            {
                                paramInfos = ((MethodCallExpression)selector.Body).Method.GetParameters();
                            }
                            else if (selector.Body is NewExpression)
                            {
                                paramInfos = ((NewExpression)selector.Body).Constructor.GetParameters();
                            }

                            if (paramInfos != null)
                            {
                                int argIdx = -1;
                                for (int i = 0; i < paramInfos.Length; i++)
                                {
                                    if (paramInfos[i].Name == paramName)
                                    {
                                        argIdx = i;
                                        break;
                                    }
                                }

                                Expression leftExpr = null;
                                if (argIdx != -1)
                                {
                                    if (selector.Body is MethodCallExpression)
                                    {
                                        leftExpr = ((MethodCallExpression)selector.Body).Arguments[argIdx];
                                    }
                                    else if (selector.Body is NewExpression)
                                    {
                                        leftExpr = ((NewExpression)selector.Body).Arguments[argIdx];
                                    }
                                }
                                if (leftExpr == null)
                                {
                                    throw new DryadLinqException(DryadLinqErrorCode.Internal,
                                                               "The source of the FieldMapping annotation was wrong. " +
                                                               paramName + " is not a formal parameter.");
                                }

                                string[] fieldNames = new string[srcFieldNames.Length - 1];
                                for (int i = 1; i < srcFieldNames.Length; i++)
                                {
                                    fieldNames[i] = srcFieldNames[i-1];
                                }
                                leftExpr = CreateMemberAccess(leftExpr, fieldNames);
                                Expression rightExpr = CreateMemberAccess(resultParam, attrib.Destination.Split('.'));
                                subst.AddSubst(leftExpr, rightExpr);
                            }
                        }
                    }
                }
                Expression resultBody = subst.Visit(expr.Body);

                // Check if the substitutions are complete
                FreeParameters freeParams = new FreeParameters();
                freeParams.Visit(resultBody);
                if (freeParams.Parameters.Count == 1 && freeParams.Parameters.Contains(resultParam))
                {
                    Type funcType = typeof(Func<,>).MakeGenericType(resultType, expr.Body.Type);
                    return Expression.Lambda(funcType, resultBody, resultParam);
                }
            }
            return null;
        }