public override LiquidExpressionResult Eval(ITemplateContext templateContext, IEnumerable <Option <ILiquidValue> > expressions)
        {
            IList <Option <ILiquidValue> > exprList = expressions.ToList();

            if (exprList.Count != 2)
            {
                return(LiquidExpressionResult.Error("Contains is a binary expression but received " + exprList.Count + "."));
            }
            if (!exprList[0].HasValue || !exprList[1].HasValue)
            {
                return(LiquidExpressionResult.Success(new LiquidBoolean(false)));
            }

            //return Contains((dynamic) exprList[0].Value, exprList[1].Value);
            var arr = exprList[0].Value as LiquidCollection;

            if (arr != null)
            {
                return(Contains(arr, exprList[1].Value));
            }
            var dict = exprList[0].Value as LiquidHash;

            if (dict != null)
            {
                return(Contains(dict, exprList[1].Value));
            }
            var str = exprList[0].Value as LiquidString;

            if (str != null)
            {
                return(Contains(str, exprList[1].Value));
            }
            return(Contains(exprList[0].Value, exprList[1].Value));
        }
示例#2
0
 public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, LiquidRange liquidGeneratorExpression)
 {
     //return GetSize(liquidGeneratorExpression, () => LiquidNumeric.Create(liquidGeneratorExpression.Length));
     return(liquidGeneratorExpression == null
         ? SizeOfNil()
         : LiquidExpressionResult.Success(LiquidNumeric.Create(liquidGeneratorExpression.Length)));
 }
示例#3
0
 public override LiquidExpressionResult Apply(ITemplateContext ctx, LiquidString liquidLiquidStringExpression)
 {
     return(LiquidExpressionResult.Success(LiquidString.Create(
                                               (liquidLiquidStringExpression == null ? "NULL" : liquidLiquidStringExpression.StringVal) + " " +
                                               (LiquidStringArg1 == null ? "NULL" : LiquidStringArg1.StringVal) + " " +
                                               (LiquidStringArg2 == null ? "NULL" : LiquidStringArg2.StringVal))));
 }
//        public override void Accept(IExpressionDescriptionVisitor expressionDescriptionVisitor)
//        {
//            expressionDescriptionVisitor.Visit(this);
//        }

        //public ILiquidValue Eval(SymbolTableStack symbolTableStack, IEnumerable<ILiquidValue> expressions)
        public override LiquidExpressionResult Eval(ITemplateContext templateContext, IEnumerable <Option <ILiquidValue> > expressions)
        {
            //IList<ILiquidValue> exprList = expressions.ToList();
            IList <Option <ILiquidValue> > exprList = expressions.ToList();

            //Console.WriteLine("EqualsExpression is Eval-ing expressions ");
            if (exprList.Count != 2)
            {
                //return LiquidExpressionResult.Error("Equals is a binary expression but received " + exprList.Count() + ".");
                return(LiquidExpressionResult.Error("Equals is a binary expression but received " + exprList.Count + "."));
            }

            if (exprList.All(x => !x.HasValue)) // both null
            {
                return(LiquidExpressionResult.Success(new LiquidBoolean(false)));
            }
            if (exprList.Any(x => !x.HasValue)) // one null
            {
                return(LiquidExpressionResult.Success(new LiquidBoolean(true)));
            }

            if (exprList[0].GetType() == exprList[1].GetType())
            {
                return(LiquidExpressionResult.Success(new LiquidBoolean(!exprList[0].Value.Equals(exprList[1].Value))));
            }

            return(LiquidExpressionResult.Error("\"Not Equals\" implementation can't cast yet"));
        }
示例#5
0
        public override LiquidExpressionResult Eval(ITemplateContext templateContext, IEnumerable <Option <ILiquidValue> > expressions)
        {
            IList <Option <ILiquidValue> > exprList = expressions.ToList();


            if (exprList.Count != 2)
            {
                // This shouldn't happen if the parser is correct.
                return(LiquidExpressionResult.Error("Equals is a binary expression but received " + exprList.Count + "."));
            }

            if (!exprList[0].HasValue && !exprList[1].HasValue)
            {
                return(LiquidExpressionResult.Success(new LiquidBoolean(true)));
            }
            if (!exprList[0].HasValue || !exprList[1].HasValue)
            {
                return(LiquidExpressionResult.Success(new LiquidBoolean(false)));
            }
            if (exprList[0].GetType() == exprList[1].GetType())
            {
                var isEqual = exprList[0].Value.Equals(exprList[1].Value);
                return(LiquidExpressionResult.Success(new LiquidBoolean(isEqual)));
            }

            return(LiquidExpressionResult.Error("\"Equals\" implementation can't cast that yet"));
        }
