From ef33d325804d8743dfed9c9a1a4eec249a8a6ab9 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Wed, 4 Jun 2025 14:36:17 -0700 Subject: [PATCH] Decouple EditorFeatures.Test.Utilities from VS services Microsoft.CodeAnalysis.EditorFeatures.Test.Utilities depended on Microsoft.VisualStudio.Editor which brought along various VS layer services. Further, we had some stub implementations of those VS services there. Digging into this this coupling wasn't really necessary: 1. There were EditorFeatures tests using the editor adapters stub, but those tests pass just fine without it, so that was easy to move to the VS specific tests. 2. StubVsServiceExporters didn't appear to be used either, so unsure why those were in this layer at all. Those were also moved. 3. We had implementations of some settings services, which it's easier to just delete and remove the options persister from the composition in the first place. This also better ensures that we don't have code that might try creating registry keys from ILocalRegistry which we absolutely don't want. --- ...isualBasicCompletionCommandHandlerTests.vb | 6 +- ...lysis.EditorFeatures.Test.Utilities.csproj | 2 - .../TestUtilities/StubLocalRegistry.cs | 105 ---------- .../TestUtilities/StubSettingsManagerHost.cs | 188 ------------------ .../StubVsEditorAdaptersFactoryService.cs | 70 ------- .../TestUtilities/StubVsServiceExporter`1.cs | 29 --- .../TestUtilities/StubVsServiceExporter`2.cs | 74 ------- .../TestUtilities2/MockServiceProvider.vb | 22 -- .../StubVsEditorAdaptersFactoryService.vb | 79 ++++++++ .../TestUtilities2/StubVsServiceExporter`1.vb | 27 +++ .../TestUtilities2/StubVsServiceExporter`2.vb | 68 +++++++ .../VisualStudioTestCompositions.vb | 3 +- 12 files changed, 179 insertions(+), 494 deletions(-) delete mode 100644 src/EditorFeatures/TestUtilities/StubLocalRegistry.cs delete mode 100644 src/EditorFeatures/TestUtilities/StubSettingsManagerHost.cs delete mode 100644 src/EditorFeatures/TestUtilities/StubVsEditorAdaptersFactoryService.cs delete mode 100644 src/EditorFeatures/TestUtilities/StubVsServiceExporter`1.cs delete mode 100644 src/EditorFeatures/TestUtilities/StubVsServiceExporter`2.cs create mode 100644 src/VisualStudio/TestUtilities2/StubVsEditorAdaptersFactoryService.vb create mode 100644 src/VisualStudio/TestUtilities2/StubVsServiceExporter`1.vb create mode 100644 src/VisualStudio/TestUtilities2/StubVsServiceExporter`2.vb diff --git a/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb b/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb index 475ba0b5ffed9..0bd026ff10c27 100644 --- a/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb +++ b/src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb @@ -2607,7 +2607,7 @@ Class C End Sub End Class }]]>, - extraExportedTypes:={GetType(MockSnippetInfoService), GetType(SnippetCompletionProvider), GetType(StubVsEditorAdaptersFactoryService)}.ToList()) + extraExportedTypes:={GetType(MockSnippetInfoService), GetType(SnippetCompletionProvider)}.ToList()) state.Workspace.GlobalOptions.SetGlobalOption(CompletionOptionsStorage.SnippetsBehavior, LanguageNames.VisualBasic, SnippetsRule.AlwaysInclude) @@ -2628,7 +2628,7 @@ Class C End Sub End Class }]]>, - extraExportedTypes:={GetType(MockSnippetInfoService), GetType(SnippetCompletionProvider), GetType(StubVsEditorAdaptersFactoryService)}.ToList()) + extraExportedTypes:={GetType(MockSnippetInfoService), GetType(SnippetCompletionProvider)}.ToList()) state.Workspace.GlobalOptions.SetGlobalOption(CompletionOptionsStorage.SnippetsBehavior, LanguageNames.VisualBasic, SnippetsRule.AlwaysInclude) @@ -2650,7 +2650,7 @@ Class C End Sub End Class }]]>, - extraExportedTypes:={GetType(MockSnippetInfoService), GetType(SnippetCompletionProvider), GetType(StubVsEditorAdaptersFactoryService)}.ToList()) + extraExportedTypes:={GetType(MockSnippetInfoService), GetType(SnippetCompletionProvider)}.ToList()) state.Workspace.GlobalOptions.SetGlobalOption(CompletionOptionsStorage.SnippetsBehavior, LanguageNames.VisualBasic, SnippetsRule.AlwaysInclude) diff --git a/src/EditorFeatures/TestUtilities/Microsoft.CodeAnalysis.EditorFeatures.Test.Utilities.csproj b/src/EditorFeatures/TestUtilities/Microsoft.CodeAnalysis.EditorFeatures.Test.Utilities.csproj index 73a17ef2dd304..6d412bd59c5d0 100644 --- a/src/EditorFeatures/TestUtilities/Microsoft.CodeAnalysis.EditorFeatures.Test.Utilities.csproj +++ b/src/EditorFeatures/TestUtilities/Microsoft.CodeAnalysis.EditorFeatures.Test.Utilities.csproj @@ -22,9 +22,7 @@ - - diff --git a/src/EditorFeatures/TestUtilities/StubLocalRegistry.cs b/src/EditorFeatures/TestUtilities/StubLocalRegistry.cs deleted file mode 100644 index 1da13ce4e0941..0000000000000 --- a/src/EditorFeatures/TestUtilities/StubLocalRegistry.cs +++ /dev/null @@ -1,105 +0,0 @@ -// 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.Runtime.InteropServices.ComTypes; -using Microsoft.VisualStudio; -using Microsoft.VisualStudio.Shell.Interop; - -namespace Microsoft.CodeAnalysis.Editor.UnitTests; - -internal sealed class StubLocalRegistry : ILocalRegistry5, ILocalRegistry4, ILocalRegistry3 -{ - int ILocalRegistry.CreateInstance(Guid clsid, object punkOuter, ref Guid riid, uint dwFlags, out IntPtr ppvObj) - { - throw new NotImplementedException(); - } - - int ILocalRegistry.GetTypeLibOfClsid(Guid clsid, out ITypeLib pptLib) - { - throw new NotImplementedException(); - } - - int ILocalRegistry.GetClassObjectOfClsid(ref Guid clsid, uint dwFlags, IntPtr lpReserved, ref Guid riid, out IntPtr ppvClassObject) - { - throw new NotImplementedException(); - } - - int ILocalRegistry2.CreateInstance(Guid clsid, object punkOuter, ref Guid riid, uint dwFlags, out IntPtr ppvObj) - { - throw new NotImplementedException(); - } - - int ILocalRegistry2.GetTypeLibOfClsid(Guid clsid, out ITypeLib pptLib) - { - throw new NotImplementedException(); - } - - int ILocalRegistry2.GetClassObjectOfClsid(ref Guid clsid, uint dwFlags, IntPtr lpReserved, ref Guid riid, IntPtr ppvClassObject) - { - throw new NotImplementedException(); - } - - int ILocalRegistry2.GetLocalRegistryRoot(out string pbstrRoot) - { - throw new NotImplementedException(); - } - - int ILocalRegistry3.CreateInstance(Guid clsid, object punkOuter, ref Guid riid, uint dwFlags, out IntPtr ppvObj) - { - throw new NotImplementedException(); - } - - int ILocalRegistry3.GetTypeLibOfClsid(Guid clsid, out ITypeLib pptLib) - { - throw new NotImplementedException(); - } - - int ILocalRegistry3.GetClassObjectOfClsid(ref Guid clsid, uint dwFlags, IntPtr lpReserved, ref Guid riid, IntPtr ppvClassObject) - { - throw new NotImplementedException(); - } - - int ILocalRegistry3.GetLocalRegistryRoot(out string pbstrRoot) - { - throw new NotImplementedException(); - } - - int ILocalRegistry3.CreateManagedInstance(string codeBase, string assemblyName, string typeName, ref Guid riid, out IntPtr ppvObj) - { - throw new NotImplementedException(); - } - - int ILocalRegistry3.GetClassObjectOfManagedClass(string codeBase, string assemblyName, string typeName, ref Guid riid, out IntPtr ppvClassObject) - { - throw new NotImplementedException(); - } - - int ILocalRegistry4.RegisterClassObject(ref Guid rclsid, out uint pdwCookie) - { - throw new NotImplementedException(); - } - - int ILocalRegistry4.RevokeClassObject(uint dwCookie) - { - throw new NotImplementedException(); - } - - int ILocalRegistry4.RegisterInterface(ref Guid riid) - { - throw new NotImplementedException(); - } - - int ILocalRegistry4.GetLocalRegistryRootEx(uint dwRegType, out uint pdwRegRootHandle, out string pbstrRoot) - { - pdwRegRootHandle = unchecked((uint)__VsLocalRegistryRootHandle.RegHandle_CurrentUser); - pbstrRoot = "Software\\Microsoft\\VisualStudio\\17.0_Test"; - return VSConstants.S_OK; - } - - int ILocalRegistry5.CreateAggregatedManagedInstance(string codeBase, string AssemblyName, string TypeName, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObj) - { - throw new NotImplementedException(); - } -} diff --git a/src/EditorFeatures/TestUtilities/StubSettingsManagerHost.cs b/src/EditorFeatures/TestUtilities/StubSettingsManagerHost.cs deleted file mode 100644 index 3b49070da8dcc..0000000000000 --- a/src/EditorFeatures/TestUtilities/StubSettingsManagerHost.cs +++ /dev/null @@ -1,188 +0,0 @@ -// 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.Collections.Generic; -using System.Collections.Immutable; -using System.ComponentModel; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.VisualStudio.PlatformUI; -using Microsoft.VisualStudio.Settings; -using Microsoft.VisualStudio.Settings.Telemetry; - -namespace Microsoft.CodeAnalysis.Editor.UnitTests; - -internal sealed class StubSettingsManagerHost : ISettingsManagerHost5 -{ - Task ISettingsManagerHost.AppInitCompletionTask => throw new NotImplementedException(); - - ISettingNameTranslator? ISettingsManagerHost.NameTranslator => null; - - IStringStorage ISettingsManagerHost.PrivateStorage { get; } = new StringStorage(); - - ISettingsLogger? ISettingsManagerHost.Logger => null; - - string ISettingsManagerHost.CollectionName => throw new NotImplementedException(); - - string? ISettingsManagerHost.TelemetrySettings => null; - - string ISettingsManagerHost.AppDir { get; } = Path.GetRandomFileName(); - - IRemoteDefaultsStore? ISettingsManagerHost3.RemoteDefaultsStore => null; - - string ISettingsManagerHost4.DurableHostIdentity => "roslyn-CI"; - - IStoreUpdateLogger? ISettingsManagerHost4.StoreUpdateLogger => null; - - bool ISettingsManagerHost4.IsRoamingEnabledByDefault => false; - - bool ISettingsManagerHost5.IsRoamingAndSharingAllowed => false; - - event EventHandler ISettingsManagerHost.IdleStateChanged - { - add - { - throw new NotImplementedException(); - } - - remove - { - throw new NotImplementedException(); - } - } - - event AsyncEventHandler ISettingsManagerHost.HostShuttingDown - { - add - { - throw new NotImplementedException(); - } - - remove - { - throw new NotImplementedException(); - } - } - - bool ISettingsManagerHost.IsSharedOrRoamedSetting(string settingName) - { - // Don't roam settings in tests - return false; - } - - Task ISettingsManagerHost2.GetTelemetrySettingsAsync() - { - throw new NotImplementedException(); - } - - Task ISettingsManagerHost5.GetServiceStreamAsync(CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - private sealed class StringStorage : IStringStorage2, IAsyncStringStorage - { - private ImmutableDictionary _values = ImmutableDictionary.Empty; - private PropertyChangedEventHandler? _propertyChanged; - private PropertyChangedAsyncEventHandler? _propertyChangedAsync; - - event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged - { - add => _propertyChanged += value; - remove => _propertyChanged -= value; - } - - event PropertyChangedAsyncEventHandler IStringStorage.PropertyChangedAsync - { - add => _propertyChangedAsync += value; - remove => _propertyChangedAsync -= value; - } - - event PropertyChangedAsyncEventHandler IAsyncStringStorage.PropertyChangedAsync - { - add => ((IStringStorage)this).PropertyChangedAsync += value; - remove => ((IStringStorage)this).PropertyChangedAsync -= value; - } - - event StoreUpdatedEventHandler IAsyncStringStorage.StoreUpdated - { - add - { - throw new NotImplementedException(); - } - - remove - { - throw new NotImplementedException(); - } - } - - private async Task FireChangeEventAsync(string name) - { - _propertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); - await (_propertyChangedAsync?.RaiseEventAsync(this, new PropertyChangedEventArgs(name)) ?? Task.CompletedTask); - } - - Task IStringStorage.ClearAsync(CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - Task IAsyncStringStorage.ClearAsync(CancellationToken cancellationToken) - => ((IStringStorage)this).ClearAsync(cancellationToken); - - async Task IStringStorage.DeleteIfExistsAsync(string name, CancellationToken cancellationToken) - { - if (ImmutableInterlocked.TryRemove(ref _values, name, out _)) - { - await FireChangeEventAsync(name); - } - } - - Task IAsyncStringStorage.DeleteIfExistsAsync(string name, CancellationToken cancellationToken) - => ((IStringStorage)this).DeleteIfExistsAsync(name, cancellationToken); - - StringWithMachineLocalFlag? IStringStorage.Get(string name) - { - return _values.GetValueOrDefault(name); - } - - Task> IAsyncStringStorage.GetAllSinceVersionAsync(int modifiedAfterRevision, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - Task IAsyncStringStorage.GetAsync(string name, CancellationToken cancellationToken) - { - return Task.FromResult(_values.GetValueOrDefault(name)); - } - - Task IAsyncStringStorage.GetStoreIdentityAsync(CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - string[] IStringStorage.NamesStartingWith(string prefix) - { - throw new NotImplementedException(); - } - - Task IStringStorage.SetAsync(string name, StringWithMachineLocalFlag value, Action onBeforePropertyChanged, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - Task IAsyncStringStorage.SetAsync(NamedVersionedString value, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - void IStringStorage2.ForEachSettingNameStartingWith(string prefix, CharSpanProcessorDelegate processFunc) - { - throw new NotImplementedException(); - } - } -} diff --git a/src/EditorFeatures/TestUtilities/StubVsEditorAdaptersFactoryService.cs b/src/EditorFeatures/TestUtilities/StubVsEditorAdaptersFactoryService.cs deleted file mode 100644 index d0832c21f13ff..0000000000000 --- a/src/EditorFeatures/TestUtilities/StubVsEditorAdaptersFactoryService.cs +++ /dev/null @@ -1,70 +0,0 @@ -// 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. - -#nullable disable - -using System; -using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.VisualStudio.Editor; -using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Text.Editor; -using Microsoft.VisualStudio.TextManager.Interop; -using Microsoft.VisualStudio.Utilities; -using IServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider; - -namespace Microsoft.CodeAnalysis.Editor.UnitTests; - -[Export(typeof(IVsEditorAdaptersFactoryService))] -[PartNotDiscoverable] -internal sealed class StubVsEditorAdaptersFactoryService : IVsEditorAdaptersFactoryService -{ - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public StubVsEditorAdaptersFactoryService() - { - } - - public IVsCodeWindow CreateVsCodeWindowAdapter(IServiceProvider serviceProvider) - => throw new NotImplementedException(); - - public IVsTextBuffer CreateVsTextBufferAdapter(IServiceProvider serviceProvider) - => throw new NotImplementedException(); - - public IVsTextBuffer CreateVsTextBufferAdapter(IServiceProvider serviceProvider, IContentType contentType) - => throw new NotImplementedException(); - - public IVsTextBuffer CreateVsTextBufferAdapterForSecondaryBuffer(IServiceProvider serviceProvider, ITextBuffer secondaryBuffer) - => throw new NotImplementedException(); - - public IVsTextBufferCoordinator CreateVsTextBufferCoordinatorAdapter() - => throw new NotImplementedException(); - - public IVsTextView CreateVsTextViewAdapter(IServiceProvider serviceProvider) - => throw new NotImplementedException(); - - public IVsTextView CreateVsTextViewAdapter(IServiceProvider serviceProvider, ITextViewRoleSet roles) - => throw new NotImplementedException(); - - public IVsTextBuffer GetBufferAdapter(ITextBuffer textBuffer) - => throw new NotImplementedException(); - - public ITextBuffer GetDataBuffer(IVsTextBuffer bufferAdapter) - => throw new NotImplementedException(); - - public ITextBuffer GetDocumentBuffer(IVsTextBuffer bufferAdapter) - => throw new NotImplementedException(); - - public IVsTextView GetViewAdapter(ITextView textView) - => throw new NotImplementedException(); - - public IWpfTextView GetWpfTextView(IVsTextView viewAdapter) - => throw new NotImplementedException(); - - public IWpfTextViewHost GetWpfTextViewHost(IVsTextView viewAdapter) - => throw new NotImplementedException(); - - public void SetDataBuffer(IVsTextBuffer bufferAdapter, ITextBuffer dataBuffer) - => throw new NotImplementedException(); -} diff --git a/src/EditorFeatures/TestUtilities/StubVsServiceExporter`1.cs b/src/EditorFeatures/TestUtilities/StubVsServiceExporter`1.cs deleted file mode 100644 index 09445bdb880cb..0000000000000 --- a/src/EditorFeatures/TestUtilities/StubVsServiceExporter`1.cs +++ /dev/null @@ -1,29 +0,0 @@ -// 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 Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.VisualStudio; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Threading; - -namespace Microsoft.CodeAnalysis.Editor.UnitTests; - -[Export(typeof(IVsService<>))] -[PartCreationPolicy(CreationPolicy.NonShared)] -[PartNotDiscoverable] -internal sealed class StubVsServiceExporter : StubVsServiceExporter - where T : class -{ - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public StubVsServiceExporter( - [Import(typeof(SAsyncServiceProvider))] IAsyncServiceProvider2 asyncServiceProvider, - JoinableTaskContext joinableTaskContext) - : base(asyncServiceProvider, joinableTaskContext) - { - } -} diff --git a/src/EditorFeatures/TestUtilities/StubVsServiceExporter`2.cs b/src/EditorFeatures/TestUtilities/StubVsServiceExporter`2.cs deleted file mode 100644 index 34d32d140719f..0000000000000 --- a/src/EditorFeatures/TestUtilities/StubVsServiceExporter`2.cs +++ /dev/null @@ -1,74 +0,0 @@ -// 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.Diagnostics; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.VisualStudio; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Threading; - -// Import Roslyn.Utilities with an alias to avoid conflicts with AsyncLazy. This implementation relies on -// AsyncLazy from vs-threading, and not the one from Roslyn. -using RoslynUtilities = Roslyn.Utilities; - -namespace Microsoft.CodeAnalysis.Editor.UnitTests; - -[Export(typeof(IVsService<,>))] -[PartCreationPolicy(CreationPolicy.NonShared)] -[PartNotDiscoverable] -internal class StubVsServiceExporter : IVsService - where TService : class - where TInterface : class -{ - private readonly AsyncLazy _serviceGetter; - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public StubVsServiceExporter( - [Import(typeof(SAsyncServiceProvider))] IAsyncServiceProvider2 asyncServiceProvider, - JoinableTaskContext joinableTaskContext) - { - _serviceGetter = new AsyncLazy(() => asyncServiceProvider.GetServiceAsync(throwOnFailure: true, CancellationToken.None)!, joinableTaskContext.Factory); - } - - /// - public Task GetValueAsync(CancellationToken cancellationToken) - => _serviceGetter.GetValueAsync(cancellationToken); - - /// - public Task GetValueOrNullAsync(CancellationToken cancellationToken) - { - var value = GetValueAsync(cancellationToken); - if (value.IsCompleted) - { - return TransformResult(value); - } - - return value.ContinueWith( - static t => TransformResult(t), - CancellationToken.None, // token is already passed to antecedent, and this is a tiny sync continuation, so no need to make it also cancelable. - TaskContinuationOptions.ExecuteSynchronously, - TaskScheduler.Default).Unwrap(); - - static Task TransformResult(Task task) - { - Debug.Assert(task.IsCompleted); - if (task.Status == TaskStatus.Faulted) - { - // Our caller never wants exceptions, so return a cached null value - return RoslynUtilities::SpecializedTasks.Null(); - } - else - { - // Whether this is cancelled or ran to completion, we return the value as-is - return RoslynUtilities::SpecializedTasks.AsNullable(task); - } - } - } -} diff --git a/src/VisualStudio/TestUtilities2/MockServiceProvider.vb b/src/VisualStudio/TestUtilities2/MockServiceProvider.vb index 7eee5783f3821..a9db0ba131a4e 100644 --- a/src/VisualStudio/TestUtilities2/MockServiceProvider.vb +++ b/src/VisualStudio/TestUtilities2/MockServiceProvider.vb @@ -3,12 +3,8 @@ ' See the LICENSE file in the project root for more information. Imports System.ComponentModel.Composition -Imports Microsoft.CodeAnalysis.Editor.UnitTests Imports Microsoft.CodeAnalysis.Host.Mef -Imports Microsoft.Internal.VisualStudio.Shell.Interop Imports Microsoft.VisualStudio.ComponentModelHost -Imports Microsoft.VisualStudio.Settings -Imports Microsoft.VisualStudio.Settings.Internal Imports Microsoft.VisualStudio.Shell Imports Microsoft.VisualStudio.Shell.Interop Imports Moq @@ -28,8 +24,6 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests Private ReadOnly _exportProvider As Composition.ExportProvider Private ReadOnly _fileChangeEx As New MockVsFileChangeEx - Private ReadOnly _localRegistry As New StubLocalRegistry - Private _settingsManager As ISettingsManager Public MockMonitorSelection As IVsMonitorSelection @@ -61,22 +55,6 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests Case GetType(SVsFileChangeEx) Return _fileChangeEx - Case GetType(SLocalRegistry) - Return _localRegistry - - Case GetType(SVsSettingsPersistenceManager) - If _settingsManager Is Nothing Then - LoggerFactory.Reset() - _settingsManager = SettingsManagerFactory.CreateInstance(New StubSettingsManagerHost()) - End If - - Return _settingsManager - - Case GetType(SVsFeatureFlags) - ' The only places that we consume this treat it as optional, so we can skip it here, and remove this in - ' https://github.com/dotnet/roslyn/pull/69160. - Return Nothing - Case Else Throw New Exception($"{NameOf(MockServiceProvider)} does not implement {serviceType.FullName}.") End Select diff --git a/src/VisualStudio/TestUtilities2/StubVsEditorAdaptersFactoryService.vb b/src/VisualStudio/TestUtilities2/StubVsEditorAdaptersFactoryService.vb new file mode 100644 index 0000000000000..aee3d9f89a54b --- /dev/null +++ b/src/VisualStudio/TestUtilities2/StubVsEditorAdaptersFactoryService.vb @@ -0,0 +1,79 @@ +' 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. + +Imports System.ComponentModel.Composition +Imports Microsoft.CodeAnalysis.Host.Mef +Imports Microsoft.VisualStudio.Editor +Imports Microsoft.VisualStudio.OLE.Interop +Imports Microsoft.VisualStudio.Text +Imports Microsoft.VisualStudio.Text.Editor +Imports Microsoft.VisualStudio.TextManager.Interop +Imports Microsoft.VisualStudio.Utilities + + + +Friend Class StubVsEditorAdaptersFactoryService + Implements IVsEditorAdaptersFactoryService + + + + Public Sub New() + End Sub + + Public Sub SetDataBuffer(bufferAdapter As IVsTextBuffer, dataBuffer As ITextBuffer) Implements IVsEditorAdaptersFactoryService.SetDataBuffer + Throw New NotImplementedException() + End Sub + + Public Function CreateVsTextBufferAdapter(serviceProvider As IServiceProvider) As IVsTextBuffer Implements IVsEditorAdaptersFactoryService.CreateVsTextBufferAdapter + Throw New NotImplementedException() + End Function + + Public Function CreateVsTextBufferAdapter(serviceProvider As IServiceProvider, contentType As IContentType) As IVsTextBuffer Implements IVsEditorAdaptersFactoryService.CreateVsTextBufferAdapter + Throw New NotImplementedException() + End Function + + Public Function CreateVsTextBufferAdapterForSecondaryBuffer(serviceProvider As IServiceProvider, secondaryBuffer As ITextBuffer) As IVsTextBuffer Implements IVsEditorAdaptersFactoryService.CreateVsTextBufferAdapterForSecondaryBuffer + Throw New NotImplementedException() + End Function + + Public Function CreateVsTextViewAdapter(serviceProvider As IServiceProvider) As IVsTextView Implements IVsEditorAdaptersFactoryService.CreateVsTextViewAdapter + Throw New NotImplementedException() + End Function + + Public Function CreateVsTextViewAdapter(serviceProvider As IServiceProvider, roles As ITextViewRoleSet) As IVsTextView Implements IVsEditorAdaptersFactoryService.CreateVsTextViewAdapter + Throw New NotImplementedException() + End Function + + Public Function CreateVsCodeWindowAdapter(serviceProvider As IServiceProvider) As IVsCodeWindow Implements IVsEditorAdaptersFactoryService.CreateVsCodeWindowAdapter + Throw New NotImplementedException() + End Function + + Public Function CreateVsTextBufferCoordinatorAdapter() As IVsTextBufferCoordinator Implements IVsEditorAdaptersFactoryService.CreateVsTextBufferCoordinatorAdapter + Throw New NotImplementedException() + End Function + + Public Function GetDataBuffer(bufferAdapter As IVsTextBuffer) As ITextBuffer Implements IVsEditorAdaptersFactoryService.GetDataBuffer + Throw New NotImplementedException() + End Function + + Public Function GetDocumentBuffer(bufferAdapter As IVsTextBuffer) As ITextBuffer Implements IVsEditorAdaptersFactoryService.GetDocumentBuffer + Throw New NotImplementedException() + End Function + + Public Function GetWpfTextView(viewAdapter As IVsTextView) As IWpfTextView Implements IVsEditorAdaptersFactoryService.GetWpfTextView + Throw New NotImplementedException() + End Function + + Public Function GetWpfTextViewHost(viewAdapter As IVsTextView) As IWpfTextViewHost Implements IVsEditorAdaptersFactoryService.GetWpfTextViewHost + Throw New NotImplementedException() + End Function + + Public Function GetBufferAdapter(textBuffer As ITextBuffer) As IVsTextBuffer Implements IVsEditorAdaptersFactoryService.GetBufferAdapter + Throw New NotImplementedException() + End Function + + Public Function GetViewAdapter(textView As ITextView) As IVsTextView Implements IVsEditorAdaptersFactoryService.GetViewAdapter + Throw New NotImplementedException() + End Function +End Class diff --git a/src/VisualStudio/TestUtilities2/StubVsServiceExporter`1.vb b/src/VisualStudio/TestUtilities2/StubVsServiceExporter`1.vb new file mode 100644 index 0000000000000..f452db68ba4bf --- /dev/null +++ b/src/VisualStudio/TestUtilities2/StubVsServiceExporter`1.vb @@ -0,0 +1,27 @@ +' 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. + +Imports System +Imports System.ComponentModel.Composition +Imports Microsoft.CodeAnalysis.Host.Mef +Imports Microsoft.VisualStudio +Imports Microsoft.VisualStudio.Shell +Imports Microsoft.VisualStudio.Shell.Interop +Imports Microsoft.VisualStudio.Threading + +Namespace Microsoft.CodeAnalysis.Editor.UnitTests + + + + Friend NotInheritable Class StubVsServiceExporter(Of T As Class) + Inherits StubVsServiceExporter(Of T, T) + + + + Public Sub New( + asyncServiceProvider As IAsyncServiceProvider2, joinableTaskContext As JoinableTaskContext) + MyBase.New(asyncServiceProvider, joinableTaskContext) + End Sub + End Class +End Namespace diff --git a/src/VisualStudio/TestUtilities2/StubVsServiceExporter`2.vb b/src/VisualStudio/TestUtilities2/StubVsServiceExporter`2.vb new file mode 100644 index 0000000000000..efe71775d2fda --- /dev/null +++ b/src/VisualStudio/TestUtilities2/StubVsServiceExporter`2.vb @@ -0,0 +1,68 @@ +' 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. + +Imports System.ComponentModel.Composition +Imports System.Threading +Imports Microsoft.CodeAnalysis.Host.Mef +Imports Microsoft.VisualStudio +Imports Microsoft.VisualStudio.Shell +Imports Microsoft.VisualStudio.Shell.Interop +Imports Microsoft.VisualStudio.Threading + +' Import Roslyn.Utilities with an alias to avoid conflicts with AsyncLazy(Of T). This implementation relies on +' AsyncLazy(Of T) from vs-threading, and not the one from Roslyn. +Imports RoslynUtilities = Roslyn.Utilities + +Namespace Microsoft.CodeAnalysis.Editor.UnitTests + + + + Friend Class StubVsServiceExporter(Of TService As Class, TInterface As Class) + Implements IVsService(Of TService, TInterface) + + Private ReadOnly _serviceGetter As AsyncLazy(Of TInterface) + + + + Public Sub New( + asyncServiceProvider As IAsyncServiceProvider2, joinableTaskContext As JoinableTaskContext) + + _serviceGetter = New AsyncLazy(Of TInterface)( + Function() asyncServiceProvider.GetServiceAsync(Of TService, TInterface)(True, CancellationToken.None), + joinableTaskContext.Factory) + End Sub + + ''' + Public Function GetValueAsync(Optional cancellationToken As CancellationToken = Nothing) As Task(Of TInterface) Implements IVsService(Of TInterface).GetValueAsync + Return _serviceGetter.GetValueAsync(cancellationToken) + End Function + + ''' + Public Function GetValueOrNullAsync(Optional cancellationToken As CancellationToken = Nothing) As Task(Of TInterface) Implements IVsService(Of TService, TInterface).GetValueOrNullAsync + Dim value = GetValueAsync(cancellationToken) + + If value.IsCompleted Then + Return TransformResult(value) + End If + + Return value.ContinueWith( + Function(t) TransformResult(t), + CancellationToken.None, ' token is already passed to antecedent, and this is a tiny sync continuation, so no need to make it also cancelable. + TaskContinuationOptions.ExecuteSynchronously, + TaskScheduler.Default).Unwrap() + End Function + + Private Shared Function TransformResult(task As Task(Of TInterface)) As Task(Of TInterface) + Debug.Assert(task.IsCompleted) + + If task.Status = TaskStatus.Faulted Then + ' Our caller never wants exceptions, so return a cached null value + Return RoslynUtilities.SpecializedTasks.Null(Of TInterface)() + Else + ' Whether this is cancelled or ran to completion, we return the value as-is + Return RoslynUtilities.SpecializedTasks.AsNullable(task) + End If + End Function + End Class +End Namespace diff --git a/src/VisualStudio/TestUtilities2/VisualStudioTestCompositions.vb b/src/VisualStudio/TestUtilities2/VisualStudioTestCompositions.vb index 85fe08432bf33..6497c2777d858 100644 --- a/src/VisualStudio/TestUtilities2/VisualStudioTestCompositions.vb +++ b/src/VisualStudio/TestUtilities2/VisualStudioTestCompositions.vb @@ -27,6 +27,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests GetType(VisualStudioRemoteHostClientProvider.Factory), ' Do not use ServiceHub in VS unit tests, run services locally. GetType(IStreamingFindUsagesPresenter), ' TODO: should we be using the actual implementation (https://github.com/dotnet/roslyn/issues/46380)? GetType(HACK_ThemeColorFixer), - GetType(Implementation.Notification.VSNotificationServiceFactory)) + GetType(Implementation.Notification.VSNotificationServiceFactory), + GetType(Options.VisualStudioOptionPersisterProvider)) End Class End Namespace