예제 #1
0
        /// <summary>
        /// Updates or creates new IProjectItemTree node
        /// </summary>
        private IProjectTree CreateOrUpdateProjectItemTreeNode(
            IProjectTree node,
            IDependencyViewModel viewModel,
            IRule rule,
            ProjectTreeFlags?additionalFlags = null,
            ProjectTreeFlags?excludedFlags   = null)
        {
            if (node == null)
            {
                var flags = FilterFlags(viewModel.Flags, additionalFlags, excludedFlags);

                var itemContext = ProjectPropertiesContext.GetContext(
                    CommonServices.Project,
                    file: viewModel.FilePath,
                    itemType: viewModel.SchemaItemType,
                    itemName: viewModel.FilePath);

                node = TreeServices.CreateTree(
                    caption: viewModel.Caption,
                    itemContext: itemContext,
                    propertySheet: null,
                    visible: true,
                    browseObjectProperties: rule,
                    flags: viewModel.Flags,
                    icon: viewModel.Icon.ToProjectSystemType(),
                    expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType());
            }
            else
            {
                node = UpdateTreeNode(node, viewModel, rule);
            }

            return(node);
        }
        private IProjectTree CreateProjectTreeNode(
            IDependencyViewModel viewModel,
            IRule rule,
            ProjectTreeFlags?additionalFlags = null,
            ProjectTreeFlags?excludedFlags   = null)
        {
            // For IProjectTree remove ProjectTreeFlags.Common.Reference flag, otherwise CPS would fail to
            // map this node to graph node and GraphProvider would be never called.
            // Only IProjectItemTree can have this flag
            ProjectTreeFlags flags = FilterFlags(viewModel.Flags.Except(DependencyTreeFlags.BaseReferenceFlags),
                                                 additionalFlags,
                                                 excludedFlags);
            string filePath = (viewModel.OriginalModel != null && viewModel.OriginalModel.TopLevel &&
                               viewModel.OriginalModel.Resolved)
                ? viewModel.OriginalModel.GetTopLevelId()
                : viewModel.FilePath;

            return(TreeServices.CreateTree(
                       caption: viewModel.Caption,
                       filePath: filePath,
                       visible: true,
                       browseObjectProperties: rule,
                       flags: flags,
                       icon: viewModel.Icon.ToProjectSystemType(),
                       expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType()));
        }
        private IProjectTree CreateProjectItemTreeNode(
            IDependencyViewModel viewModel,
            IRule rule,
            ProjectTreeFlags?additionalFlags = null,
            ProjectTreeFlags?excludedFlags   = null)
        {
            ProjectTreeFlags flags    = FilterFlags(viewModel.Flags, additionalFlags, excludedFlags);
            string           filePath = (viewModel.OriginalModel != null && viewModel.OriginalModel.TopLevel &&
                                         viewModel.OriginalModel.Resolved)
                ? viewModel.OriginalModel.GetTopLevelId()
                : viewModel.FilePath;

            var itemContext = ProjectPropertiesContext.GetContext(
                CommonServices.Project,
                file: filePath,
                itemType: viewModel.SchemaItemType,
                itemName: filePath);

            return(TreeServices.CreateTree(
                       caption: viewModel.Caption,
                       itemContext: itemContext,
                       propertySheet: null,
                       browseObjectProperties: rule,
                       icon: viewModel.Icon.ToProjectSystemType(),
                       expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType(),
                       visible: true,
                       flags: flags));
        }
예제 #4
0
        /// <summary>
        /// Updates or creates new IProjectTree node
        /// </summary>
        private IProjectTree CreateOrUpdateProjectTreeNode(
            IProjectTree node,
            IDependencyViewModel viewModel,
            IRule rule,
            ProjectTreeFlags?additionalFlags = null,
            ProjectTreeFlags?excludedFlags   = null)
        {
            if (node == null)
            {
                // For IProjectTree remove ProjectTreeFlags.Common.Reference flag, otherwise CPS would fail to
                // map this node to graph node and GraphProvider would be never called.
                // Only IProjectItemTree can have this flag
                var flags = FilterFlags(viewModel.Flags.Except(DependencyTreeFlags.BaseReferenceFlags),
                                        additionalFlags,
                                        excludedFlags);

                node = TreeServices.CreateTree(
                    caption: viewModel.Caption,
                    filePath: viewModel.FilePath,
                    visible: true,
                    browseObjectProperties: rule,
                    flags: flags,
                    icon: viewModel.Icon.ToProjectSystemType(),
                    expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType());
            }
            else
            {
                node = UpdateTreeNode(node, viewModel, rule);
            }

            return(node);
        }
