Exemplo n.º 1
0
        public static ConditionBase ParseCondition(string expr, string variable, ITemplateParser parser)
        {
            expr = expr.Trim();

            var left = expr.TryBefore("||");

            if (left != null)
            {
                return(new ConditionOr(
                           ParseCondition(left, variable, parser),
                           ParseCondition(expr.After("||"), variable, parser)));
            }

            left = expr.TryBefore(" OR ");
            if (left != null)
            {
                return(new ConditionOr(
                           ParseCondition(left, variable, parser),
                           ParseCondition(expr.After(" OR "), variable, parser)));
            }

            left = expr.TryBefore("&&");
            if (left != null)
            {
                return(new ConditionAnd(
                           ParseCondition(left, variable, parser),
                           ParseCondition(expr.After("&&"), variable, parser)));
            }

            left = expr.TryBefore(" AND ");
            if (left != null)
            {
                return(new ConditionAnd(
                           ParseCondition(left, variable, parser),
                           ParseCondition(expr.After(" AND "), variable, parser)));
            }

            var filter = TemplateUtils.TokenOperationValueRegex.Match(expr);

            if (!filter.Success)
            {
                return(new ConditionCompare(ValueProviderBase.TryParse(expr, variable, parser) !));
            }
            else
            {
                var vpb       = ValueProviderBase.TryParse(filter.Groups["token"].Value, variable, parser);
                var operation = filter.Groups["operation"].Value;
                var value     = filter.Groups["value"].Value;
                return(new ConditionCompare(vpb, operation, value, parser.AddError));
            }
        }
Exemplo n.º 2
0
        public ContinueValueProvider(string fieldOrPropertyChain, ValueProviderBase parent, Action <bool, string> addError)
        {
            this.Parent = parent;

            this.Members = ParsedModel.GetMembers(ParentType(), fieldOrPropertyChain, addError);
        }
Exemplo n.º 3
0
            void ParseInternal()
            {
                try
                {
                    this.mainBlock = new BlockNode(null);
                    this.stack     = new Stack <BlockNode>();
                    this.errors    = new List <TemplateError>();
                    PushBlock(mainBlock);

                    var matches = TemplateUtils.KeywordsRegex.Matches(text);

                    if (matches.Count == 0)
                    {
                        stack.Peek().Nodes.Add(new LiteralNode(text));
                        stack.Pop();
                        return;
                    }

                    int index = 0;
                    foreach (Match match in matches.Cast <Match>())
                    {
                        if (index < match.Index)
                        {
                            stack.Peek().Nodes.Add(new LiteralNode(text.Substring(index, match.Index - index)));
                        }
                        var expr     = match.Groups["expr"].Value;
                        var keyword  = match.Groups["keyword"].Value;
                        var variable = match.Groups["dec"].Value;
                        switch (keyword)
                        {
                        case "":
                        case "raw":
                            var s = TemplateUtils.SplitToken(expr);
                            if (s == null)
                            {
                                AddError(true, "{0} has invalid format".FormatWith(expr));
                            }
                            else
                            {
                                var t = ValueProviderBase.TryParse(s.Value.Token, variable, this);

                                stack.Peek().Nodes.Add(new ValueNode(t, s.Value.Format, isRaw: keyword.Contains("raw")));

                                DeclareVariable(t);
                            }
                            break;

                        case "declare":
                        {
                            var t = ValueProviderBase.TryParse(expr, variable, this);

                            stack.Peek().Nodes.Add(new DeclareNode(t, this.AddError));

                            DeclareVariable(t);
                        }
                        break;

                        case "any":
                        {
                            ConditionBase cond = TemplateUtils.ParseCondition(expr, variable, this);
                            AnyNode       any  = new AnyNode(cond);
                            stack.Peek().Nodes.Add(any);
                            PushBlock(any.AnyBlock);
                            if (cond is ConditionCompare cc)
                            {
                                DeclareVariable(cc.ValueProvider);
                            }
                            break;
                        }

                        case "notany":
                        {
                            var an = (AnyNode?)PopBlock(typeof(AnyNode))?.owner;
                            if (an != null)
                            {
                                PushBlock(an.CreateNotAny());
                            }
                            break;
                        }

                        case "endany":
                        {
                            PopBlock(typeof(AnyNode));
                            break;
                        }

                        case "foreach":
                        {
                            ValueProviderBase?vp = ValueProviderBase.TryParse(expr, variable, this);
                            if (vp is TokenValueProvider tvp && tvp.ParsedToken.QueryToken != null && QueryToken.IsCollection(tvp.ParsedToken.QueryToken.Type))
                            {
                                AddError(false, $"@foreach[{expr}] is a collection, missing 'Element' token at the end");
                            }

                            var fn = new ForeachNode(vp);
                            stack.Peek().Nodes.Add(fn);
                            PushBlock(fn.Block);
                            if (vp != null)
                            {
                                vp.IsForeach = true;
                            }
                            DeclareVariable(vp);
                            break;
                        }

                        case "endforeach":
                        {
                            PopBlock(typeof(ForeachNode));
                        }
                        break;

                        case "if":
                        {
                            ConditionBase cond = TemplateUtils.ParseCondition(expr, variable, this);
                            IfNode        ifn  = new IfNode(cond, this);
                            stack.Peek().Nodes.Add(ifn);
                            PushBlock(ifn.IfBlock);
                            if (cond is ConditionCompare cc)
                            {
                                DeclareVariable(cc.ValueProvider);
                            }
                            break;
                        }

                        case "else":
                        {
                            var ifn = (IfNode?)PopBlock(typeof(IfNode))?.owner;
                            if (ifn != null)
                            {
                                PushBlock(ifn.CreateElse());
                            }
                            break;
                        }

                        case "endif":
                        {
                            PopBlock(typeof(IfNode));
                            break;
                        }

                        default:
                            AddError(true, "'{0}' is deprecated".FormatWith(keyword));
                            break;
                        }
                        index = match.Index + match.Length;
                    }

                    if (stack.Count != 1)
                    {
                        AddError(true, "Last block is not closed: {0}".FormatWith(stack.Peek()));
                    }

                    var lastM = matches.Cast <Match>().LastOrDefault();
                    if (lastM != null && lastM.Index + lastM.Length < text.Length)
                    {
                        stack.Peek().Nodes.Add(new LiteralNode(text.Substring(lastM.Index + lastM.Length)));
                    }

                    stack.Pop();
                }
                catch (Exception e)
                {
                    AddError(true, e.Message);
                }
            }