IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
ExportTool.cs
Go to the documentation of this file.
1using System;
2using System.CommandLine;
3using System.CommandLine.Builder;
4using System.CommandLine.Invocation;
5using System.CommandLine.Parsing;
6using System.IO;
7using System.Linq;
8using System.Threading;
9using System.Threading.Tasks;
10
14
15using Microsoft.Extensions.DependencyInjection;
16
17namespace IKVM.Tools.Exporter
18{
19
24 {
25
32 public static async Task<int> InvokeAsync(string[] args, CancellationToken cancellationToken = default)
33 {
34 return await new ExportTool().InvokeImplAsync(args, cancellationToken);
35 }
36
44 public static Task<int> ExecuteAsync(ExportOptions options, IDiagnosticHandler diagnostics, CancellationToken cancellationToken = default)
45 {
46 return ExecuteImplAsync(options, _ => diagnostics, cancellationToken);
47 }
48
56 static Task<int> ExecuteImplAsync(ExportOptions options, Func<IServiceProvider, IDiagnosticHandler> diagnostics, CancellationToken cancellationToken)
57 {
58 var services = new ServiceCollection();
59 services.AddToolsDiagnostics();
60 services.AddSingleton(options);
61 services.AddSingleton(diagnostics);
62 services.AddSingleton<ExportImpl>();
63 services.AddSingleton<ManagedTypeResolver>();
64 services.AddSingleton<StaticCompiler>();
65 using var provider = services.BuildServiceProvider();
66 var exporter = provider.GetRequiredService<ExportImpl>();
67
68 return Task.FromResult(exporter.Execute());
69 }
70
77 static Task<int> MainAsync(IServiceProvider services, CancellationToken cancellationToken)
78 {
79 if (services is null)
80 throw new ArgumentNullException(nameof(services));
81
82 var exporter = services.GetRequiredService<ExportImpl>();
83 return Task.FromResult(exporter.Execute());
84 }
85
92 static Task ExecuteAsync(ExportCommandOptions commandOptions, CancellationToken cancellationToken)
93 {
94 if (commandOptions is null)
95 throw new ArgumentNullException(nameof(commandOptions));
96
97 var options = new ExportOptions()
98 {
99 Output = commandOptions.Output.FullName,
100 IncludeNonPublicTypes = commandOptions.IncludeNonPublicTypes,
101 IncludeNonPublicInterfaces = commandOptions.IncludeNonPublicInterfaces,
102 IncludeNonPublicMembers = commandOptions.IncludeNonPublicMembers,
103 IncludeParameterNames = commandOptions.IncludeParameterNames,
104 Forwarders = commandOptions.Forwarders,
105 NoStdLib = commandOptions.NoStdLib,
106 Shared = commandOptions.Shared,
107 Bootstrap = commandOptions.Bootstrap,
108 ContinueOnError = commandOptions.ContinueOnError,
109 Assembly = commandOptions.Assembly?.FullName,
110 };
111
112 foreach (var i in commandOptions.References)
113 options.References.Add(i.FullName);
114
115 foreach (var i in commandOptions.Libraries)
116 options.Libraries.Add(i.FullName);
117
118 return ExecuteImplAsync(options, p => GetDiagnostics(p, commandOptions.Log), cancellationToken);
119 }
120
127 static FormattedDiagnosticHandler GetDiagnostics(IServiceProvider services, string spec)
128 {
129 if (services is null)
130 throw new ArgumentNullException(nameof(services));
131 if (string.IsNullOrWhiteSpace(spec))
132 throw new ArgumentException($"'{nameof(spec)}' cannot be null or whitespace.", nameof(spec));
133
134 return ActivatorUtilities.CreateInstance<FormattedDiagnosticHandler>(services, spec);
135 }
136
137 readonly RootCommand command;
138 readonly Argument<FileInfo> assemblyArgument;
139 readonly Option<FileInfo> outputOption;
140 readonly Option<FileInfo[]> referenceOption;
141 readonly Option<DirectoryInfo[]> libraryOption;
142 readonly Option<string[]> namespaceOption;
143 readonly Option<bool> includeNonPublicTypesOption;
144 readonly Option<bool> includeNonPublicInterfacesOption;
145 readonly Option<bool> includeNonPublicMembersOption;
146 readonly Option<bool> includeParameterNamesOption;
147 readonly Option<bool> noStdLibOption;
148 readonly Option<bool> sharedOption;
149 readonly Option<bool> forwardersOption;
150 readonly Option<bool> bootstrapOption;
151 readonly Option<bool> continueOnErrorOption;
152 readonly Option<string> logOption;
153
157 public ExportTool()
158 {
159 command = new RootCommand()
160 {
161 (outputOption = new Option<FileInfo>(
162 aliases: ["--out", "-out", "-o"],
163 description: "Specify the output filename.") { IsRequired = true }),
164 (referenceOption = new Option<FileInfo[]>(
165 aliases: ["--reference", "-reference", "-r"],
166 description: "Reference an assembly.")),
167 (libraryOption = new Option<DirectoryInfo[]>(
168 aliases: ["--lib", "-lib", "-l"],
169 description: "Additional directories to search for references.")),
170 (namespaceOption = new Option<string[]>(
171 aliases: ["--ns", "-ns"],
172 description: "Only include types from specified namespace.")),
173 (includeNonPublicTypesOption = new Option<bool>(
174 aliases: ["--non-public-types", "-non-public-types"],
175 description: "Include classes for non-public types.")),
176 (includeNonPublicInterfacesOption = new Option<bool>(
177 aliases: ["--non-public-interfaces", "-non-public-interfaces"],
178 description: "Include non-public interface implementations.")),
179 (includeNonPublicMembersOption = new Option<bool>(
180 aliases: ["--non-public-members", "-non-public-members"],
181 description: "Include non-public members.")),
182 (includeParameterNamesOption = new Option<bool>(
183 aliases: ["--parameters", "-parameters"],
184 description: "Include parameter names.")),
185 (forwardersOption = new Option<bool>(
186 aliases: ["--forwarders", "-forwarders"],
187 description: "Export forwarded types.")),
188 (noStdLibOption = new Option<bool>(
189 aliases: ["--nostdlib", "-nostdlib"],
190 description: "Do not reference standard libraries.")),
191 (sharedOption = new Option<bool>(
192 aliases: ["--shared", "-shared"],
193 description: "Process all assemblies in shared group.")),
194 (bootstrapOption = new Option<bool>(
195 aliases: ["--bootstrap", "-bootstrap"],
196 description: "Enabled bootstrap mode.") { IsHidden = true }),
197 (continueOnErrorOption = new Option<bool>(
198 aliases: ["--skiperror", "-skiperror"],
199 description: "Continue when errors are encountered.")),
200 (logOption = new Option<string>(
201 aliases: ["--log", "-log"],
202 getDefaultValue: () => "text",
203 description: "Logging options.")),
204 (assemblyArgument = new Argument<FileInfo>(
205 name: "assemblyNameOrPath",
206 description: "Path or name of assembly to export.")),
207 };
208
209 command.SetHandler(ExecuteImplAsync);
210 }
211
218 async Task<int> InvokeImplAsync(string[] args, CancellationToken cancellationToken)
219 {
220 if (args is null)
221 throw new ArgumentNullException(nameof(args));
222
223 // execute command
224 return await new CommandLineBuilder(command)
225 .UseHelp()
226 .UseParseDirective()
227 .UseTypoCorrections()
228 .UseToolParseError()
229 .UseExceptionHandler()
230 .CancelOnProcessTermination()
231 .UseToolErrorExceptionHandler()
232 .Build()
233 .InvokeAsync(args);
234 }
235
241 Task ExecuteImplAsync(InvocationContext context)
242 {
243 if (context is null)
244 throw new ArgumentNullException(nameof(context));
245
246 var options = new ExportCommandOptions()
247 {
248 Output = context.ParseResult.GetValueForOption(outputOption),
249 References = context.ParseResult.GetValueForOption(referenceOption),
250 Libraries = context.ParseResult.GetValueForOption(libraryOption),
251 Namespaces = context.ParseResult.GetValueForOption(namespaceOption).ToArray(),
252 IncludeNonPublicTypes = context.ParseResult.GetValueForOption(includeNonPublicTypesOption),
253 IncludeNonPublicInterfaces = context.ParseResult.GetValueForOption(includeNonPublicInterfacesOption),
254 IncludeNonPublicMembers = context.ParseResult.GetValueForOption(includeNonPublicMembersOption),
255 IncludeParameterNames = context.ParseResult.GetValueForOption(includeParameterNamesOption),
256 Forwarders = context.ParseResult.GetValueForOption(forwardersOption),
257 NoStdLib = context.ParseResult.GetValueForOption(noStdLibOption),
258 Shared = context.ParseResult.GetValueForOption(sharedOption),
259 Bootstrap = context.ParseResult.GetValueForOption(bootstrapOption),
260 ContinueOnError = context.ParseResult.GetValueForOption(continueOnErrorOption),
261 Assembly = context.ParseResult.GetValueForArgument(assemblyArgument),
262 Log = context.ParseResult.GetValueForOption(logOption)
263 };
264
265 return ExecuteAsync(options, context.GetCancellationToken());
266 }
267
268 }
269
270}
IKVM.Reflection.Assembly Assembly
IDiagnosticHandler implementation that outputs based on a format specification.
Main entry point for the application.
Definition ExportImpl.cs:23
Options passed to the exporter.
string Output
Output JAR file.
Main entry point for the application.
Definition ExportTool.cs:24
ExportTool()
Initializes a new instance.
static async Task< int > InvokeAsync(string[] args, CancellationToken cancellationToken=default)
Executes the exporter against a set of command line options.
Definition ExportTool.cs:32
static Task< int > ExecuteAsync(ExportOptions options, IDiagnosticHandler diagnostics, CancellationToken cancellationToken=default)
Executes the exporter.
Definition ExportTool.cs:44
Holds the static compiler information.
Exposes methods to accept diagnostic invocations.