예제 #5
0
        private GraphNode DoAddGraphNode(
            GraphNodeId graphNodeId,
            IGraphContext graphContext,
            string projectPath,
            GraphNode parentNode,
            IDependencyViewModel viewModel)
        {
            RegisterIcons(viewModel.GetIcons());

            var newNode = graphContext.Graph.Nodes.GetOrCreate(graphNodeId, viewModel.Caption, null);

            newNode.SetValue(DgmlNodeProperties.Icon, GetIconStringName(viewModel.Icon));
            // priority sets correct order among peers
            newNode.SetValue(CodeNodeProperties.SourceLocation,
                             new SourceLocation(projectPath, new Position(viewModel.Priority, 0)));
            newNode.AddCategory(DependenciesGraphSchema.CategoryDependency);

            if (viewModel.OriginalModel != null)
            {
                newNode.SetValue(DependenciesGraphSchema.DependencyIdProperty, viewModel.OriginalModel.Id);
                newNode.SetValue(DependenciesGraphSchema.ResolvedProperty, viewModel.OriginalModel.Resolved);
            }

            graphContext.OutputNodes.Add(newNode);

            if (parentNode != null)
            {
                graphContext.Graph.Links.GetOrCreate(parentNode, newNode, /*label*/ null, CodeLinkCategories.Contains);
            }

            return(newNode);
        }
        public GraphNode AddTopLevelGraphNode(
            IGraphContext graphContext,
            string projectPath,
            IDependencyViewModel viewModel)
        {
            var newNodeId = GetTopLevelGraphNodeId(projectPath, viewModel.OriginalModel.GetTopLevelId());

            return(DoAddGraphNode(newNodeId, graphContext, projectPath, parentNode: null, viewModel: viewModel));
        }
        public GraphNode AddGraphNode(
            IGraphContext graphContext,
            string projectPath,
            GraphNode parentNode,
            IDependencyViewModel viewModel)
        {
            var newNodeId = GetGraphNodeId(projectPath, parentNode, viewModel);

            return(DoAddGraphNode(newNodeId, graphContext, projectPath, parentNode, viewModel));
        }
        public GraphNode AddGraphNode(
            IGraphContext graphContext,
            string projectPath,
            GraphNode parentNode,
            IDependencyViewModel viewModel)
        {
            var modelId   = viewModel.OriginalModel == null ? viewModel.Caption : viewModel.OriginalModel.Id;
            var newNodeId = GetGraphNodeId(projectPath, parentNode, modelId);

            return(DoAddGraphNode(newNodeId, graphContext, projectPath, parentNode, viewModel));
        }
        public GraphNode AddTopLevelGraphNode(
            IGraphContext graphContext,
            string projectPath,
            IDependencyViewModel viewModel)
        {
            Assumes.True(IsInitialized);

            GraphNodeId newNodeId = GetTopLevelGraphNodeId(projectPath, viewModel.OriginalModel.GetTopLevelId());

            return(DoAddGraphNode(newNodeId, graphContext, projectPath, parentNode: null, viewModel));
        }
예제 #10
0
 /// <summary>
 /// Updates or creates new node
 /// </summary>
 private IProjectTree CreateOrUpdateNode(
     IProjectTree node,
     IDependencyViewModel viewModel,
     IRule rule,
     bool isProjectItem,
     ProjectTreeFlags?additionalFlags = null,
     ProjectTreeFlags?excludedFlags   = null)
 {
     return(isProjectItem
         ? CreateOrUpdateProjectItemTreeNode(node, viewModel, rule, additionalFlags, excludedFlags)
         : CreateOrUpdateProjectTreeNode(node, viewModel, rule, additionalFlags, excludedFlags));
 }
