Skip to content
7 changes: 4 additions & 3 deletions SharedProject/Core/Model/CoverageProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Task = System.Threading.Tasks.Task;
using System.Xml.Linq;
using System.Xml.XPath;
using EnvDTE;
Expand Down Expand Up @@ -355,7 +356,7 @@ public XElement ProjectFileXElement
public bool Is64Bit { get; set; }
public string RunSettingsFile { get; set; }

public async System.Threading.Tasks.Task StepAsync(string stepName, Func<ICoverageProject, System.Threading.Tasks.Task> action)
public async Task StepAsync(string stepName, Func<ICoverageProject, Task> action)
{
if (HasFailed)
{
Expand All @@ -380,7 +381,7 @@ public async System.Threading.Tasks.Task StepAsync(string stepName, Func<ICovera
}
}

public async System.Threading.Tasks.Task<CoverageProjectFileSynchronizationDetails> PrepareForCoverageAsync()
public async Task<CoverageProjectFileSynchronizationDetails> PrepareForCoverageAsync()
{
EnsureDirectories();
CleanFCCDirectory();
Expand All @@ -389,7 +390,7 @@ public async System.Threading.Tasks.Task<CoverageProjectFileSynchronizationDetai
return synchronizationDetails;
}

private async System.Threading.Tasks.Task SetIncludedExcludedReferencedProjectsAsync()
private async Task SetIncludedExcludedReferencedProjectsAsync()
{
List<ReferencedProject> referencedProjects = await GetReferencedProjectsAsync();
SetExcludedReferencedProjects(referencedProjects);
Expand Down
15 changes: 8 additions & 7 deletions SharedProject/Core/ReportGenerator/ReportGeneratorUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Task = System.Threading.Tasks.Task;
using System.Windows;
using ExCSS;
using FineCodeCoverage.Core.Utilities;
Expand All @@ -25,8 +26,8 @@ interface IReportGeneratorUtil
string ProcessUnifiedHtml(string htmlForProcessing,string reportOutputFolder);
Task<ReportGeneratorResult> GenerateAsync(IEnumerable<string> coverOutputFiles,string reportOutputFolder, bool throwError = false);
string BlankReport(bool withHistory);
System.Threading.Tasks.Task LogCoverageProcessAsync(string message);
System.Threading.Tasks.Task EndOfCoverageRunAsync();
Task LogCoverageProcessAsync(string message);
Task EndOfCoverageRunAsync();
}

internal class ReportGeneratorResult
Expand Down Expand Up @@ -124,12 +125,12 @@ IEventAggregator eventAggregator
scriptManager.ShowFCCOutputPaneEvent += ScriptManager_ShowFCCOutputPaneEvent;
}

private async void ScriptManager_ShowFCCOutputPaneEvent(object sender, EventArgs e)
private void ScriptManager_ShowFCCOutputPaneEvent(object sender, EventArgs e)
{
await showFCCOutputPane.ShowAsync();
_ = ThreadHelper.JoinableTaskFactory.RunAsync(() => showFCCOutputPane.ShowAsync());
}

private void ScriptManager_ClearFCCWindowLogsEvent(object sender, EventArgs e)
private void ScriptManager_ClearFCCWindowLogsEvent(object sender, EventArgs e)
{
logs.Clear();
}
Expand Down Expand Up @@ -1686,14 +1687,14 @@ public string BlankReport(bool withHistory)
return ProcessUnifiedHtml(resourceProvider.ReadResource("dummyReportToProcess.html"),null);
}

public async System.Threading.Tasks.Task LogCoverageProcessAsync(string message)
public async Task LogCoverageProcessAsync(string message)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
eventAggregator.SendMessage(new InvokeScriptMessage(CoverageLogJSFunctionName, message));
logs.Add(message);
}