示例#6
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, ILiquidValue liquidExpression)
        {
            var strArray = ValueCaster.RenderAsString(liquidExpression).Split();

            // TODO: add ability to toggle lower-case on/off
            return(LiquidExpressionResult.Success(StringUtils.Eval(liquidExpression, x => Slug.Create(true, strArray))));
        }
示例#7
0
        public override LiquidExpressionResult Eval(ITemplateContext templateContext, IEnumerable <Option <ILiquidValue> > expressions)
        {
            var childExpressions = expressions.ToList();

            return(childExpressions.Count != 1 ?
                   LiquidExpressionResult.Error("Unable to parse expression in parentheses") :
                   LiquidExpressionResult.Success(childExpressions.First()));
        }
示例#8
0
 public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, ILiquidValue liquidExpression)
 {
     return(LiquidExpressionResult.Success(StringUtils.Eval(liquidExpression, before =>
     {
         return String.Concat(before.Split(new[] { ' ', '-', '_' }, StringSplitOptions.RemoveEmptyEntries)
                              .Select(x => char.ToUpper(x[0]) + x.Substring(1).ToLower()));
     })));
 }
示例#9
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, LiquidCollection liquidArrayExpression)
        {
            String separator = _separator == null ? "" : _separator.StringVal;

            var vals = liquidArrayExpression.Select(ValueCaster.RenderAsString);

            return(LiquidExpressionResult.Success(LiquidString.Create(String.Join(separator, vals))));
        }
示例#10
0
        private static LiquidExpressionResult Convert <TDest>(LiquidString str)
            where TDest : ILiquidValue
        {
            var destType = typeof(TDest);

//            if (destType == typeof (LiquidString))
//            {
//                return LiquidExpressionResult.Success(str);
//            }

            if (destType == typeof(LiquidNumeric))
            {
                try
                {
                    var stringVal = str.StringVal;
                    if (stringVal == null)
                    {
                        return(LiquidExpressionResult.Success(LiquidNumeric.Create(0)));  // liquid to_numeric seems to convert these to 0.
                    }
                    if (stringVal.Contains("."))
                    {
                        var val = ToDecimalCultureInvariant(stringVal);

                        return(LiquidExpressionResult.Success(LiquidNumeric.Create(val)));
                    }
                    else
                    {
                        try
                        {
                            var val = int.Parse(stringVal);
                            return(LiquidExpressionResult.Success(LiquidNumeric.Create(val)));
                        }
                        catch (OverflowException)
                        {
                            var val = ToDecimalCultureInvariant(stringVal);

                            return(LiquidExpressionResult.Success(LiquidNumeric.Create(val)));
                        }
                    }
                }
                catch
                {
                    // https://github.com/Shopify/liquid/blob/master/lib/liquid/standardfilters.rb
                    return(LiquidExpressionResult.Success(LiquidNumeric.Create(0)));  // liquid to_numeric seems to convert these to 0.
                }
            }

            if (destType == typeof(LiquidCollection))
            {
                var expressionConstants = new Some <ILiquidValue>(str);
                // IN liquid, it doesn't seem to cast a string to an array of chars---it casts to an array of one element.
                //var expressionConstants = str.StringVal.Select(x => (Option<ILiquidValue>) new Some<ILiquidValue>(LiquidString.Create(x.ToString())));
                return(LiquidExpressionResult.Success(new LiquidCollection {
                    expressionConstants
                }));
            }
            return(LiquidExpressionResult.Error("Can't convert from string to " + destType));
        }
