Skip to content

Commit

Permalink
Refactor and simplify (#59981)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat authored Mar 8, 2022
1 parent c831c66 commit 347cd02
Show file tree
Hide file tree
Showing 23 changed files with 196 additions and 369 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.CodeAnalysis.Editor.Implementation.Suggestions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@
// See the LICENSE file in the project root for more information.

using System;
using Microsoft.CodeAnalysis.Extensions;
using System.Composition;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Telemetry;

namespace Microsoft.CodeAnalysis.Editor.Implementation.Workspaces
namespace Microsoft.CodeAnalysis.ErrorReporting
{
internal class EditorErrorReportingService : IErrorReportingService
[ExportWorkspaceService(typeof(IErrorReportingService), ServiceLayer.Editor), Shared]
internal sealed class EditorErrorReportingService : IErrorReportingService
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public EditorErrorReportingService()
{
}

public string HostDisplayName => "host";

public void ShowDetailedErrorInfo(Exception exception)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Editor.Options;
using Microsoft.CodeAnalysis.ErrorLogger;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
Expand Down
27 changes: 0 additions & 27 deletions src/EditorFeatures/Core/InfoBar/EditorInfoBarService.cs

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.ErrorLogger;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.PooledObjects;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
Expand Down
1 change: 1 addition & 0 deletions src/Features/Core/Portable/CodeFixes/CodeFixService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.CodeAnalysis.CodeFixes.Suppression;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.ErrorLogger;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Internal.Log;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<ui:DialogWindow x:Class="Microsoft.VisualStudio.LanguageServices.Implementation.DetailedErrorInfoDialog"
<ui:DialogWindow x:Class="Microsoft.CodeAnalysis.ErrorReporting.DetailedErrorInfoDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:Microsoft.VisualStudio.LanguageServices.Implementation"
xmlns:local="clr-namespace:Microsoft.CodeAnalysis.ErrorReporting"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0"
xmlns:vs="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,12 @@
// 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.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.VisualStudio.LanguageServices;
using Microsoft.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Shell;

namespace Microsoft.VisualStudio.LanguageServices.Implementation
namespace Microsoft.CodeAnalysis.ErrorReporting
{
internal partial class DetailedErrorInfoDialog : DialogWindow
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.VisualStudio.LanguageServices;
using StreamJsonRpc;

namespace Microsoft.VisualStudio.LanguageServices.Implementation
namespace Microsoft.CodeAnalysis.ErrorReporting
{
internal partial class VisualStudioErrorReportingService
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,35 @@

using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using System.Composition;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Telemetry;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

namespace Microsoft.VisualStudio.LanguageServices.Implementation
namespace Microsoft.CodeAnalysis.ErrorReporting
{
[ExportWorkspaceService(typeof(IErrorReportingService), ServiceLayer.Host), Shared]
internal partial class VisualStudioErrorReportingService : IErrorReportingService
{
private readonly IThreadingContext _threadingContext;
private readonly IAsynchronousOperationListener _listener;
private readonly IInfoBarService _infoBarService;
private readonly VisualStudioInfoBar _infoBar;
private readonly SVsServiceProvider _serviceProvider;

[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public VisualStudioErrorReportingService(
IThreadingContext threadingContext,
IAsynchronousOperationListenerProvider listenerProvider,
IInfoBarService infoBarService,
SVsServiceProvider serviceProvider)
{
_threadingContext = threadingContext;
_listener = listenerProvider.GetListener(FeatureAttribute.Workspace);
_infoBarService = infoBarService;
_infoBar = new VisualStudioInfoBar(threadingContext, serviceProvider, listenerProvider);
_serviceProvider = serviceProvider;
}

Expand All @@ -40,7 +42,7 @@ public void ShowGlobalErrorInfo(string message, TelemetryFeatureName featureName
{
var stackTrace = exception is null ? "" : GetFormattedExceptionStack(exception);
LogGlobalErrorToActivityLog(message, stackTrace);
_infoBarService.ShowInfoBar(message, items);
_infoBar.ShowInfoBar(message, items);

Logger.Log(FunctionId.VS_ErrorReportingService_ShowGlobalErrorInfo, KeyValueLogMessage.Create(LogType.UserAction, m =>
{
Expand Down
157 changes: 157 additions & 0 deletions src/VisualStudio/Core/Def/ErrorReporting/VisualStudioInfoBar.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// 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.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.ErrorReporting
{
internal sealed class VisualStudioInfoBar
{
private readonly IThreadingContext _threadingContext;
private readonly SVsServiceProvider _serviceProvider;
private readonly IAsynchronousOperationListener _listener;

/// <summary>
/// Keep track of the messages that are currently being shown to the user. If we would
/// show the same message again, block that from happening so we don't spam the user with
/// the same message. When the info bar item is dismissed though, we then may show the
/// same message in the future. This is important for user clarity as it's possible for
/// a feature to fail for some reason, then work fine for a while, then fail again. We want
/// the second failure message to be reported to ensure the user is not confused.
///
/// Accessed on UI thread.
/// </summary>
private readonly HashSet<string> _currentlyShowingMessages = new();

public VisualStudioInfoBar(
IThreadingContext threadingContext,
SVsServiceProvider serviceProvider,
IAsynchronousOperationListenerProvider listenerProvider)
{
_threadingContext = threadingContext;
_serviceProvider = serviceProvider;
_listener = listenerProvider.GetListener(FeatureAttribute.InfoBar);
}

public void ShowInfoBar(string message, params InfoBarUI[] items)
{
// We can be called from any thread since errors can occur anywhere, however we can only construct and InfoBar from the UI thread.
_threadingContext.JoinableTaskFactory.RunAsync(async () =>
{
using var _ = _listener.BeginAsyncOperation(nameof(ShowInfoBar));
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(_threadingContext.DisposalToken);
// If we're already shown this same message to the user, then do not bother showing it
// to them again. It will just be noisy.
if (!_currentlyShowingMessages.Contains(message) &&
_serviceProvider.GetService(typeof(SVsShell)) is IVsShell shell &&
ErrorHandler.Succeeded(shell.GetProperty((int)__VSSPROPID7.VSSPROPID_MainWindowInfoBarHost, out var globalInfoBar)) &&
globalInfoBar is IVsInfoBarHost infoBarHost &&
_serviceProvider.GetService(typeof(SVsInfoBarUIFactory)) is IVsInfoBarUIFactory factory)
{
// create action item list
var actionItems = new List<IVsInfoBarActionItem>();
foreach (var item in items)
{
switch (item.Kind)
{
case InfoBarUI.UIKind.Button:
actionItems.Add(new InfoBarButton(item.Title));
break;
case InfoBarUI.UIKind.HyperLink:
actionItems.Add(new InfoBarHyperlink(item.Title));
break;
case InfoBarUI.UIKind.Close:
break;
default:
throw ExceptionUtilities.UnexpectedValue(item.Kind);
}
}
var infoBarModel = new InfoBarModel(
new[] { new InfoBarTextSpan(message) },
actionItems,
KnownMonikers.StatusInformation,
isCloseButtonVisible: true);
var infoBarUI = factory.CreateInfoBar(infoBarModel);
if (infoBarUI == null)
return;
uint? infoBarCookie = null;
var eventSink = new InfoBarEvents(items, onClose: () =>
{
Contract.ThrowIfFalse(_threadingContext.JoinableTaskContext.IsOnMainThread);
// Remove the message from the list that we're keeping track of. Future identical
// messages can now be shown.
_currentlyShowingMessages.Remove(message);
// Run given onClose action if there is one.
items.FirstOrDefault(i => i.Kind == InfoBarUI.UIKind.Close).Action?.Invoke();
if (infoBarCookie.HasValue)
{
infoBarUI.Unadvise(infoBarCookie.Value);
}
});
infoBarUI.Advise(eventSink, out var cookie);
infoBarCookie = cookie;
infoBarHost.AddInfoBar(infoBarUI);
_currentlyShowingMessages.Add(message);
}
});
}

private sealed class InfoBarEvents : IVsInfoBarUIEvents
{
private readonly InfoBarUI[] _items;
private readonly Action _onClose;

public InfoBarEvents(InfoBarUI[] items, Action onClose)
{
Contract.ThrowIfNull(onClose);

_items = items;
_onClose = onClose;
}

public void OnActionItemClicked(IVsInfoBarUIElement infoBarUIElement, IVsInfoBarActionItem actionItem)
{
var item = _items.FirstOrDefault(i => i.Title == actionItem.Text);
if (item.IsDefault)
{
return;
}

item.Action?.Invoke();

if (!item.CloseAfterAction)
{
return;
}

infoBarUIElement.Close();
}

public void OnClosed(IVsInfoBarUIElement infoBarUIElement)
=> _onClose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Composition;
using Microsoft.CodeAnalysis.Telemetry;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.ExternalAccess.LegacyCodeAnalysis.Api;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.VisualStudio.LanguageServices;
Expand Down
Loading

0 comments on commit 347cd02

Please sign in to comment.