Пример #1
0
        private IEnumerable <ISuggestedAction> GetLightBulbActions(ILightBulbBroker broker, IWpfTextView view)
        {
            if (!broker.IsLightBulbSessionActive(view))
            {
                var bufferType = view.TextBuffer.ContentType.DisplayName;
                throw new Exception(string.Format("No light bulb session in View!  Buffer content type={0}", bufferType));
            }

            var activeSession = broker.GetSession(view);

            if (activeSession == null || !activeSession.IsExpanded)
            {
                var bufferType = view.TextBuffer.ContentType.DisplayName;
                throw new InvalidOperationException(string.Format("No expanded light bulb session found after View.ShowSmartTag.  Buffer content type={0}", bufferType));
            }

            IEnumerable <SuggestedActionSet> actionSets;

            if (activeSession.TryGetSuggestedActionSets(out actionSets) != QuerySuggestedActionCompletionStatus.Completed)
            {
                actionSets = Array.Empty <SuggestedActionSet>();
            }

            return(SelectActions(actionSets));
        }
Пример #2
0
        public static async Task <bool> WaitForLightBulbSessionAsync(ILightBulbBroker broker, IWpfTextView view, CancellationToken cancellationToken)
        {
            var startTime = DateTimeOffset.Now;

            var active = await Helper.RetryAsync(async cancellationToken =>
            {
                if (broker.IsLightBulbSessionActive(view))
                {
                    return(true);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    throw new InvalidOperationException("Expected a light bulb session to appear.");
                }

                // checking whether there is any suggested action is async up to editor layer and our waiter doesn't track up to that point.
                // so here, we have no other way than sleep (with timeout) to see LB is available.
                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);

                return(broker.IsLightBulbSessionActive(view));
            }, TimeSpan.FromMilliseconds(1), cancellationToken);

            if (!active)
            {
                return(false);
            }

            await WaitForItemsAsync(broker, view, cancellationToken);

            return(true);
        }
Пример #3
0
        private static IssueLocationActionsSource CreateTestSubject(ITagAggregator <ISelectedIssueLocationTag> selectedIssueLocationsTagAggregator,
                                                                    ITagAggregator <IIssueLocationTag> issueLocationsTagAggregator,
                                                                    IIssueSelectionService selectionService = null,
                                                                    ILightBulbBroker lightBulbBroker        = null,
                                                                    ITextView textView = null)
        {
            textView = textView ?? CreateWpfTextView();
            var vsUiShell = Mock.Of <IVsUIShell>();
            var bufferTagAggregatorFactoryService = new Mock <IBufferTagAggregatorFactoryService>();

            bufferTagAggregatorFactoryService
            .Setup(x => x.CreateTagAggregator <ISelectedIssueLocationTag>(textView.TextBuffer))
            .Returns(selectedIssueLocationsTagAggregator);

            bufferTagAggregatorFactoryService
            .Setup(x => x.CreateTagAggregator <IIssueLocationTag>(textView.TextBuffer))
            .Returns(issueLocationsTagAggregator);

            var analysisIssueSelectionServiceMock = new Mock <IIssueSelectionService>();

            analysisIssueSelectionServiceMock.Setup(x => x.SelectedIssue).Returns(Mock.Of <IAnalysisIssueVisualization>());

            selectionService ??= analysisIssueSelectionServiceMock.Object;
            lightBulbBroker ??= Mock.Of <ILightBulbBroker>();

            return(new IssueLocationActionsSource(lightBulbBroker, vsUiShell, bufferTagAggregatorFactoryService.Object, textView, selectionService));
        }
Пример #4
0
        public static Task <bool> WaitForLightBulbSessionAsync(
            ILightBulbBroker broker,
            IWpfTextView view
            )
        {
            var startTime = DateTimeOffset.Now;

            return(Helper.RetryAsync(
                       async() =>
            {
                if (broker.IsLightBulbSessionActive(view))
                {
                    return true;
                }

                if (DateTimeOffset.Now > startTime + Helper.HangMitigatingTimeout)
                {
                    throw new InvalidOperationException(
                        "Expected a light bulb session to appear."
                        );
                }

                // checking whether there is any suggested action is async up to editor layer and our waiter doesn't track up to that point.
                // so here, we have no other way than sleep (with timeout) to see LB is available.
                await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(true);

                return broker.IsLightBulbSessionActive(view);
            },
                       TimeSpan.Zero
                       ));
        }
