Update to Microsoft.VisualStudio.Extensibility.Testing 0.1.135-beta

This commit is contained in:
Sam Harwell 2022-04-01 16:53:51 -07:00
Родитель a42d204803
Коммит 1b795b8e6e
11 изменённых файлов: 144 добавлений и 621 удалений

Просмотреть файл

@ -21,6 +21,7 @@
<MicrosoftCodeAnalysisPackagesVersion>4.0.0-1.21267.34</MicrosoftCodeAnalysisPackagesVersion>
<MicrosoftVisualStudioShellPackagesVersion>17.0.0-previews-4-31709-430</MicrosoftVisualStudioShellPackagesVersion>
<MicrosoftVisualStudioEditorPackagesVersion>17.0.391-preview-g5e248c9073</MicrosoftVisualStudioEditorPackagesVersion>
<MicrosoftVisualStudioExtensibilityTestingVersion>0.1.135-beta</MicrosoftVisualStudioExtensibilityTestingVersion>
<!-- Roslyn -->
<MicrosoftCodeAnalysisAnalyzersVersion>3.3.2</MicrosoftCodeAnalysisAnalyzersVersion>
<MicrosoftCodeAnalysisCommonVersion>$(MicrosoftCodeAnalysisPackagesVersion)</MicrosoftCodeAnalysisCommonVersion>
@ -74,7 +75,8 @@
<MicrosoftCodeAnalysisTestingVersion>1.0.1-beta1.20374.2</MicrosoftCodeAnalysisTestingVersion>
<xunitassertVersion>$(xunitVersion)</xunitassertVersion>
<XunitCombinatorialVersion>1.2.7</XunitCombinatorialVersion>
<MicrosoftVisualStudioExtensibilityTestingXunitVersion>0.1.100-beta</MicrosoftVisualStudioExtensibilityTestingXunitVersion>
<MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>$(MicrosoftVisualStudioExtensibilityTestingVersion)</MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>
<MicrosoftVisualStudioExtensibilityTestingXunitVersion>$(MicrosoftVisualStudioExtensibilityTestingVersion)</MicrosoftVisualStudioExtensibilityTestingXunitVersion>
<!-- Analyzers -->
<RoslynDiagnosticsAnalyzersVersion>2.9.8</RoslynDiagnosticsAnalyzersVersion>
<StyleCopAnalyzersVersion>1.2.0-beta.164</StyleCopAnalyzersVersion>

Просмотреть файл

@ -1,116 +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.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Microsoft.CodeAnalysis.Testing.InProcess;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Threading;
using Xunit;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.CodeAnalysis.Testing
{
[IdeSettings(MinVersion = VisualStudioVersion.VS2022)]
public abstract class AbstractIdeIntegrationTest : IAsyncLifetime, IDisposable
{
/// <summary>
/// A long timeout used to avoid hangs in tests, where a test failure manifests as an operation never occurring.
/// </summary>
public static readonly TimeSpan HangMitigatingTimeout = TimeSpan.FromMinutes(4);
private JoinableTaskContext? _joinableTaskContext;
private JoinableTaskCollection? _joinableTaskCollection;
private JoinableTaskFactory? _joinableTaskFactory;
private TestServices? _testServices;
private CancellationTokenSource _hangMitigatingCancellationTokenSource;
protected AbstractIdeIntegrationTest()
{
Assert.True(Application.Current.Dispatcher.CheckAccess());
JoinableTaskContext = ThreadHelper.JoinableTaskContext;
_hangMitigatingCancellationTokenSource = new CancellationTokenSource(HangMitigatingTimeout);
}
[NotNull]
protected JoinableTaskContext? JoinableTaskContext
{
get
{
return _joinableTaskContext ?? throw new InvalidOperationException();
}
private set
{
if (value == _joinableTaskContext)
{
return;
}
if (value is null)
{
_joinableTaskContext = null;
_joinableTaskCollection = null;
_joinableTaskFactory = null;
}
else
{
_joinableTaskContext = value;
_joinableTaskCollection = value.CreateCollection();
_joinableTaskFactory = value.CreateFactory(_joinableTaskCollection).WithPriority(Application.Current.Dispatcher, DispatcherPriority.Background);
}
}
}
[NotNull]
protected TestServices? TestServices
{
get
{
return _testServices ?? throw new InvalidOperationException();
}
private set
{
_testServices = value;
}
}
protected JoinableTaskFactory JoinableTaskFactory
=> _joinableTaskFactory ?? throw new InvalidOperationException();
protected CancellationToken HangMitigatingCancellationToken
=> _hangMitigatingCancellationTokenSource.Token;
public virtual async Task InitializeAsync()
{
TestServices = await CreateTestServicesAsync();
}
public virtual async Task DisposeAsync()
{
if (_joinableTaskCollection is object)
{
await _joinableTaskCollection.JoinTillEmptyAsync();
}
JoinableTaskContext = null;
}
public virtual void Dispose()
{
}
protected virtual async Task<TestServices> CreateTestServicesAsync()
=> await TestServices.CreateAsync(JoinableTaskFactory);
}
}

