提交 ab924b3d 编写于 作者: F Fred Silberberg 提交者: GitHub

Merge pull request #19366 from 333fred/info-bar-refactor

Refactored IErrorReportingService

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
VisualStudioVersion = 15.0.26507.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{A41D1B99-F489-4C43-BBDF-96D61B19A6B9}"
EndProject
......
......@@ -168,6 +168,7 @@
<Compile Include="Implementation\Structure\BlockTagState.cs" />
<Compile Include="Implementation\Suggestions\SuggestedActionSetComparer.cs" />
<Compile Include="Implementation\Suggestions\SuggestedActionsSource.cs" />
<Compile Include="Implementation\InfoBar\EditorInfoBarService.cs" />
<Compile Include="SymbolSearch\IAddReferenceDatabaseWrapper.cs" />
<Compile Include="SymbolSearch\IDatabaseFactoryService.cs" />
<Compile Include="SymbolSearch\IDelayService.cs" />
......
......@@ -70,10 +70,10 @@ public override void HandleException(object provider, Exception exception)
base.HandleException(provider, exception);
_errorReportingService?.ShowErrorInfoInActiveView(String.Format(WorkspacesResources._0_encountered_an_error_and_has_been_disabled, provider.GetType().Name),
new ErrorReportingUI(WorkspacesResources.Show_Stack_Trace, ErrorReportingUI.UIKind.HyperLink, () => ShowDetailedErrorInfo(exception), closeAfterAction: false),
new ErrorReportingUI(WorkspacesResources.Enable, ErrorReportingUI.UIKind.Button, () => { EnableProvider(provider); LogEnableProvider(provider); }),
new ErrorReportingUI(WorkspacesResources.Enable_and_ignore_future_errors, ErrorReportingUI.UIKind.Button, () => { EnableProvider(provider); LogEnableProvider(provider); }),
new ErrorReportingUI(String.Empty, ErrorReportingUI.UIKind.Close, () => LogLeaveDisabled(provider)));
new InfoBarUI(WorkspacesResources.Show_Stack_Trace, InfoBarUI.UIKind.HyperLink, () => ShowDetailedErrorInfo(exception), closeAfterAction: false),
new InfoBarUI(WorkspacesResources.Enable, InfoBarUI.UIKind.Button, () => { EnableProvider(provider); LogEnableProvider(provider); }),
new InfoBarUI(WorkspacesResources.Enable_and_ignore_future_errors, InfoBarUI.UIKind.Button, () => { EnableProvider(provider); LogEnableProvider(provider); }),
new InfoBarUI(String.Empty, InfoBarUI.UIKind.Close, () => LogLeaveDisabled(provider)));
}
else
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Composition;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Internal.Log;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Workspaces
{
[ExportWorkspaceService(typeof(IInfoBarService)), Shared]
internal class EditorInfoBarService : IInfoBarService
{
public void ShowInfoBarInActiveView(string message, params InfoBarUI[] items)
=> ShowInfoBarInGlobalView(message, items);
public void ShowInfoBarInGlobalView(string message, params InfoBarUI[] items)
=> Logger.Log(FunctionId.Extension_InfoBar, message);
}
}
......@@ -13,12 +13,12 @@ public void ShowDetailedErrorInfo(Exception exception)
Logger.Log(FunctionId.Extension_Exception, exception.StackTrace);
}
public void ShowErrorInfoInActiveView(string message, params ErrorReportingUI[] items)
public void ShowErrorInfoInActiveView(string message, params InfoBarUI[] items)
{
ShowGlobalErrorInfo(message, items);
}
public void ShowGlobalErrorInfo(string message, params ErrorReportingUI[] items)
public void ShowGlobalErrorInfo(string message, params InfoBarUI[] items)
{
Logger.Log(FunctionId.Extension_Exception, message);
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation
{
[ExportWorkspaceService(typeof(IInfoBarService), layer: ServiceLayer.Host), Shared]
internal class VisualStudioInfoBarService : ForegroundThreadAffinitizedObject, IInfoBarService
{
private readonly SVsServiceProvider _serviceProvider;
private readonly IForegroundNotificationService _foregroundNotificationService;
private readonly IAsynchronousOperationListener _listener;
[ImportingConstructor]
public VisualStudioInfoBarService(SVsServiceProvider serviceProvider,
IForegroundNotificationService foregroundNotificationService,
[ImportMany] IEnumerable<Lazy<IAsynchronousOperationListener, FeatureMetadata>> asyncListeners)
{
_serviceProvider = serviceProvider;
_foregroundNotificationService = foregroundNotificationService;
_listener = new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.InfoBar);
}
public void ShowInfoBarInActiveView(string message, params InfoBarUI[] items)
{
ThisCanBeCalledOnAnyThread();
ShowInfoBar(activeView: true, message: message, items: items);
}
public void ShowInfoBarInGlobalView(string message, params InfoBarUI[] items)
{
ThisCanBeCalledOnAnyThread();
ShowInfoBar(activeView: false, message: message, items: items);
}
private void ShowInfoBar(bool activeView, 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.
_foregroundNotificationService.RegisterNotification(() =>
{
if (TryGetInfoBarData(activeView, out var infoBarHost))
{
CreateInfoBar(infoBarHost, message, items);
}
}, _listener.BeginAsyncOperation(nameof(ShowInfoBar)));
}
private bool TryGetInfoBarData(bool activeView, out IVsInfoBarHost infoBarHost)
{
AssertIsForeground();
infoBarHost = null;
if (activeView)
{
var monitorSelectionService = _serviceProvider.GetService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
// We want to get whichever window is currently in focus (including toolbars) as we could have had an exception thrown from the error list
// or interactive window
if (monitorSelectionService == null ||
ErrorHandler.Failed(monitorSelectionService.GetCurrentElementValue((uint)VSConstants.VSSELELEMID.SEID_WindowFrame, out var value)))
{
return false;
}
var frame = value as IVsWindowFrame;
if (ErrorHandler.Failed(frame.GetProperty((int)__VSFPROPID7.VSFPROPID_InfoBarHost, out var activeViewInfoBar)))
{
return false;
}
infoBarHost = activeViewInfoBar as IVsInfoBarHost;
return infoBarHost != null;
}
// global error info, show it on main window info bar
var shell = _serviceProvider.GetService(typeof(SVsShell)) as IVsShell;
if (shell == null ||
ErrorHandler.Failed(shell.GetProperty((int)__VSSPROPID7.VSSPROPID_MainWindowInfoBarHost, out var globalInfoBar)))
{
return false;
}
infoBarHost = globalInfoBar as IVsInfoBarHost;
return infoBarHost != null;
}
private void CreateInfoBar(IVsInfoBarHost infoBarHost, string message, InfoBarUI[] items)
{
var factory = _serviceProvider.GetService(typeof(SVsInfoBarUIFactory)) as IVsInfoBarUIFactory;
if (factory == null)
{
// no info bar factory, don't do anything
return;
}
var textSpans = new List<IVsInfoBarTextSpan>()
{
new InfoBarTextSpan(message)
};
// 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(
textSpans,
actionItems.ToArray(),
KnownMonikers.StatusInformation,
isCloseButtonVisible: true);
if (!TryCreateInfoBarUI(factory, infoBarModel, out var infoBarUI))
{
return;
}
uint? infoBarCookie = null;
var eventSink = new InfoBarEvents(items, () =>
{
// 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);
}
private 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();
}
}
private static bool TryCreateInfoBarUI(IVsInfoBarUIFactory infoBarUIFactory, IVsInfoBar infoBar, out IVsInfoBarUIElement uiElement)
{
uiElement = infoBarUIFactory.CreateInfoBar(infoBar);
return uiElement != null;
}
}
}
......@@ -251,10 +251,10 @@ private void OnConnectionChanged(object sender, bool connected)
FatalError.ReportWithoutCrash(new Exception("Connection to remote host closed"));
// use info bar to show warning to users
var infoBarUIs = new List<ErrorReportingUI>();
var infoBarUIs = new List<InfoBarUI>();
infoBarUIs.Add(
new ErrorReportingUI(ServicesVSResources.Learn_more, ErrorReportingUI.UIKind.HyperLink, () =>
new InfoBarUI(ServicesVSResources.Learn_more, InfoBarUI.UIKind.HyperLink, () =>
BrowserHelper.StartBrowser(new Uri(OOPKilledMoreInfoLink)), closeAfterAction: false));
var allowRestarting = _workspace.Options.GetOption(RemoteHostOptions.RestartRemoteHostAllowed);
......@@ -263,7 +263,7 @@ private void OnConnectionChanged(object sender, bool connected)
// this is hidden restart option. by default, user can't restart remote host that got killed
// by users
infoBarUIs.Add(
new ErrorReportingUI("Restart external process", ErrorReportingUI.UIKind.Button, () =>
new InfoBarUI("Restart external process", InfoBarUI.UIKind.Button, () =>
{
// start off new remote host
var unused = RequestNewRemoteHostAsync(CancellationToken.None);
......
......@@ -95,9 +95,9 @@ public int OnBroadcastMessage(uint msg, IntPtr wParam, IntPtr lParam)
_workspace.Options = _workspace.Options.WithChangedOption(RuntimeOptions.FullSolutionAnalysisInfoBarShown, true);
_workspace.Services.GetService<IErrorReportingService>().ShowGlobalErrorInfo(ServicesVSResources.Visual_Studio_has_suspended_some_advanced_features_to_improve_performance,
new ErrorReportingUI(ServicesVSResources.Re_enable, ErrorReportingUI.UIKind.Button, () =>
new InfoBarUI(ServicesVSResources.Re_enable, InfoBarUI.UIKind.Button, () =>
_workspace.Options = _workspace.Options.WithChangedOption(RuntimeOptions.FullSolutionAnalysis, true)),
new ErrorReportingUI(ServicesVSResources.Learn_more, ErrorReportingUI.UIKind.HyperLink, () =>
new InfoBarUI(ServicesVSResources.Learn_more, InfoBarUI.UIKind.HyperLink, () =>
BrowserHelper.StartBrowser(new Uri(LowVMMoreInfoLink)), closeAfterAction: false));
}
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation
{
internal partial class VisualStudioErrorReportingService : IErrorReportingService
{
private readonly static InfoBarButton s_enableItem = new InfoBarButton(ServicesVSResources.Enable);
private readonly static InfoBarButton s_enableAndIgnoreItem = new InfoBarButton(ServicesVSResources.Enable_and_ignore_future_errors);
private readonly IInfoBarService _infoBarService;
private readonly IServiceProvider _serviceProvider;
private readonly IForegroundNotificationService _foregroundNotificationService;
private readonly IAsynchronousOperationListener _listener;
public VisualStudioErrorReportingService(
SVsServiceProvider serviceProvider, IForegroundNotificationService foregroundNotificationService, IAsynchronousOperationListener listener)
{
_serviceProvider = serviceProvider;
_foregroundNotificationService = foregroundNotificationService;
_listener = listener;
}
public void ShowErrorInfoInActiveView(string message, params ErrorReportingUI[] items)
{
ShowErrorInfo(activeView: true, message: message, items: items);
}
public void ShowGlobalErrorInfo(string message, params ErrorReportingUI[] items)
{
ShowErrorInfo(activeView: false, message: message, items: items);
}
public void ShowErrorInfo(bool activeView, string message, params ErrorReportingUI[] items)
{
// We can be called from any thread since errors can occur anywhere, however we can only construct and InfoBar from the UI thread.
_foregroundNotificationService.RegisterNotification(() =>
{
if (TryGetInfoBarData(activeView, out var infoBarHost))
{
CreateInfoBar(infoBarHost, message, items);
}
}, _listener.BeginAsyncOperation("Show InfoBar"));
}
private bool TryGetInfoBarData(bool activeView, out IVsInfoBarHost infoBarHost)
{
infoBarHost = null;
if (activeView)
{
var monitorSelectionService = _serviceProvider.GetService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
// We want to get whichever window is currently in focus (including toolbars) as we could have had an exception thrown from the error list
// or interactive window
if (monitorSelectionService == null ||
ErrorHandler.Failed(monitorSelectionService.GetCurrentElementValue((uint)VSConstants.VSSELELEMID.SEID_WindowFrame, out var value)))
{
return false;
}
var frame = value as IVsWindowFrame;
if (ErrorHandler.Failed(frame.GetProperty((int)__VSFPROPID7.VSFPROPID_InfoBarHost, out var activeViewInfoBar)))
{
return false;
}
infoBarHost = activeViewInfoBar as IVsInfoBarHost;
return infoBarHost != null;
}
// global error info, show it on main window info bar
var shell = _serviceProvider.GetService(typeof(SVsShell)) as IVsShell;
if (shell == null ||
ErrorHandler.Failed(shell.GetProperty((int)__VSSPROPID7.VSSPROPID_MainWindowInfoBarHost, out var globalInfoBar)))
{
return false;
}
infoBarHost = globalInfoBar as IVsInfoBarHost;
return infoBarHost != null;
}
private void CreateInfoBar(IVsInfoBarHost infoBarHost, string message, ErrorReportingUI[] items)
public VisualStudioErrorReportingService(IInfoBarService infoBarService)
{
var factory = _serviceProvider.GetService(typeof(SVsInfoBarUIFactory)) as IVsInfoBarUIFactory;
if (factory == null)
{
// no info bar factory, don't do anything
return;
}
var textSpans = new List<IVsInfoBarTextSpan>()
{
new InfoBarTextSpan(message)
};
// create action item list
var actionItems = new List<IVsInfoBarActionItem>();
foreach (var item in items)
{
switch (item.Kind)
{
case ErrorReportingUI.UIKind.Button:
actionItems.Add(new InfoBarButton(item.Title));
break;
case ErrorReportingUI.UIKind.HyperLink:
actionItems.Add(new InfoBarHyperlink(item.Title));
break;
case ErrorReportingUI.UIKind.Close:
break;
default:
throw ExceptionUtilities.UnexpectedValue(item.Kind);
}
}
var infoBarModel = new InfoBarModel(
textSpans,
actionItems.ToArray(),
KnownMonikers.StatusInformation,
isCloseButtonVisible: true);
if (!TryCreateInfoBarUI(factory, infoBarModel, out var infoBarUI))
{
return;
}
uint? infoBarCookie = null;
var eventSink = new InfoBarEvents(items, () =>
{
// run given onClose action if there is one.
items.FirstOrDefault(i => i.Kind == ErrorReportingUI.UIKind.Close).Action?.Invoke();
if (infoBarCookie.HasValue)
{
infoBarUI.Unadvise(infoBarCookie.Value);
}
});
infoBarUI.Advise(eventSink, out var cookie);
infoBarCookie = cookie;
infoBarHost.AddInfoBar(infoBarUI);
_infoBarService = infoBarService;
}
private class InfoBarEvents : IVsInfoBarUIEvents
public void ShowErrorInfoInActiveView(string message, params InfoBarUI[] items)
{
private readonly ErrorReportingUI[] _items;
private readonly Action _onClose;
public InfoBarEvents(ErrorReportingUI[] 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();
}
_infoBarService.ShowInfoBarInActiveView(message, items);
}
private static bool TryCreateInfoBarUI(IVsInfoBarUIFactory infoBarUIFactory, IVsInfoBar infoBar, out IVsInfoBarUIElement uiElement)
public void ShowGlobalErrorInfo(string message, params InfoBarUI[] items)
{
uiElement = infoBarUIFactory.CreateInfoBar(infoBar);
return uiElement != null;
_infoBarService.ShowInfoBarInGlobalView(message, items);
}
public void ShowDetailedErrorInfo(Exception exception)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Composition;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Extensions;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.Shell;
namespace Microsoft.VisualStudio.LanguageServices.Implementation
{
[ExportWorkspaceServiceFactory(typeof(IErrorReportingService), ServiceLayer.Host), Shared]
internal sealed class VisualStudioErrorReportingServiceFactory : IWorkspaceServiceFactory
{
private readonly IErrorReportingService _singleton;
private IErrorReportingService _singleton;
[ImportingConstructor]
public VisualStudioErrorReportingServiceFactory(
SVsServiceProvider serviceProvider,
IForegroundNotificationService foregroundNotificationService,
[ImportMany] IEnumerable<Lazy<IAsynchronousOperationListener, FeatureMetadata>> asyncListeners)
public VisualStudioErrorReportingServiceFactory()
{
_singleton = new VisualStudioErrorReportingService(serviceProvider, foregroundNotificationService, new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.InfoBar));
}
public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
{
if (_singleton == null)
{
_singleton = new VisualStudioErrorReportingService(workspaceServices.GetRequiredService<IInfoBarService>());
}
return _singleton;
}
}
......
......@@ -168,6 +168,7 @@
<Compile Include="Implementation\Workspace\VisualStudioErrorReportingService.ExceptionFormatting.cs" />
<Compile Include="Implementation\Workspace\VisualStudioErrorReportingServiceFactory.cs" />
<Compile Include="Implementation\Workspace\VisualStudioErrorReportingService.cs" />
<Compile Include="Implementation\InfoBar\VisualStudioInfoBarService.cs" />
<Compile Include="Implementation\Workspace\VisualStudioNavigationOptions.cs" />
<Compile Include="Implementation\Workspace\VisualStudioNavigationOptionsProvider.cs" />
<Compile Include="Implementation\Workspace\VisualStudioProjectCacheHostServiceFactory.cs" />
......
......@@ -2,7 +2,6 @@
using System;
using Microsoft.CodeAnalysis.Host;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Extensions
{
......@@ -10,46 +9,19 @@ internal interface IErrorReportingService : IWorkspaceService
{
/// <summary>
/// Show error info in an active view.
///
///
/// Different host can have different definition on what active view means.
/// </summary>
void ShowErrorInfoInActiveView(string message, params ErrorReportingUI[] items);
void ShowErrorInfoInActiveView(string message, params InfoBarUI[] items);
/// <summary>
/// Show global error info.
///
///
/// this kind error info should be something that affects whole roslyn such as
/// background compilation is disabled due to memory issue and etc
/// </summary>
void ShowGlobalErrorInfo(string message, params ErrorReportingUI[] items);
void ShowGlobalErrorInfo(string message, params InfoBarUI[] items);
void ShowDetailedErrorInfo(Exception exception);
}
internal struct ErrorReportingUI
{
public readonly string Title;
public readonly UIKind Kind;
public readonly Action Action;
public readonly bool CloseAfterAction;
public ErrorReportingUI(string title, UIKind kind, Action action, bool closeAfterAction = true)
{
Contract.ThrowIfNull(title);
Title = title;
Kind = kind;
Action = action;
CloseAfterAction = closeAfterAction;
}
public bool IsDefault => Title == null;
internal enum UIKind
{
Button,
HyperLink,
Close
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.CodeAnalysis.Host;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Extensions
{
internal interface IInfoBarService : IWorkspaceService
{
/// <summary>
/// Show an info bar in the current active view.
///
/// Different hosts can have different definitions on what active view means.
/// </summary>
void ShowInfoBarInActiveView(string message, params InfoBarUI[] items);
/// <summary>
/// Show global info bar
/// </summary>
void ShowInfoBarInGlobalView(string message, params InfoBarUI[] items);
}
internal struct InfoBarUI
{
public readonly string Title;
public readonly UIKind Kind;
public readonly Action Action;
public readonly bool CloseAfterAction;
public InfoBarUI(string title, UIKind kind, Action action, bool closeAfterAction = true)
{
Contract.ThrowIfNull(title);
Title = title;
Kind = kind;
Action = action;
CloseAfterAction = closeAfterAction;
}
public bool IsDefault => Title == null;
internal enum UIKind
{
Button,
HyperLink,
Close
}
}
}
......@@ -372,5 +372,6 @@ internal enum FunctionId
CodeLens_GetFullyQualifiedName,
RemoteHostClientService_Restarted,
CodeAnalysisService_GetDesignerAttributesAsync,
Extension_InfoBar
}
}
......@@ -207,6 +207,7 @@
<Compile Include="..\..\..\Compilers\Core\Portable\Syntax\SyntaxTreeExtensions.cs">
<Link>InternalUtilities\SyntaxTreeExtensions.cs</Link>
</Compile>
<Compile Include="ExtensionManager\IInfoBarService.cs" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="csi" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册