예제 #11
0
        public GraphNode AddGraphNode(
            IGraphContext graphContext,
            string projectPath,
            GraphNode parentNode,
            IDependencyViewModel viewModel)
        {
            Assumes.True(IsInitialized);

            string      modelId   = viewModel.OriginalModel == null ? viewModel.Caption : viewModel.OriginalModel.Id;
            GraphNodeId newNodeId = GetGraphNodeId(projectPath, parentNode, modelId);

            return(DoAddGraphNode(newNodeId, graphContext, projectPath, parentNode, viewModel));
        }
예제 #12
0
        public IDependency CreateDependencyModel(IDependencyViewModel dependency)
        {
            switch (dependency)
            {
            case ConditionResultDependencyViewModel conditionResultDependencyViewModel:
                return(new ConditionResultDependency()
                {
                    Condition = _conditionFillHelper.CreateConditionFromViewModel(conditionResultDependencyViewModel.SelectedConditionViewModel),
                    Result = _resultFillHelper.CreateResultFromViewModel(conditionResultDependencyViewModel.SelectedResultViewModel)
                });

                break;
            }
            return(null);
        }
예제 #13
0
        private IProjectTree UpdateTreeNode(
            IProjectTree node,
            IDependencyViewModel viewModel,
            IRule rule)
        {
            ProjectTreeCustomizablePropertyContext updatedNodeParentContext = GetCustomPropertyContext(node.Parent);
            var updatedValues = new ReferencesProjectTreeCustomizablePropertyValues
            {
                Caption      = viewModel.Caption,
                Flags        = viewModel.Flags,
                Icon         = viewModel.Icon.ToProjectSystemType(),
                ExpandedIcon = viewModel.ExpandedIcon.ToProjectSystemType()
            };

            ApplyProjectTreePropertiesCustomization(updatedNodeParentContext, updatedValues);

            return(node.SetProperties(
                       caption: viewModel.Caption,
                       browseObjectProperties: rule,
                       icon: viewModel.Icon.ToProjectSystemType(),
                       expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType()));
        }
        private IProjectTree CreateOrUpdateNode(
            IProjectTree?node,
            IDependencyViewModel viewModel,
            IRule?browseObjectProperties,
            bool isProjectItem,
            ProjectTreeFlags?additionalFlags = null,
            ProjectTreeFlags?excludedFlags   = null)
        {
            if (node != null)
            {
                return(UpdateTreeNode());
            }

            ProjectTreeFlags filteredFlags = FilterFlags(viewModel.Flags);

            return(isProjectItem
                ? CreateProjectItemTreeNode()
                : CreateProjectTreeNode());

            IProjectTree CreateProjectTreeNode()
            {
                return(_treeServices.CreateTree(
                           caption: viewModel.Caption,
                           filePath: viewModel.FilePath,
                           browseObjectProperties: browseObjectProperties,
                           icon: viewModel.Icon.ToProjectSystemType(),
                           expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType(),
                           visible: true,
                           flags: filteredFlags));
            }

            IProjectTree CreateProjectItemTreeNode()
            {
                var itemContext = ProjectPropertiesContext.GetContext(
                    _commonServices.Project,
                    file: viewModel.FilePath,
                    itemType: viewModel.SchemaItemType,
                    itemName: viewModel.FilePath);

                return(_treeServices.CreateTree(
                           caption: viewModel.Caption,
                           itemContext: itemContext,
                           browseObjectProperties: browseObjectProperties,
                           icon: viewModel.Icon.ToProjectSystemType(),
                           expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType(),
                           visible: true,
                           flags: filteredFlags));
            }

            IProjectTree UpdateTreeNode()
            {
                var updatedNodeParentContext = new ProjectTreeCustomizablePropertyContext
                {
                    ExistsOnDisk    = false,
                    ParentNodeFlags = node !.Parent?.Flags ?? default
                };

                var updatedValues = new ReferencesProjectTreeCustomizablePropertyValues
                {
                    Caption      = viewModel.Caption,
                    Flags        = viewModel.Flags,
                    Icon         = viewModel.Icon.ToProjectSystemType(),
                    ExpandedIcon = viewModel.ExpandedIcon.ToProjectSystemType()
                };

                foreach (Lazy <IProjectTreePropertiesProvider, IOrderPrecedenceMetadataView> provider in _projectTreePropertiesProviders)
                {
                    provider.Value.CalculatePropertyValues(updatedNodeParentContext, updatedValues);
                }

                return(node.SetProperties(
                           caption: updatedValues.Caption,
                           browseObjectProperties: browseObjectProperties,
                           icon: updatedValues.Icon,
                           expandedIcon: updatedValues.ExpandedIcon,
                           flags: updatedValues.Flags));
            }

            ProjectTreeFlags FilterFlags(ProjectTreeFlags flags)
            {
                if (additionalFlags.HasValue)
                {
                    flags = flags.Union(additionalFlags.Value);
                }

                if (excludedFlags.HasValue)
                {
                    flags = flags.Except(excludedFlags.Value);
                }

                return(flags);
            }
        }
