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>();
     }
 }
Ejemplo n.º 2
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);
                }
            }
        }