internal virtual Expression VisitInputReferenceExpression(InputReferenceExpression ire)
        {
            // Debug.Assert(ire != null, "ire != null -- otherwise caller never should have visited here");
            ResourceExpression re = (ResourceExpression)this.Visit(ire.Target);

            return(re.CreateReference());
        }
        internal void OverrideTarget(ResourceSetExpression newTarget)
        {
            Debug.Assert(newTarget != null, "Resource set cannot be null");
            Debug.Assert(newTarget.ResourceType.Equals(this.Type), "Cannot reference a resource set with a different resource type");

            this.target = newTarget;
        }
        private static void AnalyzeResourceExpression(LambdaExpression lambda, ResourceExpression resource)
        {
            PathBox pb = new PathBox();

            ProjectionAnalyzer.Analyze(lambda, pb);
            resource.Projection  = new ProjectionQueryOptionExpression(lambda.Body.Type, lambda, pb.ProjectionPaths.ToList());
            resource.ExpandPaths = pb.ExpandPaths.Union(resource.ExpandPaths, StringComparer.Ordinal).ToList();
        }
Exemple #4
0
        internal void VisitQueryOptions(ResourceExpression re)
        {
            if (re.HasQueryOptions)
            {
                ResourceSetExpression rse = re as ResourceSetExpression;
                if (rse != null)
                {
                    IEnumerator options = rse.SequenceQueryOptions.GetEnumerator();
                    while (options.MoveNext())
                    {
                        Expression             e  = (Expression)options.Current;
                        ResourceExpressionType et = (ResourceExpressionType)e.NodeType;
                        switch (et)
                        {
                        case ResourceExpressionType.RequestOptions:
                            this.VisitQueryOptionExpression((RequestOptionsQueryOptionExpression)e);
                            break;

                        case ResourceExpressionType.OperationContext:
                            this.VisitQueryOptionExpression((OperationContextQueryOptionExpression)e);
                            break;

                        case ResourceExpressionType.Resolver:
                            this.VisitQueryOptionExpression((EntityResolverQueryOptionExpression)e);
                            break;

                        case ResourceExpressionType.TakeQueryOption:
                            this.VisitQueryOptionExpression((TakeQueryOptionExpression)e);
                            break;

                        case ResourceExpressionType.FilterQueryOption:
                            this.VisitQueryOptionExpression((FilterQueryOptionExpression)e);
                            break;

                        default:
                            Debug.Assert(false, "Unexpected expression type " + (int)et);
                            break;
                        }
                    }
                }

                if (re.Projection != null && re.Projection.Paths.Count > 0)
                {
                    this.Projection    = re.Projection;
                    this.SelectColumns = re.Projection.Paths;
                }

                if (re.CustomQueryOptions.Count > 0)
                {
                    this.VisitCustomQueryOptions(re.CustomQueryOptions);
                }
            }
        }
Exemple #5
0
        internal static Expression Bind(Expression e, ResourceExpression currentInput, ParameterExpression inputParameter, List <ResourceExpression> referencedInputs)
        {
            Debug.Assert(e != null, "Expression cannot be null");
            Debug.Assert(currentInput != null, "A current input resource set is required");
            Debug.Assert(inputParameter != null, "The input lambda parameter is required");
            Debug.Assert(referencedInputs != null, "The referenced inputs list is required");

            InputBinder binder = new InputBinder(currentInput, inputParameter);
            Expression  result = binder.Visit(e);

            referencedInputs.AddRange(binder.referencedInputs);
            return(result);
        }
        internal static bool Analyze(LambdaExpression le, ResourceExpression re, bool matchMembers)
        {
            Debug.Assert(le != null, "le != null");

            if (le.Body.NodeType == ExpressionType.Constant)
            {
                if (CommonUtil.IsClientType(le.Body.Type))
                {
                    throw new NotSupportedException(SR.ALinqCannotCreateConstantEntity);
                }

                re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, le, new List <string>());
                return(true);
            }

            if (le.Body.NodeType == ExpressionType.Call)
            {
                MethodCallExpression mce = le.Body as MethodCallExpression;
                if (mce.Method == ReflectionUtil.ProjectMethodInfo.MakeGenericMethod(le.Body.Type))
                {
                    ConstantExpression paths = mce.Arguments[1] as ConstantExpression;

                    re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, ProjectionQueryOptionExpression.DefaultLambda, new List <string>((string[])paths.Value));
                    return(true);
                }
            }

            if (le.Body.NodeType == ExpressionType.MemberInit || le.Body.NodeType == ExpressionType.New)
            {
                AnalyzeResourceExpression(le, re);
                return(true);
            }

            if (matchMembers)
            {
                Expression withoutConverts = SkipConverts(le.Body);
                if (withoutConverts.NodeType == ExpressionType.MemberAccess)
                {
                    AnalyzeResourceExpression(le, re);
                    return(true);
                }
            }

            return(false);
        }