public async System.Threading.Tasks.Task EndOfCoverageRunAsync()
public async Task EndOfCoverageRunAsync()
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
eventAggregator.SendMessage(new InvokeScriptMessage(ShowFCCWorkingJSFunctionName, false));
Expand Down
49 changes: 26 additions & 23 deletions SharedProject/Impl/CoverageColorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,29 +102,33 @@ private void UpdateFromFontsAndColorsIfNecessary()

private void UpdateColoursFromFontsAndColors()
{
ThreadHelper.ThrowIfNotOnUIThread();
var success = fontAndColorStorage.OpenCategory(ref categoryWithCoverage, storeFlags);
if (success == VSConstants.S_OK)
ThreadHelper.JoinableTaskFactory.Run(async () =>
{
CoverageTouchedArea = GetColor("Coverage Touched Area");
CoverageNotTouchedArea = GetColor("Coverage Not Touched Area");
CoveragePartiallyTouchedArea = GetColor("Coverage Partially Touched Area");
}
fontAndColorStorage.CloseCategory();
//throw ?
requiresFromFontsAndColours = false;
}

private System.Windows.Media.Color GetColor(string displayName)
{
ThreadHelper.ThrowIfNotOnUIThread();
var touchAreaInfo = new ColorableItemInfo[1];
var getItemSuccess = fontAndColorStorage.GetItem(displayName, touchAreaInfo);
if (getItemSuccess == VSConstants.S_OK)
{
return ParseColor(touchAreaInfo[0].crBackground);
}
throw new Exception("Failed to get color");
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var success = fontAndColorStorage.OpenCategory(ref categoryWithCoverage, storeFlags);
if (success == VSConstants.S_OK)
{
// https://github.com/microsoft/vs-threading/issues/993
System.Windows.Media.Color GetColor(string displayName)
{
var touchAreaInfo = new ColorableItemInfo[1];
var getItemSuccess = fontAndColorStorage.GetItem(displayName, touchAreaInfo);
if (getItemSuccess == VSConstants.S_OK)
{
return ParseColor(touchAreaInfo[0].crBackground);
}
throw new Exception("Failed to get color");
}

CoverageTouchedArea = GetColor("Coverage Touched Area");
CoverageNotTouchedArea = GetColor("Coverage Not Touched Area");
CoveragePartiallyTouchedArea = GetColor("Coverage Partially Touched Area");
}
fontAndColorStorage.CloseCategory();
//throw ?
requiresFromFontsAndColours = false;
});

}

private System.Windows.Media.Color ParseColor(uint color)
Expand All @@ -133,7 +137,6 @@ private System.Windows.Media.Color ParseColor(uint color)
return System.Windows.Media.Color.FromArgb(dcolor.A, dcolor.R, dcolor.G, dcolor.B);
}


}

}
54 changes: 24 additions & 30 deletions SharedProject/Impl/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@
using System.Linq;
using FineCodeCoverage;
using System.Diagnostics;
using Microsoft.VisualStudio;
using System.Collections.Generic;
using Microsoft.VisualStudio.Shell;
using System.Diagnostics.CodeAnalysis;
using Microsoft.VisualStudio.Shell.Interop;
using System.ComponentModel.Composition;
using Microsoft;
using EnvDTE;
using Task = System.Threading.Tasks.Task;
using EnvDTE80;

interface IShowFCCOutputPane
{
System.Threading.Tasks.Task ShowAsync();
Task ShowAsync();
}
[Export(typeof(IShowFCCOutputPane))]
[Export(typeof(ILogger))]
public class Logger : ILogger, IShowFCCOutputPane
{
private IVsOutputWindowPane _pane;
private IVsOutputWindow _outputWindow;
private DTE dte;
private DTE2 dte;
private readonly IServiceProvider _serviceProvider;
private Guid fccPaneGuid = Guid.Parse("3B3C775A-0050-445D-9022-0230957805B2");

Expand All @@ -35,33 +35,27 @@ IServiceProvider serviceProvider
staticLogger = this;
}

