Ejemplo n.º 1
0
        protected override void Initialize()
        {
            using (UnconfiguredProjectAsynchronousTasksService.LoadedProject())
            {
                // this.IsApplicable may take a project lock, so we can't do it inline with this method
                // which is holding a private lock.  It turns out that doing it asynchronously isn't a problem anyway,
                // so long as we guard against races with the Dispose method.
                UnconfiguredProjectAsynchronousTasksService.LoadedProjectAsync(
                    async delegate
                {
                    await TaskScheduler.Default.SwitchTo(alwaysYield: true);
                    UnconfiguredProjectAsynchronousTasksService.
                    UnloadCancellationToken.ThrowIfCancellationRequested();

                    lock (SyncObject)
                    {
                        Verify.NotDisposed(this);

                        var intermediateBlock = new BufferBlock <
                            IProjectVersionedValue <
                                IProjectSubscriptionUpdate> >();

                        _projectSubscriptionLink = ProjectSubscriptionService.JointRuleSource.SourceBlock.LinkTo(
                            intermediateBlock,
                            ruleNames: UnresolvedReferenceRuleNames.Union(ResolvedReferenceRuleNames),
                            suppressVersionOnlyUpdates: false);

                        var actionBlock = new ActionBlock <
                            IProjectVersionedValue <
                                Tuple <IProjectSubscriptionUpdate,
                                       IProjectCatalogSnapshot,
                                       IProjectSharedFoldersSnapshot> > >
                                              (new Action <
                                                  IProjectVersionedValue <
                                                      Tuple <IProjectSubscriptionUpdate,
                                                             IProjectCatalogSnapshot,
                                                             IProjectSharedFoldersSnapshot> > >(
                                                  ProjectSubscriptionService_Changed),
                                              new ExecutionDataflowBlockOptions()
                        {
                            NameFormat = "ReferencesSubtree Input: {1}"
                        });

                        _projectSyncLink = ProjectDataSources.SyncLinkTo(
                            intermediateBlock.SyncLinkOptions(),
                            ProjectSubscriptionService.ProjectCatalogSource.SourceBlock.SyncLinkOptions(),
                            ProjectSubscriptionService.SharedFoldersSource.SourceBlock.SyncLinkOptions(),
                            actionBlock);
                    }
                },
                    registerFaultHandler: true);
            }
        }
        /// <summary>
        /// Generates the original references directory tree.
        /// </summary>
        protected override void Initialize()
        {
            using (UnconfiguredProjectAsynchronousTasksService.LoadedProject())
            {
                base.Initialize();

                // this.IsApplicable may take a project lock, so we can't do it inline with this method
                // which is holding a private lock.  It turns out that doing it asynchronously isn't a problem anyway,
                // so long as we guard against races with the Dispose method.
                UnconfiguredProjectAsynchronousTasksService.LoadedProjectAsync(
                    async delegate
                {
                    await TaskScheduler.Default.SwitchTo(alwaysYield: true);
                    UnconfiguredProjectAsynchronousTasksService
                    .UnloadCancellationToken.ThrowIfCancellationRequested();

                    lock (SyncObject)
                    {
                        foreach (var provider in SubTreeProviders)
                        {
                            provider.Value.DependenciesChanged += OnDependenciesChanged;
                        }

                        Verify.NotDisposed(this);
                        var nowait = SubmitTreeUpdateAsync(
                            (treeSnapshot, configuredProjectExports, cancellationToken) =>
                        {
                            var dependenciesNode = CreateDependenciesFolder(null);
                            dependenciesNode     = CreateOrUpdateSubTreeProviderNodes(dependenciesNode,
                                                                                      cancellationToken);

                            return(Task.FromResult(new TreeUpdateResult(dependenciesNode, true)));
                        });
                    }
                },
                    registerFaultHandler: true);
            }
        }