Просмотреть файл

@ -2,13 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.VisualStudio.Extensibility.Testing;
using Xunit;
namespace Microsoft.CodeAnalysis.Testing
{
internal static class WellKnownCommandNames
[IdeSettings(MinVersion = VisualStudioVersion.VS2022)]
public abstract class AbstractIntegrationTest : AbstractIdeIntegrationTest
{
public static class Build
{
public const string BuildSolution = "Build.BuildSolution";
}
}
}

Просмотреть файл

@ -5,150 +5,140 @@
using System;
using Microsoft.CodeAnalysis.Testing.Verifiers;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Threading;
using Xunit;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.CodeAnalysis.Testing
{
public class CreateProjectTests : AbstractIdeIntegrationTest
public class CreateProjectTests : AbstractIntegrationTest
{
public override async Task DisposeAsync()
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await TestServices.SolutionExplorer.CloseSolutionAsync();
await base.DisposeAsync();
}
[IdeFact]
public async Task CreateFromTemplateAsync()
{
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests));
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", WellKnownProjectTemplates.CSharpNetCoreClassLibrary, languageName: LanguageNames.CSharp);
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", WellKnownProjectTemplates.CSharpNetCoreClassLibrary, languageName: LanguageNames.CSharp, HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken);
await TestServices.Editor.SetTextAsync(@"using System");
await TestServices.Editor.SetTextAsync(@"using System", HangMitigatingCancellationToken);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken);
Assert.Equal("========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========", buildSummary);
await TestServices.ErrorList.ShowBuildErrorsAsync();
await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken);
// Verify that intentional errors get validated by the test
var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR);
var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken);
var expected = "(Compiler) Class1.cs(1, 13): error CS1002: ; expected";
new XUnitVerifier().EqualOrDiff(expected, string.Join(Environment.NewLine, errors));
Assert.Equal(1, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR));
Assert.Equal(1, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken));
}
[IdeFact]
public async Task CreateAnalyzerFromCSharpTemplateAsync()
{
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests));
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.Analyzer", languageName: LanguageNames.CSharp);
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.Analyzer", languageName: LanguageNames.CSharp, HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken);
Assert.Equal("========== Build: 5 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary);
await TestServices.ErrorList.ShowBuildErrorsAsync();
await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken);
var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR);
var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken);
new XUnitVerifier().EqualOrDiff(string.Empty, string.Join(Environment.NewLine, errors));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken));
// Currently have two analyzer warnings in the template.
var warnings = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING);
var warnings = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken);
new XUnitVerifier().EqualOrDiff(string.Empty, string.Join(Environment.NewLine, warnings));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken));
}
[IdeFact]
public async Task CreateRefactoringFromCSharpTemplateAsync()
{
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests));
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.CodeRefactoring", languageName: LanguageNames.CSharp);
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.CodeRefactoring", languageName: LanguageNames.CSharp, HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken);
Assert.Equal("========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary);
await TestServices.ErrorList.ShowBuildErrorsAsync();
await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken);
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken));
}
[IdeFact]
public async Task CreateStandaloneToolFromCSharpTemplateAsync()
{
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests));
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.StandaloneCodeAnalysis", languageName: LanguageNames.CSharp);
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.CSharp.StandaloneCodeAnalysis", languageName: LanguageNames.CSharp, HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken);
Assert.Equal("========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary);
await TestServices.ErrorList.ShowBuildErrorsAsync();
await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken);
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken));
}
[IdeFact]
public async Task CreateAnalyzerFromVisualBasicTemplateAsync()
{
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests));
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.Analyzer", languageName: LanguageNames.VisualBasic);
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.Analyzer", languageName: LanguageNames.VisualBasic, HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken);
Assert.Equal("========== Build: 5 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary);
await TestServices.ErrorList.ShowBuildErrorsAsync();
await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken);
var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR);
var errors = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken);
new XUnitVerifier().EqualOrDiff(string.Empty, string.Join(Environment.NewLine, errors));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken));
// Currently have two analyzer warnings in the template.
var warnings = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING);
var warnings = await TestServices.ErrorList.GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken);
new XUnitVerifier().EqualOrDiff(string.Empty, string.Join(Environment.NewLine, warnings));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken));
}
[IdeFact]
public async Task CreateRefactoringFromVisualBasicTemplateAsync()
{
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests));
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.CodeRefactoring", languageName: LanguageNames.VisualBasic);
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.CodeRefactoring", languageName: LanguageNames.VisualBasic, HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken);
Assert.Equal("========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary);
await TestServices.ErrorList.ShowBuildErrorsAsync();
await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken);
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken));
}
[IdeFact]
public async Task CreateStandaloneToolFromVisualBasicTemplateAsync()
{
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests));
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.StandaloneCodeAnalysis", languageName: LanguageNames.VisualBasic);
await TestServices.SolutionExplorer.CreateSolutionAsync(nameof(CreateProjectTests), HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.AddProjectAsync("TestProj", "Microsoft.VisualBasic.StandaloneCodeAnalysis", languageName: LanguageNames.VisualBasic, HangMitigatingCancellationToken);
await TestServices.SolutionExplorer.RestoreNuGetPackagesAsync(HangMitigatingCancellationToken);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true);
var buildSummary = await TestServices.SolutionExplorer.BuildSolutionAsync(waitForBuildToFinish: true, HangMitigatingCancellationToken);
Assert.Equal("========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========", buildSummary);
await TestServices.ErrorList.ShowBuildErrorsAsync();
await TestServices.ErrorList.ShowBuildErrorsAsync(HangMitigatingCancellationToken);
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_ERROR, HangMitigatingCancellationToken));
Assert.Equal(0, await TestServices.ErrorList.GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, HangMitigatingCancellationToken));
}
}
}