IVsOutputWindowPane CreatePane(Guid paneGuid, string title,
bool visible, bool clearWithSolution)
{

ThreadHelper.ThrowIfNotOnUIThread();
_outputWindow = (IVsOutputWindow)_serviceProvider.GetService(typeof(SVsOutputWindow));
Assumes.Present(_outputWindow);
dte = (EnvDTE.DTE)_serviceProvider.GetService(typeof(EnvDTE.DTE));
Assumes.Present(dte);

// Create a new pane.
_outputWindow.CreatePane(
ref paneGuid,
title,
Convert.ToInt32(visible),
Convert.ToInt32(clearWithSolution));

// Retrieve the new pane.
_outputWindow.GetPane(ref paneGuid, out IVsOutputWindowPane pane);
return pane;
}

private void SetPane()
{
ThreadHelper.ThrowIfNotOnUIThread();
// do not clear with solution otherwise will not get initialize methods
_pane = CreatePane(fccPaneGuid, "FCC", true, false);
ThreadHelper.JoinableTaskFactory.Run(async () =>
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
_outputWindow = (IVsOutputWindow)_serviceProvider.GetService(typeof(SVsOutputWindow));
Assumes.Present(_outputWindow);
dte = (DTE2)_serviceProvider.GetService(typeof(EnvDTE.DTE));
Assumes.Present(dte);

// Create a new pane.
_outputWindow.CreatePane(
ref fccPaneGuid,
"FCC",
Convert.ToInt32(true),
Convert.ToInt32(false)); // do not clear with solution otherwise will not get initialize methods

// Retrieve the new pane.
_outputWindow.GetPane(ref fccPaneGuid, out IVsOutputWindowPane pane);
_pane = pane;
});
}

[SuppressMessage("Usage", "VSTHRD102:Implement internal logic asynchronously")]
Expand Down Expand Up @@ -154,7 +148,7 @@ public void LogWithoutTitle(IEnumerable<string> message)
LogImpl(message.ToArray(), false);
}

public async System.Threading.Tasks.Task ShowAsync()
public async Task ShowAsync()
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ public void Initialize()

if (File.Exists(outputWindowInitializedFile))
{
OutputToolWindowCommand.Instance.FindToolWindow();
await OutputToolWindowCommand.Instance.FindToolWindowAsync();
}
else
{
// for first time users, the window is automatically docked
OutputToolWindowCommand.Instance.ShowToolWindow();
await OutputToolWindowCommand.Instance.ShowToolWindowAsync();
File.WriteAllText(outputWindowInitializedFile, string.Empty);
}
}
Expand Down
1 change: 0 additions & 1 deletion SharedProject/Options/AppOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ You can also ignore additional attributes by adding to this list (short name or
[Description("Set to true to hide classes, namespaces and assemblies that are fully covered.")]
public bool HideFullyCovered { get; set; }

[SuppressMessage("Usage", "VSTHRD010:Invoke single-threaded types on Main thread")]
public override void SaveSettingsToStorage()
{
AppOptionsStorageProvider.SaveSettingsToStorage(this);
Expand Down
22 changes: 13 additions & 9 deletions SharedProject/Options/AppOptionsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@ public IAppOptions Get()
return options;
}

[SuppressMessage("Usage", "VSTHRD010:Invoke single-threaded types on Main thread")]
private WritableSettingsStore EnsureStore()
{
var settingsManager = new ShellSettingsManager(ServiceProvider.GlobalProvider);
var settingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);

if (!settingsStore.CollectionExists(Vsix.Code))
WritableSettingsStore settingsStore = null;
ThreadHelper.JoinableTaskFactory.Run(async () =>
{
settingsStore.CreateCollection(Vsix.Code);
}
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var settingsManager = new ShellSettingsManager(ServiceProvider.GlobalProvider);
settingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);

if (!settingsStore.CollectionExists(Vsix.Code))
{
settingsStore.CreateCollection(Vsix.Code);
}
});

