/// <summary> /// Retargets this input reference to point to the resource set specified by <paramref name="newTarget"/>. /// </summary> /// <param name="newTarget">The <see cref="ResourceSetExpression"/> that this input reference should use as its target</param> 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; }
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; }
/// <summary> /// Analyzes a lambda expression to check whether it can be satisfied with /// $select and client-side materialization. /// </summary> /// <param name="le">Lambda expression.</param> /// <param name="re">Resource expression in scope.</param> /// <param name="matchMembers">Whether member accesses are matched as top-level projections.</param> /// <returns>true if the lambda is a client-side projection; false otherwise.</returns> internal static bool Analyze(LambdaExpression le, ResourceExpression re, bool matchMembers) { Debug.Assert(le != null, "le != null"); if (le.Body.NodeType == ExpressionType.Constant) { if (ClientType.CheckElementTypeIsEntity(le.Body.Type)) { throw new NotSupportedException(Strings.ALinq_CannotCreateConstantEntity); } re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, le, new List<string>()); return true; } if (le.Body.NodeType == ExpressionType.MemberInit || le.Body.NodeType == ExpressionType.New) { AnalyzeResourceExpression(le, re); return true; } if (matchMembers) { // Members can be projected standalone or type-casted. Expression withoutConverts = SkipConverts(le.Body); if (withoutConverts.NodeType == ExpressionType.MemberAccess) { AnalyzeResourceExpression(le, re); return true; } } return false; }
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()); }
/// <summary>Builds the Uri for the expression passed in.</summary> /// <param name="e">The expression to translate into a Uri</param> /// <returns>Query components</returns> internal QueryComponents Translate(Expression e) { Uri uri; Version version; bool addTrailingParens = false; Dictionary <Expression, Expression> normalizerRewrites = null; // short cut analysis if just a resource set // note - to be backwards compatible with V1, will only append trailing () for queries // that include more then just a resource set. if (!(e is ResourceSetExpression)) { normalizerRewrites = new Dictionary <Expression, Expression>(ReferenceEqualityComparer <Expression> .Instance); e = Evaluator.PartialEval(e); e = ExpressionNormalizer.Normalize(e, normalizerRewrites); e = ResourceBinder.Bind(e); addTrailingParens = true; } UriWriter.Translate(this.Context, addTrailingParens, e, out uri, out version); ResourceExpression re = e as ResourceExpression; Type lastSegmentType = re.Projection == null ? re.ResourceType : re.Projection.Selector.Parameters[0].Type; LambdaExpression selector = re.Projection == null ? null : re.Projection.Selector; return(new QueryComponents(uri, version, lastSegmentType, selector, normalizerRewrites)); }
internal static Expression Bind(Expression e, ResourceExpression currentInput, ParameterExpression inputParameter, List<ResourceExpression> referencedInputs) { InputBinder binder = new InputBinder(currentInput, inputParameter); Expression expression = binder.Visit(e); referencedInputs.AddRange(binder.referencedInputs); return expression; }
internal static bool Analyze(LambdaExpression le, ResourceExpression re, bool matchMembers) { Debug.Assert(le != null, "le != null"); if (le.Body.NodeType == ExpressionType.Constant) { if (ClientType.CheckElementTypeIsEntity(le.Body.Type)) { throw new NotSupportedException(Strings.ALinq_CannotCreateConstantEntity); } re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, le, new List <string>()); 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); }
internal static Expression Bind(Expression e, ResourceExpression currentInput, ParameterExpression inputParameter, List <ResourceExpression> referencedInputs) { InputBinder binder = new InputBinder(currentInput, inputParameter); Expression expression = binder.Visit(e); referencedInputs.AddRange(binder.referencedInputs); return(expression); }
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(); }
private static void AnalyzeResourceExpression(LambdaExpression lambda, ResourceExpression resource, DataServiceContext context) { PathBox pb = new PathBox(); Analyze(lambda, pb, context); resource.Projection = new ProjectionQueryOptionExpression(lambda.Body.Type, lambda, pb.ProjectionPaths.ToList<string>()); resource.ExpandPaths = pb.ExpandPaths.Union<string>(resource.ExpandPaths, StringComparer.Ordinal).ToList<string>(); resource.RaiseUriVersion(pb.UriVersion); }
private static void AnalyzeResourceExpression(LambdaExpression lambda, ResourceExpression resource, DataServiceContext context) { PathBox pb = new PathBox(); Analyze(lambda, pb, context); resource.Projection = new ProjectionQueryOptionExpression(lambda.Body.Type, lambda, pb.ProjectionPaths.ToList <string>()); resource.ExpandPaths = pb.ExpandPaths.Union <string>(resource.ExpandPaths, StringComparer.Ordinal).ToList <string>(); resource.RaiseUriVersion(pb.UriVersion); }
internal static LambdaExpression TryToRewrite(LambdaExpression le, ResourceExpression source) { Type proposedParameterType = source.ResourceType; if ((!ResourceBinder.PatternRules.MatchSingleArgumentLambda(le, out le) || ClientTypeUtil.TypeOrElementTypeIsEntity(le.Parameters[0].Type)) || !le.Parameters[0].Type.GetProperties().Any<PropertyInfo>(p => (p.PropertyType == proposedParameterType))) { return le; } ProjectionRewriter rewriter = new ProjectionRewriter(proposedParameterType); return rewriter.Rebind(le, source); }
internal static LambdaExpression TryToRewrite(LambdaExpression le, ResourceExpression source) { Type proposedParameterType = source.ResourceType; if ((!ResourceBinder.PatternRules.MatchSingleArgumentLambda(le, out le) || ClientTypeUtil.TypeOrElementTypeIsEntity(le.Parameters[0].Type)) || !le.Parameters[0].Type.GetProperties().Any <PropertyInfo>(p => (p.PropertyType == proposedParameterType))) { return(le); } ProjectionRewriter rewriter = new ProjectionRewriter(proposedParameterType); return(rewriter.Rebind(le, source)); }
internal LambdaExpression Rebind(LambdaExpression lambda, ResourceExpression source) { this.successfulRebind = true; this.oldLambdaParameter = lambda.Parameters[0]; this.projectionSource = source; Expression body = this.Visit(lambda.Body); if (!this.successfulRebind) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_CanOnlyProjectTheLeaf); } return Expression.Lambda(typeof(Func<,>).MakeGenericType(new Type[] { this.newLambdaParameter.Type, lambda.Body.Type }), body, new ParameterExpression[] { this.newLambdaParameter }); }
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 LambdaExpression Rebind(LambdaExpression lambda, ResourceExpression source) { this.successfulRebind = true; this.oldLambdaParameter = lambda.Parameters[0]; this.projectionSource = source; Expression body = this.Visit(lambda.Body); if (!this.successfulRebind) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_CanOnlyProjectTheLeaf); } return(Expression.Lambda(typeof(Func <,>).MakeGenericType(new Type[] { this.newLambdaParameter.Type, lambda.Body.Type }), body, new ParameterExpression[] { this.newLambdaParameter })); }
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 LambdaExpression TryToRewrite(LambdaExpression le, ResourceExpression source) { Type proposedParameterType = source.ResourceType; LambdaExpression result; if (!ResourceBinder.PatternRules.MatchSingleArgumentLambda(le, out le) || // can only rewrite single parameter Lambdas. ClientTypeUtil.TypeOrElementTypeIsEntity(le.Parameters[0].Type) || // only attempt to rewrite if lambda parameter is not an entity type !(le.Parameters[0].Type.GetProperties().Any(p => p.PropertyType == proposedParameterType))) // lambda parameter must have public property that is same as proposed type. { result = le; } else { ProjectionRewriter rewriter = new ProjectionRewriter(proposedParameterType); result = rewriter.Rebind(le, source); } return(result); }
internal QueryComponents Translate(Expression e) { Uri uri; Version version; bool addTrailingParens = false; Dictionary <Expression, Expression> rewrites = null; if (!(e is ResourceSetExpression)) { rewrites = new Dictionary <Expression, Expression>(ReferenceEqualityComparer <Expression> .Instance); e = Evaluator.PartialEval(e); e = ExpressionNormalizer.Normalize(e, rewrites); e = ResourceBinder.Bind(e, this.Context); addTrailingParens = true; } UriWriter.Translate(this.Context, addTrailingParens, e, out uri, out version); ResourceExpression expression = e as ResourceExpression; Type lastSegmentType = (expression.Projection == null) ? expression.ResourceType : expression.Projection.Selector.Parameters[0].Type; return(new QueryComponents(uri, version, lastSegmentType, (expression.Projection == null) ? null : expression.Projection.Selector, rewrites)); }
internal LambdaExpression Rebind(LambdaExpression lambda, ResourceExpression source) { this.successfulRebind = true; this.oldLambdaParameter = lambda.Parameters[0]; this.projectionSource = source; Expression body = this.Visit(lambda.Body); if (this.successfulRebind) { Type delegateType = typeof(Func <,>).MakeGenericType(new Type[] { newLambdaParameter.Type, lambda.Body.Type }); #if ASTORIA_LIGHT return(ExpressionHelpers.CreateLambda(delegateType, body, new ParameterExpression[] { this.newLambdaParameter })); #else return(Expression.Lambda(delegateType, body, new ParameterExpression[] { this.newLambdaParameter })); #endif } else { throw new NotSupportedException(Strings.ALinq_CanOnlyProjectTheLeaf); } }
internal static bool Analyze(LambdaExpression le, ResourceExpression re, bool matchMembers, DataServiceContext context) { if (le.Body.NodeType == ExpressionType.Constant) { if (ClientTypeUtil.TypeOrElementTypeIsEntity(le.Body.Type)) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_CannotCreateConstantEntity); } re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, le, new List<string>()); return true; } if ((le.Body.NodeType == ExpressionType.MemberInit) || (le.Body.NodeType == ExpressionType.New)) { AnalyzeResourceExpression(le, re, context); return true; } if (matchMembers && (SkipConverts(le.Body).NodeType == ExpressionType.MemberAccess)) { AnalyzeResourceExpression(le, re, context); return true; } return false; }
internal static bool Analyze(LambdaExpression le, ResourceExpression re, bool matchMembers, DataServiceContext context) { if (le.Body.NodeType == ExpressionType.Constant) { if (ClientTypeUtil.TypeOrElementTypeIsEntity(le.Body.Type)) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_CannotCreateConstantEntity); } re.Projection = new ProjectionQueryOptionExpression(le.Body.Type, le, new List <string>()); return(true); } if ((le.Body.NodeType == ExpressionType.MemberInit) || (le.Body.NodeType == ExpressionType.New)) { AnalyzeResourceExpression(le, re, context); return(true); } if (matchMembers && (SkipConverts(le.Body).NodeType == ExpressionType.MemberAccess)) { AnalyzeResourceExpression(le, re, context); return(true); } return(false); }
/// <summary> /// Constructs a new input reference expression that refers to the specified resource set /// </summary> /// <param name="target">The target resource set that the new expression will reference</param> internal InputReferenceExpression(ResourceExpression target) { Debug.Assert(target != null, "Target resource set cannot be null"); this.target = target; }
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); }
internal virtual Expression VisitInputReferenceExpression(InputReferenceExpression ire) { ResourceExpression expression = (ResourceExpression)this.Visit(ire.Target); return(expression.CreateReference()); }
private InputBinder(ResourceExpression resource, ParameterExpression setReferenceParam) { this.input = resource; this.inputSet = resource as ResourceSetExpression; this.inputParameter = setReferenceParam; }
private Expression CreateReference(ResourceExpression resource) { this.referencedInputs.Add(resource); return(resource.CreateReference()); }
internal InputReferenceExpression(ResourceExpression target) { this.target = target; }
/// <summary> /// Constructs a new input reference expression that refers to the specified resource set /// </summary> /// <param name="target">The target resource set that the new expression will reference</param> internal InputReferenceExpression(ResourceExpression target) : base((ExpressionType)ResourceExpressionType.InputReference, target.ResourceType) { Debug.Assert(target != null, "Target resource set cannot be null"); this.target = target; }
/// <summary> /// Analyzes the specified <paramref name="lambda"/> for selection and updates /// <paramref name="resource"/>. /// </summary> /// <param name="lambda">Lambda expression to analyze.</param> /// <param name="resource">Resource expression to update.</param> 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(); }
internal override Expression VisitMemberAccess(MemberExpression m) { if ((this.inputSet == null) || !this.inputSet.HasTransparentScope) { return base.VisitMemberAccess(m); } ParameterExpression expression = null; Stack<PropertyInfo> stack = new Stack<PropertyInfo>(); for (MemberExpression expression2 = m; ((expression2 != null) && PlatformHelper.IsProperty(expression2.Member)) && (expression2.Expression != null); expression2 = expression2.Expression as MemberExpression) { stack.Push((PropertyInfo) expression2.Member); if (expression2.Expression.NodeType == ExpressionType.Parameter) { expression = (ParameterExpression) expression2.Expression; } } if ((expression != this.inputParameter) || (stack.Count == 0)) { return m; } ResourceExpression input = this.input; ResourceSetExpression inputSet = this.inputSet; bool flag = false; while (stack.Count > 0) { if ((inputSet == null) || !inputSet.HasTransparentScope) { break; } PropertyInfo info = stack.Peek(); if (info.Name.Equals(inputSet.TransparentScope.Accessor, StringComparison.Ordinal)) { input = inputSet; stack.Pop(); flag = true; } else { Expression expression5; if (!inputSet.TransparentScope.SourceAccessors.TryGetValue(info.Name, out expression5)) { break; } flag = true; stack.Pop(); InputReferenceExpression expression6 = expression5 as InputReferenceExpression; if (expression6 == null) { inputSet = expression5 as ResourceSetExpression; if ((inputSet == null) || !inputSet.HasTransparentScope) { input = (ResourceExpression) expression5; } continue; } inputSet = expression6.Target as ResourceSetExpression; input = inputSet; } } if (!flag) { return m; } Expression expression7 = this.CreateReference(input); while (stack.Count > 0) { expression7 = Expression.Property(expression7, stack.Pop()); } return expression7; }
internal void VisitQueryOptions(ResourceExpression re) { bool flag = false; if (re.HasQueryOptions) { this.uriBuilder.Append('?'); ResourceSetExpression expression = re as ResourceSetExpression; if (expression != null) { IEnumerator enumerator = expression.SequenceQueryOptions.GetEnumerator(); while (enumerator.MoveNext()) { if (flag) { this.uriBuilder.Append('&'); } Expression current = (Expression)enumerator.Current; switch (current.NodeType) { case ((ExpressionType)0x2713): this.VisitQueryOptionExpression((TakeQueryOptionExpression)current); break; case ((ExpressionType)0x2714): this.VisitQueryOptionExpression((SkipQueryOptionExpression)current); break; case ((ExpressionType)0x2715): this.VisitQueryOptionExpression((OrderByQueryOptionExpression)current); break; case ((ExpressionType)0x2716): this.VisitQueryOptionExpression((FilterQueryOptionExpression)current); break; } flag = true; } } if (re.ExpandPaths.Count > 0) { if (flag) { this.uriBuilder.Append('&'); } this.VisitExpandOptions(re.ExpandPaths); flag = true; } if ((re.Projection != null) && (re.Projection.Paths.Count > 0)) { if (flag) { this.uriBuilder.Append('&'); } this.VisitProjectionPaths(re.Projection.Paths); flag = true; } if (re.CountOption == CountOption.InlineAll) { if (flag) { this.uriBuilder.Append('&'); } this.VisitCountOptions(); flag = true; } if (re.CustomQueryOptions.Count > 0) { if (flag) { this.uriBuilder.Append('&'); } this.VisitCustomQueryOptions(re.CustomQueryOptions); flag = true; } } }
/// <summary> /// Resolves member accesses that represent transparent scope property accesses to the corresponding resource set, /// iff the input resource set is enclosed in a transparent scope and the specified MemberExpression represents /// such a property access. /// </summary> /// <param name="m">MemberExpression expression to visit</param> /// <returns> /// An InputReferenceExpression if the member access represents a transparent scope property /// access that can be resolved to a resource set in the path that produces the input resource set; /// otherwise the same MemberExpression is returned. /// </returns> internal override Expression VisitMemberAccess(MemberExpression m) { // If the current input resource set is not enclosed in a transparent scope, then this // MemberExpression cannot represent a valid transparent scope access based on the input parameter. 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 && PlatformHelper.IsProperty(memberRef.Member) && memberRef.Expression != null) { nestedAccesses.Push((PropertyInfo)memberRef.Member); if (memberRef.Expression.NodeType == ExpressionType.Parameter) { innerParamRef = (ParameterExpression)memberRef.Expression; } memberRef = memberRef.Expression as MemberExpression; } // Only continue if the inner non-MemberExpression is the input reference ParameterExpression and // at least one property reference is present - otherwise this cannot be a transparent scope access. if (innerParamRef != this.inputParameter || nestedAccesses.Count == 0) { return(m); } ResourceExpression target = this.input; ResourceSetExpression targetSet = this.inputSet; bool transparentScopeTraversed = false; // Process all the traversals through transparent scopes. while (nestedAccesses.Count > 0) { if (targetSet == null || !targetSet.HasTransparentScope) { break; } // Peek the property; pop it once it's consumed // (it could be a non-transparent-identifier access). PropertyInfo currentProp = nestedAccesses.Peek(); // If this is the accessor for the target, then the member // refers to the target itself. if (currentProp.Name.Equals(targetSet.TransparentScope.Accessor, StringComparison.Ordinal)) { target = targetSet; nestedAccesses.Pop(); transparentScopeTraversed = true; continue; } // This member could also be one of the in-scope sources of the target. 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 no traversals were made, the original expression is OK. if (!transparentScopeTraversed) { return(m); } // Process traversals after the transparent scope. Expression result = this.CreateReference(target); while (nestedAccesses.Count > 0) { result = Expression.Property(result, nestedAccesses.Pop()); } return(result); }
internal void OverrideTarget(ResourceSetExpression newTarget) { this.target = newTarget; }
internal void VisitQueryOptions(ResourceExpression re) { bool needAmpersand = false; if (re.HasQueryOptions) { this.uriBuilder.Append(UriHelper.QUESTIONMARK); ResourceSetExpression rse = re as ResourceSetExpression; if (rse != null) { IEnumerator options = rse.SequenceQueryOptions.GetEnumerator(); while (options.MoveNext()) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } Expression e = ((Expression)options.Current); ResourceExpressionType et = (ResourceExpressionType)e.NodeType; switch (et) { case ResourceExpressionType.SkipQueryOption: this.VisitQueryOptionExpression((SkipQueryOptionExpression)e); break; case ResourceExpressionType.TakeQueryOption: this.VisitQueryOptionExpression((TakeQueryOptionExpression)e); break; case ResourceExpressionType.OrderByQueryOption: this.VisitQueryOptionExpression((OrderByQueryOptionExpression)e); break; case ResourceExpressionType.FilterQueryOption: this.VisitQueryOptionExpression((FilterQueryOptionExpression)e); break; default: Debug.Assert(false, "Unexpected expression type " + (int)et); break; } needAmpersand = true; } } if (re.ExpandPaths.Count > 0) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } this.VisitExpandOptions(re.ExpandPaths); needAmpersand = true; } if (re.Projection != null && re.Projection.Paths.Count > 0) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } this.VisitProjectionPaths(re.Projection.Paths); needAmpersand = true; } if (re.CountOption == CountOption.InlineAll) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } this.VisitCountOptions(); needAmpersand = true; } if (re.CustomQueryOptions.Count > 0) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } this.VisitCustomQueryOptions(re.CustomQueryOptions); needAmpersand = true; } } }
private Expression CreateReference(ResourceExpression resource) { this.referencedInputs.Add(resource); return resource.CreateReference(); }
internal override Expression VisitMemberAccess(MemberExpression m) { if ((this.inputSet == null) || !this.inputSet.HasTransparentScope) { return(base.VisitMemberAccess(m)); } ParameterExpression expression = null; Stack <PropertyInfo> stack = new Stack <PropertyInfo>(); for (MemberExpression expression2 = m; ((expression2 != null) && PlatformHelper.IsProperty(expression2.Member)) && (expression2.Expression != null); expression2 = expression2.Expression as MemberExpression) { stack.Push((PropertyInfo)expression2.Member); if (expression2.Expression.NodeType == ExpressionType.Parameter) { expression = (ParameterExpression)expression2.Expression; } } if ((expression != this.inputParameter) || (stack.Count == 0)) { return(m); } ResourceExpression input = this.input; ResourceSetExpression inputSet = this.inputSet; bool flag = false; while (stack.Count > 0) { if ((inputSet == null) || !inputSet.HasTransparentScope) { break; } PropertyInfo info = stack.Peek(); if (info.Name.Equals(inputSet.TransparentScope.Accessor, StringComparison.Ordinal)) { input = inputSet; stack.Pop(); flag = true; } else { Expression expression5; if (!inputSet.TransparentScope.SourceAccessors.TryGetValue(info.Name, out expression5)) { break; } flag = true; stack.Pop(); InputReferenceExpression expression6 = expression5 as InputReferenceExpression; if (expression6 == null) { inputSet = expression5 as ResourceSetExpression; if ((inputSet == null) || !inputSet.HasTransparentScope) { input = (ResourceExpression)expression5; } continue; } inputSet = expression6.Target as ResourceSetExpression; input = inputSet; } } if (!flag) { return(m); } Expression expression7 = this.CreateReference(input); while (stack.Count > 0) { expression7 = Expression.Property(expression7, stack.Pop()); } return(expression7); }
#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; }
internal void VisitQueryOptions(ResourceExpression re) { bool flag = false; if (re.HasQueryOptions) { this.uriBuilder.Append('?'); ResourceSetExpression expression = re as ResourceSetExpression; if (expression != null) { IEnumerator enumerator = expression.SequenceQueryOptions.GetEnumerator(); while (enumerator.MoveNext()) { if (flag) { this.uriBuilder.Append('&'); } Expression current = (Expression) enumerator.Current; switch (current.NodeType) { case ((ExpressionType) 0x2713): this.VisitQueryOptionExpression((TakeQueryOptionExpression) current); break; case ((ExpressionType) 0x2714): this.VisitQueryOptionExpression((SkipQueryOptionExpression) current); break; case ((ExpressionType) 0x2715): this.VisitQueryOptionExpression((OrderByQueryOptionExpression) current); break; case ((ExpressionType) 0x2716): this.VisitQueryOptionExpression((FilterQueryOptionExpression) current); break; } flag = true; } } if (re.ExpandPaths.Count > 0) { if (flag) { this.uriBuilder.Append('&'); } this.VisitExpandOptions(re.ExpandPaths); flag = true; } if ((re.Projection != null) && (re.Projection.Paths.Count > 0)) { if (flag) { this.uriBuilder.Append('&'); } this.VisitProjectionPaths(re.Projection.Paths); flag = true; } if (re.CountOption == CountOption.InlineAll) { if (flag) { this.uriBuilder.Append('&'); } this.VisitCountOptions(); flag = true; } if (re.CustomQueryOptions.Count > 0) { if (flag) { this.uriBuilder.Append('&'); } this.VisitCustomQueryOptions(re.CustomQueryOptions); flag = true; } } }