Пример #1
0
        public static TSource ContainsSingle <TSource>(IEnumerable <TSource> enumerable, Func <TSource, bool> expectedPredicate)
        {
            if (expectedPredicate is null)
            {
                throw new ArgumentNullException(nameof(expectedPredicate));
            }

            var     lp           = new LoopProtection();
            var     hasFoundItem = false;
            TSource matchingItem = default;

            foreach (var item in enumerable)
            {
                lp.Iterate();
                if (expectedPredicate(item))
                {
                    if (hasFoundItem)
                    {
                        throw new AssertionException($"{enumerable} contains more than one element");
                    }
                    else
                    {
                        hasFoundItem = true;
                        matchingItem = item;
                    }
                }
            }

            if (hasFoundItem)
            {
                return(matchingItem !);
            }

            throw new AssertionException($"{enumerable} contains no items satisfying the supplied condition");
        }
Пример #2
0
        public static void DoesNotContain <TSource>(IEnumerable <TSource> enumerable, TSource expectedItem)
        {
            var lp = new LoopProtection();

            foreach (var item in enumerable)
            {
                lp.Iterate();
                if (Equals(item, expectedItem))
                {
                    throw new AssertionException($"{enumerable} does contain {expectedItem}");
                }
            }
        }
Пример #3
0
        public static void None <TSource>(IEnumerable <TSource> enumerable, Func <TSource, bool> excludedPredicate)
        {
            if (excludedPredicate is null)
            {
                throw new ArgumentNullException(nameof(excludedPredicate));
            }

            var lp = new LoopProtection();

            foreach (var item in enumerable)
            {
                lp.Iterate();
                if (excludedPredicate(item))
                {
                    throw new AssertionException($"{item} matching excluded condition found in {enumerable}");
                }
            }
        }
            protected override bool Apply(Subgraph subgraph, NodeGraph fullGraph)
            {
                if (fullGraph.Nodes.GetOrDefaultFromReadOnly(_rootNodeKey) is not {
                } rootNode)
                {
                    return(false);
                }

                var modified       = false;
                var nodesSeen      = new HashSet <Node>();
                var nodesToExplore = new Queue <Node>();

                void TryEnqueue(Node toEnqueue)
                {
                    if (nodesSeen.Add(toEnqueue))
                    {
                        nodesToExplore.Enqueue(toEnqueue);
                    }
                }

                TryEnqueue(rootNode);
                var lp = new LoopProtection();

                while (nodesToExplore.Count > 0)
                {
                    lp.Iterate();
                    var current = nodesToExplore.Dequeue();
                    var links   = _isDependent ? current.BackLinks : current.ForwardLinks;
                    foreach (var dependency in links)
                    {
                        if (dependency.LinkType.HasFlagPartially(_dependencyRelationship))
                        {
                            TryEnqueue(_isDependent ? dependency.Dependent : dependency.Dependency);
                        }
                    }
                }

                foreach (var found in nodesSeen)
                {
                    modified |= subgraph.AddPinnedNode(found.Key, fullGraph);
                }

                return(modified);
            }
Пример #5
0
        public static TSource Contains <TSource>(IEnumerable <TSource> enumerable, Func <TSource, bool> expectedPredicate)
        {
            if (expectedPredicate is null)
            {
                throw new ArgumentNullException(nameof(expectedPredicate));
            }

            var lp = new LoopProtection();

            foreach (var item in enumerable)
            {
                lp.Iterate();
                if (expectedPredicate(item))
                {
                    return(item);
                }
            }

            throw new AssertionException($"{enumerable} contains no items satisfying the supplied condition");
        }