Ejemplo n.º 3
0
        protected override void Initialize()
        {
#pragma warning disable RS0030 // symbol LoadedProject is banned
            using (UnconfiguredProjectAsynchronousTasksService.LoadedProject())
            {
                base.Initialize();

                // this.IsApplicable may take a project lock, so we can't do it inline with this method
                // which is holding a private lock.  It turns out that doing it asynchronously isn't a problem anyway,
                // so long as we guard against races with the Dispose method.
                UnconfiguredProjectAsynchronousTasksService.LoadedProjectAsync(
                    async delegate
                {
                    await TaskScheduler.Default.SwitchTo(alwaysYield: true);
                    UnconfiguredProjectAsynchronousTasksService
                    .UnloadCancellationToken.ThrowIfCancellationRequested();

                    lock (SyncObject)
                    {
                        Verify.NotDisposed(this);

                        // Issue this token before hooking the SnapshotChanged event to prevent a race
                        // where a snapshot tree is replaced by the initial, empty tree created below.
                        // The handler will cancel this token before submitting its update.
                        CancellationToken initialTreeCancellationToken = _treeUpdateCancellationSeries.CreateNext();

                        _ = SubmitTreeUpdateAsync(
                            delegate
                        {
                            IProjectTree dependenciesNode = CreateDependenciesFolder();

                            return(Task.FromResult(new TreeUpdateResult(dependenciesNode)));
                        },
                            initialTreeCancellationToken);

                        ITargetBlock <SnapshotChangedEventArgs> actionBlock = DataflowBlockSlim.CreateActionBlock <SnapshotChangedEventArgs>(
                            e => OnDependenciesSnapshotChanged(_dependenciesSnapshotProvider, e),
                            "DependenciesProjectTreeProviderSource {1}",
                            skipIntermediateInputData: true);
                        _snapshotEventListener = _dependenciesSnapshotProvider.SnapshotChangedSource.LinkTo(actionBlock, new DataflowLinkOptions()
                        {
                            PropagateCompletion = true
                        });
                    }
                },
                    registerFaultHandler: true);
            }
#pragma warning restore RS0030 // symbol LoadedProject is banned

            IProjectTree CreateDependenciesFolder()
            {
                var values = new ReferencesProjectTreeCustomizablePropertyValues
                {
                    Caption      = Resources.DependenciesNodeName,
                    Icon         = ManagedImageMonikers.ReferenceGroup.ToProjectSystemType(),
                    ExpandedIcon = ManagedImageMonikers.ReferenceGroup.ToProjectSystemType(),
                    Flags        = DependencyTreeFlags.DependenciesRootNodeFlags
                };

                // Allow property providers to perform customization.
                // These are ordered from lowest priority to highest, allowing higher priority
                // providers to override lower priority providers.
                foreach (IProjectTreePropertiesProvider provider in _projectTreePropertiesProviders.ExtensionValues())
                {
                    provider.CalculatePropertyValues(null, values);
                }

                // Note that all the parameters are specified so we can force this call to an
                // overload of NewTree available prior to 15.5 versions of CPS. Once a 15.5 build
                // is publicly available we can move this to an overload with default values for
                // most of the parameters, and we'll only need to pass the interesting ones.
                return(NewTree(
                           caption: values.Caption,
                           filePath: null,
                           browseObjectProperties: null,
                           icon: values.Icon,
                           expandedIcon: values.ExpandedIcon,
                           visible: true,
                           flags: values.Flags));
            }
        }
        /// <summary>
        /// Generates the original references directory tree.
        /// </summary>
        protected override void Initialize()
        {
#pragma warning disable RS0030 // symbol LoadedProject is banned
            using (UnconfiguredProjectAsynchronousTasksService.LoadedProject())
#pragma warning restore RS0030
            {
#pragma warning disable RS0030 // https://github.com/dotnet/roslyn-analyzers/issues/3295
                base.Initialize();
#pragma warning restore RS0030

                // this.IsApplicable may take a project lock, so we can't do it inline with this method
                // which is holding a private lock.  It turns out that doing it asynchronously isn't a problem anyway,
                // so long as we guard against races with the Dispose method.
#pragma warning disable RS0030 // symbol LoadedProjectAsync is banned
                UnconfiguredProjectAsynchronousTasksService.LoadedProjectAsync(
#pragma warning restore RS0030
                    async delegate
                {
                    await TaskScheduler.Default.SwitchTo(alwaysYield: true);
                    UnconfiguredProjectAsynchronousTasksService
                    .UnloadCancellationToken.ThrowIfCancellationRequested();

                    lock (SyncObject)
                    {
                        Verify.NotDisposed(this);

                        // Issue this token before hooking the SnapshotChanged event to prevent a race
                        // where a snapshot tree is replaced by the initial, empty tree created below.
                        // The handler will cancel this token before submitting its update.
                        CancellationToken initialTreeCancellationToken = _treeUpdateCancellationSeries.CreateNext();

                        _ = SubmitTreeUpdateAsync(
                            delegate
                        {
                            IProjectTree dependenciesNode = CreateDependenciesNode();

                            return(Task.FromResult(new TreeUpdateResult(dependenciesNode)));
                        },
                            initialTreeCancellationToken);

                        ITargetBlock <SnapshotChangedEventArgs> actionBlock = DataflowBlockFactory.CreateActionBlock <SnapshotChangedEventArgs>(
                            OnDependenciesSnapshotChangedAsync,
                            _project,
                            nameFormat: "DependenciesProjectTreeProviderSource {1}",
                            skipIntermediateInputData: true);
                        _snapshotEventListener = _dependenciesSnapshotProvider.SnapshotChangedSource.LinkTo(actionBlock, DataflowOption.PropagateCompletion);
                    }
                },
                    registerFaultHandler: true);
            }

            IProjectTree CreateDependenciesNode()
            {
                var values = new ReferencesProjectTreeCustomizablePropertyValues
                {
                    Caption      = Resources.DependenciesNodeName,
                    Icon         = KnownMonikers.ReferenceGroup.ToProjectSystemType(),
                    ExpandedIcon = KnownMonikers.ReferenceGroup.ToProjectSystemType(),
                    Flags        = ProjectTreeFlags.Create(ProjectTreeFlags.Common.BubbleUp)
                                   + ProjectTreeFlags.Create(ProjectTreeFlags.Common.ReferencesFolder)
                                   + ProjectTreeFlags.Create(ProjectTreeFlags.Common.VirtualFolder)
                                   + DependencyTreeFlags.DependenciesRootNode
                };

                // Allow property providers to perform customization.
                // These are ordered from lowest priority to highest, allowing higher priority
                // providers to override lower priority providers.
                foreach (IProjectTreePropertiesProvider provider in _projectTreePropertiesProviders.ExtensionValues())
                {
                    provider.CalculatePropertyValues(ProjectTreeCustomizablePropertyContext.Instance, values);
                }

                return(NewTree(
                           caption: values.Caption,
                           icon: values.Icon,
                           expandedIcon: values.ExpandedIcon,
                           flags: values.Flags));
            }
        }