예제 #15
0
        public async Task <IProjectTree> BuildTreeAsync(
            IProjectTree dependenciesTree,
            DependenciesSnapshot snapshot,
            CancellationToken cancellationToken = default)
        {
            // Keep a reference to the original tree to return in case we are cancelled.
            IProjectTree originalTree = dependenciesTree;

            bool hasSingleTarget = snapshot.DependenciesByTargetFramework.Count(x => !x.Key.Equals(TargetFramework.Any)) == 1;

            var currentTopLevelNodes = new HashSet <IProjectTree>();

            if (hasSingleTarget)
            {
                await BuildSingleTargetTreeAsync();
            }
            else
            {
                await BuildMultiTargetTreeAsync();
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return(originalTree);
            }

            dependenciesTree = CleanupOldNodes(dependenciesTree, currentTopLevelNodes);

            ProjectImageMoniker rootIcon = _viewModelFactory.GetDependenciesRootIcon(snapshot.HasReachableVisibleUnresolvedDependency).ToProjectSystemType();

            return(dependenciesTree.SetProperties(icon: rootIcon, expandedIcon: rootIcon));

            async Task BuildSingleTargetTreeAsync()
            {
                foreach ((ITargetFramework _, TargetedDependenciesSnapshot targetedSnapshot) in snapshot.DependenciesByTargetFramework)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    dependenciesTree = await BuildSubTreesAsync(
                        rootNode : dependenciesTree,
                        snapshot.ActiveTargetFramework,
                        targetedSnapshot,
                        RememberNewNodes);
                }
            }

            async Task BuildMultiTargetTreeAsync()
            {
                foreach ((ITargetFramework targetFramework, TargetedDependenciesSnapshot targetedSnapshot) in snapshot.DependenciesByTargetFramework)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    if (targetFramework.Equals(TargetFramework.Any))
                    {
                        dependenciesTree = await BuildSubTreesAsync(
                            rootNode : dependenciesTree,
                            snapshot.ActiveTargetFramework,
                            targetedSnapshot,
                            RememberNewNodes);
                    }
                    else
                    {
                        IProjectTree?        node = dependenciesTree.FindChildWithCaption(targetFramework.FriendlyName);
                        bool                 shouldAddTargetNode = node == null;
                        IDependencyViewModel targetViewModel     = _viewModelFactory.CreateTargetViewModel(targetedSnapshot);

                        node = CreateOrUpdateNode(
                            node,
                            targetViewModel,
                            browseObjectProperties: null,
                            isProjectItem: false,
                            additionalFlags: ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp));

                        node = await BuildSubTreesAsync(
                            rootNode : node,
                            snapshot.ActiveTargetFramework,
                            targetedSnapshot,
                            CleanupOldNodes);

                        dependenciesTree = shouldAddTargetNode
                            ? dependenciesTree.Add(node).Parent !
                            : node.Parent !;

                        Assumes.NotNull(dependenciesTree);

                        currentTopLevelNodes.Add(node);
                    }
                }
            }

            IProjectTree RememberNewNodes(IProjectTree rootNode, IEnumerable <IProjectTree> currentNodes)
            {
                if (currentNodes != null)
                {
                    currentTopLevelNodes.AddRange(currentNodes);
                }

                return(rootNode);
            }
        }