示例#11
0
        public static LiquidExpressionResult Cast <TSource, TDest>(TSource src)
            where TDest : ILiquidValue
            where TSource : ILiquidValue
        {
            if (src == null)
            {
                return(LiquidExpressionResult.Success(new None <ILiquidValue>()));
            }
            if (src is TDest)
            {
                //var result = (TDest) ((dynamic) src);
                //ILiquidValue success = (TDest)((dynamic)src);
                ILiquidValue success = (TDest)(object)src;
                return(LiquidExpressionResult.Success(new Some <ILiquidValue>(success)));
            }
            if (typeof(TDest) == typeof(LiquidString))
            {
                return(LiquidExpressionResult.Success(LiquidString.Create(src.ToString())));
            }
            var str = src as LiquidString;

            if (str != null)
            {
                return(Convert <TDest>(str));
            }
            var num = src as LiquidNumeric;

            if (num != null)
            {
                return(Convert <TDest>(num));
            }
            var boo = src as LiquidBoolean;

            if (boo != null)
            {
                return(Convert <TDest>(boo));
            }
            var dict = src as LiquidHash;

            if (dict != null)
            {
                return(Convert <TDest>(dict));
            }
            var arr = src as LiquidCollection;

            if (arr != null)
            {
                return(Convert <TDest>(arr));
            }
            var date = src as LiquidDate;

            if (date != null)
            {
                return(Convert <TDest>(date));
            }
            //return Convert<TDest>(src);
            throw new Exception("Unknown type: " + src.GetType());
        }
示例#12
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, LiquidCollection liquidArrayExpression)
        {
            if (_start == null)
            {
                return(LiquidExpressionResult.Error("Please pass a start parameter."));
            }

            return(LiquidExpressionResult.Success(new LiquidCollection(SliceList(liquidArrayExpression))));
        }
示例#13
0
//        public override void Accept(IExpressionDescriptionVisitor expressionDescriptionVisitor)
//        {
//            expressionDescriptionVisitor.Visit(this);
//        }

        public override LiquidExpressionResult Eval(ITemplateContext templateContext, IEnumerable <Option <ILiquidValue> > expressions)
        {
            IList <Option <ILiquidValue> > exprList = expressions.ToList();

            if (exprList.Count != 1)
            {
                return(LiquidExpressionResult.Error("\"Not\" is a unary expression but received " + exprList.Count + " arguments."));
            }
            return(LiquidExpressionResult.Success(new LiquidBoolean(!exprList[0].HasValue || !exprList[0].Value.IsTrue)));
        }
示例#14
0
        public override LiquidExpressionResult Eval(ITemplateContext templateContext, IEnumerable <Option <ILiquidValue> > expressions)
        {
            var exprList = expressions.ToList();

            if (exprList.Count != 2)
            {
                throw new Exception("An AND expression must have two values"); // TODO: when the Eval is separated this will be redundant.
            }
            return(LiquidExpressionResult.Success(new LiquidBoolean(exprList.All(x => x.HasValue) && exprList.All(x => x.Value.IsTrue))));
        }
示例#15
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, LiquidString liquidLiquidStringExpression)
        {
            if (String.IsNullOrEmpty(liquidLiquidStringExpression.StringVal))
            {
                return(LiquidExpressionResult.Success(Option <ILiquidValue> .None()));
            }

            return(LiquidExpressionResult.Success(LiquidString.Create(String.Join(_separator.StringVal,
                                                                                  liquidLiquidStringExpression.StringVal.ToCharArray().Select(c => c.ToString())))));
        }
示例#16
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, LiquidString liquidLiquidStringExpression)
        {
            if (_delimiter == null)
            {
                return(LiquidExpressionResult.Error("Split filter must have a delimiter"));
            }
            var strings = liquidLiquidStringExpression.StringVal.Split(new[] { _delimiter.StringVal }, StringSplitOptions.RemoveEmptyEntries);

            return(LiquidExpressionResult.Success(new LiquidCollection(strings.Select(s => LiquidString.Create(s).ToOption()).ToList())));
        }
