Пример #1
0
        protected void OnDependenciesChanged(IDependenciesChangeDiff changes,
                                             IProjectVersionedValue <
                                                 Tuple <IProjectSubscriptionUpdate,
                                                        IProjectCatalogSnapshot,
                                                        IProjectSharedFoldersSnapshot> > e,
                                             RuleHandlerType handlerType)
        {
            IImmutableDictionary <NamedIdentity, IComparable> dataSourceVersions = null;

            lock (_syncObject)
            {
                if (_latestDataSourceVersions == null)
                {
                    // very first time send some versions even for Evaluation
                    dataSourceVersions = e?.DataSourceVersions;
                }

                _latestDataSourceVersions = e?.DataSourceVersions;
                if (handlerType == RuleHandlerType.DesignTimeBuild)
                {
                    // Only update versions after DesignTimeBuild events, since they would bring resolved
                    // dependencies and if some components would want to known when tree latest state changed,
                    // DesignTimeBuild events are the ones that bring final state.
                    dataSourceVersions = _latestDataSourceVersions;
                }
            }

            DependenciesChanged(this,
                                new DependenciesChangedEventArgs(
                                    this,
                                    changes,
                                    e?.Value?.Item2,
                                    dataSourceVersions));
        }
        /// <summary>
        /// Discovers if there any changes to apply for existing node, after it's context changed.
        /// </summary>
        private bool AnyChangesToTrack(IDependencyNode node,
                                       IDependencyNode updatedNode,
                                       IDependenciesChangeDiff diff,
                                       out IEnumerable <IDependencyNode> nodesToAdd,
                                       out IEnumerable <IDependencyNode> nodesToRemove)
        {
            var existingChildren = node.Children;

            if (node.Flags.Contains(DependencyNode.DependsOnOtherProviders))
            {
                var remove = new HashSet <IDependencyNode>(diff.RemovedNodes);
                var add    = new HashSet <IDependencyNode>(diff.AddedNodes);
                foreach (var changedNode in diff.UpdatedNodes)
                {
                    remove.Add(changedNode);
                    add.Add(changedNode);
                }

                nodesToAdd    = add;
                nodesToRemove = remove;
            }
            else
            {
                var updatedChildren = updatedNode.Children;
                var comparer        = new DependencyNodeResolvedStateComparer();
                nodesToRemove = existingChildren.Except(updatedChildren, comparer).ToList();
                nodesToAdd    = updatedChildren.Except(existingChildren, comparer).ToList();
            }

            return(nodesToAdd.Any() || nodesToRemove.Any());
        }
