private static object Index(TemplateContext context, ExpressionFnOuter inner, ExpressionFnOuter index) { var source = inner(context); var indexResult = index(context); if (source is JArray jArray && ExpressionHelpers.TryConvertInt(indexResult, out int arrayIndex)) { return(jArray[arrayIndex]); } if (source is JObject jObject && ExpressionHelpers.TryString(indexResult, out string propertyName)) { var property = jObject[propertyName]; if (property == null) { throw new ExpressionReferenceException(propertyName, string.Format(Thread.CurrentThread.CurrentCulture, PSRuleResources.PropertyNotFound, propertyName)); } return(property); } if (source is MockNode mockNode && ExpressionHelpers.TryConvertString(indexResult, out string memberName)) { return(mockNode.GetMember(memberName)); } throw new InvalidOperationException(string.Format(Thread.CurrentThread.CurrentCulture, PSRuleResources.IndexInvalid, indexResult)); }
private static object Property(TemplateContext context, ExpressionFnOuter inner, string propertyName) { var result = inner(context); if (result is JObject jObject) { var property = jObject.Property(propertyName, StringComparison.OrdinalIgnoreCase); if (property == null) { throw new ExpressionReferenceException(propertyName, string.Format(Thread.CurrentThread.CurrentCulture, PSRuleResources.PropertyNotFound, propertyName)); } return(property.Value); } if (result is JToken jToken) { var property = jToken[propertyName]; if (property == null) { throw new ExpressionReferenceException(propertyName, string.Format(Thread.CurrentThread.CurrentCulture, PSRuleResources.PropertyNotFound, propertyName)); } return(property.Value <object>()); } if (result is MockNode mockNode) { return(mockNode.GetMember(propertyName)); } return(PropertyOrField(result, propertyName)); }
private ExpressionFnOuter Element(TokenStream stream, ExpressionToken element) { ExpressionFnOuter result = null; // function if (stream.Skip(ExpressionTokenType.GroupStart)) { if (!_Functions.TryDescriptor(element.Content, out IFunctionDescriptor descriptor)) { throw new NotImplementedException(string.Format(PSRuleResources.FunctionNotFound, element.Content)); } var fnParams = new List <ExpressionFnOuter>(); while (!stream.Skip(ExpressionTokenType.GroupEnd)) { fnParams.Add(Inner(stream)); } var aParams = fnParams.ToArray(); result = (context) => descriptor.Invoke(context, aParams); while (stream.TryTokenType(ExpressionTokenType.IndexStart, out ExpressionToken token) || stream.TryTokenType(ExpressionTokenType.Property, out token)) { if (token.Type == ExpressionTokenType.IndexStart) { // Invert: index(fn1(p1, p2), 0) var inner = Inner(stream); ExpressionFnOuter outer = AddIndex(result, inner); result = outer; stream.Skip(ExpressionTokenType.IndexEnd); } else if (token.Type == ExpressionTokenType.Property) { // Invert: property(fn1(p1, p2), "name") ExpressionFnOuter outer = AddProperty(result, token.Content); result = outer; } } } // integer else { result = (context) => element.Content; } return(result); }
private ExpressionFnOuter Inner(TokenStream stream) { ExpressionFnOuter result = null; if (stream.TryTokenType(ExpressionTokenType.String, out ExpressionToken token)) { return(String(token)); } if (stream.TryTokenType(ExpressionTokenType.Numeric, out token)) { return(Numeric(token)); } if (stream.TryTokenType(ExpressionTokenType.Element, out token)) { result = Element(stream, token); } return(result); }
private static object Property(TemplateContext context, ExpressionFnOuter inner, string propertyName) { var result = inner(context); if (result is JObject jObject) { return(jObject.Property(propertyName, StringComparison.OrdinalIgnoreCase).Value); } if (result is JToken jToken) { return(jToken[propertyName].Value <object>()); } if (result is MockNode mockNode) { return(mockNode.GetMember(propertyName)); } return(PropertyOrField(result, propertyName)); }
private static object Index(TemplateContext context, ExpressionFnOuter inner, ExpressionFnOuter index) { var source = inner(context); var indexResult = index(context); if (source is JArray jArray && ExpressionHelpers.TryConvertInt(indexResult, out int arrayIndex)) { return(jArray[arrayIndex]); } if (source is JObject jObject && ExpressionHelpers.TryString(indexResult, out string propertyName)) { return(jObject[propertyName]); } if (source is MockNode mockNode && ExpressionHelpers.TryConvertString(indexResult, out string memberName)) { return(mockNode.GetMember(memberName)); } throw new InvalidOperationException(); }
private static ExpressionFnOuter AddProperty(ExpressionFnOuter inner, string propertyName) { return((context) => Property(context, inner, propertyName)); }
private static ExpressionFnOuter AddIndex(ExpressionFnOuter inner, ExpressionFnOuter innerInner) { return((context) => Index(context, inner, innerInner)); }
private static T EvaluateExpression <T>(ITemplateContext context, ExpressionFnOuter fn) { var result = fn(context); return(result is JToken token && !typeof(JToken).IsAssignableFrom(typeof(T)) ? token.Value <T>() : (T)result); }