Просмотреть файл

@ -2,60 +2,19 @@
// 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.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
namespace Microsoft.CodeAnalysis.Testing.InProcess
namespace Microsoft.VisualStudio.Extensibility.Testing
{
public class EditorInProcess : InProcComponent
internal partial class EditorInProcess
{
internal static readonly Guid IWpfTextViewId = new Guid("8C40265E-9FDB-4F54-A0FD-EBB72B7D0476");
public EditorInProcess(TestServices testServices)
: base(testServices)
public async Task SetTextAsync(string text, CancellationToken cancellationToken)
{
}
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
public async Task<IWpfTextView> GetActiveTextViewAsync()
=> (await GetActiveTextViewHostAsync()).TextView;
private async Task<IVsTextView> GetActiveVsTextViewAsync()
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
var vsTextManager = await GetRequiredGlobalServiceAsync<SVsTextManager, IVsTextManager>();
ErrorHandler.ThrowOnFailure(vsTextManager.GetActiveView(fMustHaveFocus: 1, pBuffer: null, ppView: out var vsTextView));
return vsTextView;
}
private async Task<IWpfTextViewHost> GetActiveTextViewHostAsync()
{
// The active text view might not have finished composing yet, waiting for the application to 'idle'
// means that it is done pumping messages (including WM_PAINT) and the window should return the correct text
// view.
await WaitForApplicationIdleAsync(CancellationToken.None);
await JoinableTaskFactory.SwitchToMainThreadAsync();
var activeVsTextView = (IVsUserData)await GetActiveVsTextViewAsync();
ErrorHandler.ThrowOnFailure(activeVsTextView.GetData(IWpfTextViewId, out var wpfTextViewHost));
return (IWpfTextViewHost)wpfTextViewHost;
}
public async Task SetTextAsync(string text)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
var view = await GetActiveTextViewAsync();
var view = await GetActiveTextViewAsync(cancellationToken);
var textSnapshot = view.TextSnapshot;
var replacementSpan = new SnapshotSpan(textSnapshot, 0, textSnapshot.Length);
view.TextBuffer.Replace(replacementSpan, text);

Просмотреть файл

@ -7,7 +7,9 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Extensibility.Testing;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.TableControl;
@ -16,18 +18,14 @@ using Task = System.Threading.Tasks.Task;
namespace Microsoft.CodeAnalysis.Testing.InProcess
{
public class ErrorListInProcess : InProcComponent
[TestService]
internal partial class ErrorListInProcess
{
public ErrorListInProcess(TestServices testServices)
: base(testServices)
public async Task ShowBuildErrorsAsync(CancellationToken cancellationToken)
{
}
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
public async Task ShowBuildErrorsAsync()
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
var errorList = await GetRequiredGlobalServiceAsync<SVsErrorList, IErrorList>();
var errorList = await GetRequiredGlobalServiceAsync<SVsErrorList, IErrorList>(cancellationToken);
errorList.AreBuildErrorSourceEntriesShown = true;
errorList.AreOtherErrorSourceEntriesShown = false;
errorList.AreErrorsShown = true;
@ -35,11 +33,16 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
errorList.AreWarningsShown = false;
}
public async Task<ImmutableArray<string>> GetBuildErrorsAsync(__VSERRORCATEGORY minimumSeverity = __VSERRORCATEGORY.EC_WARNING)
public Task<ImmutableArray<string>> GetBuildErrorsAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
return GetBuildErrorsAsync(__VSERRORCATEGORY.EC_WARNING, cancellationToken);
}
var errorItems = await GetErrorItemsAsync();
public async Task<ImmutableArray<string>> GetBuildErrorsAsync(__VSERRORCATEGORY minimumSeverity, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var errorItems = await GetErrorItemsAsync(cancellationToken);
var list = new List<string>();
foreach (var item in errorItems)
@ -79,19 +82,24 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
.ToImmutableArray();
}
public async Task<int> GetErrorCountAsync(__VSERRORCATEGORY minimumSeverity = __VSERRORCATEGORY.EC_WARNING)
public Task<int> GetErrorCountAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
return GetErrorCountAsync(__VSERRORCATEGORY.EC_WARNING, cancellationToken);
}
var errorItems = await GetErrorItemsAsync();
public async Task<int> GetErrorCountAsync(__VSERRORCATEGORY minimumSeverity, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var errorItems = await GetErrorItemsAsync(cancellationToken);
return errorItems.Count(e => e.GetCategory() <= minimumSeverity);
}
private async Task<ImmutableArray<ITableEntryHandle>> GetErrorItemsAsync()
private async Task<ImmutableArray<ITableEntryHandle>> GetErrorItemsAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var errorList = await GetRequiredGlobalServiceAsync<SVsErrorList, IErrorList>();
var errorList = await GetRequiredGlobalServiceAsync<SVsErrorList, IErrorList>(cancellationToken);
var args = await errorList.TableControl.ForceUpdateAsync();
return args.AllEntries.ToImmutableArray();
}

