private TResult EvaluateLambda <TResult>(LinqLambdaExpression lambda, params QueryValue[] currentParameterValues) where TResult : QueryValue { ExceptionUtilities.Assert(lambda.Parameters.Count == currentParameterValues.Length, "LambdaExpression parameter count must match length of currentParameterValues"); for (int i = 0; i < lambda.Parameters.Count; i++) { LinqParameterExpression lambdaParameter = lambda.Parameters[i]; ExceptionUtilities.Assert(!this.lambdaParameterAssignments.ContainsKey(lambdaParameter), "Attempt to recursively evaluate lambda."); this.lambdaParameterAssignments[lambdaParameter] = currentParameterValues[i]; } try { return((TResult)this.Evaluate(lambda.Body)); } finally { foreach (var p in lambda.Parameters) { this.lambdaParameterAssignments.Remove(p); } } }
/// <summary> /// Initializes a new instance of the ParameterReplacingVisitor class /// </summary> /// <param name="oldParameter">The parameter to replace</param> /// <param name="newParameter">The parameter to use as a replacement</param> public ParameterReplacingVisitor(LinqParameterExpression oldParameter, LinqParameterExpression newParameter) { ExceptionUtilities.CheckArgumentNotNull(oldParameter, "oldParameter"); ExceptionUtilities.CheckArgumentNotNull(newParameter, "newParameter"); this.oldParameter = oldParameter; this.newParameter = newParameter; }
/// <summary> /// Helper method to rewrite lambda expressions with different parameter expressions /// </summary> /// <param name="newParameter">The parameter to use as a replacement</param> /// <param name="lambda">The lambda to rewrite</param> /// <returns>The rewritten lambda expression</returns> private QueryExpression RewriteLambda(LinqParameterExpression newParameter, LinqLambdaExpression lambda) { ExceptionUtilities.CheckArgumentNotNull(newParameter, "newParameter"); ExceptionUtilities.CheckArgumentNotNull(lambda, "lambda"); var oldParameter = lambda.Parameters.Single(); return(new ParameterReplacingVisitor(oldParameter, newParameter).ReplaceExpression(lambda.Body)); }
/// <summary> /// Visits the given parameter expression, replacing it if needed /// </summary> /// <param name="expression">The expression to visit</param> /// <returns>The expression, possibly replaced</returns> public override QueryExpression Visit(LinqParameterExpression expression) { if (object.ReferenceEquals(this.oldParameter, expression)) { return this.newParameter; } return expression; }
/// <summary> /// Visits the given parameter expression, replacing it if needed /// </summary> /// <param name="expression">The expression to visit</param> /// <returns>The expression, possibly replaced</returns> public override QueryExpression Visit(LinqParameterExpression expression) { if (object.ReferenceEquals(this.oldParameter, expression)) { return(this.newParameter); } return(expression); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqParameterExpression expression) { CodeParameterDeclarationExpression prm; if (!this.ParameterNamesDictionary.TryGetValue(expression, out prm)) { // for query syntax specific methods we use ParameterNamesDictionary, for non-specific methods (like Count, All, Any) we fall back to // using parametr name (just like in method syntax) return(Code.Argument(expression.Name)); } else { return(Code.Argument(prm.Name)); } }
/// <summary> /// Ensures that the given parameter has a name and creates a new instance if not. /// </summary> /// <param name="expression">The expression.</param> /// <returns>Parameter with a name.</returns> /// <remarks>Subsequent calls to this method with the same expression /// will return the same instance of parameter.</remarks> public LinqParameterExpression EnsureParameterHasName(LinqParameterExpression expression) { LinqParameterExpression parameterWithName; if (!this.parameterMappings.TryGetValue(expression, out parameterWithName)) { if (expression.Name == null) { parameterWithName = LinqBuilder.Parameter(this.parameterNameGenerator.GenerateIdentifier("p"), expression.ExpressionType); } else { parameterWithName = expression; } this.parameterMappings.Add(expression, parameterWithName); } return parameterWithName; }
/// <summary> /// Ensures that the given parameter has a name and creates a new instance if not. /// </summary> /// <param name="expression">The expression.</param> /// <returns>Parameter with a name.</returns> /// <remarks>Subsequent calls to this method with the same expression /// will return the same instance of parameter.</remarks> public LinqParameterExpression EnsureParameterHasName(LinqParameterExpression expression) { LinqParameterExpression parameterWithName; if (!this.parameterMappings.TryGetValue(expression, out parameterWithName)) { if (expression.Name == null) { parameterWithName = LinqBuilder.Parameter(this.parameterNameGenerator.GenerateIdentifier("p"), expression.ExpressionType); } else { parameterWithName = expression; } this.parameterMappings.Add(expression, parameterWithName); } return(parameterWithName); }
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqParameterExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Uri query string representing the expression.</returns> public override string Visit(LinqParameterExpression expression) { string parameterString; if (this.currentLambdaParameterNames.Count == 0) { parameterString = ODataConstants.ImplicitOuterVariableName; this.currentLambdaParameterNames[expression] = parameterString; } else if (!this.currentLambdaParameterNames.TryGetValue(expression, out parameterString)) { parameterString = expression.Name; this.currentLambdaParameterNames[expression] = parameterString; } // until there are 2 known parameters within the current stack, we don't need to provide real names for them // in practice, this will trigger as soon as Any/All appears in the filter if (this.currentLambdaParameterNames.Count < 2) { return(string.Empty); } return(parameterString); }
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqParameterExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Uri query string representing the expression.</returns> public override string Visit(LinqParameterExpression expression) { string parameterString; if (this.currentLambdaParameterNames.Count == 0) { parameterString = ODataConstants.ImplicitOuterVariableName; this.currentLambdaParameterNames[expression] = parameterString; } else if (!this.currentLambdaParameterNames.TryGetValue(expression, out parameterString)) { parameterString = expression.Name; this.currentLambdaParameterNames[expression] = parameterString; } // until there are 2 known parameters within the current stack, we don't need to provide real names for them // in practice, this will trigger as soon as Any/All appears in the filter if (this.currentLambdaParameterNames.Count < 2) { return string.Empty; } return parameterString; }
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqParameterExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Replaced expression.</returns> public override QueryExpression Visit(LinqParameterExpression expression) { return this.helper.EnsureParameterHasName(expression); }
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqParameterExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Uri query string representing the expression.</returns> public virtual string Visit(LinqParameterExpression expression) { throw new TaupoNotSupportedException("Not supported"); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqParameterExpression expression) { return(Code.Argument(expression.Name)); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqParameterExpression expression) { CodeParameterDeclarationExpression prm; if (!this.ParameterNamesDictionary.TryGetValue(expression, out prm)) { // for query syntax specific methods we use ParameterNamesDictionary, for non-specific methods (like Count, All, Any) we fall back to // using parametr name (just like in method syntax) return Code.Argument(expression.Name); } else { return Code.Argument(prm.Name); } }
/// <summary> /// Resolves types for the specified expression. /// </summary> /// <param name="expression">The expression to resolve types for.</param> /// <returns>Expression with resolved types.</returns> public QueryExpression Visit(LinqParameterExpression expression) { return(this.parameterMappings[expression]); }
/// <summary> /// Helper method to rewrite lambda expressions with different parameter expressions /// </summary> /// <param name="newParameter">The parameter to use as a replacement</param> /// <param name="lambda">The lambda to rewrite</param> /// <returns>The rewritten lambda expression</returns> private QueryExpression RewriteLambda(LinqParameterExpression newParameter, LinqLambdaExpression lambda) { ExceptionUtilities.CheckArgumentNotNull(newParameter, "newParameter"); ExceptionUtilities.CheckArgumentNotNull(lambda, "lambda"); var oldParameter = lambda.Parameters.Single(); return new ParameterReplacingVisitor(oldParameter, newParameter).ReplaceExpression(lambda.Body); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public abstract CodeExpression Visit(LinqParameterExpression expression);
/// <summary> /// Visits a QueryExpression tree whose root node is the LinqParameterExpression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Replaced expression.</returns> public override QueryExpression Visit(LinqParameterExpression expression) { return(this.helper.EnsureParameterHasName(expression)); }
/// <summary> /// Generates System.CodeDom.CodeExpression from the given expression. /// </summary> /// <param name="expression">Expression from which System.CodeDom.CodeExpression is generated.</param> /// <returns>Generated System.CodeDom.CodeExpression.</returns> public override CodeExpression Visit(LinqParameterExpression expression) { return Code.Argument(expression.Name); }
/// <summary> /// Evaluates the specified expression. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <returns>Value of the expression.</returns> public QueryValue Visit(LinqParameterExpression expression) { return(this.lambdaParameterAssignments[expression]); }
/// <summary> /// Replaces the given expression. /// </summary> /// <param name="expression">The root node of the expression tree being visited.</param> /// <returns>Replaced expression.</returns> public virtual QueryExpression Visit(LinqParameterExpression expression) { return(expression); }