public static void ClearTree <TEntity, TKey>(this ISelectableTree <TEntity, TKey> tree) where TEntity : class, ISelectableEntity <TEntity, TKey> where TKey : notnull { foreach (var rootEntity in tree.RootEntities) { rootEntity.ClearBranch <TEntity, TKey>(); } }
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); } } }