Просмотреть файл

@ -1,76 +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.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Threading;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.CodeAnalysis.Testing.InProcess
{
public abstract class InProcComponent
{
protected InProcComponent(TestServices testServices)
{
TestServices = testServices ?? throw new ArgumentNullException(nameof(testServices));
}
public TestServices TestServices { get; }
protected JoinableTaskFactory JoinableTaskFactory => TestServices.JoinableTaskFactory;
protected async Task ExecuteCommandAsync(string commandName, string args = "")
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
var dte = await GetRequiredGlobalServiceAsync<SDTE, EnvDTE.DTE>();
dte.ExecuteCommand(commandName, args);
}
protected async Task<TInterface> GetRequiredGlobalServiceAsync<TService, TInterface>()
where TService : class
where TInterface : class
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
var serviceProvider = (IAsyncServiceProvider2?)await AsyncServiceProvider.GlobalProvider.GetServiceAsync(typeof(SAsyncServiceProvider));
Assumes.Present(serviceProvider);
var @interface = (TInterface?)await serviceProvider.GetServiceAsync(typeof(TService));
Assumes.Present(@interface);
return @interface;
}
protected async Task<TService> GetComponentModelServiceAsync<TService>()
where TService : class
{
var componentModel = await GetRequiredGlobalServiceAsync<SComponentModel, IComponentModel>();
return componentModel.GetService<TService>();
}
/// <summary>
/// Waiting for the application to 'idle' means that it is done pumping messages (including WM_PAINT).
/// </summary>
/// <param name="cancellationToken">The cancellation token that the operation will observe.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
protected static async Task WaitForApplicationIdleAsync(CancellationToken cancellationToken)
{
var synchronizationContext = new DispatcherSynchronizationContext(Application.Current.Dispatcher, DispatcherPriority.ApplicationIdle);
var taskScheduler = new SynchronizationContextTaskScheduler(synchronizationContext);
await Task.Factory.StartNew(
() => { },
cancellationToken,
TaskCreationOptions.None,
taskScheduler);
}
}
}

Просмотреть файл