예제 #16
0
        private IProjectTree CreateOrUpdateNode(
            IProjectTree?node,
            IDependencyViewModel viewModel,
            IRule?browseObjectProperties,
            bool isProjectItem,
            ProjectTreeFlags?additionalFlags = null,
            ProjectTreeFlags?excludedFlags   = null)
        {
            if (node != null)
            {
                return(UpdateTreeNode());
            }

            string?filePath = viewModel.OriginalModel != null &&
                              viewModel.OriginalModel.TopLevel &&
                              viewModel.OriginalModel.Resolved
                ? viewModel.OriginalModel.GetTopLevelId()
                : viewModel.FilePath;

            ProjectTreeFlags filteredFlags = FilterFlags(viewModel.Flags);

            return(isProjectItem
                ? CreateProjectItemTreeNode()
                : CreateProjectTreeNode());

            IProjectTree CreateProjectTreeNode()
            {
                // For IProjectTree remove ProjectTreeFlags.Common.Reference flag, otherwise CPS would fail to
                // map this node to graph node and GraphProvider would be never called.
                // Only IProjectItemTree can have this flag
                filteredFlags = filteredFlags.Except(DependencyTreeFlags.BaseReferenceFlags);

                return(_treeServices.CreateTree(
                           caption: viewModel.Caption,
                           filePath,
                           browseObjectProperties: browseObjectProperties,
                           icon: viewModel.Icon.ToProjectSystemType(),
                           expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType(),
                           visible: true,
                           flags: filteredFlags));
            }

            IProjectTree CreateProjectItemTreeNode()
            {
                Assumes.NotNull(filePath);

                var itemContext = ProjectPropertiesContext.GetContext(
                    _commonServices.Project,
                    file: filePath,
                    itemType: viewModel.SchemaItemType,
                    itemName: filePath);

                return(_treeServices.CreateTree(
                           caption: viewModel.Caption,
                           itemContext: itemContext,
                           browseObjectProperties: browseObjectProperties,
                           icon: viewModel.Icon.ToProjectSystemType(),
                           expandedIcon: viewModel.ExpandedIcon.ToProjectSystemType(),
                           visible: true,
                           flags: filteredFlags));
            }

            IProjectTree UpdateTreeNode()
            {
                var updatedNodeParentContext = new ProjectTreeCustomizablePropertyContext
                {
                    ExistsOnDisk    = false,
                    ParentNodeFlags = node !.Parent?.Flags ?? default
                };

                var updatedValues = new ReferencesProjectTreeCustomizablePropertyValues
                {
                    Caption      = viewModel.Caption,
                    Flags        = viewModel.Flags,
                    Icon         = viewModel.Icon.ToProjectSystemType(),
                    ExpandedIcon = viewModel.ExpandedIcon.ToProjectSystemType()
                };

                foreach (Lazy <IProjectTreePropertiesProvider, IOrderPrecedenceMetadataView> provider in _projectTreePropertiesProviders)
                {
                    provider.Value.CalculatePropertyValues(updatedNodeParentContext, updatedValues);
                }

                return(node.SetProperties(
                           caption: updatedValues.Caption,
                           browseObjectProperties: browseObjectProperties,
                           icon: updatedValues.Icon,
                           expandedIcon: updatedValues.ExpandedIcon,
                           flags: updatedValues.Flags));
            }

            ProjectTreeFlags FilterFlags(ProjectTreeFlags flags)
            {
                if (additionalFlags.HasValue)
                {
                    flags = flags.Union(additionalFlags.Value);
                }

                if (excludedFlags.HasValue)
                {
                    flags = flags.Except(excludedFlags.Value);
                }

                return(flags);
            }
        }
        /// <summary>
        /// Builds Dependencies tree for given dependencies snapshot
        /// </summary>
        public override async Task <IProjectTree> BuildTreeAsync(
            IProjectTree dependenciesTree,
            IDependenciesSnapshot snapshot,
            CancellationToken cancellationToken = default)
        {
            IProjectTree originalTree = dependenciesTree;

            var currentTopLevelNodes = new List <IProjectTree>();

            IProjectTree RememberNewNodes(IProjectTree rootNode, IEnumerable <IProjectTree> currentNodes)
            {
                if (currentNodes != null)
                {
                    currentTopLevelNodes.AddRange(currentNodes);
                }

                return(rootNode);
            }

            if (snapshot.Targets.Count(x => !x.Key.Equals(TargetFramework.Any)) == 1)
            {
                foreach ((ITargetFramework _, ITargetedDependenciesSnapshot targetedSnapshot) in snapshot.Targets)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(originalTree);
                    }

                    dependenciesTree = await BuildSubTreesAsync(
                        rootNode : dependenciesTree,
                        snapshot.ActiveTarget,
                        targetedSnapshot,
                        RememberNewNodes);
                }
            }
            else
            {
                foreach ((ITargetFramework targetFramework, ITargetedDependenciesSnapshot targetedSnapshot) in snapshot.Targets)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(originalTree);
                    }

                    if (targetFramework.Equals(TargetFramework.Any))
                    {
                        dependenciesTree = await BuildSubTreesAsync(
                            rootNode : dependenciesTree,
                            snapshot.ActiveTarget,
                            targetedSnapshot,
                            RememberNewNodes);
                    }
                    else
                    {
                        IProjectTree         node = dependenciesTree.FindChildWithCaption(targetFramework.FriendlyName);
                        bool                 shouldAddTargetNode = node == null;
                        IDependencyViewModel targetViewModel     = ViewModelFactory.CreateTargetViewModel(targetedSnapshot);

                        node = CreateOrUpdateNode(
                            node,
                            targetViewModel,
                            rule: null,
                            isProjectItem: false,
                            additionalFlags: ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp));

                        node = await BuildSubTreesAsync(
                            rootNode : node,
                            snapshot.ActiveTarget,
                            targetedSnapshot,
                            CleanupOldNodes);

                        dependenciesTree = shouldAddTargetNode
                            ? dependenciesTree.Add(node).Parent
                            : node.Parent;

                        currentTopLevelNodes.Add(node);
                    }
                }
            }

            dependenciesTree = CleanupOldNodes(dependenciesTree, currentTopLevelNodes);

            // now update root Dependencies node status
            ProjectImageMoniker rootIcon = ViewModelFactory.GetDependenciesRootIcon(snapshot.HasUnresolvedDependency).ToProjectSystemType();

            return(dependenciesTree.SetProperties(icon: rootIcon, expandedIcon: rootIcon));
        }