Пример #5
0
 internal KeyFilterFactory(
     ICompletionBroker completionBroker,
     ISignatureHelpBroker signatureHelpBroker,
     ILightBulbBroker smartTagBroker,
     IAsyncQuickInfoBroker quickInfoBroker)
 {
     _helperFactory = new DisplayWindowHelper(completionBroker, signatureHelpBroker, smartTagBroker, quickInfoBroker);
 }
Пример #6
0
		public Dev14KeyProcessor(IWpfTextView wpfTextView, ILightBulbBroker lightBulbBroker, ISuggestedActionCategoryRegistryService suggestedActionCategoryRegistryService, ISmartTagBroker smartTagBroker, IPeekBroker peekBroker) {
			this.wpfTextView = wpfTextView;
			this.lightBulbBroker = lightBulbBroker;
			this.suggestedActionCategoryRegistryService = suggestedActionCategoryRegistryService;
			this.smartTagBroker = smartTagBroker;
			this.peekBroker = peekBroker;

			AddShortcuts();
		}
Пример #7
0
        public Dev14KeyProcessor(IWpfTextView wpfTextView, ILightBulbBroker lightBulbBroker, ISuggestedActionCategoryRegistryService suggestedActionCategoryRegistryService, ISmartTagBroker smartTagBroker, IPeekBroker peekBroker)
        {
            this.wpfTextView     = wpfTextView;
            this.lightBulbBroker = lightBulbBroker;
            this.suggestedActionCategoryRegistryService = suggestedActionCategoryRegistryService;
            this.smartTagBroker = smartTagBroker;
            this.peekBroker     = peekBroker;

            AddShortcuts();
        }
