66 base(spec, formatters)
68 _options = options ??
throw new ArgumentNullException(nameof(options));
72 public override bool IsEnabled(
Diagnostic diagnostic)
74 return diagnostic.Level is not DiagnosticLevel.Trace and not
DiagnosticLevel.Info;
80 if (IsEnabled(@event.Diagnostic) ==
false)
83 var key = @
event.Diagnostic.Id.ToString();
84 for (
int i = 0; ; i++)
86 if (_options.suppressWarnings.Contains(key))
89 if (i == @event.Args.Length)
92 key +=
":" + @
event.Args[i];
95 _options.suppressWarnings.Add(key);
103 string manifestMainClass;
104 string defaultAssemblyName;
106 static string runtimeAssembly;
107 static bool nostdlib;
108 static bool nonDeterministicOutput;
110 static readonly List<string> libpaths =
new List<string>();
115 DateTime start = DateTime.Now;
116 Thread.CurrentThread.Name =
"compiler";
122 return Compile(options);
124 catch (TypeInitializationException x)
127 throw x.InnerException;
134 Console.Error.WriteLine(x.Message);
139 Console.Error.WriteLine();
140 Console.Error.WriteLine(
"*** COMPILER ERROR ***");
141 Console.Error.WriteLine();
142 Console.Error.WriteLine(
System.Reflection.Assembly.GetExecutingAssembly().FullName);
143 Console.Error.WriteLine(
System.
Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory());
144 Console.Error.WriteLine(
"{0} {1}-bit", Environment.Version, IntPtr.Size * 8);
145 Console.Error.WriteLine();
146 Console.Error.WriteLine(x);
153 Console.WriteLine(
"Total cpu time: {0}",
System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime);
154 Console.WriteLine(
"User cpu time: {0}",
System.Diagnostics.Process.GetCurrentProcess().UserProcessorTime);
155 Console.WriteLine(
"Total wall clock time: {0}", DateTime.Now - start);
156 Console.WriteLine(
"Peak virtual memory: {0}",
System.Diagnostics.Process.GetCurrentProcess().PeakVirtualMemorySize64);
157 for (
int i = 0; i <= GC.MaxGeneration; i++)
159 Console.WriteLine(
"GC({0}) count: {1}", i, GC.CollectionCount(i));
174 if (services is
null)
175 throw new ArgumentNullException(nameof(services));
176 if (
string.IsNullOrWhiteSpace(spec))
177 throw new ArgumentException($
"'{nameof(spec)}' cannot be null or whitespace.", nameof(spec));
179 return ActivatorUtilities.CreateInstance<CompilerOptionsDiagnosticHandler>(services, options, spec);
182 static int Compile(ImportOptions options)
184 var rootTarget =
new ImportState();
185 var services =
new ServiceCollection();
186 services.AddToolsDiagnostics();
187 services.AddSingleton(p => GetDiagnostics(p, rootTarget, options.Log));
189 services.AddSingleton<StaticCompiler>();
190 using var provider = services.BuildServiceProvider();
193 var compiler = provider.GetRequiredService<StaticCompiler>();
194 var targets =
new List<ImportState>();
195 var context =
new RuntimeContext(
new RuntimeContextOptions(), diagnostics, provider.GetRequiredService<
ISymbolResolver>(), options.Bootstrap, compiler);
197 compiler.rootTarget = rootTarget;
198 var importer =
new ImportContext();
199 importer.ParseCommandLine(context, compiler, diagnostics, options, targets, rootTarget);
200 compiler.Init(nonDeterministicOutput, rootTarget.debugMode, libpaths);
201 resolver.Warning += (warning, message, parameters) => loader_Warning(compiler, diagnostics, warning, message, parameters);
202 resolver.Init(compiler.Universe, nostdlib, rootTarget.unresolvedReferences, libpaths);
203 ResolveReferences(compiler, diagnostics, targets);
204 ResolveStrongNameKeys(targets);
206 if (targets.Count == 0)
209 if (compiler.errorCount != 0)
214 return ImportClassLoader.Compile(importer, context, compiler, diagnostics, runtimeAssembly, targets);
216 catch (FileFormatLimitationExceededException x)
222 static void loader_Warning(StaticCompiler compiler,
IDiagnosticHandler diagnostics, AssemblyResolver.WarningId warning,
string message,
string[] parameters)
226 case AssemblyResolver.WarningId.HigherVersion:
229 case AssemblyResolver.WarningId.InvalidLibDirectoryOption:
232 case AssemblyResolver.WarningId.InvalidLibDirectoryEnvironment:
235 case AssemblyResolver.WarningId.LegacySearchRule:
238 case AssemblyResolver.WarningId.LocationIgnored:
247 static void ResolveStrongNameKeys(List<ImportState> targets)
249 foreach (var options
in targets)
251 if (options.keyfile !=
null && options.keycontainer !=
null)
254 if (options.keyfile ==
null && options.keycontainer ==
null && options.delaysign)
257 if (options.keyfile !=
null)
259 if (options.delaysign)
261 var buf = ReadAllBytes(options.keyfile);
265 buf =
new StrongNameKeyPair(buf).PublicKey;
272 options.publicKey = buf;
276 SetStrongNameKeyPair(
ref options.keyPair, options.keyfile,
null);
279 else if (options.keycontainer !=
null)
281 StrongNameKeyPair keyPair =
null;
282 SetStrongNameKeyPair(
ref keyPair,
null, options.keycontainer);
283 if (options.delaysign)
284 options.publicKey = keyPair.PublicKey;
286 options.keyPair = keyPair;
291 internal static byte[] ReadAllBytes(FileInfo path)
293 for (var attempt = 0; ; attempt++)
297 return File.ReadAllBytes(path.FullName);
299 catch (IOException) when (attempt < 5)
302 Thread.Sleep(200 * (attempt + 1));
311 void ParseCommandLine(
RuntimeContext context, StaticCompiler compiler,
IDiagnosticHandler diagnostics, ImportOptions options, List<ImportState> targets, ImportState compilerOptions)
313 compilerOptions.target = PEFileKinds.ConsoleApplication;
314 compilerOptions.guessFileKind =
true;
315 compilerOptions.version =
new Version(0, 0, 0, 0);
316 compilerOptions.apartment = ApartmentState.STA;
317 compilerOptions.props =
new Dictionary<string, string>();
318 ContinueParseCommandLine(context, compiler, diagnostics, options, targets, compilerOptions);
321 void ContinueParseCommandLine(
RuntimeContext context, StaticCompiler compiler,
IDiagnosticHandler diagnostics, ImportOptions options, List<ImportState> targets, ImportState compilerOptions)
323 if (options.Output !=
null)
324 compilerOptions.path = options.Output;
326 if (options.AssemblyName !=
null)
327 compilerOptions.assembly = options.AssemblyName;
329 switch (options.Target)
332 compilerOptions.target = PEFileKinds.ConsoleApplication;
333 compilerOptions.guessFileKind =
false;
336 compilerOptions.target = PEFileKinds.WindowApplication;
337 compilerOptions.guessFileKind =
false;
340 compilerOptions.targetIsModule =
true;
341 compilerOptions.target = PEFileKinds.Dll;
342 compilerOptions.guessFileKind =
false;
343 nonDeterministicOutput =
true;
346 compilerOptions.target = PEFileKinds.Dll;
347 compilerOptions.guessFileKind =
false;
353 switch (options.Platform)
356 compilerOptions.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.Required32Bit;
357 compilerOptions.imageFileMachine = ImageFileMachine.I386;
360 compilerOptions.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.PE32Plus;
361 compilerOptions.imageFileMachine = ImageFileMachine.AMD64;
364 compilerOptions.pekind = PortableExecutableKinds.ILOnly;
365 compilerOptions.imageFileMachine = ImageFileMachine.ARM;
368 compilerOptions.pekind = PortableExecutableKinds.ILOnly;
369 compilerOptions.imageFileMachine = ImageFileMachine.ARM64;
372 compilerOptions.pekind = PortableExecutableKinds.ILOnly | PortableExecutableKinds.Preferred32Bit;
373 compilerOptions.imageFileMachine = ImageFileMachine.UNKNOWN;
376 compilerOptions.pekind = PortableExecutableKinds.ILOnly;
377 compilerOptions.imageFileMachine = ImageFileMachine.UNKNOWN;
383 switch (options.Apartment)
386 compilerOptions.apartment = ApartmentState.STA;
389 compilerOptions.apartment = ApartmentState.MTA;
392 compilerOptions.apartment = ApartmentState.Unknown;
398 if (options.NoGlobbing)
399 compilerOptions.noglobbing =
true;
401 if (options.Properties.Count > 0)
402 foreach (var kvp
in options.Properties)
403 compilerOptions.props[kvp.Key] = kvp.Value;
405 if (options.EnableAssertions !=
null)
407 if (options.EnableAssertions.Length == 0)
408 compilerOptions.props[
"ikvm.assert.default"] =
"true";
410 compilerOptions.props[
"ikvm.assert.enable"] =
string.Join(
";", options.EnableAssertions);
413 if (options.DisableAssertions !=
null)
415 if (options.DisableAssertions.Length == 0)
416 compilerOptions.props[
"ikvm.assert.default"] =
"false";
418 compilerOptions.props[
"ikvm.assert.disable"] =
string.Join(
";", options.DisableAssertions);
421 if (options.RemoveAssertions)
424 if (options.Main !=
null)
425 compilerOptions.mainClass = options.Main;
427 foreach (var reference
in options.References)
428 ArrayAppend(
ref compilerOptions.unresolvedReferences, reference);
430 foreach (var spec
in options.Recurse)
437 exists = Directory.Exists((
string)spec);
447 var dir =
new DirectoryInfo(spec);
448 found = Recurse(context, compiler, compilerOptions, diagnostics, dir, dir,
"*");
454 var dir =
new DirectoryInfo(Path.GetDirectoryName(spec));
457 found = Recurse(context, compiler, compilerOptions, diagnostics, dir, dir, Path.GetFileName(spec));
461 found = RecurseJar(context, compiler, compilerOptions, diagnostics, spec);
464 catch (PathTooLongException)
468 catch (DirectoryNotFoundException)
472 catch (ArgumentException)
482 foreach (var kvp
in options.Resources)
484 var fileInfo = GetFileInfo(kvp.Value.FullName);
485 var fileName = kvp.Key.TrimStart(
'/').TrimEnd(
'/');
486 compilerOptions.GetResourcesJar().Add(fileName, ReadAllBytes(fileInfo), fileInfo);
489 foreach (var kvp
in options.ExternalResources)
491 if (!File.Exists(kvp.Value.FullName))
493 if (Path.GetFileName(kvp.Value.FullName) != kvp.Value.FullName)
497 compilerOptions.externalResources ??=
new Dictionary<string, string>();
498 compilerOptions.externalResources.Add(kvp.Key, kvp.Value.FullName);
504 if (options.Exclude !=
null)
505 ProcessExclusionFile(
ref compilerOptions.classesToExclude, options.Exclude.FullName);
507 if (options.Version !=
null)
508 compilerOptions.version = options.Version;
510 if (options.FileVersion !=
null)
511 compilerOptions.fileversion = options.FileVersion.ToString();
513 if (options.Win32Icon !=
null)
515 compilerOptions.iconfile = GetFileInfo(options.Win32Icon.FullName);
518 if (options.Win32Manifest !=
null)
519 compilerOptions.manifestFile = GetFileInfo(options.Win32Manifest.FullName);
521 if (options.KeyFile !=
null)
522 compilerOptions.keyfile = GetFileInfo(options.KeyFile.FullName);
524 if (options.Key !=
null)
525 compilerOptions.keycontainer = options.Key;
527 if (options.DelaySign)
528 compilerOptions.delaysign =
true;
530 switch (options.Debug)
533 compilerOptions.debugMode =
DebugMode.None;
537 compilerOptions.debugMode =
DebugMode.Portable;
541 compilerOptions.debugMode =
DebugMode.Embedded;
545 if (options.Deterministic ==
false)
546 nonDeterministicOutput =
true;
548 if (options.Optimize ==
false)
549 compilerOptions.codegenoptions |=
CodeGenOptions.DisableOptimizations;
551 if (options.SourcePath !=
null)
552 compilerOptions.sourcepath = options.SourcePath.FullName;
554 if (options.Remap !=
null)
555 compilerOptions.remapfile = GetFileInfo(options.Remap.FullName);
557 if (options.NoStackTraceInfo)
558 compilerOptions.codegenoptions |=
CodeGenOptions.NoStackTraceInfo;
560 if (options.RemoveUnusedPrivateFields)
561 compilerOptions.codegenoptions |=
CodeGenOptions.RemoveUnusedFields;
563 if (options.CompressResources)
564 compilerOptions.compressedResources =
true;
566 if (options.StrictFinalFieldSemantics)
567 compilerOptions.codegenoptions |=
CodeGenOptions.StrictFinalFieldSemantics;
569 if (options.PrivatePackages !=
null)
570 foreach (var prefix
in options.PrivatePackages)
571 ArrayAppend(
ref compilerOptions.privatePackages, prefix);
573 if (options.PublicPackages !=
null)
574 foreach (var prefix
in options.PublicPackages)
575 ArrayAppend(
ref compilerOptions.publicPackages, prefix);
577 if (options.NoWarn !=
null)
578 foreach (var diagnostic
in options.NoWarn)
579 compilerOptions.suppressWarnings.Add(diagnostic.Id.ToString());
582 if (options.WarnAsError !=
null)
584 if (options.WarnAsError.Length == 0)
585 compilerOptions.warnaserror =
true;
587 foreach (var i
in options.WarnAsError)
588 compilerOptions.errorWarnings.Add(i.Id.ToString());
591 if (options.Runtime !=
null)
592 runtimeAssembly = options.Runtime.FullName;
597 if (options.ClassLoader !=
null)
598 compilerOptions.classLoader = options.ClassLoader;
600 if (options.SharedClassLoader)
601 compilerOptions.sharedclassloader ??=
new List<ImportClassLoader>();
603 if (options.BaseAddress !=
null)
605 var baseAddress = options.BaseAddress;
606 ulong baseAddressParsed;
607 if (baseAddress.StartsWith(
"0x", StringComparison.OrdinalIgnoreCase))
608 baseAddressParsed = ulong.Parse(baseAddress.Substring(2),
System.Globalization.NumberStyles.AllowHexSpecifier);
610 baseAddressParsed = ulong.Parse(baseAddress);
612 compilerOptions.baseAddress = (baseAddressParsed & 0xFFFFFFFFFFFF0000UL);
615 if (options.FileAlign !=
null)
617 if (!uint.TryParse(options.FileAlign, out var filealign) || filealign < 512 || filealign > 8192 || (filealign & (filealign - 1)) != 0)
620 compilerOptions.fileAlignment = filealign;
623 if (options.NoPeerCrossReference)
624 compilerOptions.crossReferenceAllPeers =
false;
626 if (options.NoStdLib)
629 if (options.Libraries !=
null)
630 foreach (var lib
in options.Libraries)
631 libpaths.Add(lib.FullName);
633 if (options.NoAutoSerialization)
634 compilerOptions.codegenoptions |=
CodeGenOptions.NoAutomagicSerialization;
636 if (options.HighEntropyVA)
638 compilerOptions.highentropyva =
true;
641 if (options.Proxies !=
null)
643 foreach (var proxy
in options.Proxies)
645 if (compilerOptions.proxies.Contains(proxy))
648 compilerOptions.proxies.Add(proxy);
652 if (options.AllowNonVirtualCalls)
653 JVM.AllowNonVirtualCalls =
true;
658 compilerOptions.codegenoptions |= CodeGenOptions.DisableDynamicBinding |
CodeGenOptions.NoRefEmitHelpers;
661 if (options.NoJarStubs)
663 compilerOptions.nojarstubs =
true;
666 if (options.AssemblyAttributes !=
null)
667 foreach (var i
in options.AssemblyAttributes)
668 ProcessAttributeAnnotationsClass(context, diagnostics,
ref compilerOptions.assemblyAttributeAnnotations, i.FullName);
670 if (options.WarningLevel4Option)
671 compilerOptions.warningLevelHigh =
true;
673 if (options.NoParameterReflection)
674 compilerOptions.noParameterReflection =
true;
676 if (options.Bootstrap)
677 compilerOptions.bootstrap =
true;
679 if (compilerOptions.targetIsModule && compilerOptions.sharedclassloader !=
null)
682 ReadFiles(context, compiler, compilerOptions, diagnostics, options.Inputs.Select(i => i.FullName).ToList());
684 foreach (var nested
in options.Nested)
686 var nestedLevel =
new ImportContext();
687 nestedLevel.manifestMainClass = manifestMainClass;
688 nestedLevel.defaultAssemblyName = defaultAssemblyName;
689 nestedLevel.ContinueParseCommandLine(context, compiler, diagnostics, nested, targets, compilerOptions.Copy());
692 if (compilerOptions.assembly ==
null)
694 var basename = compilerOptions.path ==
null ? defaultAssemblyName : compilerOptions.path.Name;
695 if (basename ==
null)
698 int idx = basename.LastIndexOf(
'.');
700 compilerOptions.assembly = basename.Substring(0, idx);
702 compilerOptions.assembly = basename;
705 if (compilerOptions.path !=
null && compilerOptions.guessFileKind)
707 if (compilerOptions.path.Extension.Equals(
".dll", StringComparison.OrdinalIgnoreCase))
708 compilerOptions.target = PEFileKinds.Dll;
710 compilerOptions.guessFileKind =
false;
713 if (compilerOptions.mainClass ==
null && manifestMainClass !=
null && (compilerOptions.guessFileKind || compilerOptions.target != PEFileKinds.Dll))
716 compilerOptions.mainClass = manifestMainClass;
720 if (options.Nested ==
null || options.Nested.Length == 0)
721 targets.Add(compilerOptions);
724 internal static FileInfo GetFileInfo(
string path)
728 FileInfo fileInfo =
new FileInfo(path);
729 if (fileInfo.Directory ==
null)
736 catch (ArgumentException)
740 catch (NotSupportedException)
744 catch (PathTooLongException)
748 catch (UnauthorizedAccessException)
757 foreach (var fileName
in fileNames)
759 if (defaultAssemblyName ==
null)
763 defaultAssemblyName =
new FileInfo(Path.GetFileName(fileName)).Name;
765 catch (ArgumentException)
770 catch (NotSupportedException)
774 catch (PathTooLongException)
780 if (HasWildcardPattern(fileName) ==
false)
782 if (File.Exists(fileName))
784 ProcessFile(context, compiler, options, diagnostics,
null, fileName);
792 string[] files =
null;
795 var path = Path.GetDirectoryName(fileName);
796 files = Directory.GetFiles(path ==
"" ?
"." : path, Path.GetFileName(fileName));
803 if (files ==
null || files.Length == 0)
809 foreach (var f
in files)
811 ProcessFile(context, compiler, options, diagnostics,
null, f);
817 static bool HasWildcardPattern(
string path)
819 return path.IndexOf(
'*') >= 0 || path.IndexOf(
'?') >= 0;
822 internal static bool TryParseVersion(
string str, out Version version)
824 if (str.EndsWith(
".*"))
826 str = str.Substring(0, str.Length - 1);
827 int count = str.Split(
'.').Length;
831 DateTime now = DateTime.Now;
832 int seconds = (int)(now.TimeOfDay.TotalSeconds / 2);
833 int days = (int)(now -
new DateTime(2000, 1, 1)).TotalDays;
836 str += days +
"." + seconds;
850 version =
new Version(str);
851 return version.Major <= 65535 && version.Minor <= 65535 && version.Build <= 65535 && version.Revision <= 65535;
853 catch (ArgumentException) { }
854 catch (FormatException) { }
855 catch (OverflowException) { }
860 static void SetStrongNameKeyPair(
ref StrongNameKeyPair strongNameKeyPair, FileInfo keyFile,
string keyContainer)
865 strongNameKeyPair =
new StrongNameKeyPair(ReadAllBytes(keyFile));
867 strongNameKeyPair =
new StrongNameKeyPair(keyContainer);
870 if (strongNameKeyPair.PublicKey !=
null)
881 static void ResolveReferences(StaticCompiler compiler,
IDiagnosticHandler diagnostics, List<ImportState> targets)
885 foreach (var target
in targets)
887 if (target.unresolvedReferences !=
null)
889 foreach (
string reference
in target.unresolvedReferences)
891 foreach (var peer
in targets)
893 if (peer.assembly.Equals(reference, StringComparison.OrdinalIgnoreCase))
895 ArrayAppend(
ref target.peerReferences, peer.assembly);
899 if (!resolver.ResolveReference(cache,
ref target.references, reference))
909 foreach (var target
in targets)
911 if (target.references !=
null)
913 foreach (var
asm in target.references)
915 var forwarder =
asm.GetType(
"__<MainAssembly>");
916 if (forwarder !=
null && forwarder.Assembly !=
asm)
923 foreach (var target
in targets)
924 foreach (var assemblyName
in target.legacyStubReferences.Keys)
925 ArrayAppend(
ref target.references, resolver.LegacyLoad(
new AssemblyName(assemblyName),
null));
928 foreach (var target
in targets)
929 if (target.references !=
null)
930 foreach (var
asm in target.references)
931 RuntimeAssemblyClassLoader.PreloadExportedAssemblies(compiler,
asm);
934 private static void ArrayAppend<T>(
ref T[] array, T element)
939 array =
ArrayUtil.Concat(array, element);
942 private static void ArrayAppend<T>(
ref T[] array, T[] append)
948 else if (append !=
null)
950 T[] tmp =
new T[array.Length + append.Length];
951 Array.Copy(array, tmp, array.Length);
952 Array.Copy(append, 0, tmp, array.Length, append.Length);
957 static byte[] ReadFromZip(ZipArchiveEntry ze)
959 using MemoryStream ms =
new MemoryStream();
960 using Stream s = ze.Open();
979 catch (ByteCodeException)
984 if (cf.IKVMAssemblyAttribute ==
null)
989 if (cf.IKVMAssemblyAttribute.StartsWith(
"[["))
991 var r =
new Regex(
@"\[([^\[\]]+)\]");
992 var mc = r.Matches(cf.IKVMAssemblyAttribute);
993 foreach (Match m
in mc)
995 options.legacyStubReferences[m.Groups[1].Value] =
null;
1001 options.legacyStubReferences[cf.IKVMAssemblyAttribute] =
null;
1013 static bool IsExcludedOrStubLegacy(
RuntimeContext context, StaticCompiler compiler, ImportState options,
IDiagnosticHandler diagnostics, ZipArchiveEntry ze,
byte[] data)
1015 if (ze.Name.EndsWith(
".class", StringComparison.OrdinalIgnoreCase))
1020 if (options.IsExcludedClass(name) || (stub && EmitStubWarning(context, compiler, options, diagnostics, data)))
1035 void ProcessManifest(StaticCompiler compiler, ImportState options, ZipArchiveEntry ze)
1037 if (manifestMainClass ==
null)
1041 using Stream stream = ze.Open();
1042 using StreamReader rdr =
new StreamReader(stream);
1044 while ((line = rdr.ReadLine()) !=
null)
1046 if (line.StartsWith(
"Main-Class: "))
1048 line = line.Substring(12);
1049 string continuation;
1050 while ((continuation = rdr.ReadLine()) !=
null
1051 && continuation.StartsWith(
" ", StringComparison.Ordinal))
1053 line += continuation.Substring(1);
1055 manifestMainClass = line.Replace(
'/',
'.');
1062 bool ProcessZipFile(
RuntimeContext context, StaticCompiler compiler, ImportState options,
IDiagnosticHandler diagnostics,
string file, Predicate<ZipArchiveEntry> filter)
1066 using var zf = ZipFile.OpenRead(file);
1070 foreach (var ze
in zf.Entries)
1072 if (filter !=
null && !filter(ze))
1079 var data = ReadFromZip(ze);
1080 if (IsExcludedOrStubLegacy(context, compiler, options, diagnostics, ze, data))
1086 jar = options.GetJar(file);
1088 jar.Add(ze.FullName, data);
1089 if (
string.Equals(ze.FullName,
"META-INF/MANIFEST.MF", StringComparison.OrdinalIgnoreCase))
1091 ProcessManifest(compiler, options, ze);
1099 options.GetJar(file);
1104 catch (InvalidDataException x)
1112 var fileInfo = GetFileInfo(file);
1113 if (fileInfo.Extension.Equals(
".jar", StringComparison.OrdinalIgnoreCase) || fileInfo.Extension.Equals(
".zip", StringComparison.OrdinalIgnoreCase))
1115 ProcessZipFile(context, compiler, options, diagnostics, file,
null);
1119 if (fileInfo.Extension.Equals(
".class", StringComparison.OrdinalIgnoreCase))
1121 byte[] data = ReadAllBytes(fileInfo);
1125 if (options.IsExcludedClass(name))
1129 if (stub && EmitStubWarning(context, compiler, options, diagnostics, data))
1132 options.GetClassesJar().Add(name.Replace(
'.',
'/') +
".class", data, fileInfo);
1141 if (baseDir ==
null)
1149 var name = file.Substring(baseDir.FullName.Length);
1150 name = name.TrimStart(Path.DirectorySeparatorChar).Replace(
'\\',
'/');
1151 options.GetResourcesJar().Add(name, ReadAllBytes(fileInfo), fileInfo);
1156 bool Recurse(
RuntimeContext context, StaticCompiler compiler, ImportState options,
IDiagnosticHandler diagnostics, DirectoryInfo baseDir, DirectoryInfo dir,
string spec)
1160 foreach (var file
in dir.GetFiles(spec))
1163 ProcessFile(context, compiler, options, diagnostics, baseDir, file.FullName);
1166 foreach (var sub
in dir.GetDirectories())
1168 found |= Recurse(context, compiler, options, diagnostics, baseDir, sub, spec);
1179 file = Path.Combine(Path.GetFileName(path), file);
1180 path = Path.GetDirectoryName(path);
1181 if (Directory.Exists(path))
1183 throw new DirectoryNotFoundException();
1185 else if (File.Exists(path))
1187 var pathFilter = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar;
1188 var fileFilter =
"^" + Regex.Escape(Path.GetFileName(file)).Replace(
"\\*",
".*").Replace(
"\\?",
".") +
"$";
1190 return ProcessZipFile(context, compiler, options, diagnostics, path, delegate (ZipArchiveEntry ze)
1193 var name = ze.FullName.Replace(
'/', Path.DirectorySeparatorChar);
1194 return (Path.GetDirectoryName(name) + Path.DirectorySeparatorChar).StartsWith(pathFilter) && Regex.IsMatch(Path.GetFileName(ze.FullName), fileFilter);
1201 private static void ProcessExclusionFile(
ref string[] classesToExclude,
string filename)
1205 var list = classesToExclude ==
null ?
new List<string>() : new List<string>(classesToExclude);
1206 using (var file =
new StreamReader(filename))
1209 while ((line = file.ReadLine()) !=
null)
1212 if (!line.StartsWith(
"//") && line.Length != 0)
1219 classesToExclude = list.ToArray();
1231 using var file = File.OpenRead(filename);
1233 ArrayAppend(
ref annotations, cf.Annotations);
1241 internal static void HandleWarnArg(ICollection<string> target,
string arg)
1243 foreach (var w
in arg.Split(
','))
1246 int prefixStart = w.StartsWith(
"IKVM", StringComparison.OrdinalIgnoreCase) ? 4 : 0;
1247 int contextIndex = w.IndexOf(
':', prefixStart);
1248 string context =
string.Empty;
1250 if (contextIndex != -1)
1253 context = w.Substring(contextIndex);
1254 parse = w.Substring(prefixStart, contextIndex - prefixStart);
1258 parse = w.Substring(prefixStart);
1261 if (!
int.TryParse(parse, out var intResult))
1267 target.Add($
"{intResult}{context}");