public static void Visit( ISelectable root, string selector, VisitorCallback visitor) { Visit(root, selector, visitor, null); }
public static void Visit( ISelectable root, OrSelector selector, VisitorCallback visitor, IndexedPredicate predicate) { Visit( root, null, root, new SelectorTracker(selector), visitor, predicate); }
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); }
/// <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; }
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); } } }