Пример #8
0
 public IssueLocationActionsSourceProvider([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
                                           IBufferTagAggregatorFactoryService bufferTagAggregatorFactoryService,
                                           IIssueSelectionService selectionService,
                                           ILightBulbBroker lightBulbBroker)
 {
     this.bufferTagAggregatorFactoryService = bufferTagAggregatorFactoryService;
     this.selectionService = selectionService;
     this.lightBulbBroker  = lightBulbBroker;
     vsUiShell             = serviceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;
 }
 private DisplayWindowHelper(
     ITextView view,
     ICompletionBroker completionBroker,
     ISignatureHelpBroker signatureHelpBroker,
     ILightBulbBroker smartTagBroker,
     IAsyncQuickInfoBroker quickInfoBroker)
     : this(completionBroker, signatureHelpBroker, smartTagBroker, quickInfoBroker)
 {
     TextView = view;
 }
 internal DisplayWindowHelper(
     ICompletionBroker completionBroker,
     ISignatureHelpBroker signatureHelpBroker,
     ILightBulbBroker smartTagBroker,
     IAsyncQuickInfoBroker quickInfoBroker)
 {
     _completionBroker    = completionBroker;
     _signatureHelpBroker = signatureHelpBroker;
     _smartTagBroker      = smartTagBroker;
     _quickInfoBroker     = quickInfoBroker;
 }
 public LightBulbItemsSourceProvider(
     JoinableTaskContext joinableTaskContext,
     SVsServiceProvider serviceProvider,
     ILightBulbBroker lightBulbBroker,
     IVsEditorAdaptersFactoryService adaptersFactoryService,
     ISuggestedActionCategoryRegistryService2 categoryRegistryService)
 {
     this.joinableTaskContext     = joinableTaskContext;
     this.serviceProvider         = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
     this.lightBulbBroker         = lightBulbBroker ?? throw new ArgumentNullException(nameof(lightBulbBroker));
     this.adaptersFactoryService  = adaptersFactoryService ?? throw new ArgumentNullException(nameof(adaptersFactoryService));
     this.categoryRegistryService = categoryRegistryService ?? throw new ArgumentNullException(nameof(categoryRegistryService));
 }
Пример #12
0
        public static bool WaitForLightBulbSession(ILightBulbBroker broker, Microsoft.VisualStudio.Text.Editor.IWpfTextView view)
        => Helper.Retry(() => {
            if (broker.IsLightBulbSessionActive(view))
            {
                return(true);
            }

            // checking whether there is any suggested action is async up to editor layer and our waiter doesnt track up to that point.
            // so here, we have no other way than sleep (with timeout) to see LB is available.
            HostWaitHelper.PumpingWait(Task.Delay(TimeSpan.FromSeconds(1)));

            return(broker.IsLightBulbSessionActive(view));
        }, TimeSpan.FromSeconds(0));
Пример #13
0
        public ILightBulbSession GetLightBulbSession()
        {
            ILightBulbBroker broker = EditorShell.Current.ExportProvider.GetExportedValue <ILightBulbBroker>();
            var session             = broker.GetSession(EditorWindow.CoreEditor.View);
            int retries             = 0;

            while (session == null && retries < 10)
            {
                this.DoIdle(1000);
                session = broker.GetSession(EditorWindow.CoreEditor.View);
                retries++;
            }
            return(session);
        }
Пример #14
0
        public static bool WaitForLightBulbSession(ILightBulbBroker broker, Microsoft.VisualStudio.Text.Editor.IWpfTextView view)
        {
            return Helper.Retry<bool>(() =>
            {
                if (broker.IsLightBulbSessionActive(view))
                {
                    return true;
                }

                // checking whether there is any suggested action is async up to editor layer and our waiter doesnt track up to that point.
                // so here, we have no other way than sleep (with timeout) to see LB is available.
                HostWaitHelper.PumpingWait(Task.Delay(TimeSpan.FromSeconds(1)));

                return broker.IsLightBulbSessionActive(view);
            }, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(20));
        }
        public IssueLocationActionsSource(ILightBulbBroker lightBulbBroker,
                                          IVsUIShell vsUiShell,
                                          IBufferTagAggregatorFactoryService bufferTagAggregatorFactoryService,
                                          ITextView textView,
                                          IIssueSelectionService selectionService)
        {
            this.lightBulbBroker  = lightBulbBroker;
            this.vsUiShell        = vsUiShell;
            this.textView         = textView;
            this.selectionService = selectionService;

            issueLocationsTagAggregator              = bufferTagAggregatorFactoryService.CreateTagAggregator <IIssueLocationTag>(textView.TextBuffer);
            issueLocationsTagAggregator.TagsChanged += TagAggregator_TagsChanged;

            selectedIssueLocationsTagAggregator              = bufferTagAggregatorFactoryService.CreateTagAggregator <ISelectedIssueLocationTag>(textView.TextBuffer);
            selectedIssueLocationsTagAggregator.TagsChanged += TagAggregator_TagsChanged;
        }
Пример #16
0
        public static async Task <bool> WaitForLightBulbSessionAsync(ILightBulbBroker broker, IWpfTextView view, CancellationToken cancellationToken)
        {
            var startTime = DateTimeOffset.Now;

            var active = await Helper.RetryAsync(async cancellationToken =>
            {
                if (broker.IsLightBulbSessionActive(view))
                {
                    return(true);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    throw new InvalidOperationException("Expected a light bulb session to appear.");
                }

                if (broker.IsLightBulbSessionActive(view))
                {
                    var session             = broker.GetSession(view);
                    var hasSuggestedActions = await broker.HasSuggestedActionsAsync(session.ActionCategories, view, cancellationToken);

                    return(hasSuggestedActions);
                }

                return(false);
            }, TimeSpan.FromMilliseconds(1), cancellationToken);

            if (!active)
            {
                return(false);
            }

            await WaitForItemsAsync(broker, view, cancellationToken);

            return(true);
        }
Пример #17
0
        private static async Task <IEnumerable <SuggestedActionSet>?> TryWaitForItemsAsync(TestServices testServices, ILightBulbBroker broker, IWpfTextView view, CancellationToken cancellationToken)
        {
            var activeSession = broker.GetSession(view);

            if (activeSession == null)
            {
                var bufferType = view.TextBuffer.ContentType.DisplayName;
                throw new InvalidOperationException($"No expanded light bulb session found after View.ShowSmartTag.  Buffer content type={bufferType}");
            }

            var asyncSession = (IAsyncLightBulbSession)activeSession;
            var tcs          = new TaskCompletionSource <List <SuggestedActionSet> >();

            EventHandler <SuggestedActionsUpdatedArgs>?handler = null;

            handler = (s, e) =>
            {
                // ignore these.  we care about when the lightbulb items are all completed.
                if (e.Status == QuerySuggestedActionCompletionStatus.InProgress)
                {
                    return;
                }

                if (e.Status == QuerySuggestedActionCompletionStatus.Completed)
                {
                    tcs.SetResult(e.ActionSets.ToList());
                }
                else
                {
                    tcs.SetException(new InvalidOperationException($"Light bulb transitioned to non-complete state: {e.Status}"));
                }

                asyncSession.SuggestedActionsUpdated -= handler;
            };

            asyncSession.SuggestedActionsUpdated += handler;

            asyncSession.Dismissed += (_, _) => tcs.TrySetCanceled(new CancellationToken(true));

            if (asyncSession.IsDismissed)
            {
                tcs.TrySetCanceled(new CancellationToken(true));
            }

            // Calling PopulateWithData ensures the underlying session will call SuggestedActionsUpdated at least once
            // with the latest data computed.  This is needed so that if the lightbulb computation is already complete
            // that we hear about the results.
            asyncSession.PopulateWithData(overrideRequestedActionCategories: null, operationContext: null);

            try
            {
                return(await tcs.Task.WithCancellation(cancellationToken));
            }
            catch (OperationCanceledException) when(!cancellationToken.IsCancellationRequested)
            {
                if (Version.Parse("17.1.31928.29") >= await testServices.Shell.GetVersionAsync(cancellationToken))
                {
                    // Unexpected cancellation can occur when the editor dismisses the light bulb without request
                    return(null);
                }

                throw;
            }
        }
Пример #18
0
        public static async Task <IEnumerable <SuggestedActionSet> > WaitForItemsAsync(TestServices testServices, ILightBulbBroker broker, IWpfTextView view, CancellationToken cancellationToken)
        {
            while (true)
            {
                var items = await TryWaitForItemsAsync(testServices, broker, view, cancellationToken);

                if (items is not null)
                {
                    return(items);
                }

                // The session was dismissed unexpectedly. The editor might show it again.
                await testServices.Editor.WaitForEditorOperationsAsync(cancellationToken);
            }
        }
Пример #19
0
        public static async Task <bool> WaitForLightBulbSessionAsync(TestServices testServices, ILightBulbBroker broker, IWpfTextView view, CancellationToken cancellationToken)
        {
            await testServices.Editor.WaitForEditorOperationsAsync(cancellationToken);

            var active = broker.IsLightBulbSessionActive(view);

            if (!active)
            {
                return(false);
            }

            await WaitForItemsAsync(testServices, broker, view, cancellationToken);

            return(true);
        }
Пример #20
0
        private ClassifiedToken[] GetLightbulbPreviewClassifications(
            string menuText,
            ILightBulbBroker broker,
            IWpfTextView view,
            IViewClassifierAggregatorService viewClassifierAggregator,
            IEditorPrimitivesFactoryService editorPrimitives)
        {
            LightBulbHelper.WaitForLightBulbSession(broker, view);

            var bufferType = view.TextBuffer.ContentType.DisplayName;

            if (!broker.IsLightBulbSessionActive(view))
            {
                throw new Exception(string.Format("No Active Smart Tags in View!  Buffer content type={0}", bufferType));
            }

            var activeSession = broker.GetSession(view);

            if (activeSession == null || !activeSession.IsExpanded)
            {
                throw new InvalidOperationException(string.Format("No expanded light bulb session found after View.ShowSmartTag.  Buffer content type={0}", bufferType));
            }

            if (!string.IsNullOrEmpty(menuText))
            {
                IEnumerable <SuggestedActionSet> actionSets;
                if (activeSession.TryGetSuggestedActionSets(out actionSets) != QuerySuggestedActionCompletionStatus.Completed)
                {
                    actionSets = Array.Empty <SuggestedActionSet>();
                }

                var set = actionSets.SelectMany(s => s.Actions).FirstOrDefault(a => a.DisplayText == menuText);
                if (set == null)
                {
                    throw new InvalidOperationException(
                              string.Format("ISuggestionAction {0} not found.  Buffer content type={1}", menuText, bufferType));
                }

                IWpfTextView preview = null;
                object       pane    = HostWaitHelper.PumpingWaitResult(set.GetPreviewAsync(CancellationToken.None));
                if (pane is System.Windows.Controls.UserControl)
                {
                    var container = ((System.Windows.Controls.UserControl)pane).FindName("PreviewDockPanel") as DockPanel;
                    var host      = FindDescendants <UIElement>(container).OfType <IWpfTextViewHost>().LastOrDefault();
                    preview = (host == null) ? null : host.TextView;
                }

                if (preview == null)
                {
                    throw new InvalidOperationException(string.Format("Could not find light bulb preview.  Buffer content type={0}", bufferType));
                }

                activeSession.Collapse();
                var classifier      = viewClassifierAggregator.GetClassifier(preview);
                var classifiedSpans = classifier.GetClassificationSpans(new SnapshotSpan(preview.TextBuffer.CurrentSnapshot, 0, preview.TextBuffer.CurrentSnapshot.Length));
                return(classifiedSpans.Select(x => new ClassifiedToken(x.Span.GetText().ToString(), x.ClassificationType.Classification)).ToArray());
            }

            activeSession.Collapse();
            return(Array.Empty <ClassifiedToken>());
        }
Пример #21
0
        public static async Task <IEnumerable <SuggestedActionSet> > WaitForItemsAsync(ILightBulbBroker broker, IWpfTextView view, CancellationToken cancellationToken)
        {
            var activeSession = broker.GetSession(view);

            if (activeSession is null)
            {
                var bufferType = view.TextBuffer.ContentType.DisplayName;
                throw new InvalidOperationException($"No expanded light bulb session found after View.ShowSmartTag.  Buffer content type={bufferType}");
            }

            var asyncSession = (IAsyncLightBulbSession)activeSession;
            var tcs          = new TaskCompletionSource <List <SuggestedActionSet> >();

            void Handler(object s, SuggestedActionsUpdatedArgs e)
            {
                // ignore these.  we care about when the lightbulb items are all completed.
                if (e.Status == QuerySuggestedActionCompletionStatus.InProgress)
                {
                    return;
                }

                if (e.Status == QuerySuggestedActionCompletionStatus.Completed || e.Status == QuerySuggestedActionCompletionStatus.CompletedWithoutData)
                {
                    tcs.SetResult(e.ActionSets.ToList());
                }
                else
                {
                    tcs.SetException(new InvalidOperationException($"Light bulb transitioned to non-complete state: {e.Status}"));
                }

                asyncSession.SuggestedActionsUpdated -= Handler;
            }

            asyncSession.SuggestedActionsUpdated += Handler;

            asyncSession.Dismissed += (_, _) => tcs.TrySetCanceled(new CancellationToken(true));

            if (asyncSession.IsDismissed)
            {
                tcs.TrySetCanceled(new CancellationToken(true));
            }

            // Calling PopulateWithData ensures the underlying session will call SuggestedActionsUpdated at least once
            // with the latest data computed.  This is needed so that if the lightbulb computation is already complete
            // that we hear about the results.
            asyncSession.PopulateWithData(overrideRequestedActionCategories: null, operationContext: null);

            return(await tcs.Task.WithCancellation(cancellationToken));
        }
Пример #22
0
        public static async Task <IEnumerable <SuggestedActionSet> > WaitForItemsAsync(ILightBulbBroker broker, IWpfTextView view)
        {
            using var cancellationTokenSource = new CancellationTokenSource(Helper.HangMitigatingTimeout);
            var editor = Editor_InProc.Create();

            while (true)
            {
                var items = await TryWaitForItemsAsync(broker, view, cancellationTokenSource.Token);

                if (items is not null)
                {
                    return(items);
                }

                // The session was dismissed unexpectedly. The editor might show it again.
                editor.WaitForEditorOperations(Helper.HangMitigatingTimeout);
            }
        }
Пример #23
0
        public static async Task <IEnumerable <SuggestedActionSet> > WaitForItemsAsync(ILightBulbBroker broker, IWpfTextView view)
        {
            var activeSession = broker.GetSession(view);

            if (activeSession == null)
            {
                var bufferType = view.TextBuffer.ContentType.DisplayName;
                throw new InvalidOperationException($"No expanded light bulb session found after View.ShowSmartTag.  Buffer content type={bufferType}");
            }

            var asyncSession = (IAsyncLightBulbSession)activeSession;
            var tcs          = new TaskCompletionSource <List <SuggestedActionSet> >();

            EventHandler <SuggestedActionsUpdatedArgs>?handler = null;

            handler = (s, e) =>
            {
                // ignore these.  we care about when the lightbulb items are all completed.
                if (e.Status == QuerySuggestedActionCompletionStatus.InProgress)
                {
                    return;
                }

                if (e.Status == QuerySuggestedActionCompletionStatus.Completed)
                {
                    tcs.SetResult(e.ActionSets.ToList());
                }
                else
                {
                    tcs.SetException(new InvalidOperationException($"Light bulb transitioned to non-complete state: {e.Status}"));
                }

                asyncSession.SuggestedActionsUpdated -= handler;
            };

            asyncSession.SuggestedActionsUpdated += handler;

            // Calling PopulateWithData ensures the underlying session will call SuggestedActionsUpdated at least once
            // with the latest data computed.  This is needed so that if the lightbulb computation is already complete
            // that we hear about the results.
            asyncSession.PopulateWithData(overrideRequestedActionCategories: null, operationContext: null);

            return(await tcs.Task.WithTimeout(Helper.HangMitigatingTimeout).ConfigureAwait(false));
        }