示例#17
0
        public static LiquidExpressionResult Eval(
            LiquidExpression expression,
            IEnumerable <Option <ILiquidValue> > leaves,
            ITemplateContext templateContext)
        {
            // calculate the first part of the expression
            var objResult = expression.Expression == null?
                            LiquidExpressionResult.Success(new None <ILiquidValue>()) :
                                expression.Expression.Eval(templateContext, leaves);

            if (objResult.IsError)
            {
                return(objResult);
            }

            // Compose a chain of filters, making sure type-casting
            // is done between them.
            //IEnumerable<Tuple<FilterSymbol, IFilterExpression>> filterExpressionTuples;
//            try
//            {
            var filterExpressionTuples = expression.FilterSymbols.Select(symbol =>
                                                                         new Tuple <FilterSymbol, Try <IFilterExpression> >(symbol, InstantiateFilter(templateContext, symbol)))
                                         .ToList();

            //}
            //catch (Exception ex)
            //{
            //   return LiquidExpressionResult.Error(ex.Message);
            //}
            if (filterExpressionTuples.Any(x => x.Item2.IsFailure))
            {
                // just return the first error.
                return(LiquidExpressionResult.Error(filterExpressionTuples.First().Item2.Exception.Message));
            }

            var erroringFilternames = filterExpressionTuples.Where(x => x.Item2 == null).Select(x => x.Item1).ToList();

            if (erroringFilternames.Any())
            {
                //throw new Exception("Missing filters...");
                //return ConstantFactory.CreateError<LiquidString>();
                return(LiquidExpressionResult.Error("Missing filters: " + String.Join(", ", erroringFilternames.Select(x => x.Name))));
            }

            var filterChain = FilterChain.CreateChain(
                objResult.GetType(),
                templateContext,
                filterExpressionTuples.Select(x => x.Item2.Value));

            // apply the composed function to the object

            var result = filterChain(objResult.SuccessResult);

            return(result);
        }
示例#18
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, LiquidString liquidString)
        {
            var list = liquidString.StringVal.ToCharArray().ToList();

            if (_start == null)
            {
                return(LiquidExpressionResult.Error("Please pass a start parameter."));
            }

            return(LiquidExpressionResult.Success(LiquidString.Create(String.Concat(SliceList(list)))));
        }
        public override LiquidExpressionResult Eval(ITemplateContext templateContext,
                                                    IEnumerable <Option <ILiquidValue> > expressions)
        {
            var expressionList = expressions.ToList();

            if (expressionList.Any(x => !x.HasValue))
            {
                return(LiquidExpressionResult.Success(new LiquidBoolean(false)));
            }
            return(LiquidExpressionResult.Success(ComparisonExpressions.Compare(expressionList[0].Value, expressionList[1].Value, (x, y) => x >= y)));
        }
示例#20
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, LiquidCollection liquidArrayExpression)
        {
            var list = liquidArrayExpression.Select(x => x.HasValue
                ? FieldAccessor.TryField(ctx, x.Value, _selector.StringVal)
                : LiquidExpressionResult.ErrorOrNone(ctx, _selector.StringVal)).ToList();

            //new None<ILiquidValue>()).ToList();
            return(list.Any(x => x.IsError) ?
                   list.First(x => x.IsError) :
                   LiquidExpressionResult.Success(new LiquidCollection(list.Select(x => x.SuccessResult).ToList())));
        }
 private LiquidExpressionResult ErrorOrNone(ITemplateContext templateContext, LiquidExpressionResult failureResult)
 {
     if (templateContext.Options.ErrorWhenValueMissing)
     {
         return(failureResult);
     }
     else
     {
         return(LiquidExpressionResult.Success(new None <ILiquidValue>()));
     }
 }
示例#22
0
 public Object ReferenceLocalRegistryVariable(String reference, int skiplevels = 0)
 {
     for (int i = _symbolTables.Count - 1 - skiplevels; i >= 0; i--)
     {
         if (_symbolTables[i].HasLocalRegistryVariableReference(reference))
         {
             return(_symbolTables[i].ReferenceLocalRegistryVariable(reference));
         }
     }
     return(LiquidExpressionResult.Success(new None <ILiquidValue>()));
 }
