protected override async Task ApplyAsync(IProjectVersionedValue <ImmutableList <string> > value)
        {
            await JoinableFactory.SwitchToMainThreadAsync();

            IProjectVersionedValue <ImmutableList <string> >?previous = AppliedValue;

            AppliedValue = value;

            // To avoid callers seeing an inconsistent state where there are no Imports,
            // we use BlockInitializeOnFirstAppliedValue to block on the first value
            // being applied.
            //
            // Due to that, and to avoid a deadlock when event handlers call back into us
            // while we're still initializing, we avoid firing the events the first time
            // a value is applied.
            if (previous != null)
            {
                VisualBasicVSImports   imports       = VSImports.Value;
                ImmutableList <string> currentValue  = value.Value;
                ImmutableList <string> previousValue = previous.Value;

                foreach (string import in previousValue.Except(currentValue))
                {
                    imports.OnImportRemoved(import);
                }

                foreach (string import in currentValue.Except(previousValue))
                {
                    imports.OnImportAdded(import);
                }
            }
        }
        private void StartupAnalyzerEventSink_MiddlewareAnalysisCompleted(object sender, MiddlewareAnalysis e)
        {
            // Fire-and-forget. We need to get to the UI thread for DTE/IVsHierarchy.
            JoinableCollection.Add(JoinableFactory.RunAsync(async() =>
            {
                await JoinableFactory.SwitchToMainThreadAsync();

                var solution    = _workspace.Value.CurrentSolution;
                var syntaxTrees = new HashSet <SyntaxTree>();
                foreach (var syntax in e.ConfigureMethod.DeclaringSyntaxReferences)
                {
                    syntaxTrees.Add(syntax.SyntaxTree);
                }

                var documentIds = syntaxTrees.Select(s => solution.GetDocumentId(s));
                var hierarchies = documentIds.Select(d => _workspace.Value.GetHierarchy(d.ProjectId)).Where(h => h != null);

                foreach (var hierarchy in hierarchies)
                {
                    if (hierarchy is IVsBrowseObjectContext context && context.UnconfiguredProject == ConfiguredProject.UnconfiguredProject)
                    {
                        var capabilities = ImmutableHashSet <string> .Empty;
                        if (e.Middleware.Any(m => m.UseMethod.Name == "UseSignalR"))
                        {
                            capabilities = ImmutableHashSet.Create("_PublishSignalRService");
                        }

                        await UpdateCapabilitiesAsync(capabilities, CancellationToken.None).ConfigureAwait(false);
                    }
                }
            }));
        }
Example #3
0
        /// <summary>
        /// ApplyAsync is called on the UI thread and its job is to update AppliedValue to be correct based on the changes that have come through data flow after being processed
        /// </summary>
        protected override async Task ApplyAsync(IProjectVersionedValue <DesignTimeInputSnapshot> value)
        {
            // Not using use the ThreadingService property because unit tests
            await JoinableFactory.SwitchToMainThreadAsync();

            IProjectVersionedValue <DesignTimeInputSnapshot>?previous = AppliedValue;

            AppliedValue = value;

            // To avoid callers seeing an inconsistent state where there are no monikers,
            // we use BlockInitializeOnFirstAppliedValue to block on the first value
            // being applied.
            //
            // Due to that, and to avoid a deadlock when event handlers call back into us
            // while we're still initializing, we avoid firing the events the first time
            // a value is applied.
            if (previous != null)
            {
                DesignTimeInputSnapshot currentValue  = value.Value;
                DesignTimeInputSnapshot previousValue = previous.Value;

                foreach (DesignTimeInputFileChange change in currentValue.ChangedInputs)
                {
                    _buildManager.OnDesignTimeOutputDirty(_project.MakeRelative(change.File));
                }

                foreach (string item in previousValue.Inputs.Except(currentValue.Inputs))
                {
                    _buildManager.OnDesignTimeOutputDeleted(_project.MakeRelative(item));
                }
            }
        }
        protected override async Task ApplyAsync(IProjectVersionedValue <ImmutableList <string> > value)
        {
            await JoinableFactory.SwitchToMainThreadAsync();

            ImmutableList <string> current = AppliedValue?.Value ?? ImmutableList <string> .Empty;
            ImmutableList <string> input   = value.Value;

            IEnumerable <string> removed = current.Except(input);
            IEnumerable <string> added   = input.Except(current);

            AppliedValue = value;

            VisualBasicVSImports?imports = VSImports?.Value;

            if (imports != null)
            {
                foreach (string import in removed)
                {
                    imports.OnImportRemoved(import);
                }

                foreach (string import in added)
                {
                    imports.OnImportAdded(import);
                }
            }
        }