return settingsStore;
}

Expand All @@ -53,7 +58,6 @@ private PropertyInfo[] ReflectProperties()
return AppOptionsType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
}

[SuppressMessage("Usage", "VSTHRD010:Invoke single-threaded types on Main thread")]
public void LoadSettingsFromStorage(AppOptions instance)
{
var settingsStore = EnsureStore();
Expand Down Expand Up @@ -85,7 +89,7 @@ public void LoadSettingsFromStorage(AppOptions instance)
}
}
}
[SuppressMessage("Usage", "VSTHRD010:Invoke single-threaded types on Main thread")]

public void SaveSettingsToStorage(AppOptions appOptions)
{
var settingsStore = EnsureStore();
Expand Down
33 changes: 12 additions & 21 deletions SharedProject/Output/OutputToolWindowCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.ComponentModel.Design;
using Microsoft.VisualStudio.Shell;
using System.Threading.Tasks;
using Task = System.Threading.Tasks.Task;

namespace FineCodeCoverage.Output
Expand Down Expand Up @@ -82,39 +83,29 @@ public static async Task InitializeAsync(AsyncPackage package)
/// <param name="e">The event args.</param>
public void Execute(object sender, EventArgs e)
{
ShowToolWindow();
_ = ThreadHelper.JoinableTaskFactory.RunAsync(ShowToolWindowAsync);
}

public ToolWindowPane ShowToolWindow()
public async Task<ToolWindowPane> ShowToolWindowAsync()
{
ToolWindowPane window = null;
ToolWindowPane window = await package.ShowToolWindowAsync(typeof(OutputToolWindow), 0, true, package.DisposalToken);

package.JoinableTaskFactory.RunAsync(async delegate
if ((null == window) || (null == window.Frame))
{
window = await package.ShowToolWindowAsync(typeof(OutputToolWindow), 0, true, package.DisposalToken);

if ((null == window) || (null == window.Frame))
{
throw new NotSupportedException($"Cannot create '{Vsix.Name}' output window");
}
});
throw new NotSupportedException($"Cannot create '{Vsix.Name}' output window");
}

return window;
}

public ToolWindowPane FindToolWindow()
public async Task<ToolWindowPane> FindToolWindowAsync()
{
ToolWindowPane window = null;
ToolWindowPane window = await package.FindToolWindowAsync(typeof(OutputToolWindow), 0, true, package.DisposalToken);

package.JoinableTaskFactory.RunAsync(async delegate
if ((null == window) || (null == window.Frame))
{
window = await package.FindToolWindowAsync(typeof(OutputToolWindow), 0, true, package.DisposalToken);

if ((null == window) || (null == window.Frame))
{
throw new NotSupportedException($"Cannot create '{Vsix.Name}' output window");
}
});
throw new NotSupportedException($"Cannot create '{Vsix.Name}' output window");
}

return window;
}
Expand Down
5 changes: 3 additions & 2 deletions SharedProject/Output/OutputToolWindowPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;
using System.ComponentModel.Composition;
using System.Threading.Tasks;
using Task = System.Threading.Tasks.Task;
using Microsoft.VisualStudio.Shell.Interop;
using EnvDTE80;
Expand Down Expand Up @@ -91,9 +92,9 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke
await ClearUICommand.InitializeAsync(this, componentModel.GetService<IFCCEngine>());
}

protected override System.Threading.Tasks.Task<object> InitializeToolWindowAsync(Type toolWindowType, int id, CancellationToken cancellationToken)
protected override Task<object> InitializeToolWindowAsync(Type toolWindowType, int id, CancellationToken cancellationToken)
{
return System.Threading.Tasks.Task.FromResult<object>(GetOutputToolWindowContext());
return Task.FromResult<object>(GetOutputToolWindowContext());
}
public override IVsAsyncToolWindowFactory GetAsyncToolWindowFactory(Guid toolWindowType)
{
Expand Down