/// <summary> /// Specifies if there is unresolved child somewhere in the dependency graph /// </summary> public static bool HasUnresolvedDependency(this IDependency self, ITargetedDependenciesSnapshot snapshot) { return(snapshot.CheckForUnresolvedDependencies(self)); }
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 a dependency is not visible we will still register a top-level group if it // has the ShowEmptyProviderRootNode flag. if (!dependency.Flags.Contains(DependencyTreeFlags.ShowEmptyProviderRootNode)) { // No such flag, so skip it completely. continue; } } if (!groupedByProviderType.TryGetValue(dependency.ProviderType, out List <IDependency> dependencies)) { dependencies = new List <IDependency>(); groupedByProviderType.Add(dependency.ProviderType, dependencies); } // Only add visible dependencies. See note above. if (dependency.Visible) { 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)); if (subTreeViewModel == null) { // In theory this should never happen, as it means we have a dependency model of a type // that no provider claims. https://github.com/dotnet/project-system/issues/3653 continue; } 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)); }
/// <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)); }
/// <summary> /// Builds all available sub trees under root: target framework or Dependencies node /// when there is only one target. /// </summary> private IProjectTree BuildSubTrees( 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 (var 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); } var isActiveTarget = targetedSnapshot.TargetFramework.Equals(activeTarget); foreach (var dependencyGroup in grouppedByProviderType) { var subTreeViewModel = ViewModelFactory.CreateRootViewModel( dependencyGroup.Key, targetedSnapshot.CheckForUnresolvedDependencies(dependencyGroup.Key)); var subTreeNode = rootNode.FindNodeByCaption(subTreeViewModel.Caption); var isNewSubTreeNode = subTreeNode == null; var 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 = BuildSubTree( subTreeNode, targetedSnapshot, dependencyGroup.Value, catalogs, isActiveTarget, shouldCleanup: !isNewSubTreeNode); currentNodes.Add(subTreeNode); if (isNewSubTreeNode) { rootNode = rootNode.Add(subTreeNode).Parent; } else { rootNode = subTreeNode.Parent; } } return(syncFunc(rootNode, currentNodes)); }