예제 #18
0
        /// <summary>
        /// Builds all available sub trees under root: target framework or Dependencies node
        /// when there is only one target.
        /// </summary>
        private async Task <IProjectTree> BuildSubTreesAsync(
            IProjectTree rootNode,
            ITargetFramework activeTarget,
            ITargetedDependenciesSnapshot targetedSnapshot,
            IProjectCatalogSnapshot catalogs,
            Func <IProjectTree, IEnumerable <IProjectTree>, IProjectTree> syncFunc)
        {
            var currentNodes           = new List <IProjectTree>();
            var grouppedByProviderType = new Dictionary <string, List <IDependency> >(StringComparer.OrdinalIgnoreCase);

            foreach (IDependency dependency in targetedSnapshot.TopLevelDependencies)
            {
                if (!dependency.Visible)
                {
                    if (dependency.Flags.Contains(DependencyTreeFlags.ShowEmptyProviderRootNode))
                    {
                        // if provider sends special invisible node with flag ShowEmptyProviderRootNode, we
                        // need to show provider node even if it does not have any dependencies.
                        grouppedByProviderType.Add(dependency.ProviderType, new List <IDependency>());
                    }

                    continue;
                }

                if (!grouppedByProviderType.TryGetValue(dependency.ProviderType, out List <IDependency> dependencies))
                {
                    dependencies = new List <IDependency>();
                    grouppedByProviderType.Add(dependency.ProviderType, dependencies);
                }

                dependencies.Add(dependency);
            }

            bool isActiveTarget = targetedSnapshot.TargetFramework.Equals(activeTarget);

            foreach (KeyValuePair <string, List <IDependency> > dependencyGroup in grouppedByProviderType)
            {
                IDependencyViewModel subTreeViewModel = ViewModelFactory.CreateRootViewModel(
                    dependencyGroup.Key, targetedSnapshot.CheckForUnresolvedDependencies(dependencyGroup.Key));
                IProjectTree subTreeNode      = rootNode.FindNodeByCaption(subTreeViewModel.Caption);
                bool         isNewSubTreeNode = subTreeNode == null;

                ProjectTreeFlags excludedFlags = ProjectTreeFlags.Empty;
                if (targetedSnapshot.TargetFramework.Equals(TargetFramework.Any))
                {
                    excludedFlags = ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp);
                }

                subTreeNode = CreateOrUpdateNode(
                    subTreeNode,
                    subTreeViewModel,
                    rule: null,
                    isProjectItem: false,
                    excludedFlags: excludedFlags);

                subTreeNode = await BuildSubTreeAsync(
                    subTreeNode,
                    targetedSnapshot,
                    dependencyGroup.Value,
                    catalogs,
                    isActiveTarget,
                    shouldCleanup : !isNewSubTreeNode).ConfigureAwait(false);

                currentNodes.Add(subTreeNode);

                if (isNewSubTreeNode)
                {
                    rootNode = rootNode.Add(subTreeNode).Parent;
                }
                else
                {
                    rootNode = subTreeNode.Parent;
                }
            }

            return(syncFunc(rootNode, currentNodes));
        }
        /// <summary>
        /// Builds all available sub trees under root: target framework or Dependencies node
        /// when there is only one target.
        /// </summary>
        private async Task <IProjectTree> BuildSubTreesAsync(
            IProjectTree rootNode,
            ITargetFramework activeTarget,
            ITargetedDependenciesSnapshot targetedSnapshot,
            Func <IProjectTree, IEnumerable <IProjectTree>, IProjectTree> syncFunc)
        {
            var groupedByProviderType = new Dictionary <string, List <IDependency> >(StringComparers.DependencyProviderTypes);

            foreach (IDependency dependency in targetedSnapshot.TopLevelDependencies)
            {
                if (!dependency.Visible)
                {
                    if (dependency.Flags.Contains(DependencyTreeFlags.ShowEmptyProviderRootNode))
                    {
                        // if provider sends special invisible node with flag ShowEmptyProviderRootNode, we
                        // need to show provider node even if it does not have any dependencies.
                        groupedByProviderType.Add(dependency.ProviderType, new List <IDependency>());
                    }

                    continue;
                }

                if (!groupedByProviderType.TryGetValue(dependency.ProviderType, out List <IDependency> dependencies))
                {
                    dependencies = new List <IDependency>();
                    groupedByProviderType.Add(dependency.ProviderType, dependencies);
                }

                dependencies.Add(dependency);
            }

            var currentNodes = new List <IProjectTree>(capacity: groupedByProviderType.Count);

            bool isActiveTarget = targetedSnapshot.TargetFramework.Equals(activeTarget);

            foreach ((string providerType, List <IDependency> dependencies) in groupedByProviderType)
            {
                IDependencyViewModel subTreeViewModel = ViewModelFactory.CreateRootViewModel(
                    providerType, targetedSnapshot.CheckForUnresolvedDependencies(providerType));
                IProjectTree subTreeNode      = rootNode.FindChildWithCaption(subTreeViewModel.Caption);
                bool         isNewSubTreeNode = subTreeNode == null;

                ProjectTreeFlags excludedFlags = targetedSnapshot.TargetFramework.Equals(TargetFramework.Any)
                    ? ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp)
                    : ProjectTreeFlags.Empty;

                subTreeNode = CreateOrUpdateNode(
                    subTreeNode,
                    subTreeViewModel,
                    rule: null,
                    isProjectItem: false,
                    excludedFlags: excludedFlags);

                subTreeNode = await BuildSubTreeAsync(
                    subTreeNode,
                    targetedSnapshot,
                    dependencies,
                    isActiveTarget,
                    shouldCleanup : !isNewSubTreeNode);

                currentNodes.Add(subTreeNode);

                rootNode = isNewSubTreeNode
                    ? rootNode.Add(subTreeNode).Parent
                    : subTreeNode.Parent;
            }

            return(syncFunc(rootNode, currentNodes));
        }
 private GraphNodeId GetGraphNodeId(string projectPath, GraphNode parentNode, IDependencyViewModel viewModel)
 {
     return(GetGraphNodeId(projectPath, parentNode, viewModel.Caption));
 }
        public static IEnumerable <ImageMoniker> GetIcons(this IDependencyViewModel self)
        {
            yield return(self.Icon);

            yield return(self.ExpandedIcon);
        }