Пример #3
0
 public DependenciesChangedEventArgs(IProjectDependenciesSubTreeProvider provider,
                                     IDependenciesChangeDiff changes,
                                     IProjectCatalogSnapshot catalogs,
                                     IImmutableDictionary <NamedIdentity, IComparable> dataSourceVersions)
 {
     Provider           = provider;
     Changes            = changes;
     Catalogs           = catalogs;
     DataSourceVersions = dataSourceVersions;
 }
 protected void OnDependenciesChanged(IDependenciesChangeDiff changes,
                                      IProjectVersionedValue <
                                          Tuple <IProjectSubscriptionUpdate,
                                                 IProjectCatalogSnapshot,
                                                 IProjectSharedFoldersSnapshot> > e)
 {
     DependenciesChanged(this,
                         new DependenciesChangedEventArgs(
                             this,
                             changes,
                             e?.Value?.Item2,
                             e?.DataSourceVersions));
 }
        /// <summary>
        /// Creates or updates a project tree for a given IProjectDependenciesSubTreeProvider
        /// </summary>
        /// <param name="dependenciesNode"></param>
        /// <param name="subTreeProvider"></param>
        /// <param name="changes"></param>
        /// <param name="catalogs">Can be null if sub tree provider does not use design time build</param>
        /// <param name="cancellationToken"></param>
        /// <returns>IProjectTree for root Dependencies node</returns>
        private IProjectTree CreateOrUpdateSubTreeProviderNode(IProjectTree dependenciesNode,
                                                               IProjectDependenciesSubTreeProvider subTreeProvider,
                                                               IDependenciesChangeDiff changes,
                                                               IProjectCatalogSnapshot catalogs,
                                                               CancellationToken cancellationToken)
        {
            Requires.NotNull(dependenciesNode, nameof(dependenciesNode));
            Requires.NotNull(subTreeProvider, nameof(subTreeProvider));
            Requires.NotNull(subTreeProvider.RootNode, nameof(subTreeProvider.RootNode));
            Requires.NotNullOrEmpty(subTreeProvider.RootNode.Caption, nameof(subTreeProvider.RootNode.Caption));
            Requires.NotNullOrEmpty(subTreeProvider.ProviderType, nameof(subTreeProvider.ProviderType));

            var projectFolder        = Path.GetDirectoryName(UnconfiguredProject.FullPath);
            var providerRootTreeNode = GetSubTreeRootNode(dependenciesNode,
                                                          subTreeProvider.RootNode.Flags);

            if (subTreeProvider.RootNode.HasChildren || subTreeProvider.ShouldBeVisibleWhenEmpty)
            {
                bool newNode = false;
                if (providerRootTreeNode == null)
                {
                    providerRootTreeNode = NewTree(
                        caption: subTreeProvider.RootNode.Caption,
                        visible: true,
                        filePath: subTreeProvider.RootNode.Id.ToString(),
                        browseObjectProperties: null,
                        flags: subTreeProvider.RootNode.Flags,
                        icon: subTreeProvider.RootNode.Icon.ToProjectSystemType(),
                        expandedIcon: subTreeProvider.RootNode.ExpandedIcon.ToProjectSystemType());

                    newNode = true;
                }

                if (changes != null)
                {
                    foreach (var removedItem in changes.RemovedNodes)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(dependenciesNode);
                        }

                        var treeNode = FindProjectTreeNode(providerRootTreeNode, removedItem, projectFolder);
                        if (treeNode != null)
                        {
                            providerRootTreeNode = treeNode.Remove();
                        }
                    }

                    foreach (var updatedItem in changes.UpdatedNodes)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(dependenciesNode);
                        }

                        var treeNode = FindProjectTreeNode(providerRootTreeNode, updatedItem, projectFolder);
                        if (treeNode != null)
                        {
                            var updatedNodeParentContext = GetCustomPropertyContext(treeNode.Parent);
                            var updatedValues            = new ReferencesProjectTreeCustomizablePropertyValues
                            {
                                Caption      = updatedItem.Caption,
                                Flags        = updatedItem.Flags,
                                Icon         = updatedItem.Icon.ToProjectSystemType(),
                                ExpandedIcon = updatedItem.ExpandedIcon.ToProjectSystemType()
                            };

                            ApplyProjectTreePropertiesCustomization(updatedNodeParentContext, updatedValues);

                            // update existing tree node properties
                            treeNode = treeNode.SetProperties(
                                caption: updatedItem.Caption,
                                flags: updatedItem.Flags,
                                icon: updatedItem.Icon.ToProjectSystemType(),
                                expandedIcon: updatedItem.ExpandedIcon.ToProjectSystemType());

                            providerRootTreeNode = treeNode.Parent;
                        }
                    }

                    foreach (var addedItem in changes.AddedNodes)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(dependenciesNode);
                        }

                        var treeNode = FindProjectTreeNode(providerRootTreeNode, addedItem, projectFolder);
                        if (treeNode == null)
                        {
                            treeNode = CreateProjectItemTreeNode(providerRootTreeNode, addedItem, catalogs);

                            providerRootTreeNode = providerRootTreeNode.Add(treeNode).Parent;
                        }
                    }
                }

                if (newNode)
                {
                    dependenciesNode = dependenciesNode.Add(providerRootTreeNode).Parent;
                }
                else
                {
                    dependenciesNode = providerRootTreeNode.Parent;
                }
            }
            else
            {
                if (providerRootTreeNode != null)
                {
                    dependenciesNode = dependenciesNode.Remove(providerRootTreeNode);
                }
            }

            return(dependenciesNode);
        }
        /// <summary>
        /// Creates or updates a project tree for a given IProjectDependenciesSubTreeProvider
        /// </summary>
        /// <param name="dependenciesNode"></param>
        /// <param name="subTreeProvider"></param>
        /// <param name="changes"></param>
        /// <param name="catalogs">Can be null if sub tree provider does not use design time build</param>
        /// <param name="cancellationToken"></param>
        /// <returns>IProjectTree for root Dependencies node</returns>
        private IProjectTree CreateOrUpdateSubTreeProviderNode(IProjectTree dependenciesNode,
                                                               IProjectDependenciesSubTreeProvider subTreeProvider,
                                                               IDependenciesChangeDiff changes,
                                                               IProjectCatalogSnapshot catalogs,
                                                               CancellationToken cancellationToken)
        {
            Requires.NotNull(dependenciesNode, nameof(dependenciesNode));
            Requires.NotNull(subTreeProvider, nameof(subTreeProvider));
            Requires.NotNull(subTreeProvider.RootNode, nameof(subTreeProvider.RootNode));
            Requires.NotNullOrEmpty(subTreeProvider.RootNode.Caption, nameof(subTreeProvider.RootNode.Caption));
            Requires.NotNullOrEmpty(subTreeProvider.ProviderType, nameof(subTreeProvider.ProviderType));

            var providerRootTreeNode = GetSubTreeRootNode(dependenciesNode,
                                                          subTreeProvider.RootNode.Flags);

            if (subTreeProvider.RootNode.HasChildren || subTreeProvider.ShouldBeVisibleWhenEmpty)
            {
                bool newNode = false;
                if (providerRootTreeNode == null)
                {
                    providerRootTreeNode = NewTree(
                        caption: subTreeProvider.RootNode.Caption,
                        visible: true,
                        filePath: subTreeProvider.RootNode.Id.ToString(),
                        browseObjectProperties: null,
                        flags: subTreeProvider.RootNode.Flags,
                        icon: subTreeProvider.RootNode.Icon.ToProjectSystemType(),
                        expandedIcon: subTreeProvider.RootNode.ExpandedIcon.ToProjectSystemType());

                    newNode = true;
                }

                if (changes != null)
                {
                    foreach (var removedItem in changes.RemovedNodes)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(dependenciesNode);
                        }

                        var treeNode = providerRootTreeNode.FindNodeByPath(removedItem.Id.ToString());
                        if (treeNode != null)
                        {
                            providerRootTreeNode = treeNode.Remove();
                        }
                    }

                    foreach (var updatedItem in changes.UpdatedNodes)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(dependenciesNode);
                        }

                        var treeNode = providerRootTreeNode.FindNodeByPath(updatedItem.Id.ToString());
                        if (treeNode != null)
                        {
                            var updatedNodeParentContext = GetCustomPropertyContext(treeNode.Parent);
                            var updatedValues            = new ReferencesProjectTreeCustomizablePropertyValues
                            {
                                Caption      = updatedItem.Caption,
                                Flags        = updatedItem.Flags,
                                Icon         = updatedItem.Icon.ToProjectSystemType(),
                                ExpandedIcon = updatedItem.ExpandedIcon.ToProjectSystemType()
                            };

                            ApplyProjectTreePropertiesCustomization(updatedNodeParentContext, updatedValues);

                            // update existing tree node properties
                            treeNode = treeNode.SetProperties(
                                caption: updatedItem.Caption,
                                flags: updatedItem.Flags,
                                icon: updatedItem.Icon.ToProjectSystemType(),
                                expandedIcon: updatedItem.ExpandedIcon.ToProjectSystemType());

                            providerRootTreeNode = treeNode.Parent;
                        }
                    }

                    var configuredProjectExports = GetActiveConfiguredProjectExports(ActiveConfiguredProject);
                    foreach (var addedItem in changes.AddedNodes)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(dependenciesNode);
                        }

                        var treeNode = providerRootTreeNode.FindNodeByPath(addedItem.Id.ToString());
                        if (treeNode == null)
                        {
                            IRule rule = null;
                            if (addedItem.Properties != null)
                            {
                                // when itemSpec is not in valid absolute path format, property page does not show
                                // item name correctly.
                                var itemSpec = addedItem.Flags.Contains(DependencyNode.CustomItemSpec)
                                    ? addedItem.Caption
                                    : addedItem.Id.ItemSpec;
                                var itemContext = ProjectPropertiesContext.GetContext(UnconfiguredProject,
                                                                                      addedItem.Id.ItemType,
                                                                                      itemSpec);
                                if (addedItem.Resolved)
                                {
                                    rule = GetRuleForResolvableReference(
                                        itemContext,
                                        new KeyValuePair <string, IImmutableDictionary <string, string> >(
                                            addedItem.Id.ItemSpec, addedItem.Properties),
                                        catalogs,
                                        configuredProjectExports);
                                }
                                else
                                {
                                    rule = GetRuleForUnresolvableReference(
                                        itemContext,
                                        catalogs,
                                        configuredProjectExports);
                                }
                            }

                            // Notify about tree changes to customization context
                            var customTreePropertyContext = GetCustomPropertyContext(providerRootTreeNode);
                            var customTreePropertyValues  = new ReferencesProjectTreeCustomizablePropertyValues
                            {
                                Caption = addedItem.Caption,
                                Flags   = addedItem.Flags,
                                Icon    = addedItem.Icon.ToProjectSystemType()
                            };

                            ApplyProjectTreePropertiesCustomization(customTreePropertyContext, customTreePropertyValues);

                            treeNode = NewTree(caption: addedItem.Caption,
                                               visible: true,
                                               filePath: addedItem.Id.ToString(),
                                               browseObjectProperties: rule,
                                               flags: addedItem.Flags,
                                               icon: addedItem.Icon.ToProjectSystemType(),
                                               expandedIcon: addedItem.ExpandedIcon.ToProjectSystemType());

                            providerRootTreeNode = providerRootTreeNode.Add(treeNode).Parent;
                        }
                    }
                }

                if (newNode)
                {
                    dependenciesNode = dependenciesNode.Add(providerRootTreeNode).Parent;
                }
                else
                {
                    dependenciesNode = providerRootTreeNode.Parent;
                }
            }
            else
            {
                if (providerRootTreeNode != null)
                {
                    dependenciesNode = dependenciesNode.Remove(providerRootTreeNode);
                }
            }

            return(dependenciesNode);
        }
 public ProjectContextEventArgs(IDependenciesGraphProjectContext context,
                                IDependenciesChangeDiff diff = null)
 {
     Context = context;
     Diff    = diff ?? new DependenciesChange().GetDiff();
 }