Пример #6
0
        public static IEnumerable <NodePath> GetMultiDependencyRootPaths(NodeGraph graph, ISet <Node> roots)
        {
            if (roots.Count < 2)
            {
                throw new ArgumentOutOfRangeException(nameof(roots));
            }

            var toExplore = new Queue <SearchEntry>();
            var nodesSeen = new HashSet <Node>();

            foreach (var root in roots)
            {
                toExplore.Clear();
                nodesSeen.Clear();
                var rootsNotFound = roots.Count - 1;
                toExplore.Enqueue(new SearchEntry(root, previous: null, generation: 0));

                var lp = new LoopProtection();
                while (toExplore.Count > 0)
                {
                    lp.Iterate();

                    var current = toExplore.Dequeue();

                    foreach (var link in current.Node.ForwardLinkNodes)
                    {
                        if (nodesSeen.Contains(link))
                        {
                            // Seen before, is either in queue or already explored (or is a root)
                            continue;
                        }

                        // Mark as seen
                        nodesSeen.Add(link);

                        if (roots.Contains(link) && link != root)
                        {
                            // We've found another root
                            yield return(NodePath.FromSearch(current, link));

                            rootsNotFound--;

                            // Note: we don't add it to the explore queue, because we don't want paths with more than 2 roots. Any connections out of that root
                            // will be found when that root is processed.
                        }
                        else
                        {
                            // Regular node we haven't seen - queue it up to explore
                            toExplore.Enqueue(current.NextGeneration(link));
                        }

                        if (rootsNotFound == 0)
                        {
                            // All roots have been found for this root, go to the next one
                            break;
                        }
                    }

                    if (rootsNotFound == 0)
                    {
                        // All roots have been found for this root, go to the next one
                        break;
                    }
                }
            }
        }
Пример #7
0
        private async Task <ICollection <Node> > UpdateNode(Node node, CompilationCache compilationCache, CancellationToken ct)
        {
            var(symbol, project) = await compilationCache.GetSymbolForNode(node, ct);

            if (symbol == null)
            {
                // It's gone! Clear node (remove all its forward links and back links). Back links need to be invalidated.
                var dirtied = new HashSet <Node>();
                var lp      = new LoopProtection();
                while (node.ForwardLinks.Count > 0)
                {
                    lp.Iterate();
                    var forwardLink = node.ForwardLinks.First();
                    dirtied.Add(forwardLink.Dependency);
                    node.RemoveForwardLink(forwardLink);
                }

                while (node.BackLinks.Count > 0)
                {
                    lp.Iterate();
                    var backLink     = node.BackLinks.First();
                    var backLinkNode = backLink.Dependent;
                    dirtied.Add(backLinkNode);
                    backLinkNode.RemoveForwardLink(node);
                    InvalidateNode(backLinkNode);
                }

                return(dirtied);
            }

            // Reconcile AssociatedFiles (including _nodesByDocument)
            var associated = GetAssociatedFiles(symbol);
            var fileDiffs  = associated.GetUnorderedDiff(node.AssociatedFiles);

            if (fileDiffs.IsDifferent)
            {
                foreach (var added in fileDiffs.Added)
                {
                    AddAssociatedFile(node, added);
                }

                foreach (var removed in fileDiffs.Removed)
                {
                    RemoveAssociatedFile(node, removed);
                }
            }

            var dependencySymbols = await symbol.GetTypeDependencies(compilationCache, project, includeExternalMetadata : false, ct)
                                    .Where(IsSymbolIncluded)
                                    .ToListAsync();

            var symbolsForDependencies = dependencySymbols.ToDictionary(s => (Node)GetOrCreateNode(s, compilationCache));

            var dependencies = symbolsForDependencies.Keys;

            if (ct.IsCancellationRequested)
            {
                return(ArrayUtils.GetEmpty <Node>());
            }

            var diffs = dependencies.GetUnorderedDiff(node.ForwardLinkNodes);

            if (diffs.IsDifferent)
            {
                var dirtied = new HashSet <Node>();
                dirtied.Add(node);

                foreach (var removedItem in diffs.Removed)
                {
                    node.RemoveForwardLink(removedItem);
                    dirtied.Add(removedItem);
                }

                foreach (var addedItem in diffs.Added)
                {
                    if (addedItem != node)
                    {
                        var linkType = GetLinkType(symbolsForDependencies[addedItem], symbol);
                        node.AddForwardLink(addedItem, linkType);
                    }
                    dirtied.Add(addedItem);
                }

                return(dirtied);
            }

            return(ArrayUtils.GetEmpty <Node>());
        }