/// <summary>Visits a method call.</summary> /// <param name="m">The method call to visit.</param> /// <returns>The visited expression.</returns> internal override Expression VisitMethodCall(MethodCallExpression m) { // Select - we should mark it with ResourceType of the return type of the Func var selectMatch = ExpressionUtil.MatchSelectCall(m); if (selectMatch != null) { Expression result = base.VisitMethodCall(m); selectMatch = ExpressionUtil.MatchSelectCall(result); if (selectMatch != null) { return(this.annotations.PropagateResourceType(selectMatch.LambdaBody, result)); } } // SelectMany - we should mark it with ResourceType of the return type of the Func var selectManyMatch = ExpressionUtil.MatchSelectManyCall(m); if (selectManyMatch != null) { Expression result = base.VisitMethodCall(m); selectManyMatch = ExpressionUtil.MatchSelectManyCall(result); if (selectManyMatch != null) { return(this.annotations.PropagateResourceType(selectManyMatch.LambdaBody, result)); } } // Where - simply propagate the resource type of the source as it doesn't change the results (just filters them) var whereMatch = ExpressionUtil.MatchWhereCall(m); if (whereMatch != null) { Expression result = base.VisitMethodCall(m); whereMatch = ExpressionUtil.MatchWhereCall(result); if (whereMatch != null) { return(this.annotations.PropagateResourceType(whereMatch.Source, result)); } } // OrderBy/ThenBy - simply propagate the resource type of the source as it doesn't change the results (just sorts them) var orderByMatch = ExpressionUtil.MatchOrderByCall(m) ?? ExpressionUtil.MatchThenByCall(m); if (orderByMatch != null) { Expression result = base.VisitMethodCall(m); orderByMatch = ExpressionUtil.MatchOrderByCall(result) ?? ExpressionUtil.MatchThenByCall(result); if (orderByMatch != null) { return(this.annotations.PropagateResourceType(orderByMatch.Source, result)); } } return(base.VisitMethodCall(m)); }
/// <summary> /// Visits the method call. /// </summary> /// <param name="m">The m.</param> /// <returns></returns> internal override Expression VisitMethodCall(MethodCallExpression m) { var whereMatch = ExpressionUtil.MatchWhereCall(m); if (whereMatch != null) { Expression source = this.Visit(whereMatch.Source); LambdaExpression lambda = Expression.Lambda( OptimizeFilterNullableBooleanToCondition(this.Visit(whereMatch.LambdaBody)), whereMatch.Lambda.Parameters.ToArray()); return(Expression.Call( whereMatch.MethodCall.Method, source, lambda)); } return(VisitMethodCallSkipProjections(m)); }
/// <summary>Visits a method call.</summary> /// <param name="m">The method call to visit.</param> /// <returns>The visited expression.</returns> internal override Expression VisitMethodCall(MethodCallExpression m) { if (m.Method == GetValueMethodInfo) { ResourceProperty property = (ResourceProperty)((ConstantExpression)m.Arguments[1]).Value; return(this.Annotations.AnnotateResourceProperty( Expression.Property(this.Visit(m.Arguments[0]), property.Name), property)); } if (m.Method.IsGenericMethod && m.Method.GetGenericMethodDefinition() == GetSequenceValueMethodInfo) { ResourceProperty property = (ResourceProperty)((ConstantExpression)m.Arguments[1]).Value; return(this.Annotations.AnnotateResourceProperty( Expression.Property(this.Visit(m.Arguments[0]), property.Name), property)); } if (m.Method == ConvertMethodInfo) { ResourceType type = (ResourceType)((ConstantExpression)m.Arguments[1]).Value; return(this.Annotations.AnnotateResourceType( Expression.Convert(this.Visit(m.Arguments[0]), type.InstanceType), type)); } if (m.Method == TypeIsMethodInfo) { ResourceType type = (ResourceType)((ConstantExpression)m.Arguments[1]).Value; return(Expression.TypeIs( this.Visit(m.Arguments[0]), type.InstanceType)); } var selectMatch = ExpressionUtil.MatchSelectCall(m); if (selectMatch != null) { // Annotate the source first Expression source = this.Visit(selectMatch.Source); // Annotate the lambda parameter with the source type this.Annotations.PropagateResourceType( source, selectMatch.Lambda.Parameters[0]); // Now annotate the lambda LambdaExpression lambda = (LambdaExpression)this.Visit(selectMatch.Lambda); Expression body = lambda.Body; return(this.Annotations.PropagateResourceType( body, Expression.Call(selectMatch.MethodCall.Method, source, lambda))); } var selectManyMatch = ExpressionUtil.MatchSelectManyCall(m); if (selectManyMatch != null) { // Annotate the lambda parameter with the source type this.Annotations.PropagateResourceType( selectManyMatch.Source, selectManyMatch.Lambda.Parameters[0]); return(base.VisitMethodCall(m)); } var whereMatch = ExpressionUtil.MatchWhereCall(m); if (whereMatch != null) { // Annotate the lambda parameter with the source type this.Annotations.PropagateResourceType( whereMatch.Source, whereMatch.Lambda.Parameters[0]); return(base.VisitMethodCall(m)); } var orderByMatch = ExpressionUtil.MatchOrderByCall(m) ?? ExpressionUtil.MatchThenByCall(m); if (orderByMatch != null) { // Annotate the lambda parameter with the source type this.Annotations.PropagateResourceType( orderByMatch.Source, orderByMatch.Lambda.Parameters[0]); return(base.VisitMethodCall(m)); } return(base.VisitMethodCall(m)); }