File: InProcess\CodeDefinitionWindow_InProc.cs
Web Access
Project: ..\..\..\src\VisualStudio\IntegrationTest\TestUtilities\Microsoft.VisualStudio.IntegrationTest.Utilities.csproj (Microsoft.VisualStudio.IntegrationTest.Utilities)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.ComponentModel.Composition;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;
 
namespace Microsoft.VisualStudio.IntegrationTest.Utilities.InProcess
{
    internal class CodeDefinitionWindow_InProc : InProcComponent
    {
        private CodeDefinitionWindow_InProc()
        {
        }
 
        public static CodeDefinitionWindow_InProc Create()
            => new CodeDefinitionWindow_InProc();
 
        private static IWpfTextView GetCodeDefinitionWpfTextView()
        {
            var shell = GetGlobalService<SVsUIShell, IVsUIShell>();
            var windowGuid = Guid.Parse(ToolWindowGuids80.CodedefinitionWindow);
 
            Marshal.ThrowExceptionForHR(shell.FindToolWindow(0, ref windowGuid, out var windowFrame));
 
            var view = VsShellUtilities.GetTextView(windowFrame);
            var editorAdaptersService = GetComponentModelService<IVsEditorAdaptersFactoryService>();
 
            var wpfView = editorAdaptersService.GetWpfTextView(view);
 
            Contract.ThrowIfNull(wpfView, "We were unable to get the Code Definition Window view.");
 
            return wpfView;
        }
 
        public void Show()
        {
            InvokeOnUIThread(cancellationToken =>
            {
                var codeDefinitionWindow = GetGlobalService<SVsCodeDefView, IVsCodeDefView>();
                codeDefinitionWindow.ShowWindow();
            });
        }
 
        /// <summary>
        /// Waits for all async processing to complete, including the async processing in the
        /// code definition window itself.
        /// </summary>
        private static void WaitUntilProcessingComplete()
        {
            GetWaitingService().WaitForAsyncOperations(FeatureAttribute.CodeDefinitionWindow);
 
            InvokeOnUIThread(cancellationToken =>
            {
                var codeDefinitionWindow = GetGlobalService<SVsCodeDefView, IVsCodeDefView>();
 
                // The code definition window does some processing on idle, which we can force after we've completed our
                // processing.
                codeDefinitionWindow.ForceIdleProcessing();
            });
        }
 
        /// <summary>
        /// Returns the current line of text in the code definition window itself.
        /// </summary>
        public string GetCurrentLineText()
        {
            WaitUntilProcessingComplete();
 
            return InvokeOnUIThread(cancellationToken =>
            {
                var view = GetCodeDefinitionWpfTextView();
                var subjectBuffer = view.GetBufferContainingCaret();
                var bufferPosition = view.Caret.Position.BufferPosition;
                var line = bufferPosition.GetContainingLine();
 
                return line.GetText();
            });
        }
 
        /// <summary>
        /// Returns the entire text of the code definition window itself.
        /// </summary>
        public string GetText()
        {
            WaitUntilProcessingComplete();
 
            return InvokeOnUIThread(cancellationToken =>
            {
                var view = GetCodeDefinitionWpfTextView();
                return view.TextSnapshot.GetText();
            });
        }
    }
}