-
Notifications
You must be signed in to change notification settings - Fork 242
Expand file tree
/
Copy pathConvertVBToCSCommand.cs
More file actions
202 lines (176 loc) · 8.76 KB
/
Copy pathConvertVBToCSCommand.cs
File metadata and controls
202 lines (176 loc) · 8.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq;
using System.Threading;
using ICSharpCode.CodeConverter.CSharp;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text;
using Task = System.Threading.Tasks.Task;
namespace ICSharpCode.CodeConverter.VsExtension;
/// <summary>
/// Command handler
/// </summary>
internal sealed class ConvertVBToCSCommand
{
public const int MainMenuCommandId = 0x0200;
public const int CtxMenuCommandId = 0x0201;
public const int ProjectItemCtxMenuCommandId = 0x0202;
public const int ProjectCtxMenuCommandId = 0x0203;
public const int SolutionCtxMenuCommandId = 0x0204;
public const int NodeItemCtxMenuCommandId = 0x0205;
private const string ProjectExtension = ".vbproj";
/// <summary>
/// Command menu group (command set GUID).
/// </summary>
public static readonly Guid CommandSet = new("a3378a21-e939-40c9-9e4b-eb0cec7b7854");
private readonly CodeConversion _codeConversion;
/// <summary>
/// VS Package that provides this command, not null.
/// </summary>
private readonly CodeConverterPackage _package;
/// <summary>
/// Initializes a new instance of the <see cref="ConvertVBToCSCommand" /> class.
/// Adds our command handlers for menu (commands must exist in the command table file)
/// </summary>
/// <param name="package">Owner package, not null.</param>
/// <param name="codeConversion"></param>
/// <param name="commandService"></param>
/// <remarks>Must be called on the UI thread due to VS 2017's implementation of AddCommand which calls GetService</remarks>
private ConvertVBToCSCommand(CodeConverterPackage package, CodeConversion codeConversion,
OleMenuCommandService commandService)
{
ThreadHelper.ThrowIfNotOnUIThread();
_package = package ?? throw new ArgumentNullException(nameof(package));
_codeConversion = codeConversion;
if (commandService != null) {
// Command in main menu
var menuCommandId = new CommandID(CommandSet, MainMenuCommandId);
var menuItem = package.CreateCommand(CodeEditorMenuItemCallbackAsync, menuCommandId);
menuItem.BeforeQueryStatus += MainEditMenuItem_BeforeQueryStatusAsync;
commandService.AddCommand(menuItem);
// Command in code editor's context menu
var ctxMenuCommandId = new CommandID(CommandSet, CtxMenuCommandId);
var ctxMenuItem = package.CreateCommand(CodeEditorMenuItemCallbackAsync, ctxMenuCommandId);
ctxMenuItem.BeforeQueryStatus += CodeEditorMenuItem_BeforeQueryStatusAsync;
commandService.AddCommand(ctxMenuItem);
// Command in project item context menu
var projectItemCtxMenuCommandId = new CommandID(CommandSet, ProjectItemCtxMenuCommandId);
var projectItemCtxMenuItem =
package.CreateCommand(ProjectItemMenuItemCallbackAsync, projectItemCtxMenuCommandId);
projectItemCtxMenuItem.BeforeQueryStatus += ProjectItemMenuItem_BeforeQueryStatusAsync;
commandService.AddCommand(projectItemCtxMenuItem);
// Command in project context menu
var projectCtxMenuCommandId = new CommandID(CommandSet, ProjectCtxMenuCommandId);
var projectCtxMenuItem =
package.CreateCommand(SolutionOrProjectMenuItemCallbackAsync, projectCtxMenuCommandId);
projectCtxMenuItem.BeforeQueryStatus += SolutionOrProjectMenuItem_BeforeQueryStatusAsync;
commandService.AddCommand(projectCtxMenuItem);
// Command in project context menu
var solutionCtxMenuCommandId = new CommandID(CommandSet, SolutionCtxMenuCommandId);
var solutionCtxMenuItem =
package.CreateCommand(SolutionOrProjectMenuItemCallbackAsync, solutionCtxMenuCommandId);
solutionCtxMenuItem.BeforeQueryStatus += SolutionOrProjectMenuItem_BeforeQueryStatusAsync;
commandService.AddCommand(solutionCtxMenuItem);
var nodeItemCtxMenuCommandId = new CommandID(CommandSet, NodeItemCtxMenuCommandId);
var nodeItemCtxMenuItem = package.CreateCommand(ProjectItemMenuItemCallbackAsync, nodeItemCtxMenuCommandId);
nodeItemCtxMenuItem.BeforeQueryStatus += ProjectItemMenuItem_BeforeQueryStatusAsync;
commandService.AddCommand(nodeItemCtxMenuItem);
}
}
/// <summary>
/// Gets the instance of the command.
/// </summary>
public static ConvertVBToCSCommand Instance { get; private set; }
/// <summary>
/// Gets the service provider from the owner package.
/// </summary>
private IAsyncServiceProvider ServiceProvider => _package;
/// <remarks>
/// Must be called from UI thread
/// </remarks>
public static void Initialize(CodeConverterPackage package, OleMenuCommandService menuCommandService,
CodeConversion codeConversion)
{
ThreadHelper.ThrowIfNotOnUIThread();
Instance = new ConvertVBToCSCommand(package, codeConversion, menuCommandService);
}
private async Task MainEditMenuItem_BeforeQueryStatusAsync(object sender, EventArgs e)
{
if (sender is OleMenuCommand menuItem) {
var selectionInCurrentViewAsync =
await VisualStudioInteraction.GetFirstSelectedSpanInCurrentViewAsync(ServiceProvider,
CodeConversion.IsVBFileName, true);
menuItem.Visible = selectionInCurrentViewAsync != null;
}
}
private async Task CodeEditorMenuItem_BeforeQueryStatusAsync(object sender, EventArgs e)
{
if (sender is OleMenuCommand menuItem) {
var selectionInCurrentViewAsync =
await VisualStudioInteraction.GetFirstSelectedSpanInCurrentViewAsync(ServiceProvider,
CodeConversion.IsVBFileName, false);
menuItem.Visible = selectionInCurrentViewAsync != null;
}
}
private async Task ProjectItemMenuItem_BeforeQueryStatusAsync(object sender, EventArgs e)
{
if (sender is OleMenuCommand menuItem) {
var itemsPath = await VisualStudioInteraction.GetSelectedItemsPathAsync(CodeConversion.IsVBFileName);
menuItem.Visible = menuItem.Enabled = itemsPath.Count != 0;
}
}
private async Task SolutionOrProjectMenuItem_BeforeQueryStatusAsync(object sender, EventArgs e)
{
if (sender is OleMenuCommand menuItem) {
var selectedProjectsAsync = await VisualStudioInteraction.GetSelectedProjectsAsync(ProjectExtension);
menuItem.Visible = menuItem.Enabled = selectedProjectsAsync.Any();
}
}
private async Task CodeEditorMenuItemCallbackAsync(CancellationToken cancellationToken)
{
(string filePath, var selection) =
await VisualStudioInteraction.GetCurrentFilenameAndSelectionAsync(ServiceProvider,
CodeConversion.IsVBFileName, false);
if (filePath != null && selection != null) {
await ConvertDocumentAsync(filePath, selection.Value, cancellationToken);
}
}
private async Task ProjectItemMenuItemCallbackAsync(CancellationToken cancellationToken)
{
var itemsPath = await VisualStudioInteraction.GetSelectedItemsPathAsync(CodeConversion.IsVBFileName);
await ConvertDocumentsAsync(itemsPath, cancellationToken);
}
private async Task SolutionOrProjectMenuItemCallbackAsync(CancellationToken cancellationToken)
{
try {
var projects = VisualStudioInteraction.GetSelectedProjectsAsync(ProjectExtension);
await _codeConversion.ConvertProjectsAsync<VBToCSConversion>(await projects, cancellationToken);
} catch (Exception ex) {
await _package.ShowExceptionAsync(ex);
}
}
private async Task ConvertDocumentAsync(string documentPath, Span selected, CancellationToken cancellationToken)
{
if (documentPath == null || !CodeConversion.IsVBFileName(documentPath)) {
return;
}
try {
await _codeConversion.ConvertDocumentAsync<VBToCSConversion>(documentPath, selected, cancellationToken);
} catch (Exception ex) {
await _package.ShowExceptionAsync(ex);
}
}
private async Task ConvertDocumentsAsync(IReadOnlyCollection<string> documentsPath, CancellationToken cancellationToken)
{
if (documentsPath.Count == 0) {
await VisualStudioInteraction.ShowMessageBoxAsync("Unable to find any files valid for conversion.");
return;
}
try {
await _codeConversion.ConvertDocumentsAsync<VBToCSConversion>(documentsPath, cancellationToken);
} catch (Exception ex) {
await _package.ShowExceptionAsync(ex);
}
}
}