#pragma warning disable 618
        internal InputReferenceExpression(ResourceExpression target)
            : base((ExpressionType)ResourceExpressionType.InputReference, target.ResourceType)
        {
            Debug.Assert(target != null, "Target resource set cannot be null");
            this.target = target;
        }
Exemple #8
0
        internal override Expression VisitMemberAccess(MemberExpression m)
        {
            if (this.inputSet == null ||
                !this.inputSet.HasTransparentScope)
            {
                return(base.VisitMemberAccess(m));
            }

            ParameterExpression  innerParamRef  = null;
            Stack <PropertyInfo> nestedAccesses = new Stack <PropertyInfo>();
            MemberExpression     memberRef      = m;

            while (memberRef != null &&
                   memberRef.Member.MemberType == MemberTypes.Property &&
                   memberRef.Expression != null)
            {
                nestedAccesses.Push((PropertyInfo)memberRef.Member);

                if (memberRef.Expression.NodeType == ExpressionType.Parameter)
                {
                    innerParamRef = (ParameterExpression)memberRef.Expression;
                }

                memberRef = memberRef.Expression as MemberExpression;
            }

            if (innerParamRef != this.inputParameter || nestedAccesses.Count == 0)
            {
                return(m);
            }

            ResourceExpression    target    = this.input;
            ResourceSetExpression targetSet = this.inputSet;
            bool transparentScopeTraversed  = false;

            while (nestedAccesses.Count > 0)
            {
                if (targetSet == null || !targetSet.HasTransparentScope)
                {
                    break;
                }

                PropertyInfo currentProp = nestedAccesses.Peek();

                if (currentProp.Name.Equals(targetSet.TransparentScope.Accessor, StringComparison.Ordinal))
                {
                    target = targetSet;
                    nestedAccesses.Pop();
                    transparentScopeTraversed = true;
                    continue;
                }

                Expression source;
                if (!targetSet.TransparentScope.SourceAccessors.TryGetValue(currentProp.Name, out source))
                {
                    break;
                }

                transparentScopeTraversed = true;
                nestedAccesses.Pop();
                Debug.Assert(source != null, "source != null -- otherwise ResourceBinder created an accessor to nowhere");
                InputReferenceExpression sourceReference = source as InputReferenceExpression;
                if (sourceReference == null)
                {
                    targetSet = source as ResourceSetExpression;
                    if (targetSet == null || !targetSet.HasTransparentScope)
                    {
                        target = (ResourceExpression)source;
                    }
                }
                else
                {
                    targetSet = sourceReference.Target as ResourceSetExpression;
                    target    = targetSet;
                }
            }

            if (!transparentScopeTraversed)
            {
                return(m);
            }

            Expression result = this.CreateReference(target);

            while (nestedAccesses.Count > 0)
            {
                result = Expression.Property(result, nestedAccesses.Pop());
            }

            return(result);
        }
Exemple #9
0
 private InputBinder(ResourceExpression resource, ParameterExpression setReferenceParam)
 {
     this.input          = resource;
     this.inputSet       = resource as ResourceSetExpression;
     this.inputParameter = setReferenceParam;
 }
Exemple #10
0
 private Expression CreateReference(ResourceExpression resource)
 {
     this.referencedInputs.Add(resource);
     return(resource.CreateReference());
 }