IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
ModuleDescriptor.Builder.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Collections.Immutable;
4using System.Diagnostics;
5
6using IKVM.ByteCode;
7
9{
10
11 internal readonly partial struct ModuleDescriptor
12 {
13
20 public static Builder CreateModule(string name, ModuleFlag modifiers)
21 {
22 return new Builder(name, modifiers);
23 }
24
30 public static Builder CreateModule(string name)
31 {
32 return new Builder(name, false);
33 }
34
40 public static Builder CreateAutomaticModule(string name)
41 {
42 return new Builder(name, true);
43 }
44
48 public class Builder
49 {
50
51 readonly string _name;
52 readonly ModuleFlag _modifiers;
53 readonly bool _automatic;
54 ModuleVersion _version;
55 HashSet<string>? _requiresKeys;
56 ImmutableHashSet<ModuleRequires>.Builder? _requires;
57 HashSet<string>? _exportsKeys;
58 ImmutableHashSet<ModuleExports>.Builder? _exports;
59 HashSet<string>? _opensKeys;
60 ImmutableHashSet<ModuleOpens>.Builder? _opens;
61 ImmutableHashSet<string>.Builder? _uses;
62 HashSet<string>? _providesKeys;
63 ImmutableHashSet<ModuleProvides>.Builder? _provides;
64 ImmutableHashSet<string>.Builder? _packages;
65 string? _mainClass;
66
70 internal Builder(string name, bool automatic)
71 {
72 _name = name;
73 _modifiers = default;
74 _automatic = automatic;
75 _version = default;
76 Debug.Assert(!IsOpen || !IsAutomatic);
77 }
78
82 internal Builder(string name, ModuleFlag modifiers)
83 {
84 _name = name;
85 _modifiers = modifiers;
86 _automatic = false;
87 _version = default;
88 Debug.Assert(!IsOpen || !IsAutomatic);
89 }
90
94 public string Name => _name;
95
99 public ModuleFlag Modifiers => _modifiers;
100
104 public bool IsAutomatic => _automatic;
105
109 public bool IsOpen => (_modifiers & ModuleFlag.Open) != 0;
110
118 public Builder Requires(ModuleRequires requires)
119 {
120 if (_automatic)
121 throw new InvalidOperationException("Automatic modules cannot declare dependences");
122 if (_name.Equals(requires.Name))
123 throw new ArgumentException("Dependence on self.");
124 if (_requiresKeys != null && _requiresKeys.Contains(requires.Name))
125 throw new InvalidOperationException($"Dependence upon {requires.Name} already declared.");
126
127 _requiresKeys ??= new HashSet<string>();
128 _requiresKeys.Add(requires.Name);
129 _requires ??= ImmutableHashSet.CreateBuilder<ModuleRequires>();
130 _requires.Add(requires);
131
132 return this;
133 }
134
143 public Builder Requires(ModuleRequiresFlag modifiers, string name, ModuleVersion version)
144 {
145 return Requires(new ModuleRequires(modifiers, name, version));
146 }
147
156 public Builder Requires(ModuleRequiresFlag modifiers, string name, string? version)
157 {
158 var v = default(ModuleVersion);
159 if (version is not null)
160 ModuleVersion.TryParse(version, out v);
161
162 return Requires(new ModuleRequires(modifiers, name, v));
163 }
164
172 public Builder Requires(ModuleRequiresFlag modifiers, string name)
173 {
174 return Requires(new ModuleRequires(modifiers, name, default));
175 }
176
183 public Builder Requires(string name)
184 {
185 return Requires(new ModuleRequires(default, name, default));
186 }
187
195 public Builder Exports(ModuleExports exports)
196 {
197 if (_automatic)
198 throw new InvalidOperationException("Automatic modules cannot declare dependences.");
199 if (_exportsKeys != null && _exportsKeys.Contains(exports.Source))
200 throw new InvalidOperationException($"Exported package {exports.Source} already declared.");
201
202 _exportsKeys ??= new HashSet<string>();
203 _exportsKeys.Add(exports.Source);
204 _exports ??= ImmutableHashSet.CreateBuilder<ModuleExports>();
205 _exports.Add(exports);
206
207 return this;
208 }
209
217 public Builder Exports(ModuleExportsFlag modifiers, string name, ImmutableHashSet<string> targets)
218 {
219 return Exports(new ModuleExports(modifiers, name, targets));
220 }
221
228 public Builder Exports(ModuleExportsFlag modifiers, string name)
229 {
230 return Exports(modifiers, name, []);
231 }
232
239 public Builder Exports(string name, ImmutableHashSet<string> targets)
240 {
241 return Exports(default, name, targets);
242 }
243
249 public Builder Exports(string name)
250 {
251 return Exports(default, name, []);
252 }
253
261 public Builder Opens(ModuleOpens opens)
262 {
263 if (IsOpen || IsAutomatic)
264 throw new InvalidOperationException("Open or automatic modules cannot declare open packages.");
265 if (_opensKeys != null && _opensKeys.Contains(opens.Source))
266 throw new InvalidOperationException($"Open package {opens.Source} already declared.");
267
268 _opensKeys ??= new HashSet<string>();
269 _opensKeys.Add(opens.Source);
270 _opens ??= ImmutableHashSet.CreateBuilder<ModuleOpens>();
271 _opens.Add(opens);
272 _packages ??= ImmutableHashSet.CreateBuilder<string>();
273 _packages.Add(opens.Source);
274
275 return this;
276 }
277
285 public Builder Opens(ModuleOpensFlag modifiers, string packageName, ImmutableHashSet<string> targets)
286 {
287 return Opens(new ModuleOpens(modifiers, packageName, targets));
288 }
289
296 public Builder Opens(ModuleOpensFlag modifiers, string packageName)
297 {
298 return Opens(modifiers, packageName, []);
299 }
300
307 public Builder Opens(string packageName, ImmutableHashSet<string> targets)
308 {
309 return Opens(default, packageName, targets);
310 }
311
317 public Builder Opens(string packageName)
318 {
319 return Opens(default, packageName, []);
320 }
321
329 public Builder Uses(string service)
330 {
331 if (service is null)
332 throw new ArgumentNullException(nameof(service));
333
334 if (_automatic)
335 throw new InvalidOperationException("Automatic modules cannot declare service dependencies.");
336 if (_uses != null && _uses.Contains(service))
337 throw new InvalidOperationException($"Dependence upon service {service} already declared.");
338
339 _uses ??= ImmutableHashSet.CreateBuilder<string>();
340 _uses.Add(service);
341
342 return this;
343 }
344
352 public Builder Provides(ModuleProvides provides)
353 {
354 if (_providesKeys != null && _providesKeys.Contains(provides.Service))
355 throw new InvalidOperationException($"Providers of service {provides.Service} already declared.");
356
357 _providesKeys ??= new HashSet<string>();
358 _providesKeys.Add(provides.Service);
359 _provides ??= ImmutableHashSet.CreateBuilder<ModuleProvides>();
360 _provides.Add(provides);
361
362 _packages ??= ImmutableHashSet.CreateBuilder<string>();
363 foreach (var p in provides.Providers)
364 _packages.Add(GetPackageName(p));
365
366 return this;
367 }
368
375 public Builder Provides(string service, ImmutableArray<string> providers)
376 {
377 return Provides(new ModuleProvides(service, providers));
378 }
379
385 string GetPackageName(string cn)
386 {
387 if (cn is null)
388 throw new ArgumentNullException(nameof(cn));
389
390 int index = cn.LastIndexOf('.');
391 return (index == -1) ? "" : cn[..index];
392 }
393
399 public Builder Package(string name)
400 {
401 if (name is null)
402 throw new ArgumentNullException(nameof(name));
403
404 _packages ??= ImmutableHashSet.CreateBuilder<string>();
405 _packages.Add(name);
406 return this;
407 }
408
414 public Builder Version(ModuleVersion version)
415 {
416 _version = version;
417 return this;
418 }
419
425 public Builder Version(string value)
426 {
427 if (value is not null && ModuleVersion.TryParse(value.AsSpan(), out _version))
428 return this;
429
430 _version = default;
431 return this;
432 }
433
442 public Builder MainClass(string mainClass)
443 {
444 var packageName = GetPackageName(mainClass);
445 if (string.IsNullOrEmpty(packageName))
446 throw new ArgumentException($"{mainClass}: unnamed package", nameof(mainClass));
447
448 _packages ??= ImmutableHashSet.CreateBuilder<string>();
449 _packages.Add(packageName);
450 _mainClass = mainClass;
451
452 return this;
453 }
454
459 public ModuleDescriptor Build()
460 {
461 return new ModuleDescriptor(
462 _name,
463 _version,
465 _modifiers,
466 _requires?.ToImmutable() ?? [],
467 _exports?.ToImmutable() ?? [],
468 _opens?.ToImmutable() ?? [],
469 _uses?.ToImmutable() ?? [],
470 _provides?.ToImmutable() ?? [],
471 _packages?.ToImmutable() ?? [],
472 _mainClass);
473 }
474
475 }
476
477 }
478
479}
global::java.lang.invoke.LambdaForm.Name Name
A builder for building ModuleDescriptor objects.
bool IsAutomatic
Gets whether this is an automatic module or not.
Builder Exports(string name, ImmutableHashSet< string > targets)
Adds an exported package. The package is exported to a set of target modules.
Builder Requires(ModuleRequires requires)
Adds a dependence on a module.
Builder Requires(ModuleRequiresFlag modifiers, string name, ModuleVersion version)
Adds a dependence on a module with the given (and possibly empty) set of modifiers....
Builder Exports(string name)
Adds an exported package. The package is exported to all modules.
bool IsOpen
Gets whether this is an open module or not.
Builder Uses(string service)
Adds a service dependence.
Builder Package(string name)
Adds a package to the module.
Builder Provides(string service, ImmutableArray< string > providers)
Provides implementations of a service. The package for each provider (or provider factory) is added t...
Builder Requires(string name)
Adds a dependence on a module with the given (and possibly empty) set of modifiers....
Builder Opens(ModuleOpens opens)
Adds an open package.
Builder Requires(ModuleRequiresFlag modifiers, string name, string? version)
Adds a dependence on a module with the given (and possibly empty) set of modifiers....
Builder Opens(ModuleOpensFlag modifiers, string packageName, ImmutableHashSet< string > targets)
Adds an open package with the given(and possibly empty) set of modifiers. The package is open to a se...
Builder Version(string value)
Sets the module version.
ModuleDescriptor Build()
Builds and returns a ModuleDescriptor from its components.
Builder Exports(ModuleExportsFlag modifiers, string name, ImmutableHashSet< string > targets)
Adds an exported package with the given (and possibly empty) set of modifiers. The package is exporte...
Builder Requires(ModuleRequiresFlag modifiers, string name)
Adds a dependence on a module with the given (and possibly empty) set of modifiers....
Builder MainClass(string mainClass)
Sets the module main class. The package for the main class is added to the module if not already adde...
Builder Exports(ModuleExportsFlag modifiers, string name)
Adds an exported package with the given (and possibly empty) set of modifiers.The package is exported...
Builder Provides(ModuleProvides provides)
Provides a service with one or more implementations. The package for each ModuleProvides (or provider...
Builder Exports(ModuleExports exports)
Adds an exported package.
Builder Version(ModuleVersion version)
Sets the module version.
Builder Opens(ModuleOpensFlag modifiers, string packageName)
Adds an open package with the given (and possibly empty) set of modifiers. The package is open to all...
Builder Opens(string packageName, ImmutableHashSet< string > targets)
Adds an open package. The package is open to a set of target modules.
Builder Opens(string packageName)
Adds an open package. The package is open to all modules.