示例#23
0
        // TODO: use StringUtils.Eval?
        public override LiquidExpressionResult Apply(ITemplateContext ctx, LiquidString liquidLiquidStringExpression)
        {
            // TODO: Return errors
            //Console.WriteLine("APPLYING REMOVE " + _replacement.Value + "TO " + liquidLiquidStringExpression.Value);
            if (_replacement == null || _replacement.Value == null)
            {
                return(LiquidExpressionResult.Error("Please specify a replacement string."));
            }

            return(LiquidExpressionResult.Success(Remove((String)liquidLiquidStringExpression.Value, _replacement)));
        }
示例#24
0
        private LiquidExpressionResult SortByProperty(ITemplateContext ctx, LiquidCollection val, string sortfield)
        {
            if (ctx.Options.ErrorWhenValueMissing &&
                val.Any(x => FieldAccessor.TryField(ctx, x.Value, sortfield).IsError))
            {
                return(LiquidExpressionResult.Error("an array element is missing the field '" + sortfield + "'"));
            }
            var ordered = val.OrderBy(x => AsString(ctx, x, sortfield));

            return(LiquidExpressionResult.Success(new LiquidCollection(ordered.ToList())));
        }
示例#25
0
 private static Func <Option <ILiquidValue>, LiquidExpressionResult> BindAll(
     ITemplateContext ctx,
     IEnumerable <IFilterExpression> filterExpressions)
 {
     return(initValue => filterExpressions.Aggregate(
                LiquidExpressionResult.Success(initValue),
                (current, filter) =>
     {
         var result = filter.BindFilter(ctx, current);
         return result;
     }));
 }
示例#26
0
        private static Func <ILiquidValue, LiquidExpressionResult> InitialCast(
            ITemplateContext ctx, IFilterExpression initialExpression)
        {
            return(expressionConstant =>
            {
                var result = expressionConstant != null
                    ? CreateCastFilter(expressionConstant.GetType(), initialExpression.SourceType)
                             .Apply(ctx, expressionConstant)
                    : LiquidExpressionResult.Success(new None <ILiquidValue>());

                return result;
            });
        }
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, ILiquidValue liquidExpression)
        {
            String before = ValueCaster.RenderAsString(liquidExpression);

            if (String.IsNullOrWhiteSpace(before))
            {
                return(LiquidExpressionResult.Success(LiquidString.Create("")));
            }
            var    nospaces = before.TrimStart();
            String trimmed  = before.Substring(0, before.Length - nospaces.Length);

            return(LiquidExpressionResult.Success(LiquidString.Create(trimmed + char.ToUpper(nospaces[0]) + nospaces.Substring(1))));
        }
示例#28
0
        public override LiquidExpressionResult ApplyTo(ITemplateContext ctx, LiquidCollection liquidArrayExpression)
        {
            var sortfield = _sortField.StringVal;

            if (String.IsNullOrWhiteSpace(sortfield)) // try to sort as an array
            {
                return(LiquidExpressionResult.Success(SortAsArrayOfStrings(liquidArrayExpression)));
            }
            else
            {
                return(SortByProperty(ctx, liquidArrayExpression, sortfield));
            }
        }
示例#29
0
 public static LiquidExpressionResult GetReturnValue(decimal result, LiquidNumeric val1, LiquidNumeric val2)
 {
     if (val1.IsInt && val2.IsInt)
     {
         //var int32 = Convert.ToInt32(val);
         var int32 = (int)System.Math.Floor(result); // ruby liquid seems to round down.
         return(LiquidExpressionResult.Success(LiquidNumeric.Create(int32)));
     }
     else
     {
         return(LiquidExpressionResult.Success(LiquidNumeric.Create(result)));
     }
 }
示例#30
0
        public override LiquidExpressionResult Apply(ITemplateContext ctx, LiquidNumeric liquidNumeric)
        {
            if (_operand == null)
            {
                return(LiquidExpressionResult.Error("The argument to \"modulo\" is missing."));
            }
            if (_operand.DecimalValue == 0)
            {
                return(LiquidExpressionResult.Error("Liquid error: divided by 0"));
            }
            var val = (int)(liquidNumeric.DecimalValue % _operand.DecimalValue);

            return(LiquidExpressionResult.Success(LiquidNumeric.Create(val)));
        }