@ -8,119 +8,42 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.VisualStudio.OperationProgress;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Threading;
using NuGet.SolutionRestoreManager;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.CodeAnalysis.Testing.InProcess
namespace Microsoft.VisualStudio.Extensibility.Testing
{
public class SolutionExplorerInProcess : InProcComponent
internal partial class SolutionExplorerInProcess
{
public SolutionExplorerInProcess(TestServices testServices)
: base(testServices)
public async Task CreateSolutionAsync(string solutionName, CancellationToken cancellationToken)
{
}
private async Task<bool> IsSolutionOpenAsync()
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution>();
ErrorHandler.ThrowOnFailure(solution.GetProperty((int)__VSPROPID.VSPROPID_IsSolutionOpen, out var isOpen));
return (bool)isOpen;
}
public async Task CloseSolutionAsync(bool saveFirst = false)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
if (!await IsSolutionOpenAsync())
{
return;
}
if (saveFirst)
{
await SaveSolutionAsync();
}
await CloseSolutionAsync();
}
private async Task CloseSolutionAsync()
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution>();
if (!await IsSolutionOpenAsync())
{
return;
}
using var semaphore = new SemaphoreSlim(1);
using var solutionEvents = new SolutionEvents(JoinableTaskFactory, solution);
await semaphore.WaitAsync();
void HandleAfterCloseSolution(object sender, EventArgs e) => semaphore.Release();
solutionEvents.AfterCloseSolution += HandleAfterCloseSolution;
try
{
ErrorHandler.ThrowOnFailure(solution.CloseSolutionElement((uint)__VSSLNCLOSEOPTIONS.SLNCLOSEOPT_DeleteProject | (uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave, null, 0));
await semaphore.WaitAsync();
}
finally
{
solutionEvents.AfterCloseSolution -= HandleAfterCloseSolution;
}
}
public async Task CreateSolutionAsync(string solutionName)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var solutionPath = CreateTemporaryPath();
await CreateSolutionAsync(solutionPath, solutionName);
await CreateSolutionAsync(solutionPath, solutionName, cancellationToken);
}
private async Task CreateSolutionAsync(string solutionPath, string solutionName)
private async Task CreateSolutionAsync(string solutionPath, string solutionName, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
await CloseSolutionAsync();
await CloseSolutionAsync(cancellationToken);
var solutionFileName = Path.ChangeExtension(solutionName, ".sln");
Directory.CreateDirectory(solutionPath);
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution>();
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution>(cancellationToken);
ErrorHandler.ThrowOnFailure(solution.CreateSolution(solutionPath, solutionFileName, (uint)__VSCREATESOLUTIONFLAGS.CSF_SILENT));
ErrorHandler.ThrowOnFailure(solution.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0));
}
public async Task SaveSolutionAsync()
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
if (!await IsSolutionOpenAsync())
{
throw new InvalidOperationException("Cannot save solution when no solution is open.");
}
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution>();
// Make sure the directory exists so the Save dialog doesn't appear
ErrorHandler.ThrowOnFailure(solution.GetSolutionInfo(out var solutionDirectory, out _, out _));
Directory.CreateDirectory(solutionDirectory);
ErrorHandler.ThrowOnFailure(solution.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0));
}
private static string ConvertLanguageName(string languageName)
{
return languageName switch
@ -131,11 +54,11 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
};
}
private async Task<string> GetDirectoryNameAsync()
private async Task<string> GetDirectoryNameAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution>();
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution>(cancellationToken);
ErrorHandler.ThrowOnFailure(solution.GetSolutionInfo(out _, out var solutionFileFullPath, out _));
if (string.IsNullOrEmpty(solutionFileFullPath))
{
@ -145,11 +68,11 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
return Path.GetDirectoryName(solutionFileFullPath);
}
private async Task<ImmutableDictionary<string, string>> GetCSharpProjectTemplatesAsync()
private async Task<ImmutableDictionary<string, string>> GetCSharpProjectTemplatesAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var hostLocale = await GetRequiredGlobalServiceAsync<SUIHostLocale, IUIHostLocale>();
var hostLocale = await GetRequiredGlobalServiceAsync<SUIHostLocale, IUIHostLocale>(cancellationToken);
ErrorHandler.ThrowOnFailure(hostLocale.GetUILocale(out var localeID));
var builder = ImmutableDictionary.CreateBuilder<string, string>();
@ -162,11 +85,11 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
return builder.ToImmutable();
}
private async Task<ImmutableDictionary<string, string>> GetVisualBasicProjectTemplatesAsync()
private async Task<ImmutableDictionary<string, string>> GetVisualBasicProjectTemplatesAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var hostLocale = await GetRequiredGlobalServiceAsync<SUIHostLocale, IUIHostLocale>();
var hostLocale = await GetRequiredGlobalServiceAsync<SUIHostLocale, IUIHostLocale>(cancellationToken);
ErrorHandler.ThrowOnFailure(hostLocale.GetUILocale(out var localeID));
var builder = ImmutableDictionary.CreateBuilder<string, string>();
@ -179,31 +102,31 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
return builder.ToImmutable();
}
public async Task AddProjectAsync(string projectName, string projectTemplate, string languageName)
public async Task AddProjectAsync(string projectName, string projectTemplate, string languageName, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var projectPath = Path.Combine(await GetDirectoryNameAsync(), projectName);
var projectTemplatePath = await GetProjectTemplatePathAsync(projectTemplate, ConvertLanguageName(languageName));
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution6>();
var projectPath = Path.Combine(await GetDirectoryNameAsync(cancellationToken), projectName);
var projectTemplatePath = await GetProjectTemplatePathAsync(projectTemplate, ConvertLanguageName(languageName), cancellationToken);
var solution = await GetRequiredGlobalServiceAsync<SVsSolution, IVsSolution6>(cancellationToken);
ErrorHandler.ThrowOnFailure(solution.AddNewProjectFromTemplate(projectTemplatePath, null, null, projectPath, projectName, null, out _));
}
private async Task<string> GetProjectTemplatePathAsync(string projectTemplate, string languageName)
private async Task<string> GetProjectTemplatePathAsync(string projectTemplate, string languageName, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var dte = await GetRequiredGlobalServiceAsync<SDTE, EnvDTE.DTE>();
var dte = await GetRequiredGlobalServiceAsync<SDTE, EnvDTE.DTE>(cancellationToken);
var solution = (EnvDTE80.Solution2)dte.Solution;
if (string.Equals(languageName, "csharp", StringComparison.OrdinalIgnoreCase)
&& (await GetCSharpProjectTemplatesAsync()).TryGetValue(projectTemplate, out var csharpProjectTemplate))
&& (await GetCSharpProjectTemplatesAsync(cancellationToken)).TryGetValue(projectTemplate, out var csharpProjectTemplate))
{
return solution.GetProjectTemplate(csharpProjectTemplate, languageName);
}
if (string.Equals(languageName, "visualbasic", StringComparison.OrdinalIgnoreCase)
&& (await GetVisualBasicProjectTemplatesAsync()).TryGetValue(projectTemplate, out var visualBasicProjectTemplate))
&& (await GetVisualBasicProjectTemplatesAsync(cancellationToken)).TryGetValue(projectTemplate, out var visualBasicProjectTemplate))
{
return solution.GetProjectTemplate(visualBasicProjectTemplate, languageName);
}
@ -213,9 +136,9 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
public async Task RestoreNuGetPackagesAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var dte = await GetRequiredGlobalServiceAsync<SDTE, EnvDTE.DTE>();
var dte = await GetRequiredGlobalServiceAsync<SDTE, EnvDTE.DTE>(cancellationToken);
var solution = (EnvDTE80.Solution2)dte.Solution;
foreach (var project in solution.Projects.OfType<EnvDTE.Project>())
{
@ -225,17 +148,17 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
public async Task RestoreNuGetPackagesAsync(string projectName, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var operationProgressStatus = await GetRequiredGlobalServiceAsync<SVsOperationProgress, IVsOperationProgressStatusService>();
var operationProgressStatus = await GetRequiredGlobalServiceAsync<SVsOperationProgress, IVsOperationProgressStatusService>(cancellationToken);
var stageStatus = operationProgressStatus.GetStageStatus(CommonOperationProgressStageIds.Intellisense);
await stageStatus.WaitForCompletionAsync();
var solutionRestoreService = await GetComponentModelServiceAsync<IVsSolutionRestoreService>();
var solutionRestoreService = await GetComponentModelServiceAsync<IVsSolutionRestoreService>(cancellationToken);
await solutionRestoreService.CurrentRestoreOperation;
var projectFullPath = (await GetProjectAsync(projectName)).FullName;
var solutionRestoreStatusProvider = await GetComponentModelServiceAsync<IVsSolutionRestoreStatusProvider>();
var projectFullPath = (await GetProjectAsync(projectName, cancellationToken)).FullName;
var solutionRestoreStatusProvider = await GetComponentModelServiceAsync<IVsSolutionRestoreStatusProvider>(cancellationToken);
if (await solutionRestoreStatusProvider.IsRestoreCompleteAsync(cancellationToken))
{
return;
@ -255,42 +178,42 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
}
}
public async Task<string?> BuildSolutionAsync(bool waitForBuildToFinish)
public async Task<string?> BuildSolutionAsync(bool waitForBuildToFinish, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var buildOutputWindowPane = await GetBuildOutputWindowPaneAsync();
var buildOutputWindowPane = await GetBuildOutputWindowPaneAsync(cancellationToken);
buildOutputWindowPane.Clear();
await ExecuteCommandAsync(WellKnownCommandNames.Build.BuildSolution);
await TestServices.Shell.ExecuteCommandAsync(VSConstants.VSStd97CmdID.BuildSln, cancellationToken);
if (waitForBuildToFinish)
{
return await WaitForBuildToFinishAsync(buildOutputWindowPane);
return await WaitForBuildToFinishAsync(buildOutputWindowPane, cancellationToken);
}
return null;
}
public async Task<string> WaitForBuildToFinishAsync()
public async Task<string> WaitForBuildToFinishAsync(CancellationToken cancellationToken)
{
var buildOutputWindowPane = await GetBuildOutputWindowPaneAsync();
return await WaitForBuildToFinishAsync(buildOutputWindowPane);
var buildOutputWindowPane = await GetBuildOutputWindowPaneAsync(cancellationToken);
return await WaitForBuildToFinishAsync(buildOutputWindowPane, cancellationToken);
}
public async Task<IVsOutputWindowPane> GetBuildOutputWindowPaneAsync()
public async Task<IVsOutputWindowPane> GetBuildOutputWindowPaneAsync(CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var outputWindow = await GetRequiredGlobalServiceAsync<SVsOutputWindow, IVsOutputWindow>();
var outputWindow = await GetRequiredGlobalServiceAsync<SVsOutputWindow, IVsOutputWindow>(cancellationToken);
ErrorHandler.ThrowOnFailure(outputWindow.GetPane(VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid, out var pane));
return pane;
}
private async Task<string> WaitForBuildToFinishAsync(IVsOutputWindowPane buildOutputWindowPane)
private async Task<string> WaitForBuildToFinishAsync(IVsOutputWindowPane buildOutputWindowPane, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var buildManager = await GetRequiredGlobalServiceAsync<SVsSolutionBuildManager, IVsSolutionBuildManager2>();
var buildManager = await GetRequiredGlobalServiceAsync<SVsSolutionBuildManager, IVsSolutionBuildManager2>(cancellationToken);
using var semaphore = new SemaphoreSlim(1);
using var solutionEvents = new UpdateSolutionEvents(buildManager);
@ -311,8 +234,8 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
ErrorHandler.ThrowOnFailure(buildOutputWindowPane.FlushToTaskList());
var textView = (IVsTextView)buildOutputWindowPane;
ErrorHandler.ThrowOnFailure(((IVsUserData)textView).GetData(EditorInProcess.IWpfTextViewId, out var wpfTextViewHost));
var lines = ((IWpfTextViewHost)wpfTextViewHost).TextView.TextViewLines;
var wpfTextViewHost = await textView.GetTextViewHostAsync(JoinableTaskFactory, cancellationToken);
var lines = wpfTextViewHost.TextView.TextViewLines;
if (lines.Count < 1)
{
return string.Empty;
@ -326,11 +249,11 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
return Path.Combine(Path.GetTempPath(), "roslyn-sdk-test", Path.GetRandomFileName());
}
private async Task<EnvDTE.Project> GetProjectAsync(string nameOrFileName)
private async Task<EnvDTE.Project> GetProjectAsync(string nameOrFileName, CancellationToken cancellationToken)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var dte = await GetRequiredGlobalServiceAsync<SDTE, EnvDTE.DTE>();
var dte = await GetRequiredGlobalServiceAsync<SDTE, EnvDTE.DTE>(cancellationToken);
var solution = (EnvDTE80.Solution2)dte.Solution;
return solution.Projects.OfType<EnvDTE.Project>().First(
project =>
@ -341,84 +264,6 @@ namespace Microsoft.CodeAnalysis.Testing.InProcess
});
}
private sealed class SolutionEvents : IVsSolutionEvents, IDisposable
{
private readonly JoinableTaskFactory _joinableTaskFactory;
private readonly IVsSolution _solution;
private readonly uint _cookie;
public SolutionEvents(JoinableTaskFactory joinableTaskFactory, IVsSolution solution)
{
ThreadHelper.ThrowIfNotOnUIThread();
_joinableTaskFactory = joinableTaskFactory;
_solution = solution;
ErrorHandler.ThrowOnFailure(solution.AdviseSolutionEvents(this, out _cookie));
}
public event EventHandler? AfterCloseSolution;
public void Dispose()
{
_joinableTaskFactory.Run(async () =>
{
await _joinableTaskFactory.SwitchToMainThreadAsync();
ErrorHandler.ThrowOnFailure(_solution.UnadviseSolutionEvents(_cookie));
});
}
public int OnAfterOpenProject(IVsHierarchy pHierarchy, int fAdded)
{
return VSConstants.S_OK;
}
public int OnQueryCloseProject(IVsHierarchy pHierarchy, int fRemoving, ref int pfCancel)
{
return VSConstants.S_OK;
}
public int OnBeforeCloseProject(IVsHierarchy pHierarchy, int fRemoved)
{
return VSConstants.S_OK;
}
public int OnAfterLoadProject(IVsHierarchy pStubHierarchy, IVsHierarchy pRealHierarchy)
{
return VSConstants.S_OK;
}
public int OnQueryUnloadProject(IVsHierarchy pRealHierarchy, ref int pfCancel)
{
return VSConstants.S_OK;
}
public int OnBeforeUnloadProject(IVsHierarchy pRealHierarchy, IVsHierarchy pStubHierarchy)
{
return VSConstants.S_OK;
}
public int OnAfterOpenSolution(object pUnkReserved, int fNewSolution)
{
return VSConstants.S_OK;
}
public int OnQueryCloseSolution(object pUnkReserved, ref int pfCancel)
{
return VSConstants.S_OK;
}
public int OnBeforeCloseSolution(object pUnkReserved)
{
return VSConstants.S_OK;
}
public int OnAfterCloseSolution(object pUnkReserved)
{
AfterCloseSolution?.Invoke(this, EventArgs.Empty);
return VSConstants.S_OK;
}
}
internal sealed class UpdateSolutionEvents : IVsUpdateSolutionEvents, IVsUpdateSolutionEvents2, IDisposable
{
private uint _cookie;

Просмотреть файл

@ -1,49 +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.Threading;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.Testing.InProcess
{
// Based on CoreCLR's implementation of the TaskScheduler they return from TaskScheduler.FromCurrentSynchronizationContext
internal class SynchronizationContextTaskScheduler : TaskScheduler
{
private readonly SendOrPostCallback _postCallback;
private readonly SynchronizationContext _synchronizationContext;
internal SynchronizationContextTaskScheduler(SynchronizationContext synchronizationContext)
{
_postCallback = new SendOrPostCallback(PostCallback);
_synchronizationContext = synchronizationContext ?? throw new ArgumentNullException(nameof(synchronizationContext));
}
public override int MaximumConcurrencyLevel => 1;
protected override void QueueTask(Task task)
{
#pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs
_synchronizationContext.Post(_postCallback, task);
#pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs
}
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
if (SynchronizationContext.Current == _synchronizationContext)
{
return TryExecuteTask(task);
}
return false;
}
protected override IEnumerable<Task>? GetScheduledTasks()
=> null;
private void PostCallback(object obj)
=> TryExecuteTask((Task)obj);
}
}

