private static void EnsureTokensAreValidInner(IEnumerable <FilterExpressionToken> tokens, ref int numberOfCalls) { numberOfCalls++; if (numberOfCalls > 10 * 1000) { throw new InternalJsonPathwayException( "Number of calls to EnsureTokensAreValidInner exceeded max expected number of 10000, possible stack overflow or infinite loop."); } foreach (FilterExpressionToken t in tokens) { if (t is PrimitiveExpressionToken) { throw new UnexpectedTokenException(t); } if (t is MethodCallExpressionToken tc) { EnsureTokensAreValidInner(tc.Arguments, ref numberOfCalls); MethodCallExpressionToken calleeMethod = tc.CalledOnExpression as MethodCallExpressionToken; while (calleeMethod != null) { EnsureTokensAreValidInner(calleeMethod.Arguments, ref numberOfCalls); calleeMethod = calleeMethod.CalledOnExpression as MethodCallExpressionToken; } } } }
private static void EnsureMethodArgumentsAreValid(MethodCallExpressionToken mct, ref int callCount) { callCount++; if (callCount > 10 * 1000) { throw new InternalJsonPathwayException( "Number of calls to EnsureTokensAreValidInner exceeded max expected number of 10000, possible stack overflow or infinite loop."); } if (mct.CalledOnExpression is MethodCallExpressionToken inner1) { EnsureMethodArgumentsAreValid(inner1, ref callCount); } foreach (FilterExpressionToken arg in mct.Arguments) { if (arg is MethodCallExpressionToken inner2) { EnsureMethodArgumentsAreValid(inner2, ref callCount); } } FilterExpressionToken prim = mct.Arguments.FirstOrDefault(x => x is PrimitiveExpressionToken); if (prim != null) { throw new UnexpectedTokenException((prim as PrimitiveExpressionToken).Token); } }
private static List <FilterExpressionToken> ReplaceMethodCallsOnArrayAccess(List <FilterExpressionToken> tokens) { List <ArrayAccessExpressionToken> arrayTokens = tokens.Where(x => x is ArrayAccessExpressionToken).Cast <ArrayAccessExpressionToken>().ToList(); List <FilterExpressionToken> ret = tokens.ToList(); foreach (ArrayAccessExpressionToken at in arrayTokens) { int arrayIndex = ret.IndexOf(at); int dotIndex = arrayIndex + 1; if (dotIndex < ret.Count - 4 && ret[dotIndex] is PrimitiveExpressionToken petDot && petDot.Token.IsSymbolToken('.')) { int methodNameIndex = dotIndex + 1; if (ret[methodNameIndex] is PrimitiveExpressionToken petMethodName && petMethodName.Token.IsPropertyToken()) { PropertyToken propToken = petMethodName.Token.CastToPropertyToken(); if (propToken.Escaped) { throw new UnexpectedTokenException(propToken, "Expected method call on array element"); } string methodName = propToken.StringValue; int openGroupIndex = methodNameIndex + 1; if (openGroupIndex < ret.Count && ret[openGroupIndex] is OpenGroupToken ogt) { FilterExpressionToken closed = ret.FirstOrDefault(x => x is CloseGroupToken cgt && cgt.GroupId == ogt.GroupId); if (closed == null) { throw new ParsingException("Failed to find ) for ( at " + ogt.StartIndex); } List <FilterExpressionToken> args = new List <FilterExpressionToken>(); int startIndex = ret.IndexOf(ogt); int endIndex = ret.IndexOf(closed); for (int i = startIndex + 1; i < endIndex; i++) { args.Add(ret[i]); } args = FormatAndValidateMethodArgumentTokens(args); ret[arrayIndex] = new MethodCallExpressionToken(at, methodName, args.ToArray()); for (int i = arrayIndex + 1; i <= endIndex; i++) { ret[i] = null; } } } } } return(ret.Where(x => x != null).ToList()); }
private static List <FilterExpressionToken> ReplaceMethodCallsOnMethodsInner(List <FilterExpressionToken> tokens, ref int callCount, out int replacedCount) { callCount++; replacedCount = 0; if (callCount > 10 * 1000) { throw new InternalJsonPathwayException( "Number of calls to ReplaceMethodCallsOnMethodsInner exceeded max expected number of 10000, possible stack overflow or infinite loop."); } List <FilterExpressionToken> ret = tokens.ToList(); foreach (MethodCallExpressionToken mc in tokens.Where(x => x is MethodCallExpressionToken)) { int index = ret.IndexOf(mc); if (index < ret.Count - 4 && ret[index + 1] is PrimitiveExpressionToken pet1 && pet1.Token.IsSymbolToken('.') && ret[index + 2] is PrimitiveExpressionToken pet2 && pet2.Token.IsPropertyToken() && ret[index + 3] is OpenGroupToken) { OpenGroupToken open = ret[index + 3] as OpenGroupToken; FilterExpressionToken close = ret.Single(x => x is CloseGroupToken cgt && cgt.GroupId == open.GroupId); string methodName = (ret[index + 2] as PrimitiveExpressionToken).Token.CastToPropertyToken().StringValue; List <FilterExpressionToken> args = new List <FilterExpressionToken>(); int closeIndex = ret.IndexOf(close); for (int i = index + 4; i < closeIndex; i++) { args.Add(ret[i]); } args = FormatAndValidateMethodArgumentTokens(args); ret[index] = new MethodCallExpressionToken(mc, methodName, args.ToArray()); for (int i = index + 1; i <= closeIndex; i++) { ret[i] = null; } replacedCount++; } } return(ret.Where(x => x != null).ToList()); }
private static List <FilterExpressionToken> ReplaceMethodCallsOnProps(List <FilterExpressionToken> tokens) { List <PropertyExpressionToken> propTokens = tokens.Where(x => x is PropertyExpressionToken).Cast <PropertyExpressionToken>().ToList(); List <FilterExpressionToken> ret = tokens.ToList(); foreach (PropertyExpressionToken pt in propTokens) { int nextIndex = ret.IndexOf(pt) + 1; if (nextIndex < ret.Count && ret[nextIndex] is OpenGroupToken) { OpenGroupToken open = ret[nextIndex] as OpenGroupToken; CloseGroupToken close = ret.First(x => x is CloseGroupToken cgt && cgt.GroupId == open.GroupId) as CloseGroupToken; int openIndex = ret.IndexOf(open); int closeIndex = ret.IndexOf(close); List <FilterExpressionToken> args = new List <FilterExpressionToken>(); for (int i = openIndex + 1; i < closeIndex; i++) { args.Add(ret[i]); } args = FormatAndValidateMethodArgumentTokens(args); string methodName; PropertyExpressionToken allButLast = pt.AllButLast(out methodName); int ptIndex = ret.IndexOf(pt); ret[ptIndex] = new MethodCallExpressionToken(allButLast, methodName, args.ToArray()); List <FilterExpressionToken> toRemove = new List <FilterExpressionToken>(); for (int i = ptIndex + 1; i <= closeIndex; i++) { ret[i] = null; } } } return(ret.Where(x => x != null).ToList()); }
public MethodCallFilterSubExpression(MethodCallExpressionToken token) { if (token == null) { throw new ArgumentNullException(nameof(token)); } CalledOnExpression = FilterParser.Parse(new List <FilterExpressionToken> { token.CalledOnExpression }); MethodName = token.MethodName; List <FilterSubExpression> args = new List <FilterSubExpression>(); foreach (FilterExpressionToken a in token.Arguments) { args.Add(FilterParser.Parse(new List <FilterExpressionToken> { a })); } Arguments = args; }
private static List <FilterExpressionToken> ReplaceMethodCallsOnConstants(List <FilterExpressionToken> tokens) { List <FilterExpressionToken> ret = tokens.ToList(); foreach (ConstantBaseExpressionToken ct in tokens.Where(x => x is ConstantBaseExpressionToken)) { int index = ret.IndexOf(ct); if (index < ret.Count - 4 && ret[index + 1] is PrimitiveExpressionToken pet1 && pet1.Token.IsSymbolToken('.') && ret[index + 2] is PrimitiveExpressionToken pet2 && pet2.Token.IsPropertyToken() && ret[index + 3] is OpenGroupToken) { OpenGroupToken open = ret[index + 3] as OpenGroupToken; FilterExpressionToken close = ret.Single(x => x is CloseGroupToken cgt && cgt.GroupId == open.GroupId); string methodName = (ret[index + 2] as PrimitiveExpressionToken).Token.CastToPropertyToken().StringValue; List <FilterExpressionToken> args = new List <FilterExpressionToken>(); int closeIndex = ret.IndexOf(close); for (int i = index + 4; i < closeIndex; i++) { args.Add(ret[i]); } args = FormatAndValidateMethodArgumentTokens(args); ret[index] = new MethodCallExpressionToken(ct, methodName, args.ToArray()); for (int i = index + 1; i <= closeIndex; i++) { ret[i] = null; } } } return(ret.Where(x => x != null).ToList()); }