protected override bool TryGetProjectNode(IProjectTree targetRootNode, IRelatableItem item, [NotNullWhen(returnValue: true)] out IProjectTree?projectTree)
        {
            IProjectTree?typeGroupNode = targetRootNode.FindChildWithFlags(DependencyTreeFlags.ProjectDependencyGroup);

            projectTree = typeGroupNode?.FindChildWithFlags(ProjectTreeFlags.Create("$ID:" + Library.Name));

            return(projectTree != null);
        }
        public override IProjectTree?FindByPath(IProjectTree root, string path)
        {
            // We are _usually_ passed the project root here, and we know that our tree items are limited to the
            // "Dependencies" subtree, so scope the search to that node.
            //
            // If we are passed a root which is not the project node, we will not find any search results.
            // This does not appear to be an issue, but may one day be required.
            IProjectTree?dependenciesRootNode = root.FindChildWithFlags(DependencyTreeFlags.DependenciesRootNode);

            return(dependenciesRootNode?.GetSelfAndDescendentsDepthFirst().FirstOrDefault((node, p) => StringComparers.Paths.Equals(node.FilePath, p), path));
        }
Esempio n. 3
0
        public async Task <IDependenciesTreeConfiguredProjectSearchContext?> ForConfiguredProjectAsync(ConfiguredProject configuredProject, CancellationToken cancellationToken = default)
        {
            Requires.NotNull(configuredProject, nameof(configuredProject));

            IProjectTree targetRootNode;

            if (_dependenciesNode.FindChildWithFlags(DependencyTreeFlags.TargetNode) == null)
            {
                // Tree does not show any target nodes
                targetRootNode = _dependenciesNode;
            }
            else
            {
                if (configuredProject.Services.ProjectSubscription == null)
                {
                    return(null);
                }

                IProjectSubscriptionUpdate subscriptionUpdate = (await configuredProject.Services.ProjectSubscription.ProjectRuleSource.GetLatestVersionAsync(configuredProject, cancellationToken: cancellationToken)).Value;

                if (!subscriptionUpdate.CurrentState.TryGetValue(ConfigurationGeneral.SchemaName, out IProjectRuleSnapshot configurationGeneralSnapshot) ||
                    !configurationGeneralSnapshot.Properties.TryGetValue(ConfigurationGeneral.TargetFrameworkProperty, out string tf))
                {
                    return(null);
                }

                IProjectTree?targetNode = _dependenciesNode.FindChildWithFlags(ProjectTreeFlags.Create("$TFM:" + tf));

                if (targetNode == null)
                {
                    TraceUtilities.TraceError("Should not fail to find the target node.");
                    return(null);
                }

                targetRootNode = targetNode;
            }

            return(new DependenciesTreeConfiguredProjectSearchContext(_inner, targetRootNode, _hierarchyItemManager, _projectVsServices, _relationProvider));
        }
Esempio n. 4
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,
            TargetFramework activeTarget,
            TargetedDependenciesSnapshot targetedSnapshot,
            Func <IProjectTree, HashSet <IProjectTree>, IProjectTree> syncFunc)
        {
            var groupedByProviderType = new Dictionary <string, List <IDependency> >(StringComparers.DependencyProviderTypes);

            foreach (IDependency dependency in targetedSnapshot.Dependencies)
            {
                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 HashSet <IProjectTree>(capacity: groupedByProviderType.Count);

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

            foreach ((string providerType, List <IDependency> dependencies) in groupedByProviderType)
            {
                (IDependencyViewModel? subTreeViewModel, ProjectTreeFlags? subtreeFlag) = _viewModelFactory.CreateGroupNodeViewModel(
                    providerType,
                    targetedSnapshot.GetMaximumVisibleDiagnosticLevelForProvider(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 = subtreeFlag != null
                    ? rootNode.FindChildWithFlags(subtreeFlag.Value)
                    : 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,
                    browseObjectProperties: 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 !;

                Assumes.NotNull(rootNode);
            }

            return(syncFunc(rootNode, currentNodes));
        }