/// <summary>Parse one of the literals of skip token.</summary> /// <param name="literal">Input literal.</param> /// <returns>Object resulting from conversion of literal.</returns> internal static object ParseSkipTokenLiteral(string literal) { ExpressionLexer l = new ExpressionLexer(literal); ConstantNode node; if (!TokenToQueryNodeTranslator.TryCreateLiteral(l.CurrentToken, out node)) { throw new InvalidOperationException(ServiceStrings.RequsetQueryParser_ExpectingLiteralInSkipToken(literal)); } return(node.Value); }
/// <summary>Makes the expression that is used as a filter corresponding to skip token.</summary> /// <param name="topLevelOrderingInfo">Ordering expression.</param> /// <param name="skipToken">The provided skip token.</param> /// <param name="parameterType">The parameter type of the lambda.</param> /// <returns>LambdaExpression corresponding to the skip token filter.</returns> internal LambdaExpression BuildSkipTokenFilter(OrderingInfo topLevelOrderingInfo, IList <object> skipToken, Type parameterType) { ParameterExpression element = Expression.Parameter(parameterType, "element"); Expression lastCondition = Expression.Constant(true, typeof(bool)); Expression lastMatch = Expression.Constant(false, typeof(bool)); foreach (var v in WebUtil.Zip(topLevelOrderingInfo.OrderingExpressions, skipToken, (x, y) => new { Order = x, Value = y })) { BinaryOperatorKind comparisonExp = v.Order.IsAscending ? BinaryOperatorKind.GreaterThan : BinaryOperatorKind.LessThan; Expression fixedLambda = ParameterReplacerVisitor.Replace( ((LambdaExpression)v.Order.Expression).Body, ((LambdaExpression)v.Order.Expression).Parameters[0], element); // TODO: this will be an EnumNode if $skiptoken contains enum constant. ConstantNode node; var lexer = new ExpressionLexer((string)v.Value); bool success = TokenToQueryNodeTranslator.TryCreateLiteral(lexer.CurrentToken, out node); Debug.Assert(success, "Was not a literal"); node = this.EnsureCorrectTypeAndPrecisionForLFDM(node, fixedLambda.Type); Expression right = this.nodeToExpressionTranslator.TranslateNode(node); Expression comparison = ExpressionGenerator.GenerateLogicalAnd( lastCondition, this.GenerateNullAwareComparison(fixedLambda, right, comparisonExp)); lastMatch = ExpressionGenerator.GenerateLogicalOr(lastMatch, comparison); lastCondition = ExpressionGenerator.GenerateLogicalAnd( lastCondition, this.GenerateComparisonExpression(fixedLambda, right, BinaryOperatorKind.Equal)); } lastMatch = ExpressionUtils.EnsurePredicateExpressionIsBoolean(lastMatch); Debug.Assert(lastMatch.Type == typeof(bool), "Skip token should generate boolean expression."); return(Expression.Lambda(lastMatch, element)); }