Просмотреть файл

@ -1,41 +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.Threading.Tasks;
using Microsoft.VisualStudio.Threading;
namespace Microsoft.CodeAnalysis.Testing.InProcess
{
public class TestServices
{
protected TestServices(JoinableTaskFactory joinableTaskFactory)
{
JoinableTaskFactory = joinableTaskFactory;
Editor = new EditorInProcess(this);
ErrorList = new ErrorListInProcess(this);
SolutionExplorer = new SolutionExplorerInProcess(this);
}
public JoinableTaskFactory JoinableTaskFactory { get; }
public EditorInProcess Editor { get; }
public ErrorListInProcess ErrorList { get; }
public SolutionExplorerInProcess SolutionExplorer { get; }
internal static async Task<TestServices> CreateAsync(JoinableTaskFactory joinableTaskFactory)
{
var services = new TestServices(joinableTaskFactory);
await services.InitializeAsync();
return services;
}
protected virtual Task InitializeAsync()
{
return Task.CompletedTask;
}
}
}

Просмотреть файл

@ -22,6 +22,7 @@
<PackageReference Include="DiffPlex" Version="$(DiffPlexVersion)" />
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
<PackageReference Include="NuGet.SolutionRestoreManager.Interop" Version="$(NuGetSolutionRestoreManagerInteropVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Testing.SourceGenerator" Version="$(MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Testing.Xunit" Version="$(MicrosoftVisualStudioExtensibilityTestingXunitVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Interop" Version="$(MicrosoftVisualStudioInteropVersion)" />
</ItemGroup>