提交 6131e988 编写于 作者: A Artur Spychaj

Merge pull request #8812 from drognanar/delayloadinteractivedll

Move interactive commands out of InteractiveFeatures
// 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 Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.VisualStudio.Text;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
namespace Microsoft.CodeAnalysis.Editor.CommandHandlers
{
/// <summary>
/// Implements a execute in interactive command handler.
/// This class is separated from the <see cref="IExecuteInInteractiveCommandHandler"/>
/// in order to ensure that the interactive command can be exposed without the necessity
/// to load any of the interactive dll files just to get the command's status.
/// </summary>
[ExportCommandHandler("Interactive Command Handler", ContentTypeNames.RoslynContentType)]
internal class ExecuteInInteractiveCommandHandler
: ICommandHandler<ExecuteInInteractiveCommandArgs>
{
private readonly IEnumerable<Lazy<IExecuteInInteractiveCommandHandler, ContentTypeMetadata>> _executeInInteractiveHandlers;
[ImportingConstructor]
public ExecuteInInteractiveCommandHandler(
[ImportMany]IEnumerable<Lazy<IExecuteInInteractiveCommandHandler, ContentTypeMetadata>> executeInInteractiveHandlers)
{
_executeInInteractiveHandlers = executeInInteractiveHandlers;
}
private Lazy<IExecuteInInteractiveCommandHandler> GetCommandHandler(ITextBuffer textBuffer)
{
return _executeInInteractiveHandlers
.Where(handler => handler.Metadata.ContentTypes.Contains(textBuffer.ContentType.TypeName))
.SingleOrDefault();
}
void ICommandHandler<ExecuteInInteractiveCommandArgs>.ExecuteCommand(ExecuteInInteractiveCommandArgs args, Action nextHandler)
{
GetCommandHandler(args.SubjectBuffer)?.Value.ExecuteCommand(args, nextHandler);
}
CommandState ICommandHandler<ExecuteInInteractiveCommandArgs>.GetCommandState(ExecuteInInteractiveCommandArgs args, Func<CommandState> nextHandler)
{
return GetCommandHandler(args.SubjectBuffer) == null
? CommandState.Unavailable
: CommandState.Available;
}
}
}
// 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 Microsoft.CodeAnalysis.Editor.Commands;
namespace Microsoft.CodeAnalysis.Editor.CommandHandlers
{
/// <summary>
/// Interface for the ExecuteInInteractiveCommand handler.
/// Ensures that the command handler can be exported via MEF
/// without actually being instantiated as all other command handlers.
/// </summary>
internal interface IExecuteInInteractiveCommandHandler
: ICommandHandler<ExecuteInInteractiveCommandArgs>
{
}
}
......@@ -140,7 +140,9 @@
<Compile Include="CommandHandlers\AbstractCompletionCommandHandler.cs" />
<Compile Include="CommandHandlers\AbstractIntelliSenseCommandHandler.cs" />
<Compile Include="CommandHandlers\CompletionCommandHandler.cs" />
<Compile Include="CommandHandlers\ExecuteInInteractiveCommandHandler.cs" />
<Compile Include="CommandHandlers\GoToAdjacentMemberCommandHandler.cs" />
<Compile Include="CommandHandlers\IExecuteInInteractiveCommandHandler.cs" />
<Compile Include="CommandHandlers\IntelliSenseCommandHandler.cs" />
<Compile Include="CommandHandlers\InteractivePasteCommandHandler.cs" />
<Compile Include="CommandHandlers\QuickInfoCommandHandlerAndSourceProvider.cs" />
......@@ -223,6 +225,7 @@
<Compile Include="Extensibility\BraceMatching\ExportBraceMatcherAttribute.cs" />
<Compile Include="Extensibility\BraceMatching\IBraceMatcher.cs" />
<Compile Include="Extensibility\Commands\ExportCommandHandlerAttribute.cs" />
<Compile Include="Extensibility\Commands\ExportInteractiveCommandAttribute.cs" />
<Compile Include="Extensibility\Commands\ICommandHandler.cs" />
<Compile Include="Extensibility\Commands\PredefinedCommandHandlerNames.cs" />
<Compile Include="Extensibility\Completion\CompletionItemEventArgs.cs" />
......@@ -284,6 +287,7 @@
<Compile Include="Implementation\GoToImplementation\AbstractGoToImplementationService.cs" />
<Compile Include="Implementation\GoToImplementation\IGoToImplementationService.cs" />
<Compile Include="Implementation\Intellisense\Completion\OptionSetExtensions.cs" />
<Compile Include="Implementation\Interactive\IAbstractResetInteractiveCommand.cs" />
<Compile Include="Implementation\Outlining\AbstractSyntaxOutliner.cs" />
<Compile Include="Implementation\Outlining\InvalidOutliningRegionException.cs" />
<Compile Include="Implementation\Suggestions\FixMultipleOccurrencesService.cs" />
......@@ -818,4 +822,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
// 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.ComponentModel.Composition;
namespace Microsoft.CodeAnalysis.Editor
{
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class)]
internal class ExportInteractiveAttribute : ExportAttribute
{
public IEnumerable<string> ContentTypes { get; }
public ExportInteractiveAttribute(Type t, params string[] contentTypes) :
base(t)
{
this.ContentTypes = contentTypes;
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Roslyn.VisualStudio.Services.Interactive
{
/// <summary>
/// An interface that implements the execution of ResetInteractive.
/// Implementation is defined separately from command declaration in order
/// to avoid the need to load the dll.
/// </summary>
internal interface IResetInteractiveCommand
{
void ExecuteResetInteractive();
}
}
......@@ -9,11 +9,12 @@
using Microsoft.VisualStudio.Utilities;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.CSharp.Interactive;
using Microsoft.CodeAnalysis.Editor.CommandHandlers;
namespace Microsoft.VisualStudio.LanguageServices.CSharp.Interactive
{
[ExportCommandHandler("Interactive Command Handler", ContentTypeNames.CSharpContentType)]
internal sealed class CSharpInteractiveCommandHandler : InteractiveCommandHandler
[ExportInteractive(typeof(IExecuteInInteractiveCommandHandler), ContentTypeNames.CSharpContentType)]
internal sealed class CSharpInteractiveCommandHandler : InteractiveCommandHandler, IExecuteInInteractiveCommandHandler
{
private readonly CSharpVsInteractiveWindowProvider _interactiveWindowProvider;
......
......@@ -145,6 +145,7 @@
<Compile Include="CSharpVsInteractiveWindowProvider.cs" />
<Compile Include="CSharpVsInteractiveWindowPackage.cs" />
<Compile Include="CSharpVsInteractiveWindowCommandProvider.cs" />
<Compile Include="CSharpVsResetInteractiveCommand.cs" />
<Content Include="CSharpInteractive.rsp" />
<Content Include="Resources\ScriptFile.ico" />
</ItemGroup>
......@@ -174,4 +175,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
......@@ -29,21 +29,11 @@ protected override Guid ToolWindowId
get { return Id; }
}
protected override string LanguageName
{
get { return "C#"; }
}
protected override Guid LanguageServiceGuid
{
get { return LanguageServiceGuids.CSharpLanguageServiceId; }
}
protected override string ProjectKind
{
get { return VSLangProj.PrjKind.prjKindCSharpProject; }
}
protected override void InitializeMenuCommands(OleMenuCommandService menuCommandService)
{
var openInteractiveCommand = new MenuCommand(
......@@ -52,20 +42,5 @@ protected override void InitializeMenuCommands(OleMenuCommandService menuCommand
menuCommandService.AddCommand(openInteractiveCommand);
}
protected override CommandID GetResetInteractiveFromProjectCommandID()
{
return new CommandID(CSharpInteractiveCommands.InteractiveCommandSetId, CSharpInteractiveCommands.ResetInteractiveFromProject);
}
protected override string CreateReference(string referenceName)
{
return string.Format("#r \"{0}\"", referenceName);
}
protected override string CreateImport(string namespaceName)
{
return string.Format("using {0};", namespaceName);
}
}
}
// 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 Microsoft.CodeAnalysis.Editor;
using Microsoft.VisualStudio.Shell;
using Roslyn.VisualStudio.Services.Interactive;
using System;
using System.ComponentModel.Composition;
namespace Microsoft.VisualStudio.LanguageServices.CSharp.Interactive
{
[ExportInteractive(typeof(IResetInteractiveCommand), ContentTypeNames.CSharpContentType)]
internal sealed class CSharpVsResetInteractiveCommand
: AbstractResetInteractiveCommand
{
[ImportingConstructor]
public CSharpVsResetInteractiveCommand(
[Import]CSharpVsInteractiveWindowProvider interactiveWindowProvider,
[Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider)
: base(interactiveWindowProvider, serviceProvider)
{
}
protected override string LanguageName
{
get { return "C#"; }
}
protected override string CreateReference(string referenceName)
{
return string.Format("#r \"{0}\"", referenceName);
}
protected override string CreateImport(string namespaceName)
{
return string.Format("using {0};", namespaceName);
}
}
}
......@@ -23,25 +23,9 @@
<ButtonText>C# Interactive</ButtonText>
</Strings>
</Button>
<Button guid="guidCSharpInteractiveCommandSet" id="cmdidResetInteractiveFromProject" priority="0x0100" type="Button">
<Parent guid="guidCSharpInteractiveCommandSet" id="IDG_INTERACTIVE_PROJECT"/>
<CommandFlag>DynamicVisibility</CommandFlag>
<CommandFlag>DefaultInvisible</CommandFlag>
<Strings>
<ButtonText>Reset C# Interactive from Project</ButtonText>
<CanonicalName>ResetC#InteractiveFromProject</CanonicalName>
<LocCanonicalName>ResetC#InteractiveFromProject</LocCanonicalName>
</Strings>
</Button>
</Buttons>
</Commands>
<VisibilityConstraints>
<VisibilityItem context="guidCSProjectContext" guid="guidCSharpInteractiveCommandSet" id="cmdidResetInteractiveFromProject" />
<VisibilityItem context="guidVBProjectContext" guid="guidCSharpInteractiveCommandSet" id="cmdidResetInteractiveFromProject" />
</VisibilityConstraints>
<!-- https://github.com/dotnet/roslyn/issues/3941
<KeyBindings>
<KeyBinding guid="guidCSharpInteractiveCommandSet" id="cmdidCSharpInteractiveToolWindow" editor="guidVSStd97" mod1="Control" key1="W" mod2="Control" key2="I" />
......
......@@ -339,6 +339,28 @@
<CommandName>GoToImplementation</CommandName>
</Strings>
</Button>
<!-- Interactive context menu in solution explorer. -->
<Button guid="guidCSharpInteractiveCommandSet" id="cmdidResetInteractiveFromProject" priority="0x0100" type="Button">
<Parent guid="guidCSharpInteractiveCommandSet" id="IDG_INTERACTIVE_PROJECT"/>
<CommandFlag>DynamicVisibility</CommandFlag>
<CommandFlag>DefaultInvisible</CommandFlag>
<Strings>
<ButtonText>Initialize Interactive with Project</ButtonText>
<CanonicalName>ResetC#InteractiveFromProject</CanonicalName>
<LocCanonicalName>ResetC#InteractiveFromProject</LocCanonicalName>
</Strings>
</Button>
<Button guid="guidVisualBasicInteractiveCommandSet" id="cmdidResetInteractiveFromProject" priority="0x0100" type="Button">
<Parent guid="guidVisualBasicInteractiveCommandSet" id="IDG_INTERACTIVE_PROJECT"/>
<CommandFlag>DynamicVisibility</CommandFlag>
<CommandFlag>DefaultInvisible</CommandFlag>
<Strings>
<ButtonText>Reset Visual Basic Interactive from Project</ButtonText>
<CanonicalName>ResetVisualBasicInteractiveFromProject</CanonicalName>
<LocCanonicalName>ResetVisualBasicInteractiveFromProject</LocCanonicalName>
</Strings>
</Button>
</Buttons>
<Menus>
......@@ -508,5 +530,19 @@
<IDSymbol name="cmdidGoToImplementation" value="0x0200" />
</GuidSymbol>
<GuidSymbol name="guidCSharpInteractiveCommandSet" value="{1492db0a-85a2-4e43-bf0d-ce55b89a8cc6}">
<IDSymbol name="IDG_INTERACTIVE_PROJECT" value="0x0100" />
<IDSymbol name="cmdidCSharpInteractiveToolWindow" value="0x0001" />
<IDSymbol name="cmdidResetInteractiveFromProject" value="0x0002"/>
</GuidSymbol>
<GuidSymbol name="guidVisualBasicInteractiveCommandSet" value="{93DF185E-D75B-4FDB-9D47-E90F111971C5}">
<IDSymbol name="IDG_INTERACTIVE_PROJECT" value="0x100" />
<IDSymbol name="cmdidVisualBasicInteractiveToolWindow" value="0x0001" />
<IDSymbol name="cmdidResetInteractiveFromProject" value="0x0002"/>
</GuidSymbol>
</Symbols>
</CommandTable>
// 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;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Interactive
{
internal static partial class ID
{
internal static class InteractiveCommands
{
public const int InteractiveToolWindow = 0x0001;
public const int ResetInteractiveFromProject = 0x0002;
public static readonly string CSharpInteractiveCommandSetIdString = "1492DB0A-85A2-4E43-BF0D-CE55B89A8CC6";
public static readonly Guid CSharpInteractiveCommandSetId = new Guid(CSharpInteractiveCommandSetIdString);
public static readonly string VisualBasicInteractiveCommandSetIdString = "93DF185E-D75B-4FDB-9D47-E90F111971C5";
public static readonly Guid VisualBasicInteractiveCommandSetId = new Guid(VisualBasicInteractiveCommandSetIdString);
}
}
}
// 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 Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.VisualStudio.Services.Interactive;
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.ComponentModel.Design;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.CodeAnalysis.Editor;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Interactive
{
internal abstract class AbstractResetInteractiveMenuCommand
{
protected abstract string ProjectKind { get; }
protected abstract CommandID GetResetInteractiveFromProjectCommandID();
private readonly OleMenuCommandService _menuCommandService;
private readonly IVsMonitorSelection _monitorSelection;
private readonly IComponentModel _componentModel;
private readonly string _contentType;
private Lazy<IResetInteractiveCommand> _resetInteractiveCommand;
private Lazy<IResetInteractiveCommand> ResetInteractiveCommand => _resetInteractiveCommand;
public AbstractResetInteractiveMenuCommand(
string contentType,
OleMenuCommandService menuCommandService,
IVsMonitorSelection monitorSelection,
IComponentModel componentModel)
{
_contentType = contentType;
_menuCommandService = menuCommandService;
_monitorSelection = monitorSelection;
_componentModel = componentModel;
_resetInteractiveCommand = _componentModel.DefaultExportProvider
.GetExports<IResetInteractiveCommand, ContentTypeMetadata>()
.Where(resetInteractiveService => resetInteractiveService.Metadata.ContentTypes.Contains(_contentType))
.SingleOrDefault();
}
internal void InitializeResetInteractiveFromProjectCommand()
{
var resetInteractiveFromProjectCommand = new OleMenuCommand(
(sender, args) =>
{
ResetInteractiveCommand.Value.ExecuteResetInteractive();
},
GetResetInteractiveFromProjectCommandID());
resetInteractiveFromProjectCommand.Supported = true;
resetInteractiveFromProjectCommand.BeforeQueryStatus += (_, __) =>
{
EnvDTE.Project project;
FrameworkName frameworkName;
GetActiveProject(out project, out frameworkName);
var available = ResetInteractiveCommand != null
&& project != null && project.Kind == ProjectKind
&& frameworkName != null && frameworkName.Identifier == ".NETFramework";
resetInteractiveFromProjectCommand.Enabled = available;
resetInteractiveFromProjectCommand.Supported = available;
resetInteractiveFromProjectCommand.Visible = available;
};
_menuCommandService.AddCommand(resetInteractiveFromProjectCommand);
}
private bool GetActiveProject(out EnvDTE.Project project, out FrameworkName frameworkName)
{
project = null;
frameworkName = null;
IntPtr hierarchyPointer = IntPtr.Zero;
IntPtr selectionContainerPointer = IntPtr.Zero;
try
{
uint itemid;
IVsMultiItemSelect multiItemSelect;
Marshal.ThrowExceptionForHR(
_monitorSelection.GetCurrentSelection(
out hierarchyPointer,
out itemid,
out multiItemSelect,
out selectionContainerPointer));
if (itemid != (uint)VSConstants.VSITEMID.Root)
{
return false;
}
var hierarchy = Marshal.GetObjectForIUnknown(hierarchyPointer) as IVsHierarchy;
if (hierarchy == null)
{
return false;
}
object extensibilityObject;
object targetFrameworkVersion;
object targetFrameworkMonikerObject;
Marshal.ThrowExceptionForHR(
hierarchy.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_ExtObject, out extensibilityObject));
Marshal.ThrowExceptionForHR(
hierarchy.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID3.VSHPROPID_TargetFrameworkVersion, out targetFrameworkVersion));
Marshal.ThrowExceptionForHR(
hierarchy.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID4.VSHPROPID_TargetFrameworkMoniker, out targetFrameworkMonikerObject));
string targetFrameworkMoniker = targetFrameworkMonikerObject as string;
frameworkName = new System.Runtime.Versioning.FrameworkName(targetFrameworkMoniker);
project = extensibilityObject as EnvDTE.Project;
return true;
}
finally
{
if (hierarchyPointer != IntPtr.Zero)
{
Marshal.Release(hierarchyPointer);
}
if (selectionContainerPointer != IntPtr.Zero)
{
Marshal.Release(selectionContainerPointer);
}
}
}
}
}
// 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 Microsoft.CodeAnalysis.Editor;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using System.ComponentModel.Design;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Interactive
{
internal sealed class CSharpResetInteractiveMenuCommand
: AbstractResetInteractiveMenuCommand
{
public CSharpResetInteractiveMenuCommand(
OleMenuCommandService menuCommandService,
IVsMonitorSelection monitorSelection,
IComponentModel componentModel)
: base(ContentTypeNames.CSharpContentType, menuCommandService, monitorSelection, componentModel)
{
}
protected override string ProjectKind => VSLangProj.PrjKind.prjKindCSharpProject;
protected override CommandID GetResetInteractiveFromProjectCommandID()
{
return new CommandID(ID.InteractiveCommands.CSharpInteractiveCommandSetId, ID.InteractiveCommands.ResetInteractiveFromProject);
}
}
}
// 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 Microsoft.CodeAnalysis.Editor;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using System.ComponentModel.Design;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Interactive
{
internal sealed class VisualBasicResetInteractiveMenuCommand
: AbstractResetInteractiveMenuCommand
{
public VisualBasicResetInteractiveMenuCommand(
OleMenuCommandService menuCommandService,
IVsMonitorSelection monitorSelection,
IComponentModel componentModel)
: base(ContentTypeNames.VisualBasicContentType, menuCommandService, monitorSelection, componentModel)
{
}
protected override string ProjectKind => VSLangProj.PrjKind.prjKindVBProject;
protected override CommandID GetResetInteractiveFromProjectCommandID()
{
return new CommandID(ID.InteractiveCommands.VisualBasicInteractiveCommandSetId, ID.InteractiveCommands.ResetInteractiveFromProject);
}
}
}
......@@ -23,6 +23,7 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
using Microsoft.VisualStudio.LanguageServices.Implementation.Interactive;
namespace Microsoft.VisualStudio.LanguageServices.Setup
{
......@@ -169,11 +170,24 @@ private void LoadComponentsBackground()
// Perf: Initialize the command handlers.
var commandHandlerServiceFactory = this.ComponentModel.GetService<ICommandHandlerServiceFactory>();
commandHandlerServiceFactory.Initialize(ContentTypeNames.RoslynContentType);
LoadInteractiveMenus();
this.ComponentModel.GetService<MiscellaneousTodoListTable>();
this.ComponentModel.GetService<MiscellaneousDiagnosticListTable>();
}
private void LoadInteractiveMenus()
{
var menuCommandService = (OleMenuCommandService)GetService(typeof(IMenuCommandService));
var monitorSelectionService = (IVsMonitorSelection)this.GetService(typeof(SVsShellMonitorSelection));
new CSharpResetInteractiveMenuCommand(menuCommandService, monitorSelectionService, ComponentModel)
.InitializeResetInteractiveFromProjectCommand();
new VisualBasicResetInteractiveMenuCommand(menuCommandService, monitorSelectionService, ComponentModel)
.InitializeResetInteractiveFromProjectCommand();
}
internal IComponentModel ComponentModel
{
get
......
......@@ -43,6 +43,10 @@
<Compile Include="Implementation\AnalyzerDependency\IIgnorableAssemblyList.cs" />
<Compile Include="Implementation\AnalyzerDependency\IBindingRedirectionService.cs" />
<Compile Include="Implementation\Extensions\ServiceProviderExtensions.cs" />
<Compile Include="ID.InteractiveCommands.cs" />
<Compile Include="Implementation\Interactive\CSharpResetInteractiveMenuCommand.cs" />
<Compile Include="Implementation\Interactive\AbstractResetInteractiveMenuCommand.cs" />
<Compile Include="Implementation\Interactive\VisualBasicResetInteractiveMenuCommand.cs" />
<Compile Include="Implementation\Interop\CleanableWeakComHandleTable.cs" />
<Compile Include="Implementation\LanguageService\AbstractLanguageService`2.IVsLanguageBlock.cs" />
<Compile Include="Implementation\Library\AbstractLibraryService.cs" />
......
// 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 EnvDTE;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.LanguageServices.Interactive;
using Microsoft.VisualStudio.Shell.Interop;
using System;
namespace Roslyn.VisualStudio.Services.Interactive
{
internal abstract class AbstractResetInteractiveCommand : IResetInteractiveCommand
{
private readonly IComponentModel _componentModel;
private readonly VsInteractiveWindowProvider _interactiveWindowProvider;
private readonly IServiceProvider _serviceProvider;
protected abstract string LanguageName { get; }
protected abstract string CreateReference(string referenceName);
protected abstract string CreateImport(string namespaceName);
public AbstractResetInteractiveCommand(
VsInteractiveWindowProvider interactiveWindowProvider,
IServiceProvider serviceProvider)
{
_interactiveWindowProvider = interactiveWindowProvider;
_serviceProvider = serviceProvider;
_componentModel = (IComponentModel)GetService(typeof(SComponentModel));
}
private object GetService(Type type)
{
return _serviceProvider.GetService(type);
}
public void ExecuteResetInteractive()
{
var resetInteractive = new VsResetInteractive(
(DTE)this.GetService(typeof(SDTE)),
_componentModel,
(IVsMonitorSelection)this.GetService(typeof(SVsShellMonitorSelection)),
(IVsSolutionBuildManager)this.GetService(typeof(SVsSolutionBuildManager)),
CreateReference,
CreateImport);
var vsInteractiveWindow = _interactiveWindowProvider.Open(instanceId: 0, focus: true);
EventHandler focusWindow = null;
focusWindow = (s, e) =>
{
// We have to set focus to the Interactive Window *after* the wait indicator is dismissed.
vsInteractiveWindow.Show(focus: true);
resetInteractive.ExecutionCompleted -= focusWindow;
};
resetInteractive.Execute(vsInteractiveWindow.InteractiveWindow, LanguageName + " Interactive");
resetInteractive.ExecutionCompleted += focusWindow;
}
}
}
......@@ -18,14 +18,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Interactive
internal abstract partial class VsInteractiveWindowPackage<TVsInteractiveWindowProvider> : Package, IVsToolWindowFactory
where TVsInteractiveWindowProvider : VsInteractiveWindowProvider
{
protected abstract string LanguageName { get; }
protected abstract string ProjectKind { get; }
protected abstract void InitializeMenuCommands(OleMenuCommandService menuCommandService);
protected abstract CommandID GetResetInteractiveFromProjectCommandID();
protected abstract string CreateReference(string referenceName);
protected abstract string CreateImport(string namespaceName);
protected abstract Guid LanguageServiceGuid { get; }
protected abstract Guid ToolWindowId { get; }
......@@ -57,7 +51,6 @@ protected override void Initialize()
var menuCommandService = (OleMenuCommandService)GetService(typeof(IMenuCommandService));
InitializeMenuCommands(menuCommandService);
InitializeResetInteractiveFromProjectCommand(menuCommandService);
}
protected TVsInteractiveWindowProvider InteractiveWindowProvider
......@@ -79,98 +72,5 @@ int IVsToolWindowFactory.CreateToolWindow(ref Guid rguidPersistenceSlot, uint id
return VSConstants.E_FAIL;
}
private void InitializeResetInteractiveFromProjectCommand(OleMenuCommandService menuCommandService)
{
var resetInteractiveFromProjectCommand = new OleMenuCommand(
(sender, args) =>
{
var resetInteractive = new VsResetInteractive(
(DTE)this.GetService(typeof(SDTE)),
_componentModel,
(IVsMonitorSelection)this.GetService(typeof(SVsShellMonitorSelection)),
(IVsSolutionBuildManager)this.GetService(typeof(SVsSolutionBuildManager)),
CreateReference,
CreateImport);
var vsInteractiveWindow = _interactiveWindowProvider.Open(instanceId: 0, focus: true);
EventHandler focusWindow = null;
focusWindow = (s, e) =>
{
// We have to set focus to the Interactive Window *after* the wait indicator is dismissed.
vsInteractiveWindow.Show(focus: true);
resetInteractive.ExecutionCompleted -= focusWindow;
};
resetInteractive.Execute(vsInteractiveWindow.InteractiveWindow, LanguageName + " Interactive");
resetInteractive.ExecutionCompleted += focusWindow;
},
GetResetInteractiveFromProjectCommandID());
resetInteractiveFromProjectCommand.Supported = true;
resetInteractiveFromProjectCommand.BeforeQueryStatus += (_, __) =>
{
var project = GetActiveProject();
var available = project != null && project.Kind == ProjectKind;
resetInteractiveFromProjectCommand.Enabled = available;
resetInteractiveFromProjectCommand.Supported = available;
resetInteractiveFromProjectCommand.Visible = available;
};
menuCommandService.AddCommand(resetInteractiveFromProjectCommand);
}
private EnvDTE.Project GetActiveProject()
{
var monitorSelection = (IVsMonitorSelection)this.GetService(typeof(SVsShellMonitorSelection));
IntPtr hierarchyPointer = IntPtr.Zero;
IntPtr selectionContainerPointer = IntPtr.Zero;
try
{
uint itemid;
IVsMultiItemSelect multiItemSelect;
Marshal.ThrowExceptionForHR(
monitorSelection.GetCurrentSelection(
out hierarchyPointer,
out itemid,
out multiItemSelect,
out selectionContainerPointer));
if (itemid != (uint)VSConstants.VSITEMID.Root)
{
return null;
}
var hierarchy = Marshal.GetObjectForIUnknown(hierarchyPointer) as IVsHierarchy;
if (hierarchy == null)
{
return null;
}
object extensibilityObject;
Marshal.ThrowExceptionForHR(
hierarchy.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_ExtObject, out extensibilityObject));
return extensibilityObject as EnvDTE.Project;
}
finally
{
if (hierarchyPointer != IntPtr.Zero)
{
Marshal.Release(hierarchyPointer);
}
if (selectionContainerPointer != IntPtr.Zero)
{
Marshal.Release(selectionContainerPointer);
}
}
}
}
}
......@@ -196,6 +196,7 @@
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>
<ItemGroup>
<Compile Include="Interactive\AbstractResetInteractiveCommand.cs" />
<Compile Include="Interactive\LogMessage.cs" />
<Compile Include="Interactive\VsInteractiveWindowPackage.cs" />
<Compile Include="Interactive\VsInteractiveWindowProvider.cs" />
......
......@@ -145,6 +145,7 @@
<Compile Include="VisualBasicVsInteractiveWindowProvider.vb" />
<Compile Include="VisualBasicVsInteractiveWindowPackage.vb" />
<Compile Include="VisualBasicVsInteractiveWindowCommandProvider.vb" />
<Compile Include="VisualBasicVsResetInteractiveCommand.vb" />
<Content Include="Resources\ScriptFile.ico" />
<Content Include="VisualBasicInteractive.rsp" />
</ItemGroup>
......
......@@ -38,10 +38,6 @@
-->
</Buttons>
</Commands>
<VisibilityConstraints>
<VisibilityItem context="guidVBProjectContext" guid="guidVisualBasicInteractiveCommandSet" id="cmdidResetInteractiveFromProject" />
</VisibilityConstraints>
<!-- https://github.com/dotnet/roslyn/issues/3941
<KeyBindings>
......
......@@ -29,24 +29,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Interactive
End Get
End Property
Protected Overrides ReadOnly Property LanguageName As String
Get
Return "Visual Basic"
End Get
End Property
Protected Overrides ReadOnly Property LanguageServiceGuid As Guid
Get
Return LanguageServiceGuids.VisualBasicLanguageServiceId
End Get
End Property
Protected Overrides ReadOnly Property ProjectKind As String
Get
Return VSLangProj.PrjKind.prjKindVBProject
End Get
End Property
Protected Overrides Sub InitializeMenuCommands(menuCommandService As OleMenuCommandService)
Dim openInteractiveCommand = New MenuCommand(
handler:=Sub(sender, args) Me.InteractiveWindowProvider.Open(instanceId:=0, focus:=True),
......@@ -54,18 +42,6 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Interactive
menuCommandService.AddCommand(openInteractiveCommand)
End Sub
Protected Overrides Function GetResetInteractiveFromProjectCommandID() As CommandID
Return New CommandID(VisualBasicInteractiveCommands.InteractiveCommandSetId, VisualBasicInteractiveCommands.ResetInteractiveFromProject)
End Function
Protected Overrides Function CreateReference(referenceName As String) As String
Return String.Format("#R ""{0}""", referenceName)
End Function
Protected Overrides Function CreateImport(namespaceName As String) As String
Return String.Format("Imports {0}", namespaceName)
End Function
End Class
End Namespace
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.VisualStudio.LanguageServices.Interactive
Imports Roslyn.VisualStudio.Services.Interactive
Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Interactive
Friend Class VisualBasicVsResetInteractiveCommand
Inherits AbstractResetInteractiveCommand
Public Sub New(interactiveWindowProvider As VsInteractiveWindowProvider, serviceProvider As IServiceProvider)
MyBase.New(interactiveWindowProvider, serviceProvider)
End Sub
Protected Overrides ReadOnly Property LanguageName As String
Get
Return "VisualBasic"
End Get
End Property
Protected Overrides Function CreateImport(referenceName As String) As String
Return String.Format("#R ""{0}""", referenceName)
End Function
Protected Overrides Function CreateReference(namespaceName As String) As String
Return String.Format("Imports {0}", namespaceName)
End Function
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册