Beispiel #1
0
 public static void Visit(
     ISelectable root,
     string selector,
     VisitorCallback visitor)
 {
     Visit(root, selector, visitor, null);
 }
Beispiel #2
0
 public static void Visit(
     ISelectable root,
     OrSelector selector,
     VisitorCallback visitor,
     IndexedPredicate predicate)
 {
     Visit(
         root,
         null,
         root,
         new SelectorTracker(selector),
         visitor,
         predicate);
 }
Beispiel #3
0
        public static void Visit(
            ISelectable root,
            string selector,
            VisitorCallback visitor,
            IndexedPredicate predicate)
        {
            if (Cache.TryGetValue(selector, out var or))
            {
                Visit(root, or, visitor, predicate);
                return;
            }

            or = Parser.ParseOrSelector(new TokenStream(Token.Parse(selector)), false);
            Cache[selector] = or;
            Visit(root, or, visitor, predicate);
        }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Visitor{T}"/> class
 /// by using the specified <see cref="VisitorCallback{T}"/>.
 /// </summary>
 /// <param name="callback">
 /// A <see cref="VisitorCallback{T}"/> to forwards the <see cref="Visit"/>
 /// method.
 /// </param>
 public Visitor(VisitorCallback <T> callback)
 {
     callback_ = callback;
 }
Beispiel #5
0
        private static void Visit(
            ISelectable current,
            ISelectableTree parent,
            ISelectable root,
            SelectorTracker tracker,
            VisitorCallback visitor,
            IndexedPredicate predicate)
        {
            var lines      = tracker.Lines;
            var linesAlive = 0;
            var visit      = false;
            var tree       = current as ISelectableTree;
            var pruneable  = current as IPruneableSelectableTree;

            for (var line = 0; line < lines; line++)
            {
                if (tracker.IsPruned(line))
                {
                    continue;
                }

                var(terminal, rule) = tracker.LineState(line);
                var isMatch = true;
                foreach (var s in rule.ElementSelectors)
                {
                    if (!s.Match(current, parent, root, predicate))
                    {
                        isMatch = false;
                        break;
                    }
                }

                if (isMatch)
                {
                    if (terminal)
                    {
                        visit = true;
                    }
                    else
                    {
                        tracker.Advance(line);
                    }
                }

                if ((!isMatch || terminal) && rule.HasContextSelector)
                {
                    tracker.Prune(line);
                    continue;
                }

                if (pruneable != null)
                {
                    if ((!isMatch || terminal) && pruneable.IsUniqueInPath())
                    {
                        var type = rule.TypeSelector;
                        if (type != null && pruneable.Matches(type))
                        {
                            tracker.Prune(line);
                            continue;
                        }
                    }

                    var pruned = false;
                    // ReSharper disable once LoopCanBeConvertedToQuery
                    foreach (var selector in tracker.RemainingRules(line))
                    {
                        if (selector.HasContextSelector)
                        {
                            tracker.Prune(line);
                            pruned = true;
                            break;
                        }

                        var type = selector.TypeSelector;
                        if (type != null && !pruneable.CanContainDescendant(type))
                        {
                            tracker.Prune(line);
                            pruned = true;
                            break;
                        }
                    }

                    if (!pruned)
                    {
                        linesAlive++;
                    }
                }
                else
                {
                    linesAlive++;
                }
            }

            if (visit)
            {
                visitor(current, parent, root);
            }

            if (linesAlive > 0 && tree != null)
            {
                foreach (var child in tree.GetChildren())
                {
                    Visit(child, tree, root, tracker.Clone(), visitor, predicate);
                }
            }
        }