Example #5
0
        /// <summary>
        /// ApplyAsync is called on the UI thread and its job is to update AppliedValue to be correct based on the changes that have come through data flow after being processed
        /// </summary>
        protected override async Task ApplyAsync(IProjectVersionedValue <DesignTimeInputsDelta> value)
        {
            // Not using use the ThreadingService property because unit tests
            await JoinableFactory.SwitchToMainThreadAsync();

            DesignTimeInputsDelta delta = value.Value;

            ImmutableHashSet <string>?removedFiles = AppliedValue?.Value.Inputs.Except(delta.Inputs);

            // As it happens the DesignTimeInputsDelta contains all of the state we need
            AppliedValue = value;

            foreach (DesignTimeInputFileChange change in delta.ChangedInputs)
            {
                _buildManager.OnDesignTimeOutputDirty(_project.MakeRelative(change.File));
            }

            if (removedFiles != null)
            {
                foreach (string item in removedFiles)
                {
                    _buildManager.OnDesignTimeOutputDeleted(_project.MakeRelative(item));
                }
            }
        }
        protected override async Task InitializeCoreAsync(CancellationToken cancellationToken)
        {
            // AdviseUpdateSolutionEvents call needs UI thread.
            await JoinableFactory.SwitchToMainThreadAsync(cancellationToken);

            _solutionBuildManager = await _solutionBuildManagerService.GetValueAsync(cancellationToken);

            (_solutionBuildManager as IVsSolutionBuildManager2)?.AdviseUpdateSolutionEvents(this, out _cookie);
            ErrorHandler.ThrowOnFailure(_solutionBuildManager.AdviseUpdateSolutionEvents3(this, out _cookie3));

            _skipAnalyzersForImplicitlyTriggeredBuild = await _options.GetSkipAnalyzersForImplicitlyTriggeredBuildAsync(cancellationToken);

            _options.RegisterOptionChangedEventHandler(OnOptionChangedAsync);
        }
Example #7
0
        protected override async Task DisposeCoreAsync(bool initialized)
        {
            if (initialized)
            {
                if (_cookie != VSConstants.VSCOOKIE_NIL)
                {
                    await JoinableFactory.SwitchToMainThreadAsync();

                    Verify.HResult(_solution.Value.UnadviseSolutionEvents(_cookie));

                    _loadedInHost.TrySetCanceled();
                    _cookie = VSConstants.VSCOOKIE_NIL;
                }
            }
        }
Example #8
0
        protected override async Task InitializeCoreAsync(CancellationToken cancellationToken)
        {
            await JoinableFactory.SwitchToMainThreadAsync(cancellationToken);

            Verify.HResult(_solution.Value.AdviseSolutionEvents(this, out _cookie));

            // In the situation where the solution has already been loaded by the time we're
            // initialized, we need to make sure we set LoadedInHost as we will have missed the
            // event. This can occur when the first CPS project is loaded due to reload of
            // an unloaded project or the first CPS project is loaded in the Add New/Existing Project
            // case.
            Verify.HResult(_solution.Value.GetProperty((int)__VSPROPID4.VSPROPID_IsSolutionFullyLoaded, out object isFullyLoaded));

            if ((bool)isFullyLoaded)
            {
                _loadedInHost.SetResult();
            }
        }