diff --git a/IKVM.refs.targets b/IKVM.refs.targets index 35581bf4c8..ff52d30390 100644 --- a/IKVM.refs.targets +++ b/IKVM.refs.targets @@ -5,6 +5,11 @@ + + true + all + IkvmLibsItem + true all diff --git a/IKVM.sln b/IKVM.sln index 42bf046667..7f64c4545b 100644 --- a/IKVM.sln +++ b/IKVM.sln @@ -339,6 +339,8 @@ Project("{6DE1C62B-E8D7-451A-8734-87EAEB46E35B}") = "libj2gss", "src\libj2gss\li EndProject Project("{6DE1C62B-E8D7-451A-8734-87EAEB46E35B}") = "libsspi_bridge", "src\libsspi_bridge\libsspi_bridge.clangproj", "{461D3F93-30AD-481E-B3D3-476A3CE2BF7B}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IKVM.CoreLib", "src\IKVM.CoreLib\IKVM.CoreLib.csproj", "{C6556982-85B8-4E58-A693-1239D4823BD7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -909,6 +911,10 @@ Global {461D3F93-30AD-481E-B3D3-476A3CE2BF7B}.Debug|Any CPU.Build.0 = Debug|Any CPU {461D3F93-30AD-481E-B3D3-476A3CE2BF7B}.Release|Any CPU.ActiveCfg = Release|Any CPU {461D3F93-30AD-481E-B3D3-476A3CE2BF7B}.Release|Any CPU.Build.0 = Release|Any CPU + {C6556982-85B8-4E58-A693-1239D4823BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6556982-85B8-4E58-A693-1239D4823BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6556982-85B8-4E58-A693-1239D4823BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6556982-85B8-4E58-A693-1239D4823BD7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/IKVM.ConsoleApp/Program.cs b/src/IKVM.ConsoleApp/Program.cs index 8aec91fc20..863d308112 100644 --- a/src/IKVM.ConsoleApp/Program.cs +++ b/src/IKVM.ConsoleApp/Program.cs @@ -1,4 +1,9 @@ -namespace IKVM.ConsoleApp +using System; +using System.Diagnostics.Tracing; + +using IKVM.Runtime; + +namespace IKVM.ConsoleApp { public class Program @@ -6,7 +11,19 @@ public class Program public static void Main(string[] args) { + var l = new Listener(); + var o = new java.lang.Object(); + java.lang.System.loadLibrary("hi"); + } + + } + + class Listener : EventListener + { + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + Console.WriteLine(eventData); } } diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.cs b/src/IKVM.CoreLib/Diagnostics/Diagnostic.cs new file mode 100644 index 0000000000..eee2302037 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.cs @@ -0,0 +1,23 @@ +using System; +using System.Text; + +namespace IKVM.CoreLib.Diagnostics +{ + +#if NET8_0_OR_GREATER + internal partial record class Diagnostic(int Id, string Name, CompositeFormat Message, DiagnosticLevel Level) +#else + internal partial record class Diagnostic(int Id, string Name, string Message, DiagnosticLevel Level) +#endif + { + + /// + /// Creates a new diagnostic event with the specified arguments. + /// + /// + /// + public DiagnosticEvent Event(ReadOnlySpan args) => new DiagnosticEvent(this, args); + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs new file mode 100644 index 0000000000..8f4d0f246a --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.cs @@ -0,0 +1,2396 @@ +#nullable enable + +using System.Text; + +namespace IKVM.CoreLib.Diagnostics +{ + + partial record class Diagnostic + { + + /// + /// The 'MainMethodFound' diagnostic. + /// + /// +/// Found main method in class "{arg0}". + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MainMethodFound = new Diagnostic(1, nameof(MainMethodFound), CompositeFormat.Parse("Found main method in class \"{0}\"."), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic MainMethodFound = new Diagnostic(1, nameof(MainMethodFound), "Found main method in class \"{0}\".", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'OutputFileIs' diagnostic. + /// + /// +/// Output file is "{arg0}". + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic OutputFileIs = new Diagnostic(2, nameof(OutputFileIs), CompositeFormat.Parse("Output file is \"{0}\"."), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic OutputFileIs = new Diagnostic(2, nameof(OutputFileIs), "Output file is \"{0}\".", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'AutoAddRef' diagnostic. + /// + /// +/// Automatically adding reference to "{arg0}". + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic AutoAddRef = new Diagnostic(3, nameof(AutoAddRef), CompositeFormat.Parse("Automatically adding reference to \"{0}\"."), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic AutoAddRef = new Diagnostic(3, nameof(AutoAddRef), "Automatically adding reference to \"{0}\".", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MainMethodFromManifest' diagnostic. + /// + /// +/// Using main class "{arg0}" based on jar manifest. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MainMethodFromManifest = new Diagnostic(4, nameof(MainMethodFromManifest), CompositeFormat.Parse("Using main class \"{0}\" based on jar manifest."), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic MainMethodFromManifest = new Diagnostic(4, nameof(MainMethodFromManifest), "Using main class \"{0}\" based on jar manifest.", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericCompilerInfo' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericCompilerInfo = new Diagnostic(5, nameof(GenericCompilerInfo), CompositeFormat.Parse("{0}"), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic GenericCompilerInfo = new Diagnostic(5, nameof(GenericCompilerInfo), "{0}", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericClassLoadingInfo' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericClassLoadingInfo = new Diagnostic(6, nameof(GenericClassLoadingInfo), CompositeFormat.Parse("{0}"), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic GenericClassLoadingInfo = new Diagnostic(6, nameof(GenericClassLoadingInfo), "{0}", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericVerifierInfo' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericVerifierInfo = new Diagnostic(7, nameof(GenericVerifierInfo), CompositeFormat.Parse("{0}"), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic GenericVerifierInfo = new Diagnostic(7, nameof(GenericVerifierInfo), "{0}", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericRuntimeInfo' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericRuntimeInfo = new Diagnostic(8, nameof(GenericRuntimeInfo), CompositeFormat.Parse("{0}"), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic GenericRuntimeInfo = new Diagnostic(8, nameof(GenericRuntimeInfo), "{0}", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericJniInfo' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericJniInfo = new Diagnostic(9, nameof(GenericJniInfo), CompositeFormat.Parse("{0}"), DiagnosticLevel.Informational); +#else + public static readonly Diagnostic GenericJniInfo = new Diagnostic(9, nameof(GenericJniInfo), "{0}", DiagnosticLevel.Informational); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ClassNotFound' diagnostic. + /// + /// +/// Class "{arg0}" not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ClassNotFound = new Diagnostic(100, nameof(ClassNotFound), CompositeFormat.Parse("Class \"{0}\" not found."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic ClassNotFound = new Diagnostic(100, nameof(ClassNotFound), "Class \"{0}\" not found.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ClassFormatError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (class format error "{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ClassFormatError = new Diagnostic(101, nameof(ClassFormatError), CompositeFormat.Parse("Unable to compile class \"{0}\". (class format error \"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic ClassFormatError = new Diagnostic(101, nameof(ClassFormatError), "Unable to compile class \"{0}\". (class format error \"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'DuplicateClassName' diagnostic. + /// + /// +/// Duplicate class name: "{arg0}". + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic DuplicateClassName = new Diagnostic(102, nameof(DuplicateClassName), CompositeFormat.Parse("Duplicate class name: \"{0}\"."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic DuplicateClassName = new Diagnostic(102, nameof(DuplicateClassName), "Duplicate class name: \"{0}\".", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'IllegalAccessError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (illegal access error "{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic IllegalAccessError = new Diagnostic(103, nameof(IllegalAccessError), CompositeFormat.Parse("Unable to compile class \"{0}\". (illegal access error \"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic IllegalAccessError = new Diagnostic(103, nameof(IllegalAccessError), "Unable to compile class \"{0}\". (illegal access error \"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'VerificationError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (verification error "{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic VerificationError = new Diagnostic(104, nameof(VerificationError), CompositeFormat.Parse("Unable to compile class \"{0}\". (verification error \"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic VerificationError = new Diagnostic(104, nameof(VerificationError), "Unable to compile class \"{0}\". (verification error \"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'NoClassDefFoundError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (missing class "{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic NoClassDefFoundError = new Diagnostic(105, nameof(NoClassDefFoundError), CompositeFormat.Parse("Unable to compile class \"{0}\". (missing class \"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic NoClassDefFoundError = new Diagnostic(105, nameof(NoClassDefFoundError), "Unable to compile class \"{0}\". (missing class \"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericUnableToCompileError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericUnableToCompileError = new Diagnostic(106, nameof(GenericUnableToCompileError), CompositeFormat.Parse("Unable to compile class \"{0}\". (\"{1}\": \"{2}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic GenericUnableToCompileError = new Diagnostic(106, nameof(GenericUnableToCompileError), "Unable to compile class \"{0}\". (\"{1}\": \"{2}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'DuplicateResourceName' diagnostic. + /// + /// +/// Skipping resource (name clash): "{arg0}" + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic DuplicateResourceName = new Diagnostic(107, nameof(DuplicateResourceName), CompositeFormat.Parse("Skipping resource (name clash): \"{0}\""), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic DuplicateResourceName = new Diagnostic(107, nameof(DuplicateResourceName), "Skipping resource (name clash): \"{0}\"", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'SkippingReferencedClass' diagnostic. + /// + /// +/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic SkippingReferencedClass = new Diagnostic(109, nameof(SkippingReferencedClass), CompositeFormat.Parse("Skipping class: \"{0}\". (class is already available in referenced assembly \"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic SkippingReferencedClass = new Diagnostic(109, nameof(SkippingReferencedClass), "Skipping class: \"{0}\". (class is already available in referenced assembly \"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'NoJniRuntime' diagnostic. + /// + /// +/// Unable to load runtime JNI assembly. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic NoJniRuntime = new Diagnostic(110, nameof(NoJniRuntime), CompositeFormat.Parse("Unable to load runtime JNI assembly."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic NoJniRuntime = new Diagnostic(110, nameof(NoJniRuntime), "Unable to load runtime JNI assembly.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedNoClassDefFoundError' diagnostic. + /// + /// +/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedNoClassDefFoundError = new Diagnostic(111, nameof(EmittedNoClassDefFoundError), CompositeFormat.Parse("Emitted java.lang.NoClassDefFoundError in \"{0}\". (\"{1}\")."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedNoClassDefFoundError = new Diagnostic(111, nameof(EmittedNoClassDefFoundError), "Emitted java.lang.NoClassDefFoundError in \"{0}\". (\"{1}\").", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedIllegalAccessError' diagnostic. + /// + /// +/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedIllegalAccessError = new Diagnostic(112, nameof(EmittedIllegalAccessError), CompositeFormat.Parse("Emitted java.lang.IllegalAccessError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedIllegalAccessError = new Diagnostic(112, nameof(EmittedIllegalAccessError), "Emitted java.lang.IllegalAccessError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedInstantiationError' diagnostic. + /// + /// +/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedInstantiationError = new Diagnostic(113, nameof(EmittedInstantiationError), CompositeFormat.Parse("Emitted java.lang.InstantiationError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedInstantiationError = new Diagnostic(113, nameof(EmittedInstantiationError), "Emitted java.lang.InstantiationError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedIncompatibleClassChangeError' diagnostic. + /// + /// +/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedIncompatibleClassChangeError = new Diagnostic(114, nameof(EmittedIncompatibleClassChangeError), CompositeFormat.Parse("Emitted java.lang.IncompatibleClassChangeError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedIncompatibleClassChangeError = new Diagnostic(114, nameof(EmittedIncompatibleClassChangeError), "Emitted java.lang.IncompatibleClassChangeError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedNoSuchFieldError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedNoSuchFieldError = new Diagnostic(115, nameof(EmittedNoSuchFieldError), CompositeFormat.Parse("Emitted java.lang.NoSuchFieldError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedNoSuchFieldError = new Diagnostic(115, nameof(EmittedNoSuchFieldError), "Emitted java.lang.NoSuchFieldError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedAbstractMethodError' diagnostic. + /// + /// +/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedAbstractMethodError = new Diagnostic(116, nameof(EmittedAbstractMethodError), CompositeFormat.Parse("Emitted java.lang.AbstractMethodError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedAbstractMethodError = new Diagnostic(116, nameof(EmittedAbstractMethodError), "Emitted java.lang.AbstractMethodError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedNoSuchMethodError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedNoSuchMethodError = new Diagnostic(117, nameof(EmittedNoSuchMethodError), CompositeFormat.Parse("Emitted java.lang.NoSuchMethodError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedNoSuchMethodError = new Diagnostic(117, nameof(EmittedNoSuchMethodError), "Emitted java.lang.NoSuchMethodError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedLinkageError' diagnostic. + /// + /// +/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedLinkageError = new Diagnostic(118, nameof(EmittedLinkageError), CompositeFormat.Parse("Emitted java.lang.LinkageError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedLinkageError = new Diagnostic(118, nameof(EmittedLinkageError), "Emitted java.lang.LinkageError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedVerificationError' diagnostic. + /// + /// +/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedVerificationError = new Diagnostic(119, nameof(EmittedVerificationError), CompositeFormat.Parse("Emitted java.lang.VerificationError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedVerificationError = new Diagnostic(119, nameof(EmittedVerificationError), "Emitted java.lang.VerificationError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'EmittedClassFormatError' diagnostic. + /// + /// +/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic EmittedClassFormatError = new Diagnostic(120, nameof(EmittedClassFormatError), CompositeFormat.Parse("Emitted java.lang.ClassFormatError in \"{0}\". (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic EmittedClassFormatError = new Diagnostic(120, nameof(EmittedClassFormatError), "Emitted java.lang.ClassFormatError in \"{0}\". (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidCustomAttribute' diagnostic. + /// + /// +/// Error emitting "{arg0}" custom attribute. ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidCustomAttribute = new Diagnostic(121, nameof(InvalidCustomAttribute), CompositeFormat.Parse("Error emitting \"{0}\" custom attribute. (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic InvalidCustomAttribute = new Diagnostic(121, nameof(InvalidCustomAttribute), "Error emitting \"{0}\" custom attribute. (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'IgnoredCustomAttribute' diagnostic. + /// + /// +/// Custom attribute "{arg0}" was ignored. ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic IgnoredCustomAttribute = new Diagnostic(122, nameof(IgnoredCustomAttribute), CompositeFormat.Parse("Custom attribute \"{0}\" was ignored. (\"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic IgnoredCustomAttribute = new Diagnostic(122, nameof(IgnoredCustomAttribute), "Custom attribute \"{0}\" was ignored. (\"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'AssumeAssemblyVersionMatch' diagnostic. + /// + /// +/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic AssumeAssemblyVersionMatch = new Diagnostic(123, nameof(AssumeAssemblyVersionMatch), CompositeFormat.Parse("Assuming assembly reference \"{0}\" matches \"{1}\", you may need to supply runtime p" + + "olicy"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic AssumeAssemblyVersionMatch = new Diagnostic(123, nameof(AssumeAssemblyVersionMatch), "Assuming assembly reference \"{0}\" matches \"{1}\", you may need to supply runtime p" + + "olicy", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidDirectoryInLibOptionPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in -lib option is not valid. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidDirectoryInLibOptionPath = new Diagnostic(124, nameof(InvalidDirectoryInLibOptionPath), CompositeFormat.Parse("Directory \"{0}\" specified in -lib option is not valid."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic InvalidDirectoryInLibOptionPath = new Diagnostic(124, nameof(InvalidDirectoryInLibOptionPath), "Directory \"{0}\" specified in -lib option is not valid.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in LIB environment is not valid. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidDirectoryInLibEnvironmentPath = new Diagnostic(125, nameof(InvalidDirectoryInLibEnvironmentPath), CompositeFormat.Parse("Directory \"{0}\" specified in LIB environment is not valid."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic InvalidDirectoryInLibEnvironmentPath = new Diagnostic(125, nameof(InvalidDirectoryInLibEnvironmentPath), "Directory \"{0}\" specified in LIB environment is not valid.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'LegacySearchRule' diagnostic. + /// + /// +/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic LegacySearchRule = new Diagnostic(126, nameof(LegacySearchRule), CompositeFormat.Parse("Found assembly \"{0}\" using legacy search rule, please append \'.dll\' to the refere" + + "nce."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic LegacySearchRule = new Diagnostic(126, nameof(LegacySearchRule), "Found assembly \"{0}\" using legacy search rule, please append \'.dll\' to the refere" + + "nce.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'AssemblyLocationIgnored' diagnostic. + /// + /// +/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic AssemblyLocationIgnored = new Diagnostic(127, nameof(AssemblyLocationIgnored), CompositeFormat.Parse("Assembly \"{0}\" is ignored as previously loaded assembly \"{1}\" has the same identi" + + "ty \"{2}\"."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic AssemblyLocationIgnored = new Diagnostic(127, nameof(AssemblyLocationIgnored), "Assembly \"{0}\" is ignored as previously loaded assembly \"{1}\" has the same identi" + + "ty \"{2}\".", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InterfaceMethodCantBeInternal' diagnostic. + /// + /// +/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InterfaceMethodCantBeInternal = new Diagnostic(128, nameof(InterfaceMethodCantBeInternal), CompositeFormat.Parse("Ignoring @ikvm.lang.Internal annotation on interface method. (\"{0}.{1}{2}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic InterfaceMethodCantBeInternal = new Diagnostic(128, nameof(InterfaceMethodCantBeInternal), "Ignoring @ikvm.lang.Internal annotation on interface method. (\"{0}.{1}{2}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'DuplicateAssemblyReference' diagnostic. + /// + /// +/// Duplicate assembly reference "{arg0}" + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic DuplicateAssemblyReference = new Diagnostic(132, nameof(DuplicateAssemblyReference), CompositeFormat.Parse("Duplicate assembly reference \"{0}\""), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic DuplicateAssemblyReference = new Diagnostic(132, nameof(DuplicateAssemblyReference), "Duplicate assembly reference \"{0}\"", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnableToResolveType' diagnostic. + /// + /// +/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnableToResolveType = new Diagnostic(133, nameof(UnableToResolveType), CompositeFormat.Parse("Reference in \"{0}\" to type \"{1}\" claims it is defined in \"{2}\", but it could not " + + "be found."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic UnableToResolveType = new Diagnostic(133, nameof(UnableToResolveType), "Reference in \"{0}\" to type \"{1}\" claims it is defined in \"{2}\", but it could not " + + "be found.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'StubsAreDeprecated' diagnostic. + /// + /// +/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic StubsAreDeprecated = new Diagnostic(134, nameof(StubsAreDeprecated), CompositeFormat.Parse("Compiling stubs is deprecated. Please add a reference to assembly \"{0}\" instead."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic StubsAreDeprecated = new Diagnostic(134, nameof(StubsAreDeprecated), "Compiling stubs is deprecated. Please add a reference to assembly \"{0}\" instead.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'WrongClassName' diagnostic. + /// + /// +/// Unable to compile "{arg0}" (wrong name: "{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic WrongClassName = new Diagnostic(135, nameof(WrongClassName), CompositeFormat.Parse("Unable to compile \"{0}\" (wrong name: \"{1}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic WrongClassName = new Diagnostic(135, nameof(WrongClassName), "Unable to compile \"{0}\" (wrong name: \"{1}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. + /// + /// +/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ReflectionCallerClassRequiresCallerID = new Diagnostic(136, nameof(ReflectionCallerClassRequiresCallerID), CompositeFormat.Parse("Reflection.getCallerClass() called from non-CallerID method. (\"{0}.{1}{2}\")"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic ReflectionCallerClassRequiresCallerID = new Diagnostic(136, nameof(ReflectionCallerClassRequiresCallerID), "Reflection.getCallerClass() called from non-CallerID method. (\"{0}.{1}{2}\")", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'LegacyAssemblyAttributesFound' diagnostic. + /// + /// +/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic LegacyAssemblyAttributesFound = new Diagnostic(137, nameof(LegacyAssemblyAttributesFound), CompositeFormat.Parse("Legacy assembly attributes container found. Please use the -assemblyattributes: option."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic LegacyAssemblyAttributesFound = new Diagnostic(137, nameof(LegacyAssemblyAttributesFound), "Legacy assembly attributes container found. Please use the -assemblyattributes: option.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnableToCreateLambdaFactory' diagnostic. + /// + /// +/// Unable to create static lambda factory. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnableToCreateLambdaFactory = new Diagnostic(138, nameof(UnableToCreateLambdaFactory), CompositeFormat.Parse("Unable to create static lambda factory."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic UnableToCreateLambdaFactory = new Diagnostic(138, nameof(UnableToCreateLambdaFactory), "Unable to create static lambda factory.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnknownWarning' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnknownWarning = new Diagnostic(999, nameof(UnknownWarning), CompositeFormat.Parse("{0}"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic UnknownWarning = new Diagnostic(999, nameof(UnknownWarning), "{0}", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'DuplicateIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic DuplicateIkvmLangProperty = new Diagnostic(139, nameof(DuplicateIkvmLangProperty), CompositeFormat.Parse("Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic DuplicateIkvmLangProperty = new Diagnostic(139, nameof(DuplicateIkvmLangProperty), "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MalformedIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MalformedIkvmLangProperty = new Diagnostic(140, nameof(MalformedIkvmLangProperty), CompositeFormat.Parse("Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}."), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic MalformedIkvmLangProperty = new Diagnostic(140, nameof(MalformedIkvmLangProperty), "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}.", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericCompilerWarning' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericCompilerWarning = new Diagnostic(141, nameof(GenericCompilerWarning), CompositeFormat.Parse("{0}"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic GenericCompilerWarning = new Diagnostic(141, nameof(GenericCompilerWarning), "{0}", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericClassLoadingWarning' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericClassLoadingWarning = new Diagnostic(142, nameof(GenericClassLoadingWarning), CompositeFormat.Parse("{0}"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic GenericClassLoadingWarning = new Diagnostic(142, nameof(GenericClassLoadingWarning), "{0}", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericVerifierWarning' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericVerifierWarning = new Diagnostic(143, nameof(GenericVerifierWarning), CompositeFormat.Parse("{0}"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic GenericVerifierWarning = new Diagnostic(143, nameof(GenericVerifierWarning), "{0}", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericRuntimeWarning' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericRuntimeWarning = new Diagnostic(144, nameof(GenericRuntimeWarning), CompositeFormat.Parse("{0}"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic GenericRuntimeWarning = new Diagnostic(144, nameof(GenericRuntimeWarning), "{0}", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericJniWarning' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericJniWarning = new Diagnostic(145, nameof(GenericJniWarning), CompositeFormat.Parse("{0}"), DiagnosticLevel.Warning); +#else + public static readonly Diagnostic GenericJniWarning = new Diagnostic(145, nameof(GenericJniWarning), "{0}", DiagnosticLevel.Warning); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnableToCreateProxy' diagnostic. + /// + /// +/// Unable to create proxy "{arg0}". ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnableToCreateProxy = new Diagnostic(4001, nameof(UnableToCreateProxy), CompositeFormat.Parse("Unable to create proxy \"{0}\". (\"{1}\")"), DiagnosticLevel.Error); +#else + public static readonly Diagnostic UnableToCreateProxy = new Diagnostic(4001, nameof(UnableToCreateProxy), "Unable to create proxy \"{0}\". (\"{1}\")", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'DuplicateProxy' diagnostic. + /// + /// +/// Duplicate proxy "{arg0}". + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic DuplicateProxy = new Diagnostic(4002, nameof(DuplicateProxy), CompositeFormat.Parse("Duplicate proxy \"{0}\"."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic DuplicateProxy = new Diagnostic(4002, nameof(DuplicateProxy), "Duplicate proxy \"{0}\".", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MapXmlUnableToResolveOpCode' diagnostic. + /// + /// +/// Unable to resolve opcode in remap file: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MapXmlUnableToResolveOpCode = new Diagnostic(4003, nameof(MapXmlUnableToResolveOpCode), CompositeFormat.Parse("Unable to resolve opcode in remap file: {0}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic MapXmlUnableToResolveOpCode = new Diagnostic(4003, nameof(MapXmlUnableToResolveOpCode), "Unable to resolve opcode in remap file: {0}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MapXmlError' diagnostic. + /// + /// +/// Error in remap file: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MapXmlError = new Diagnostic(4004, nameof(MapXmlError), CompositeFormat.Parse("Error in remap file: {0}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic MapXmlError = new Diagnostic(4004, nameof(MapXmlError), "Error in remap file: {0}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InputFileNotFound' diagnostic. + /// + /// +/// Source file '{arg0}' not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InputFileNotFound = new Diagnostic(4005, nameof(InputFileNotFound), CompositeFormat.Parse("Source file \'{0}\' not found."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic InputFileNotFound = new Diagnostic(4005, nameof(InputFileNotFound), "Source file \'{0}\' not found.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnknownFileType' diagnostic. + /// + /// +/// Unknown file type: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnknownFileType = new Diagnostic(4006, nameof(UnknownFileType), CompositeFormat.Parse("Unknown file type: {0}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic UnknownFileType = new Diagnostic(4006, nameof(UnknownFileType), "Unknown file type: {0}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnknownElementInMapFile' diagnostic. + /// + /// +/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnknownElementInMapFile = new Diagnostic(4007, nameof(UnknownElementInMapFile), CompositeFormat.Parse("Unknown element {0} in remap file, line {1}, column {2}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic UnknownElementInMapFile = new Diagnostic(4007, nameof(UnknownElementInMapFile), "Unknown element {0} in remap file, line {1}, column {2}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnknownAttributeInMapFile' diagnostic. + /// + /// +/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnknownAttributeInMapFile = new Diagnostic(4008, nameof(UnknownAttributeInMapFile), CompositeFormat.Parse("Unknown attribute {0} in remap file, line {1}, column {2}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic UnknownAttributeInMapFile = new Diagnostic(4008, nameof(UnknownAttributeInMapFile), "Unknown attribute {0} in remap file, line {1}, column {2}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidMemberNameInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidMemberNameInMapFile = new Diagnostic(4009, nameof(InvalidMemberNameInMapFile), CompositeFormat.Parse("Invalid {0} name \'{1}\' in remap file in class {2}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic InvalidMemberNameInMapFile = new Diagnostic(4009, nameof(InvalidMemberNameInMapFile), "Invalid {0} name \'{1}\' in remap file in class {2}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidMemberSignatureInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidMemberSignatureInMapFile = new Diagnostic(4010, nameof(InvalidMemberSignatureInMapFile), CompositeFormat.Parse("Invalid {0} signature \'{3}\' in remap file for {0} {1}.{2}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic InvalidMemberSignatureInMapFile = new Diagnostic(4010, nameof(InvalidMemberSignatureInMapFile), "Invalid {0} signature \'{3}\' in remap file for {0} {1}.{2}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidPropertyNameInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidPropertyNameInMapFile = new Diagnostic(4011, nameof(InvalidPropertyNameInMapFile), CompositeFormat.Parse("Invalid property {0} name \'{3}\' in remap file for property {1}.{2}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic InvalidPropertyNameInMapFile = new Diagnostic(4011, nameof(InvalidPropertyNameInMapFile), "Invalid property {0} name \'{3}\' in remap file for property {1}.{2}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidPropertySignatureInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidPropertySignatureInMapFile = new Diagnostic(4012, nameof(InvalidPropertySignatureInMapFile), CompositeFormat.Parse("Invalid property {0} signature \'{3}\' in remap file for property {1}.{2}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic InvalidPropertySignatureInMapFile = new Diagnostic(4012, nameof(InvalidPropertySignatureInMapFile), "Invalid property {0} signature \'{3}\' in remap file for property {1}.{2}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'NonPrimaryAssemblyReference' diagnostic. + /// + /// +/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic NonPrimaryAssemblyReference = new Diagnostic(4013, nameof(NonPrimaryAssemblyReference), CompositeFormat.Parse("Referenced assembly \"{0}\" is not the primary assembly of a shared class loader gr" + + "oup, please reference primary assembly \"{1}\" instead."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic NonPrimaryAssemblyReference = new Diagnostic(4013, nameof(NonPrimaryAssemblyReference), "Referenced assembly \"{0}\" is not the primary assembly of a shared class loader gr" + + "oup, please reference primary assembly \"{1}\" instead.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MissingType' diagnostic. + /// + /// +/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MissingType = new Diagnostic(4014, nameof(MissingType), CompositeFormat.Parse("Reference to type \"{0}\" claims it is defined in \"{1}\", but it could not be found." + + ""), DiagnosticLevel.Error); +#else + public static readonly Diagnostic MissingType = new Diagnostic(4014, nameof(MissingType), "Reference to type \"{0}\" claims it is defined in \"{1}\", but it could not be found." + + "", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MissingReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MissingReference = new Diagnostic(4015, nameof(MissingReference), CompositeFormat.Parse("The type \'{0}\' is defined in an assembly that is notResponseFileDepthExceeded ref" + + "erenced. You must add a reference to assembly \'{1}\'."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic MissingReference = new Diagnostic(4015, nameof(MissingReference), "The type \'{0}\' is defined in an assembly that is notResponseFileDepthExceeded ref" + + "erenced. You must add a reference to assembly \'{1}\'.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. + /// + /// +/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic CallerSensitiveOnUnsupportedMethod = new Diagnostic(4016, nameof(CallerSensitiveOnUnsupportedMethod), CompositeFormat.Parse("CallerSensitive annotation on unsupported method. (\"{0}.{1}{2}\")"), DiagnosticLevel.Error); +#else + public static readonly Diagnostic CallerSensitiveOnUnsupportedMethod = new Diagnostic(4016, nameof(CallerSensitiveOnUnsupportedMethod), "CallerSensitive annotation on unsupported method. (\"{0}.{1}{2}\")", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. + /// + /// +/// {arg0} does not implement default interface method {arg1}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic RemappedTypeMissingDefaultInterfaceMethod = new Diagnostic(4017, nameof(RemappedTypeMissingDefaultInterfaceMethod), CompositeFormat.Parse("{0} does not implement default interface method {1}."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic RemappedTypeMissingDefaultInterfaceMethod = new Diagnostic(4017, nameof(RemappedTypeMissingDefaultInterfaceMethod), "{0} does not implement default interface method {1}.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericCompilerError' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericCompilerError = new Diagnostic(4018, nameof(GenericCompilerError), CompositeFormat.Parse("{0}"), DiagnosticLevel.Error); +#else + public static readonly Diagnostic GenericCompilerError = new Diagnostic(4018, nameof(GenericCompilerError), "{0}", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericClassLoadingError' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericClassLoadingError = new Diagnostic(4019, nameof(GenericClassLoadingError), CompositeFormat.Parse("{0}"), DiagnosticLevel.Error); +#else + public static readonly Diagnostic GenericClassLoadingError = new Diagnostic(4019, nameof(GenericClassLoadingError), "{0}", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericVerifierError' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericVerifierError = new Diagnostic(4020, nameof(GenericVerifierError), CompositeFormat.Parse("{0}"), DiagnosticLevel.Error); +#else + public static readonly Diagnostic GenericVerifierError = new Diagnostic(4020, nameof(GenericVerifierError), "{0}", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericRuntimeError' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericRuntimeError = new Diagnostic(4021, nameof(GenericRuntimeError), CompositeFormat.Parse("{0}"), DiagnosticLevel.Error); +#else + public static readonly Diagnostic GenericRuntimeError = new Diagnostic(4021, nameof(GenericRuntimeError), "{0}", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericJniError' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericJniError = new Diagnostic(4022, nameof(GenericJniError), CompositeFormat.Parse("{0}"), DiagnosticLevel.Error); +#else + public static readonly Diagnostic GenericJniError = new Diagnostic(4022, nameof(GenericJniError), "{0}", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ExportingImportsNotSupported' diagnostic. + /// + /// +/// Exporting previously imported assemblies is not supported. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ExportingImportsNotSupported = new Diagnostic(4023, nameof(ExportingImportsNotSupported), CompositeFormat.Parse("Exporting previously imported assemblies is not supported."), DiagnosticLevel.Error); +#else + public static readonly Diagnostic ExportingImportsNotSupported = new Diagnostic(4023, nameof(ExportingImportsNotSupported), "Exporting previously imported assemblies is not supported.", DiagnosticLevel.Error); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ResponseFileDepthExceeded' diagnostic. + /// + /// +/// Response file nesting depth exceeded. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ResponseFileDepthExceeded = new Diagnostic(5000, nameof(ResponseFileDepthExceeded), CompositeFormat.Parse("Response file nesting depth exceeded."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ResponseFileDepthExceeded = new Diagnostic(5000, nameof(ResponseFileDepthExceeded), "Response file nesting depth exceeded.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ErrorReadingFile' diagnostic. + /// + /// +/// Unable to read file: {arg0}. ({arg1}) + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ErrorReadingFile = new Diagnostic(5001, nameof(ErrorReadingFile), CompositeFormat.Parse("Unable to read file: {0}. ({1})"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ErrorReadingFile = new Diagnostic(5001, nameof(ErrorReadingFile), "Unable to read file: {0}. ({1})", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'NoTargetsFound' diagnostic. + /// + /// +/// No targets found + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic NoTargetsFound = new Diagnostic(5002, nameof(NoTargetsFound), CompositeFormat.Parse("No targets found"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic NoTargetsFound = new Diagnostic(5002, nameof(NoTargetsFound), "No targets found", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'FileFormatLimitationExceeded' diagnostic. + /// + /// +/// File format limitation exceeded: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic FileFormatLimitationExceeded = new Diagnostic(5003, nameof(FileFormatLimitationExceeded), CompositeFormat.Parse("File format limitation exceeded: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic FileFormatLimitationExceeded = new Diagnostic(5003, nameof(FileFormatLimitationExceeded), "File format limitation exceeded: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. + /// + /// +/// You cannot specify both a key file and container. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic CannotSpecifyBothKeyFileAndContainer = new Diagnostic(5004, nameof(CannotSpecifyBothKeyFileAndContainer), CompositeFormat.Parse("You cannot specify both a key file and container."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic CannotSpecifyBothKeyFileAndContainer = new Diagnostic(5004, nameof(CannotSpecifyBothKeyFileAndContainer), "You cannot specify both a key file and container.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'DelaySignRequiresKey' diagnostic. + /// + /// +/// You cannot delay sign without a key file or container. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic DelaySignRequiresKey = new Diagnostic(5005, nameof(DelaySignRequiresKey), CompositeFormat.Parse("You cannot delay sign without a key file or container."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic DelaySignRequiresKey = new Diagnostic(5005, nameof(DelaySignRequiresKey), "You cannot delay sign without a key file or container.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidStrongNameKeyPair' diagnostic. + /// + /// +/// Invalid key {arg0} specified. ("{arg1}") + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidStrongNameKeyPair = new Diagnostic(5006, nameof(InvalidStrongNameKeyPair), CompositeFormat.Parse("Invalid key {0} specified. (\"{1}\")"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic InvalidStrongNameKeyPair = new Diagnostic(5006, nameof(InvalidStrongNameKeyPair), "Invalid key {0} specified. (\"{1}\")", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ReferenceNotFound' diagnostic. + /// + /// +/// Reference not found: {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ReferenceNotFound = new Diagnostic(5007, nameof(ReferenceNotFound), CompositeFormat.Parse("Reference not found: {0}"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ReferenceNotFound = new Diagnostic(5007, nameof(ReferenceNotFound), "Reference not found: {0}", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'OptionsMustPreceedChildLevels' diagnostic. + /// + /// +/// You can only specify options before any child levels. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic OptionsMustPreceedChildLevels = new Diagnostic(5008, nameof(OptionsMustPreceedChildLevels), CompositeFormat.Parse("You can only specify options before any child levels."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic OptionsMustPreceedChildLevels = new Diagnostic(5008, nameof(OptionsMustPreceedChildLevels), "You can only specify options before any child levels.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnrecognizedTargetType' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -target option. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnrecognizedTargetType = new Diagnostic(5009, nameof(UnrecognizedTargetType), CompositeFormat.Parse("Invalid value \'{0}\' for -target option."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic UnrecognizedTargetType = new Diagnostic(5009, nameof(UnrecognizedTargetType), "Invalid value \'{0}\' for -target option.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnrecognizedPlatform' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -platform option. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnrecognizedPlatform = new Diagnostic(5010, nameof(UnrecognizedPlatform), CompositeFormat.Parse("Invalid value \'{0}\' for -platform option."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic UnrecognizedPlatform = new Diagnostic(5010, nameof(UnrecognizedPlatform), "Invalid value \'{0}\' for -platform option.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnrecognizedApartment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -apartment option. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnrecognizedApartment = new Diagnostic(5011, nameof(UnrecognizedApartment), CompositeFormat.Parse("Invalid value \'{0}\' for -apartment option."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic UnrecognizedApartment = new Diagnostic(5011, nameof(UnrecognizedApartment), "Invalid value \'{0}\' for -apartment option.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MissingFileSpecification' diagnostic. + /// + /// +/// Missing file specification for '{arg0}' option. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MissingFileSpecification = new Diagnostic(5012, nameof(MissingFileSpecification), CompositeFormat.Parse("Missing file specification for \'{0}\' option."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MissingFileSpecification = new Diagnostic(5012, nameof(MissingFileSpecification), "Missing file specification for \'{0}\' option.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'PathTooLong' diagnostic. + /// + /// +/// Path too long: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic PathTooLong = new Diagnostic(5013, nameof(PathTooLong), CompositeFormat.Parse("Path too long: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic PathTooLong = new Diagnostic(5013, nameof(PathTooLong), "Path too long: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'PathNotFound' diagnostic. + /// + /// +/// Path not found: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic PathNotFound = new Diagnostic(5014, nameof(PathNotFound), CompositeFormat.Parse("Path not found: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic PathNotFound = new Diagnostic(5014, nameof(PathNotFound), "Path not found: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidPath' diagnostic. + /// + /// +/// Invalid path: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidPath = new Diagnostic(5015, nameof(InvalidPath), CompositeFormat.Parse("Invalid path: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic InvalidPath = new Diagnostic(5015, nameof(InvalidPath), "Invalid path: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidOptionSyntax' diagnostic. + /// + /// +/// Invalid option: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidOptionSyntax = new Diagnostic(5016, nameof(InvalidOptionSyntax), CompositeFormat.Parse("Invalid option: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic InvalidOptionSyntax = new Diagnostic(5016, nameof(InvalidOptionSyntax), "Invalid option: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ExternalResourceNotFound' diagnostic. + /// + /// +/// External resource file does not exist: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ExternalResourceNotFound = new Diagnostic(5017, nameof(ExternalResourceNotFound), CompositeFormat.Parse("External resource file does not exist: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ExternalResourceNotFound = new Diagnostic(5017, nameof(ExternalResourceNotFound), "External resource file does not exist: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ExternalResourceNameInvalid' diagnostic. + /// + /// +/// External resource file may not include path specification: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ExternalResourceNameInvalid = new Diagnostic(5018, nameof(ExternalResourceNameInvalid), CompositeFormat.Parse("External resource file may not include path specification: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ExternalResourceNameInvalid = new Diagnostic(5018, nameof(ExternalResourceNameInvalid), "External resource file may not include path specification: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidVersionFormat' diagnostic. + /// + /// +/// Invalid version specified: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidVersionFormat = new Diagnostic(5019, nameof(InvalidVersionFormat), CompositeFormat.Parse("Invalid version specified: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic InvalidVersionFormat = new Diagnostic(5019, nameof(InvalidVersionFormat), "Invalid version specified: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidFileAlignment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -filealign option. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidFileAlignment = new Diagnostic(5020, nameof(InvalidFileAlignment), CompositeFormat.Parse("Invalid value \'{0}\' for -filealign option."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic InvalidFileAlignment = new Diagnostic(5020, nameof(InvalidFileAlignment), "Invalid value \'{0}\' for -filealign option.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ErrorWritingFile' diagnostic. + /// + /// +/// Unable to write file: {arg0}. ({arg1}) + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ErrorWritingFile = new Diagnostic(5021, nameof(ErrorWritingFile), CompositeFormat.Parse("Unable to write file: {0}. ({1})"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ErrorWritingFile = new Diagnostic(5021, nameof(ErrorWritingFile), "Unable to write file: {0}. ({1})", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnrecognizedOption' diagnostic. + /// + /// +/// Unrecognized option: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnrecognizedOption = new Diagnostic(5022, nameof(UnrecognizedOption), CompositeFormat.Parse("Unrecognized option: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic UnrecognizedOption = new Diagnostic(5022, nameof(UnrecognizedOption), "Unrecognized option: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'NoOutputFileSpecified' diagnostic. + /// + /// +/// No output file specified. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic NoOutputFileSpecified = new Diagnostic(5023, nameof(NoOutputFileSpecified), CompositeFormat.Parse("No output file specified."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic NoOutputFileSpecified = new Diagnostic(5023, nameof(NoOutputFileSpecified), "No output file specified.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. + /// + /// +/// Incompatible options: -target:module and -sharedclassloader cannot be combined. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic SharedClassLoaderCannotBeUsedOnModuleTarget = new Diagnostic(5024, nameof(SharedClassLoaderCannotBeUsedOnModuleTarget), CompositeFormat.Parse("Incompatible options: -target:module and -sharedclassloader cannot be combined."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic SharedClassLoaderCannotBeUsedOnModuleTarget = new Diagnostic(5024, nameof(SharedClassLoaderCannotBeUsedOnModuleTarget), "Incompatible options: -target:module and -sharedclassloader cannot be combined.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'RuntimeNotFound' diagnostic. + /// + /// +/// Unable to load runtime assembly. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic RuntimeNotFound = new Diagnostic(5025, nameof(RuntimeNotFound), CompositeFormat.Parse("Unable to load runtime assembly."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic RuntimeNotFound = new Diagnostic(5025, nameof(RuntimeNotFound), "Unable to load runtime assembly.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MainClassRequiresExe' diagnostic. + /// + /// +/// Main class cannot be specified for library or module. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MainClassRequiresExe = new Diagnostic(5026, nameof(MainClassRequiresExe), CompositeFormat.Parse("Main class cannot be specified for library or module."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MainClassRequiresExe = new Diagnostic(5026, nameof(MainClassRequiresExe), "Main class cannot be specified for library or module.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ExeRequiresMainClass' diagnostic. + /// + /// +/// No main method found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ExeRequiresMainClass = new Diagnostic(5027, nameof(ExeRequiresMainClass), CompositeFormat.Parse("No main method found."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ExeRequiresMainClass = new Diagnostic(5027, nameof(ExeRequiresMainClass), "No main method found.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'PropertiesRequireExe' diagnostic. + /// + /// +/// Properties cannot be specified for library or module. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic PropertiesRequireExe = new Diagnostic(5028, nameof(PropertiesRequireExe), CompositeFormat.Parse("Properties cannot be specified for library or module."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic PropertiesRequireExe = new Diagnostic(5028, nameof(PropertiesRequireExe), "Properties cannot be specified for library or module.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ModuleCannotHaveClassLoader' diagnostic. + /// + /// +/// Cannot specify assembly class loader for modules. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ModuleCannotHaveClassLoader = new Diagnostic(5029, nameof(ModuleCannotHaveClassLoader), CompositeFormat.Parse("Cannot specify assembly class loader for modules."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ModuleCannotHaveClassLoader = new Diagnostic(5029, nameof(ModuleCannotHaveClassLoader), "Cannot specify assembly class loader for modules.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ErrorParsingMapFile' diagnostic. + /// + /// +/// Unable to parse remap file: {arg0}. ({arg1}) + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ErrorParsingMapFile = new Diagnostic(5030, nameof(ErrorParsingMapFile), CompositeFormat.Parse("Unable to parse remap file: {0}. ({1})"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ErrorParsingMapFile = new Diagnostic(5030, nameof(ErrorParsingMapFile), "Unable to parse remap file: {0}. ({1})", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'BootstrapClassesMissing' diagnostic. + /// + /// +/// Bootstrap classes missing and core assembly not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic BootstrapClassesMissing = new Diagnostic(5031, nameof(BootstrapClassesMissing), CompositeFormat.Parse("Bootstrap classes missing and core assembly not found."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic BootstrapClassesMissing = new Diagnostic(5031, nameof(BootstrapClassesMissing), "Bootstrap classes missing and core assembly not found.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. + /// + /// +/// All referenced assemblies must be strong named, to be able to sign the output assembly. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic StrongNameRequiresStrongNamedRefs = new Diagnostic(5032, nameof(StrongNameRequiresStrongNamedRefs), CompositeFormat.Parse("All referenced assemblies must be strong named, to be able to sign the output ass" + + "embly."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic StrongNameRequiresStrongNamedRefs = new Diagnostic(5032, nameof(StrongNameRequiresStrongNamedRefs), "All referenced assemblies must be strong named, to be able to sign the output ass" + + "embly.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MainClassNotFound' diagnostic. + /// + /// +/// Main class not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MainClassNotFound = new Diagnostic(5033, nameof(MainClassNotFound), CompositeFormat.Parse("Main class not found."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MainClassNotFound = new Diagnostic(5033, nameof(MainClassNotFound), "Main class not found.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MainMethodNotFound' diagnostic. + /// + /// +/// Main method not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MainMethodNotFound = new Diagnostic(5034, nameof(MainMethodNotFound), CompositeFormat.Parse("Main method not found."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MainMethodNotFound = new Diagnostic(5034, nameof(MainMethodNotFound), "Main method not found.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnsupportedMainMethod' diagnostic. + /// + /// +/// Redirected main method not supported. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnsupportedMainMethod = new Diagnostic(5035, nameof(UnsupportedMainMethod), CompositeFormat.Parse("Redirected main method not supported."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic UnsupportedMainMethod = new Diagnostic(5035, nameof(UnsupportedMainMethod), "Redirected main method not supported.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ExternalMainNotAccessible' diagnostic. + /// + /// +/// External main method must be public and in a public class. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ExternalMainNotAccessible = new Diagnostic(5036, nameof(ExternalMainNotAccessible), CompositeFormat.Parse("External main method must be public and in a public class."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ExternalMainNotAccessible = new Diagnostic(5036, nameof(ExternalMainNotAccessible), "External main method must be public and in a public class.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ClassLoaderNotFound' diagnostic. + /// + /// +/// Custom assembly class loader class not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ClassLoaderNotFound = new Diagnostic(5037, nameof(ClassLoaderNotFound), CompositeFormat.Parse("Custom assembly class loader class not found."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ClassLoaderNotFound = new Diagnostic(5037, nameof(ClassLoaderNotFound), "Custom assembly class loader class not found.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ClassLoaderNotAccessible' diagnostic. + /// + /// +/// Custom assembly class loader class is not accessible. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ClassLoaderNotAccessible = new Diagnostic(5038, nameof(ClassLoaderNotAccessible), CompositeFormat.Parse("Custom assembly class loader class is not accessible."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ClassLoaderNotAccessible = new Diagnostic(5038, nameof(ClassLoaderNotAccessible), "Custom assembly class loader class is not accessible.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ClassLoaderIsAbstract' diagnostic. + /// + /// +/// Custom assembly class loader class is abstract. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ClassLoaderIsAbstract = new Diagnostic(5039, nameof(ClassLoaderIsAbstract), CompositeFormat.Parse("Custom assembly class loader class is abstract."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ClassLoaderIsAbstract = new Diagnostic(5039, nameof(ClassLoaderIsAbstract), "Custom assembly class loader class is abstract.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ClassLoaderNotClassLoader' diagnostic. + /// + /// +/// Custom assembly class loader class does not extend java.lang.ClassLoader. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ClassLoaderNotClassLoader = new Diagnostic(5040, nameof(ClassLoaderNotClassLoader), CompositeFormat.Parse("Custom assembly class loader class does not extend java.lang.ClassLoader."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ClassLoaderNotClassLoader = new Diagnostic(5040, nameof(ClassLoaderNotClassLoader), "Custom assembly class loader class does not extend java.lang.ClassLoader.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ClassLoaderConstructorMissing' diagnostic. + /// + /// +/// Custom assembly class loader constructor is missing. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ClassLoaderConstructorMissing = new Diagnostic(5041, nameof(ClassLoaderConstructorMissing), CompositeFormat.Parse("Custom assembly class loader constructor is missing."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ClassLoaderConstructorMissing = new Diagnostic(5041, nameof(ClassLoaderConstructorMissing), "Custom assembly class loader constructor is missing.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MapFileTypeNotFound' diagnostic. + /// + /// +/// Type '{arg0}' referenced in remap file was not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MapFileTypeNotFound = new Diagnostic(5042, nameof(MapFileTypeNotFound), CompositeFormat.Parse("Type \'{0}\' referenced in remap file was not found."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MapFileTypeNotFound = new Diagnostic(5042, nameof(MapFileTypeNotFound), "Type \'{0}\' referenced in remap file was not found.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MapFileClassNotFound' diagnostic. + /// + /// +/// Class '{arg0}' referenced in remap file was not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MapFileClassNotFound = new Diagnostic(5043, nameof(MapFileClassNotFound), CompositeFormat.Parse("Class \'{0}\' referenced in remap file was not found."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MapFileClassNotFound = new Diagnostic(5043, nameof(MapFileClassNotFound), "Class \'{0}\' referenced in remap file was not found.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MaximumErrorCountReached' diagnostic. + /// + /// +/// Maximum error count reached. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MaximumErrorCountReached = new Diagnostic(5044, nameof(MaximumErrorCountReached), CompositeFormat.Parse("Maximum error count reached."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MaximumErrorCountReached = new Diagnostic(5044, nameof(MaximumErrorCountReached), "Maximum error count reached.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'LinkageError' diagnostic. + /// + /// +/// Link error: {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic LinkageError = new Diagnostic(5045, nameof(LinkageError), CompositeFormat.Parse("Link error: {0}"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic LinkageError = new Diagnostic(5045, nameof(LinkageError), "Link error: {0}", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'RuntimeMismatch' diagnostic. + /// + /// +/// Referenced assembly {arg0} was compiled with an incompatible IKVM.Runtime version. Current runtime: {arg1}. Referenced assembly runtime: {arg2} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic RuntimeMismatch = new Diagnostic(5046, nameof(RuntimeMismatch), CompositeFormat.Parse("Referenced assembly {0} was compiled with an incompatible IKVM.Runtime version. C" + + "urrent runtime: {1}. Referenced assembly runtime: {2}"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic RuntimeMismatch = new Diagnostic(5046, nameof(RuntimeMismatch), "Referenced assembly {0} was compiled with an incompatible IKVM.Runtime version. C" + + "urrent runtime: {1}. Referenced assembly runtime: {2}", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'RuntimeMismatchStrongName' diagnostic. + /// + /// +/// + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic RuntimeMismatchStrongName = new Diagnostic(5047, nameof(RuntimeMismatchStrongName), CompositeFormat.Parse(""), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic RuntimeMismatchStrongName = new Diagnostic(5047, nameof(RuntimeMismatchStrongName), "", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'CoreClassesMissing' diagnostic. + /// + /// +/// Failed to find core classes in core library. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic CoreClassesMissing = new Diagnostic(5048, nameof(CoreClassesMissing), CompositeFormat.Parse("Failed to find core classes in core library."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic CoreClassesMissing = new Diagnostic(5048, nameof(CoreClassesMissing), "Failed to find core classes in core library.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'CriticalClassNotFound' diagnostic. + /// + /// +/// Unable to load critical class '{arg0}'. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic CriticalClassNotFound = new Diagnostic(5049, nameof(CriticalClassNotFound), CompositeFormat.Parse("Unable to load critical class \'{0}\'."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic CriticalClassNotFound = new Diagnostic(5049, nameof(CriticalClassNotFound), "Unable to load critical class \'{0}\'.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'AssemblyContainsDuplicateClassNames' diagnostic. + /// + /// +/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic AssemblyContainsDuplicateClassNames = new Diagnostic(5050, nameof(AssemblyContainsDuplicateClassNames), CompositeFormat.Parse("Type \'{0}\' and \'{1}\' both map to the same name \'{2}\'. ({3})"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic AssemblyContainsDuplicateClassNames = new Diagnostic(5050, nameof(AssemblyContainsDuplicateClassNames), "Type \'{0}\' and \'{1}\' both map to the same name \'{2}\'. ({3})", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. + /// + /// +/// CallerID.getCallerID() requires a HasCallerID annotation. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic CallerIDRequiresHasCallerIDAnnotation = new Diagnostic(5051, nameof(CallerIDRequiresHasCallerIDAnnotation), CompositeFormat.Parse("CallerID.getCallerID() requires a HasCallerID annotation."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic CallerIDRequiresHasCallerIDAnnotation = new Diagnostic(5051, nameof(CallerIDRequiresHasCallerIDAnnotation), "CallerID.getCallerID() requires a HasCallerID annotation.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'UnableToResolveInterface' diagnostic. + /// + /// +/// Unable to resolve interface '{arg0}' on type '{arg1}'. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic UnableToResolveInterface = new Diagnostic(5052, nameof(UnableToResolveInterface), CompositeFormat.Parse("Unable to resolve interface \'{0}\' on type \'{1}\'."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic UnableToResolveInterface = new Diagnostic(5052, nameof(UnableToResolveInterface), "Unable to resolve interface \'{0}\' on type \'{1}\'.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MissingBaseType' diagnostic. + /// + /// +/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MissingBaseType = new Diagnostic(5053, nameof(MissingBaseType), CompositeFormat.Parse("The base class or interface \'{0}\' in assembly \'{1}\' referenced by type \'{2}\' in \'" + + "{3}\' could not be resolved."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MissingBaseType = new Diagnostic(5053, nameof(MissingBaseType), "The base class or interface \'{0}\' in assembly \'{1}\' referenced by type \'{2}\' in \'" + + "{3}\' could not be resolved.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MissingBaseTypeReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MissingBaseTypeReference = new Diagnostic(5054, nameof(MissingBaseTypeReference), CompositeFormat.Parse("The type \'{0}\' is defined in an assembly that is not referenced. You must add a r" + + "eference to assembly \'{1}\'."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MissingBaseTypeReference = new Diagnostic(5054, nameof(MissingBaseTypeReference), "The type \'{0}\' is defined in an assembly that is not referenced. You must add a r" + + "eference to assembly \'{1}\'.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'FileNotFound' diagnostic. + /// + /// +/// File not found: {arg0}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic FileNotFound = new Diagnostic(5055, nameof(FileNotFound), CompositeFormat.Parse("File not found: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic FileNotFound = new Diagnostic(5055, nameof(FileNotFound), "File not found: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'RuntimeMethodMissing' diagnostic. + /// + /// +/// Runtime method '{arg0}' not found. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic RuntimeMethodMissing = new Diagnostic(5056, nameof(RuntimeMethodMissing), CompositeFormat.Parse("Runtime method \'{0}\' not found."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic RuntimeMethodMissing = new Diagnostic(5056, nameof(RuntimeMethodMissing), "Runtime method \'{0}\' not found.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'MapFileFieldNotFound' diagnostic. + /// + /// +/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic MapFileFieldNotFound = new Diagnostic(5057, nameof(MapFileFieldNotFound), CompositeFormat.Parse("Field \'{0}\' referenced in remap file was not found in class \'{1}\'."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic MapFileFieldNotFound = new Diagnostic(5057, nameof(MapFileFieldNotFound), "Field \'{0}\' referenced in remap file was not found in class \'{1}\'.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GhostInterfaceMethodMissing' diagnostic. + /// + /// +/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GhostInterfaceMethodMissing = new Diagnostic(5058, nameof(GhostInterfaceMethodMissing), CompositeFormat.Parse("Remapped class \'{0}\' does not implement ghost interface method. ({1}.{2}{3})"), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic GhostInterfaceMethodMissing = new Diagnostic(5058, nameof(GhostInterfaceMethodMissing), "Remapped class \'{0}\' does not implement ghost interface method. ({1}.{2}{3})", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'ModuleInitializerMethodRequirements' diagnostic. + /// + /// +/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic ModuleInitializerMethodRequirements = new Diagnostic(5059, nameof(ModuleInitializerMethodRequirements), CompositeFormat.Parse("Method \'{0}.{1}{2}\' does not meet the requirements of a module initializer."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic ModuleInitializerMethodRequirements = new Diagnostic(5059, nameof(ModuleInitializerMethodRequirements), "Method \'{0}.{1}{2}\' does not meet the requirements of a module initializer.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'InvalidZip' diagnostic. + /// + /// +/// Invalid zip: {name}. + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic InvalidZip = new Diagnostic(5060, nameof(InvalidZip), CompositeFormat.Parse("Invalid zip: {0}."), DiagnosticLevel.Fatal); +#else + public static readonly Diagnostic InvalidZip = new Diagnostic(5060, nameof(InvalidZip), "Invalid zip: {0}.", DiagnosticLevel.Fatal); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericRuntimeTrace' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericRuntimeTrace = new Diagnostic(6000, nameof(GenericRuntimeTrace), CompositeFormat.Parse("{0}"), DiagnosticLevel.Trace); +#else + public static readonly Diagnostic GenericRuntimeTrace = new Diagnostic(6000, nameof(GenericRuntimeTrace), "{0}", DiagnosticLevel.Trace); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericJniTrace' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericJniTrace = new Diagnostic(6001, nameof(GenericJniTrace), CompositeFormat.Parse("{0}"), DiagnosticLevel.Trace); +#else + public static readonly Diagnostic GenericJniTrace = new Diagnostic(6001, nameof(GenericJniTrace), "{0}", DiagnosticLevel.Trace); +#endif + + } + + partial record class Diagnostic + { + + /// + /// The 'GenericCompilerTrace' diagnostic. + /// + /// +/// {arg0} + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic GenericCompilerTrace = new Diagnostic(6002, nameof(GenericCompilerTrace), CompositeFormat.Parse("{0}"), DiagnosticLevel.Trace); +#else + public static readonly Diagnostic GenericCompilerTrace = new Diagnostic(6002, nameof(GenericCompilerTrace), "{0}", DiagnosticLevel.Trace); +#endif + + } + + +} diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.tt b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.tt new file mode 100644 index 0000000000..b854e5c36d --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.g.tt @@ -0,0 +1,61 @@ +<#@ template debug="false" hostspecific="true" language="C#" compilerOptions="/unsafe" #> +<#@ include file="Diagnostic.t4" #> +<#@ assembly name="System.CodeDom" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Memory" #> +<#@ assembly name="System.Buffers" #> +<#@ assembly name="Newtonsoft.Json" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Buffers" #> +<#@ import namespace="System.CodeDom" #> +<#@ import namespace="System.CodeDom.Compiler" #> +<#@ import namespace="System.Diagnostics" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Runtime.CompilerServices" #> +<#@ import namespace="System.Runtime.InteropServices" #> +<#@ import namespace="Newtonsoft.Json" #> +<#@ import namespace="Newtonsoft.Json.Linq" #> +<#@ output extension=".cs" #> +#nullable enable + +using System.Text; + +namespace IKVM.CoreLib.Diagnostics +{ + +<# +foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnostic.json")))) +{ + var desc = kvp.Value.Description; + if (string.IsNullOrWhiteSpace(desc)) + desc = $"The '{kvp.Key}' diagnostic."; + + var message = new List(); + foreach (var segment in CompositeFormat.Parse(kvp.Value.Message ?? "").Segments) + message.Add(segment.Literal != null ? segment.Literal : $"{{{kvp.Value.Args.FindIndex(i => i.Name == segment.Arg)}}}"); + +#> + partial record class Diagnostic + { + + /// + /// <#= desc #> + /// + /// +<#= Util.ToCommentString(kvp.Value.Message ?? "") #> + /// +#if NET8_0_OR_GREATER + public static readonly Diagnostic <#= kvp.Key #> = new Diagnostic(<#= kvp.Value.Id #>, nameof(<#= kvp.Key #>), CompositeFormat.Parse(<#= Util.ToStringLiteral(string.Join("", message)) #>), DiagnosticLevel.<#= kvp.Value.Level #>); +#else + public static readonly Diagnostic <#= kvp.Key #> = new Diagnostic(<#= kvp.Value.Id #>, nameof(<#= kvp.Key #>), <#= Util.ToStringLiteral(string.Join("", message)) #>, DiagnosticLevel.<#= kvp.Value.Level #>); +#endif + + } + +<# +} +#> + +} diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.json b/src/IKVM.CoreLib/Diagnostics/Diagnostic.json new file mode 100644 index 0000000000..aa04273b10 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.json @@ -0,0 +1,1667 @@ +{ + "MainMethodFound": { + "id": 1, + "level": "Informational", + "message": "Found main method in class \"{arg0}\".", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "OutputFileIs": { + "id": 2, + "level": "Informational", + "message": "Output file is \"{arg0}\".", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "AutoAddRef": { + "id": 3, + "level": "Informational", + "message": "Automatically adding reference to \"{arg0}\".", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "MainMethodFromManifest": { + "id": 4, + "level": "Informational", + "message": "Using main class \"{arg0}\" based on jar manifest.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericCompilerInfo": { + "id": 5, + "level": "Informational", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericClassLoadingInfo": { + "id": 6, + "level": "Informational", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericVerifierInfo": { + "id": 7, + "level": "Informational", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericRuntimeInfo": { + "id": 8, + "level": "Informational", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericJniInfo": { + "id": 9, + "level": "Informational", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "ClassNotFound": { + "id": 100, + "level": "Warning", + "message": "Class \"{arg0}\" not found.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "ClassFormatError": { + "id": 101, + "level": "Warning", + "message": "Unable to compile class \"{arg0}\". (class format error \"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "DuplicateClassName": { + "id": 102, + "level": "Warning", + "message": "Duplicate class name: \"{arg0}\".", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "IllegalAccessError": { + "id": 103, + "level": "Warning", + "message": "Unable to compile class \"{arg0}\". (illegal access error \"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "VerificationError": { + "id": 104, + "level": "Warning", + "message": "Unable to compile class \"{arg0}\". (verification error \"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "NoClassDefFoundError": { + "id": 105, + "level": "Warning", + "message": "Unable to compile class \"{arg0}\". (missing class \"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "GenericUnableToCompileError": { + "id": 106, + "level": "Warning", + "message": "Unable to compile class \"{arg0}\". (\"{arg1}\": \"{arg2}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "DuplicateResourceName": { + "id": 107, + "level": "Warning", + "message": "Skipping resource (name clash): \"{arg0}\"", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "SkippingReferencedClass": { + "id": 109, + "level": "Warning", + "message": "Skipping class: \"{arg0}\". (class is already available in referenced assembly \"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "NoJniRuntime": { + "id": 110, + "level": "Warning", + "message": "Unable to load runtime JNI assembly.", + "args": [] + }, + "EmittedNoClassDefFoundError": { + "id": 111, + "level": "Warning", + "message": "Emitted java.lang.NoClassDefFoundError in \"{arg0}\". (\"{arg1}\").", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedIllegalAccessError": { + "id": 112, + "level": "Warning", + "message": "Emitted java.lang.IllegalAccessError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedInstantiationError": { + "id": 113, + "level": "Warning", + "message": "Emitted java.lang.InstantiationError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedIncompatibleClassChangeError": { + "id": 114, + "level": "Warning", + "message": "Emitted java.lang.IncompatibleClassChangeError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedNoSuchFieldError": { + "id": 115, + "level": "Warning", + "message": "Emitted java.lang.NoSuchFieldError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedAbstractMethodError": { + "id": 116, + "level": "Warning", + "message": "Emitted java.lang.AbstractMethodError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedNoSuchMethodError": { + "id": 117, + "level": "Warning", + "message": "Emitted java.lang.NoSuchMethodError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedLinkageError": { + "id": 118, + "level": "Warning", + "message": "Emitted java.lang.LinkageError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedVerificationError": { + "id": 119, + "level": "Warning", + "message": "Emitted java.lang.VerificationError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "EmittedClassFormatError": { + "id": 120, + "level": "Warning", + "message": "Emitted java.lang.ClassFormatError in \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "InvalidCustomAttribute": { + "id": 121, + "level": "Warning", + "message": "Error emitting \"{arg0}\" custom attribute. (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "IgnoredCustomAttribute": { + "id": 122, + "level": "Warning", + "message": "Custom attribute \"{arg0}\" was ignored. (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "AssumeAssemblyVersionMatch": { + "id": 123, + "level": "Warning", + "message": "Assuming assembly reference \"{arg0}\" matches \"{arg1}\", you may need to supply runtime policy", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "InvalidDirectoryInLibOptionPath": { + "id": 124, + "level": "Warning", + "message": "Directory \"{arg0}\" specified in -lib option is not valid.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "InvalidDirectoryInLibEnvironmentPath": { + "id": 125, + "level": "Warning", + "message": "Directory \"{arg0}\" specified in LIB environment is not valid.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "LegacySearchRule": { + "id": 126, + "level": "Warning", + "message": "Found assembly \"{arg0}\" using legacy search rule, please append '.dll' to the reference.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "AssemblyLocationIgnored": { + "id": 127, + "level": "Warning", + "message": "Assembly \"{arg0}\" is ignored as previously loaded assembly \"{arg1}\" has the same identity \"{arg2}\".", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "InterfaceMethodCantBeInternal": { + "id": 128, + "level": "Warning", + "message": "Ignoring @ikvm.lang.Internal annotation on interface method. (\"{arg0}.{arg1}{arg2}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "DuplicateAssemblyReference": { + "id": 132, + "level": "Warning", + "message": "Duplicate assembly reference \"{arg0}\"", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "UnableToResolveType": { + "id": 133, + "level": "Warning", + "message": "Reference in \"{arg0}\" to type \"{arg1}\" claims it is defined in \"{arg2}\", but it could not be found.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "StubsAreDeprecated": { + "id": 134, + "level": "Warning", + "message": "Compiling stubs is deprecated. Please add a reference to assembly \"{arg0}\" instead.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "WrongClassName": { + "id": 135, + "level": "Warning", + "message": "Unable to compile \"{arg0}\" (wrong name: \"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "ReflectionCallerClassRequiresCallerID": { + "id": 136, + "level": "Warning", + "message": "Reflection.getCallerClass() called from non-CallerID method. (\"{arg0}.{arg1}{arg2}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "LegacyAssemblyAttributesFound": { + "id": 137, + "level": "Warning", + "message": "Legacy assembly attributes container found. Please use the -assemblyattributes: option.", + "args": [] + }, + "UnableToCreateLambdaFactory": { + "id": 138, + "level": "Warning", + "message": "Unable to create static lambda factory.", + "args": [] + }, + "UnknownWarning": { + "id": 999, + "level": "Warning", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "DuplicateIkvmLangProperty": { + "id": 139, + "level": "Warning", + "message": "Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "MalformedIkvmLangProperty": { + "id": 140, + "level": "Warning", + "message": "Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "GenericCompilerWarning": { + "id": 141, + "level": "Warning", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericClassLoadingWarning": { + "id": 142, + "level": "Warning", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericVerifierWarning": { + "id": 143, + "level": "Warning", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericRuntimeWarning": { + "id": 144, + "level": "Warning", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericJniWarning": { + "id": 145, + "level": "Warning", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "UnableToCreateProxy": { + "id": 4001, + "level": "Error", + "message": "Unable to create proxy \"{arg0}\". (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "DuplicateProxy": { + "id": 4002, + "level": "Error", + "message": "Duplicate proxy \"{arg0}\".", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "MapXmlUnableToResolveOpCode": { + "id": 4003, + "level": "Error", + "message": "Unable to resolve opcode in remap file: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "MapXmlError": { + "id": 4004, + "level": "Error", + "message": "Error in remap file: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "InputFileNotFound": { + "id": 4005, + "level": "Error", + "message": "Source file '{arg0}' not found.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "UnknownFileType": { + "id": 4006, + "level": "Error", + "message": "Unknown file type: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "UnknownElementInMapFile": { + "id": 4007, + "level": "Error", + "message": "Unknown element {arg0} in remap file, line {arg1}, column {arg2}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "UnknownAttributeInMapFile": { + "id": 4008, + "level": "Error", + "message": "Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "InvalidMemberNameInMapFile": { + "id": 4009, + "level": "Error", + "message": "Invalid {arg0} name '{arg1}' in remap file in class {arg2}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "InvalidMemberSignatureInMapFile": { + "id": 4010, + "level": "Error", + "message": "Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + }, + { + "name": "arg3", + "type": "string" + } + ] + }, + "InvalidPropertyNameInMapFile": { + "id": 4011, + "level": "Error", + "message": "Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + }, + { + "name": "arg3", + "type": "string" + } + ] + }, + "InvalidPropertySignatureInMapFile": { + "id": 4012, + "level": "Error", + "message": "Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + }, + { + "name": "arg3", + "type": "string" + } + ] + }, + "NonPrimaryAssemblyReference": { + "id": 4013, + "level": "Error", + "message": "Referenced assembly \"{arg0}\" is not the primary assembly of a shared class loader group, please reference primary assembly \"{arg1}\" instead.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "MissingType": { + "id": 4014, + "level": "Error", + "message": "Reference to type \"{arg0}\" claims it is defined in \"{arg1}\", but it could not be found.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "MissingReference": { + "id": 4015, + "level": "Error", + "message": "The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "CallerSensitiveOnUnsupportedMethod": { + "id": 4016, + "level": "Error", + "message": "CallerSensitive annotation on unsupported method. (\"{arg0}.{arg1}{arg2}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "RemappedTypeMissingDefaultInterfaceMethod": { + "id": 4017, + "level": "Error", + "message": "{arg0} does not implement default interface method {arg1}.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "GenericCompilerError": { + "id": 4018, + "level": "Error", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericClassLoadingError": { + "id": 4019, + "level": "Error", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericVerifierError": { + "id": 4020, + "level": "Error", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericRuntimeError": { + "id": 4021, + "level": "Error", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericJniError": { + "id": 4022, + "level": "Error", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "ExportingImportsNotSupported": { + "id": 4023, + "level": "Error", + "message": "Exporting previously imported assemblies is not supported.", + "args": [] + }, + "ResponseFileDepthExceeded": { + "id": 5000, + "level": "Fatal", + "message": "Response file nesting depth exceeded.", + "args": [] + }, + "ErrorReadingFile": { + "id": 5001, + "level": "Fatal", + "message": "Unable to read file: {arg0}. ({arg1})", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "NoTargetsFound": { + "id": 5002, + "level": "Fatal", + "message": "No targets found", + "args": [] + }, + "FileFormatLimitationExceeded": { + "id": 5003, + "level": "Fatal", + "message": "File format limitation exceeded: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "CannotSpecifyBothKeyFileAndContainer": { + "id": 5004, + "level": "Fatal", + "message": "You cannot specify both a key file and container.", + "args": [] + }, + "DelaySignRequiresKey": { + "id": 5005, + "level": "Fatal", + "message": "You cannot delay sign without a key file or container.", + "args": [] + }, + "InvalidStrongNameKeyPair": { + "id": 5006, + "level": "Fatal", + "message": "Invalid key {arg0} specified. (\"{arg1}\")", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "ReferenceNotFound": { + "id": 5007, + "level": "Fatal", + "message": "Reference not found: {arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "OptionsMustPreceedChildLevels": { + "id": 5008, + "level": "Fatal", + "message": "You can only specify options before any child levels.", + "args": [] + }, + "UnrecognizedTargetType": { + "id": 5009, + "level": "Fatal", + "message": "Invalid value '{arg0}' for -target option.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "UnrecognizedPlatform": { + "id": 5010, + "level": "Fatal", + "message": "Invalid value '{arg0}' for -platform option.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "UnrecognizedApartment": { + "id": 5011, + "level": "Fatal", + "message": "Invalid value '{arg0}' for -apartment option.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "MissingFileSpecification": { + "id": 5012, + "level": "Fatal", + "message": "Missing file specification for '{arg0}' option.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "PathTooLong": { + "id": 5013, + "level": "Fatal", + "message": "Path too long: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "PathNotFound": { + "id": 5014, + "level": "Fatal", + "message": "Path not found: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "InvalidPath": { + "id": 5015, + "level": "Fatal", + "message": "Invalid path: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "InvalidOptionSyntax": { + "id": 5016, + "level": "Fatal", + "message": "Invalid option: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "ExternalResourceNotFound": { + "id": 5017, + "level": "Fatal", + "message": "External resource file does not exist: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "ExternalResourceNameInvalid": { + "id": 5018, + "level": "Fatal", + "message": "External resource file may not include path specification: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "InvalidVersionFormat": { + "id": 5019, + "level": "Fatal", + "message": "Invalid version specified: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "InvalidFileAlignment": { + "id": 5020, + "level": "Fatal", + "message": "Invalid value '{arg0}' for -filealign option.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "ErrorWritingFile": { + "id": 5021, + "level": "Fatal", + "message": "Unable to write file: {arg0}. ({arg1})", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "UnrecognizedOption": { + "id": 5022, + "level": "Fatal", + "message": "Unrecognized option: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "NoOutputFileSpecified": { + "id": 5023, + "level": "Fatal", + "message": "No output file specified.", + "args": [] + }, + "SharedClassLoaderCannotBeUsedOnModuleTarget": { + "id": 5024, + "level": "Fatal", + "message": "Incompatible options: -target:module and -sharedclassloader cannot be combined.", + "args": [] + }, + "RuntimeNotFound": { + "id": 5025, + "level": "Fatal", + "message": "Unable to load runtime assembly.", + "args": [] + }, + "MainClassRequiresExe": { + "id": 5026, + "level": "Fatal", + "message": "Main class cannot be specified for library or module.", + "args": [] + }, + "ExeRequiresMainClass": { + "id": 5027, + "level": "Fatal", + "message": "No main method found.", + "args": [] + }, + "PropertiesRequireExe": { + "id": 5028, + "level": "Fatal", + "message": "Properties cannot be specified for library or module.", + "args": [] + }, + "ModuleCannotHaveClassLoader": { + "id": 5029, + "level": "Fatal", + "message": "Cannot specify assembly class loader for modules.", + "args": [] + }, + "ErrorParsingMapFile": { + "id": 5030, + "level": "Fatal", + "message": "Unable to parse remap file: {arg0}. ({arg1})", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "BootstrapClassesMissing": { + "id": 5031, + "level": "Fatal", + "message": "Bootstrap classes missing and core assembly not found.", + "args": [] + }, + "StrongNameRequiresStrongNamedRefs": { + "id": 5032, + "level": "Fatal", + "message": "All referenced assemblies must be strong named, to be able to sign the output assembly.", + "args": [] + }, + "MainClassNotFound": { + "id": 5033, + "level": "Fatal", + "message": "Main class not found.", + "args": [] + }, + "MainMethodNotFound": { + "id": 5034, + "level": "Fatal", + "message": "Main method not found.", + "args": [] + }, + "UnsupportedMainMethod": { + "id": 5035, + "level": "Fatal", + "message": "Redirected main method not supported.", + "args": [] + }, + "ExternalMainNotAccessible": { + "id": 5036, + "level": "Fatal", + "message": "External main method must be public and in a public class.", + "args": [] + }, + "ClassLoaderNotFound": { + "id": 5037, + "level": "Fatal", + "message": "Custom assembly class loader class not found.", + "args": [] + }, + "ClassLoaderNotAccessible": { + "id": 5038, + "level": "Fatal", + "message": "Custom assembly class loader class is not accessible.", + "args": [] + }, + "ClassLoaderIsAbstract": { + "id": 5039, + "level": "Fatal", + "message": "Custom assembly class loader class is abstract.", + "args": [] + }, + "ClassLoaderNotClassLoader": { + "id": 5040, + "level": "Fatal", + "message": "Custom assembly class loader class does not extend java.lang.ClassLoader.", + "args": [] + }, + "ClassLoaderConstructorMissing": { + "id": 5041, + "level": "Fatal", + "message": "Custom assembly class loader constructor is missing.", + "args": [] + }, + "MapFileTypeNotFound": { + "id": 5042, + "level": "Fatal", + "message": "Type '{arg0}' referenced in remap file was not found.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "MapFileClassNotFound": { + "id": 5043, + "level": "Fatal", + "message": "Class '{arg0}' referenced in remap file was not found.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "MaximumErrorCountReached": { + "id": 5044, + "level": "Fatal", + "message": "Maximum error count reached.", + "args": [] + }, + "LinkageError": { + "id": 5045, + "level": "Fatal", + "message": "Link error: {arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "RuntimeMismatch": { + "id": 5046, + "level": "Fatal", + "message": "Referenced assembly {arg0} was compiled with an incompatible IKVM.Runtime version. Current runtime: {arg1}. Referenced assembly runtime: {arg2}", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + } + ] + }, + "RuntimeMismatchStrongName": { + "id": 5047, + "level": "Fatal", + "args": [] + }, + "CoreClassesMissing": { + "id": 5048, + "level": "Fatal", + "message": "Failed to find core classes in core library.", + "args": [] + }, + "CriticalClassNotFound": { + "id": 5049, + "level": "Fatal", + "message": "Unable to load critical class '{arg0}'.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "AssemblyContainsDuplicateClassNames": { + "id": 5050, + "level": "Fatal", + "message": "Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3})", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + }, + { + "name": "arg3", + "type": "string" + } + ] + }, + "CallerIDRequiresHasCallerIDAnnotation": { + "id": 5051, + "level": "Fatal", + "message": "CallerID.getCallerID() requires a HasCallerID annotation.", + "args": [] + }, + "UnableToResolveInterface": { + "id": 5052, + "level": "Fatal", + "message": "Unable to resolve interface '{arg0}' on type '{arg1}'.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "MissingBaseType": { + "id": 5053, + "level": "Fatal", + "message": "The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + }, + { + "name": "arg3", + "type": "string" + } + ] + }, + "MissingBaseTypeReference": { + "id": 5054, + "level": "Fatal", + "message": "The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "FileNotFound": { + "id": 5055, + "level": "Fatal", + "message": "File not found: {arg0}.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "RuntimeMethodMissing": { + "id": 5056, + "level": "Fatal", + "message": "Runtime method '{arg0}' not found.", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "MapFileFieldNotFound": { + "id": 5057, + "level": "Fatal", + "message": "Field '{arg0}' referenced in remap file was not found in class '{arg1}'.", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + } + ] + }, + "GhostInterfaceMethodMissing": { + "id": 5058, + "level": "Fatal", + "message": "Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3})", + "args": [ + { + "name": "arg0", + "type": "string" + }, + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + }, + { + "name": "arg3", + "type": "string" + } + ] + }, + "ModuleInitializerMethodRequirements": { + "id": 5059, + "level": "Fatal", + "message": "Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer.", + "args": [ + { + "name": "arg1", + "type": "string" + }, + { + "name": "arg2", + "type": "string" + }, + { + "name": "arg3", + "type": "string" + } + ] + }, + "InvalidZip": { + "id": 5060, + "level": "Fatal", + "message": "Invalid zip: {name}.", + "args": [ + { + "name": "name", + "type": "string" + } + ] + }, + "GenericRuntimeTrace": { + "id": 6000, + "level": "Trace", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericJniTrace": { + "id": 6001, + "level": "Trace", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + }, + "GenericCompilerTrace": { + "id": 6002, + "level": "Trace", + "message": "{arg0}", + "args": [ + { + "name": "arg0", + "type": "string" + } + ] + } +} \ No newline at end of file diff --git a/src/IKVM.CoreLib/Diagnostics/Diagnostic.t4 b/src/IKVM.CoreLib/Diagnostics/Diagnostic.t4 new file mode 100644 index 0000000000..e7fe518497 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/Diagnostic.t4 @@ -0,0 +1,723 @@ +<#+ + +public class DiagnosticFile : Dictionary +{ + + public static DiagnosticFile Read(string path) + { + return JObject.Parse(File.ReadAllText(path)).ToObject(); + } + +} + +public class Diagnostic +{ + + [JsonProperty("id")] + public int Id { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("message")] + public string Message { get; set; } + + [JsonProperty("level")] + public string Level { get; set; } + + [JsonProperty("args")] + public List Args { get; set; } = []; + +} + +public class DiagnosticArg +{ + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + +} + +public static class Util +{ + + public static string ToStringLiteral(string input) + { + using (var writer = new StringWriter()) + { + using (var provider = CodeDomProvider.CreateProvider("CSharp")) + { + provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null); + return writer.ToString(); + } + } + } + + public static string ToCommentString(string input) + { + using (var writer = new StringWriter()) + { + using (var provider = CodeDomProvider.CreateProvider("CSharp")) + { + provider.GenerateCodeFromStatement(new CodeCommentStatement(input, true), writer, null); + return writer.ToString().Trim(); + } + } + } + +} + +static bool IsBetween(char c, char minInclusive, char maxInclusive) => (uint)(c - minInclusive) <= (uint)(maxInclusive - minInclusive); + +static bool IsAsciiDigit(char c) => IsBetween(c, '0', '9'); + +/// Represents a parsed composite format string. +[DebuggerDisplay("{Format}")] +public sealed class CompositeFormat +{ + /// The parsed segments that make up the composite format string. + /// + /// Every segment represents either a literal or a format hole, based on whether Literal + /// is non-null or ArgIndex is non-negative. + /// + internal readonly (string Literal, string Arg, int Alignment, string Format)[] _segments; + /// The sum of the lengths of all of the literals in . + internal readonly int _literalLength; + /// The number of segments in that represent format holes. + internal readonly int _formattedCount; + /// The number of args required to satisfy the format holes. + /// This is equal to one more than the largest index required by any format hole. + internal readonly int _argsRequired; + + public IReadOnlyList<(string Literal, string Arg, int Alignment, string Format)> Segments => _segments; + + /// Initializes the instance. + /// The composite format string that was parsed. + /// The parsed segments. + private CompositeFormat(string format, (string Literal, string Arg, int Alignment, string Format)[] segments) + { + // Store the format. + Debug.Assert(format is not null); + Format = format; + + // Store the segments. + Debug.Assert(segments is not null); + _segments = segments; + + // Compute derivative information from the segments. + int literalLength = 0, formattedCount = 0, argsRequired = 0; + foreach ((string Literal, string Arg, int Alignment, string Format) segment in segments) + { + Debug.Assert((segment.Literal is not null) ^ (segment.Arg is not null), "The segment should represent a literal or a format hole, but not both."); + + if (segment.Literal is string literal) + { + literalLength += literal.Length; // no concern about overflow as these were parsed out of a single string + } + else if (segment.Arg is not null) + { + formattedCount++; + argsRequired = Math.Max(argsRequired, formattedCount); + } + } + + // Store the derivative information. + Debug.Assert(literalLength >= 0); + Debug.Assert(formattedCount >= 0); + Debug.Assert(formattedCount == 0 || argsRequired > 0); + _literalLength = literalLength; + _formattedCount = formattedCount; + _argsRequired = argsRequired; + } + + /// Parse the composite format string . + /// The string to parse. + /// The parsed . + /// is null. + /// A format item in is invalid. + public static CompositeFormat Parse(string format) + { + if (format is null) + throw new ArgumentNullException(nameof(format)); + + var segments = new List<(string Literal, string Arg, int Alignment, string Format)>(); + if (!TryParseLiterals(format.AsSpan(), segments)) + { + throw new FormatException(); + } + + return new CompositeFormat(format, segments.ToArray()); + } + + /// Gets the original composite format string used to create this instance. + public string Format { get; } + + /// Gets the minimum number of arguments that must be passed to a formatting operation using this . + /// It's permissible to supply more arguments than this value, but it's an error to pass fewer. + public int MinimumArgumentCount => _argsRequired; + + public IReadOnlyList Args => _segments.Select(i => i.Arg).ToList(); + + /// Throws an exception if the specified number of arguments is fewer than the number required. + /// The number of arguments provided by the caller. + /// An insufficient number of arguments were provided. + internal void ValidateNumberOfArgs(int numArgs) + { + if (numArgs < _argsRequired) + { + throw new IndexOutOfRangeException(); + } + } + + /// Parse the composite format string into segments. + /// The format string. + /// The list into which to store the segments. + /// true if the format string can be parsed successfully; otherwise, false. + private static bool TryParseLiterals(ReadOnlySpan format, List<(string Literal, string Arg, int Alignment, string Format)> segments) + { + // This parsing logic is copied from string.Format. It's the same code modified to not format + // as part of parsing and instead store the parsed literals and argument specifiers (alignment + // and format) for later use. + + // Rather than parsing directly into the segments list, literals are parsed into a reusable builder. + // Due to the nature of the parsing logic copied from string.Format, and our desire not to veer from + // it significantly in order to maintain compatibility and accidental regression, multiple literals + // next to each other might be parsed separately due to braces in between them. This builder then + // allows us to merge those segments back together easily prior to their being appended to the list. + var vsb = new ValueStringBuilder(stackalloc char[256]); + + // Repeatedly find the next hole and process it. + int pos = 0; + char ch; + while (true) + { + // Skip until either the end of the input or the first unescaped opening brace, whichever comes first. + // Along the way we need to also unescape escaped closing braces. + while (true) + { + // Find the next brace. If there isn't one, the remainder of the input is text to be appended, and we're done. + ReadOnlySpan remainder = format.Slice(pos); + int countUntilNextBrace = remainder.IndexOfAny('{', '}'); + if (countUntilNextBrace < 0) + { + vsb.Append(remainder); + segments.Add((vsb.ToString(), null, 0, null)); + return true; + } + + // Append the text until the brace. + vsb.Append(remainder.Slice(0, countUntilNextBrace)); + pos += countUntilNextBrace; + + // Get the brace. It must be followed by another character, either a copy of itself in the case of being + // escaped, or an arbitrary character that's part of the hole in the case of an opening brace. + char brace = format[pos]; + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + if (brace == ch) + { + vsb.Append(ch); + pos++; + continue; + } + + // This wasn't an escape, so it must be an opening brace. + if (brace != '{') + { + goto FailureUnexpectedClosingBrace; + } + + // Proceed to parse the hole. + segments.Add((vsb.ToString(), null, 0, null)); + vsb.Length = 0; + break; + } + + // We're now positioned just after the opening brace of an argument hole, which consists of + // an opening brace, an index, an optional width preceded by a comma, and an optional format + // preceded by a colon, with arbitrary amounts of spaces throughout. + int width = 0; + string itemFormat = null; // used if itemFormat is null + + // First up is the index parameter, which is of the form: + // at least on digit + // optional any number of spaces + // We've already read the first digit into ch. + Debug.Assert(format[pos - 1] == '{'); + Debug.Assert(ch != '{'); + string index = ch.ToString(); + if (char.IsLetterOrDigit(ch) == false) + { + goto FailureExpectedAsciiDigit; + } + + // Common case is a single digit index followed by a closing brace. If it's not a closing brace, + // proceed to finish parsing the full hole format. + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + if (ch != '}') + { + // Continue consuming optional additional digits. + while (char.IsLetterOrDigit(ch)) + { + index += ch; + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + } + + // Consume optional whitespace. + while (ch == ' ') + { + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + } + + // Parse the optional alignment, which is of the form: + // comma + // optional any number of spaces + // optional - + // at least one digit + // optional any number of spaces + if (ch == ',') + { + // Consume optional whitespace. + do + { + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + } + while (ch == ' '); + + // Consume an optional minus sign indicating left alignment. + int leftJustify = 1; + if (ch == '-') + { + leftJustify = -1; + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + } + + // Parse alignment digits. The read character must be a digit. + width = ch - '0'; + if ((uint)width >= 10u) + { + goto FailureExpectedAsciiDigit; + } + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + while (char.IsLetterOrDigit(ch)) + { + width = width * 10 + ch - '0'; + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + } + width *= leftJustify; + + // Consume optional whitespace + while (ch == ' ') + { + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + } + } + + // The next character needs to either be a closing brace for the end of the hole, + // or a colon indicating the start of the format. + if (ch != '}') + { + if (ch != ':') + { + // Unexpected character + goto FailureUnclosedFormatItem; + } + + // Search for the closing brace; everything in between is the format, + // but opening braces aren't allowed. + int startingPos = pos; + while (true) + { + if (!TryMoveNext(format, ref pos, out ch)) + { + goto FailureUnclosedFormatItem; + } + + if (ch == '}') + { + // Argument hole closed + break; + } + + if (ch == '{') + { + // Braces inside the argument hole are not supported + goto FailureUnclosedFormatItem; + } + } + + startingPos++; + itemFormat = format.Slice(startingPos, pos - startingPos).ToString(); + } + } + + Debug.Assert(format[pos] == '}'); + pos++; + + segments.Add((null, index, width, itemFormat)); + + // Continue parsing the rest of the format string. + } + + FailureUnexpectedClosingBrace: + return false; + + FailureUnclosedFormatItem: + return false; + + FailureExpectedAsciiDigit: + return false; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool TryMoveNext(ReadOnlySpan format, ref int pos, out char nextChar) + { + pos++; + if ((uint)pos >= (uint)format.Length) + { + nextChar = '\0'; + return false; + } + + nextChar = format[pos]; + return true; + } + } +} + + +internal ref partial struct ValueStringBuilder +{ + private char[] _arrayToReturnToPool; + private Span _chars; + private int _pos; + + public ValueStringBuilder(Span initialBuffer) + { + _arrayToReturnToPool = null; + _chars = initialBuffer; + _pos = 0; + } + + public ValueStringBuilder(int initialCapacity) + { + _arrayToReturnToPool = ArrayPool.Shared.Rent(initialCapacity); + _chars = _arrayToReturnToPool; + _pos = 0; + } + + public int Length + { + get => _pos; + set + { + Debug.Assert(value >= 0); + Debug.Assert(value <= _chars.Length); + _pos = value; + } + } + + public int Capacity => _chars.Length; + + public void EnsureCapacity(int capacity) + { + // This is not expected to be called this with negative capacity + Debug.Assert(capacity >= 0); + + // If the caller has a bug and calls this with negative capacity, make sure to call Grow to throw an exception. + if ((uint)capacity > (uint)_chars.Length) + Grow(capacity - _pos); + } + + /// + /// Get a pinnable reference to the builder. + /// Does not ensure there is a null char after + /// This overload is pattern matched in the C# 7.3+ compiler so you can omit + /// the explicit method call, and write eg "fixed (char* c = builder)" + /// + public ref char GetPinnableReference() + { + return ref MemoryMarshal.GetReference(_chars); + } + + /// + /// Get a pinnable reference to the builder. + /// + /// Ensures that the builder has a null char after + public ref char GetPinnableReference(bool terminate) + { + if (terminate) + { + EnsureCapacity(Length + 1); + _chars[Length] = '\0'; + } + return ref MemoryMarshal.GetReference(_chars); + } + + public ref char this[int index] + { + get + { + Debug.Assert(index < _pos); + return ref _chars[index]; + } + } + + public override string ToString() + { + string s = _chars.Slice(0, _pos).ToString(); + Dispose(); + return s; + } + + /// Returns the underlying storage of the builder. + public Span RawChars => _chars; + + /// + /// Returns a span around the contents of the builder. + /// + /// Ensures that the builder has a null char after + public ReadOnlySpan AsSpan(bool terminate) + { + if (terminate) + { + EnsureCapacity(Length + 1); + _chars[Length] = '\0'; + } + return _chars.Slice(0, _pos); + } + + public ReadOnlySpan AsSpan() => _chars.Slice(0, _pos); + public ReadOnlySpan AsSpan(int start) => _chars.Slice(start, _pos - start); + public ReadOnlySpan AsSpan(int start, int length) => _chars.Slice(start, length); + + public bool TryCopyTo(Span destination, out int charsWritten) + { + if (_chars.Slice(0, _pos).TryCopyTo(destination)) + { + charsWritten = _pos; + Dispose(); + return true; + } + else + { + charsWritten = 0; + Dispose(); + return false; + } + } + + public void Insert(int index, char value, int count) + { + if (_pos > _chars.Length - count) + { + Grow(count); + } + + int remaining = _pos - index; + _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); + _chars.Slice(index, count).Fill(value); + _pos += count; + } + + public void Insert(int index, string s) + { + if (s == null) + { + return; + } + + int count = s.Length; + + if (_pos > (_chars.Length - count)) + { + Grow(count); + } + + int remaining = _pos - index; + _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); + s +#if !NET + .AsSpan() +#endif + .CopyTo(_chars.Slice(index)); + _pos += count; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(char c) + { + int pos = _pos; + Span chars = _chars; + if ((uint)pos < (uint)chars.Length) + { + chars[pos] = c; + _pos = pos + 1; + } + else + { + GrowAndAppend(c); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Append(string s) + { + if (s == null) + { + return; + } + + int pos = _pos; + if (s.Length == 1 && (uint)pos < (uint)_chars.Length) // very common case, e.g. appending strings from NumberFormatInfo like separators, percent symbols, etc. + { + _chars[pos] = s[0]; + _pos = pos + 1; + } + else + { + AppendSlow(s); + } + } + + private void AppendSlow(string s) + { + int pos = _pos; + if (pos > _chars.Length - s.Length) + { + Grow(s.Length); + } + + s +#if !NET + .AsSpan() +#endif + .CopyTo(_chars.Slice(pos)); + _pos += s.Length; + } + + public void Append(char c, int count) + { + if (_pos > _chars.Length - count) + { + Grow(count); + } + + Span dst = _chars.Slice(_pos, count); + for (int i = 0; i < dst.Length; i++) + { + dst[i] = c; + } + _pos += count; + } + + public void Append(scoped ReadOnlySpan value) + { + int pos = _pos; + if (pos > _chars.Length - value.Length) + { + Grow(value.Length); + } + + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span AppendSpan(int length) + { + int origPos = _pos; + if (origPos > _chars.Length - length) + { + Grow(length); + } + + _pos = origPos + length; + return _chars.Slice(origPos, length); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowAndAppend(char c) + { + Grow(1); + Append(c); + } + + /// + /// Resize the internal buffer either by doubling current buffer size or + /// by adding to + /// whichever is greater. + /// + /// + /// Number of chars requested beyond current position. + /// + [MethodImpl(MethodImplOptions.NoInlining)] + private void Grow(int additionalCapacityBeyondPos) + { + Debug.Assert(additionalCapacityBeyondPos > 0); + Debug.Assert(_pos > _chars.Length - additionalCapacityBeyondPos, "Grow called incorrectly, no resize is needed."); + + const uint ArrayMaxLength = 0x7FFFFFC7; // same as Array.MaxLength + + // Increase to at least the required size (_pos + additionalCapacityBeyondPos), but try + // to double the size if possible, bounding the doubling to not go beyond the max array length. + int newCapacity = (int)Math.Max( + (uint)(_pos + additionalCapacityBeyondPos), + Math.Min((uint)_chars.Length * 2, ArrayMaxLength)); + + // Make sure to let Rent throw an exception if the caller has a bug and the desired capacity is negative. + // This could also go negative if the actual required length wraps around. + char[] poolArray = ArrayPool.Shared.Rent(newCapacity); + + _chars.Slice(0, _pos).CopyTo(poolArray); + + char[] toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = poolArray; + if (toReturn != null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + char[] toReturn = _arrayToReturnToPool; + this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again + if (toReturn != null) + { + ArrayPool.Shared.Return(toReturn); + } + } + +} + +#> \ No newline at end of file diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs new file mode 100644 index 0000000000..14edfb0250 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.cs @@ -0,0 +1,34 @@ +using System; + +namespace IKVM.CoreLib.Diagnostics +{ + + readonly ref partial struct DiagnosticEvent(Diagnostic Diagnostic, ReadOnlySpan Args) + { + + /// + /// Gets the this is an event of. + /// + public readonly Diagnostic Diagnostic = Diagnostic; + + /// + /// Gets the arguments of the event. + /// + public readonly ReadOnlySpan Args = Args; + + /// + /// Formats the diagnostic event message. + /// + /// + public override string ToString() + { +#if NET8_0_OR_GREATER + return string.Format(null, Diagnostic.Message, Args); +#else + return string.Format(Diagnostic.Message, Args.ToArray()); +#endif + } + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs new file mode 100644 index 0000000000..413ca1a210 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.cs @@ -0,0 +1,1125 @@ +#nullable enable + +using System.Text; + +namespace IKVM.CoreLib.Diagnostics +{ + + partial struct DiagnosticEvent + { + + /// + /// The 'MainMethodFound' diagnostic. + /// + /// +/// Found main method in class "{arg0}". + /// + public static DiagnosticEvent MainMethodFound(string arg0) => Diagnostic.MainMethodFound.Event((object?[])[arg0]); + + /// + /// The 'OutputFileIs' diagnostic. + /// + /// +/// Output file is "{arg0}". + /// + public static DiagnosticEvent OutputFileIs(string arg0) => Diagnostic.OutputFileIs.Event((object?[])[arg0]); + + /// + /// The 'AutoAddRef' diagnostic. + /// + /// +/// Automatically adding reference to "{arg0}". + /// + public static DiagnosticEvent AutoAddRef(string arg0) => Diagnostic.AutoAddRef.Event((object?[])[arg0]); + + /// + /// The 'MainMethodFromManifest' diagnostic. + /// + /// +/// Using main class "{arg0}" based on jar manifest. + /// + public static DiagnosticEvent MainMethodFromManifest(string arg0) => Diagnostic.MainMethodFromManifest.Event((object?[])[arg0]); + + /// + /// The 'GenericCompilerInfo' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericCompilerInfo(string arg0) => Diagnostic.GenericCompilerInfo.Event((object?[])[arg0]); + + /// + /// The 'GenericClassLoadingInfo' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericClassLoadingInfo(string arg0) => Diagnostic.GenericClassLoadingInfo.Event((object?[])[arg0]); + + /// + /// The 'GenericVerifierInfo' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericVerifierInfo(string arg0) => Diagnostic.GenericVerifierInfo.Event((object?[])[arg0]); + + /// + /// The 'GenericRuntimeInfo' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericRuntimeInfo(string arg0) => Diagnostic.GenericRuntimeInfo.Event((object?[])[arg0]); + + /// + /// The 'GenericJniInfo' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericJniInfo(string arg0) => Diagnostic.GenericJniInfo.Event((object?[])[arg0]); + + /// + /// The 'ClassNotFound' diagnostic. + /// + /// +/// Class "{arg0}" not found. + /// + public static DiagnosticEvent ClassNotFound(string arg0) => Diagnostic.ClassNotFound.Event((object?[])[arg0]); + + /// + /// The 'ClassFormatError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (class format error "{arg1}") + /// + public static DiagnosticEvent ClassFormatError(string arg0, string arg1) => Diagnostic.ClassFormatError.Event((object?[])[arg0, arg1]); + + /// + /// The 'DuplicateClassName' diagnostic. + /// + /// +/// Duplicate class name: "{arg0}". + /// + public static DiagnosticEvent DuplicateClassName(string arg0) => Diagnostic.DuplicateClassName.Event((object?[])[arg0]); + + /// + /// The 'IllegalAccessError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (illegal access error "{arg1}") + /// + public static DiagnosticEvent IllegalAccessError(string arg0, string arg1) => Diagnostic.IllegalAccessError.Event((object?[])[arg0, arg1]); + + /// + /// The 'VerificationError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (verification error "{arg1}") + /// + public static DiagnosticEvent VerificationError(string arg0, string arg1) => Diagnostic.VerificationError.Event((object?[])[arg0, arg1]); + + /// + /// The 'NoClassDefFoundError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (missing class "{arg1}") + /// + public static DiagnosticEvent NoClassDefFoundError(string arg0, string arg1) => Diagnostic.NoClassDefFoundError.Event((object?[])[arg0, arg1]); + + /// + /// The 'GenericUnableToCompileError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") + /// + public static DiagnosticEvent GenericUnableToCompileError(string arg0, string arg1, string arg2) => Diagnostic.GenericUnableToCompileError.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'DuplicateResourceName' diagnostic. + /// + /// +/// Skipping resource (name clash): "{arg0}" + /// + public static DiagnosticEvent DuplicateResourceName(string arg0) => Diagnostic.DuplicateResourceName.Event((object?[])[arg0]); + + /// + /// The 'SkippingReferencedClass' diagnostic. + /// + /// +/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") + /// + public static DiagnosticEvent SkippingReferencedClass(string arg0, string arg1) => Diagnostic.SkippingReferencedClass.Event((object?[])[arg0, arg1]); + + /// + /// The 'NoJniRuntime' diagnostic. + /// + /// +/// Unable to load runtime JNI assembly. + /// + public static DiagnosticEvent NoJniRuntime() => Diagnostic.NoJniRuntime.Event((object?[])[]); + + /// + /// The 'EmittedNoClassDefFoundError' diagnostic. + /// + /// +/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). + /// + public static DiagnosticEvent EmittedNoClassDefFoundError(string arg0, string arg1) => Diagnostic.EmittedNoClassDefFoundError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedIllegalAccessError' diagnostic. + /// + /// +/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedIllegalAccessError(string arg0, string arg1) => Diagnostic.EmittedIllegalAccessError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedInstantiationError' diagnostic. + /// + /// +/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedInstantiationError(string arg0, string arg1) => Diagnostic.EmittedInstantiationError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedIncompatibleClassChangeError' diagnostic. + /// + /// +/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedIncompatibleClassChangeError(string arg0, string arg1) => Diagnostic.EmittedIncompatibleClassChangeError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedNoSuchFieldError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedNoSuchFieldError(string arg0, string arg1) => Diagnostic.EmittedNoSuchFieldError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedAbstractMethodError' diagnostic. + /// + /// +/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedAbstractMethodError(string arg0, string arg1) => Diagnostic.EmittedAbstractMethodError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedNoSuchMethodError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedNoSuchMethodError(string arg0, string arg1) => Diagnostic.EmittedNoSuchMethodError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedLinkageError' diagnostic. + /// + /// +/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedLinkageError(string arg0, string arg1) => Diagnostic.EmittedLinkageError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedVerificationError' diagnostic. + /// + /// +/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedVerificationError(string arg0, string arg1) => Diagnostic.EmittedVerificationError.Event((object?[])[arg0, arg1]); + + /// + /// The 'EmittedClassFormatError' diagnostic. + /// + /// +/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent EmittedClassFormatError(string arg0, string arg1) => Diagnostic.EmittedClassFormatError.Event((object?[])[arg0, arg1]); + + /// + /// The 'InvalidCustomAttribute' diagnostic. + /// + /// +/// Error emitting "{arg0}" custom attribute. ("{arg1}") + /// + public static DiagnosticEvent InvalidCustomAttribute(string arg0, string arg1) => Diagnostic.InvalidCustomAttribute.Event((object?[])[arg0, arg1]); + + /// + /// The 'IgnoredCustomAttribute' diagnostic. + /// + /// +/// Custom attribute "{arg0}" was ignored. ("{arg1}") + /// + public static DiagnosticEvent IgnoredCustomAttribute(string arg0, string arg1) => Diagnostic.IgnoredCustomAttribute.Event((object?[])[arg0, arg1]); + + /// + /// The 'AssumeAssemblyVersionMatch' diagnostic. + /// + /// +/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy + /// + public static DiagnosticEvent AssumeAssemblyVersionMatch(string arg0, string arg1) => Diagnostic.AssumeAssemblyVersionMatch.Event((object?[])[arg0, arg1]); + + /// + /// The 'InvalidDirectoryInLibOptionPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in -lib option is not valid. + /// + public static DiagnosticEvent InvalidDirectoryInLibOptionPath(string arg0) => Diagnostic.InvalidDirectoryInLibOptionPath.Event((object?[])[arg0]); + + /// + /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in LIB environment is not valid. + /// + public static DiagnosticEvent InvalidDirectoryInLibEnvironmentPath(string arg0) => Diagnostic.InvalidDirectoryInLibEnvironmentPath.Event((object?[])[arg0]); + + /// + /// The 'LegacySearchRule' diagnostic. + /// + /// +/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. + /// + public static DiagnosticEvent LegacySearchRule(string arg0) => Diagnostic.LegacySearchRule.Event((object?[])[arg0]); + + /// + /// The 'AssemblyLocationIgnored' diagnostic. + /// + /// +/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". + /// + public static DiagnosticEvent AssemblyLocationIgnored(string arg0, string arg1, string arg2) => Diagnostic.AssemblyLocationIgnored.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'InterfaceMethodCantBeInternal' diagnostic. + /// + /// +/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") + /// + public static DiagnosticEvent InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2) => Diagnostic.InterfaceMethodCantBeInternal.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'DuplicateAssemblyReference' diagnostic. + /// + /// +/// Duplicate assembly reference "{arg0}" + /// + public static DiagnosticEvent DuplicateAssemblyReference(string arg0) => Diagnostic.DuplicateAssemblyReference.Event((object?[])[arg0]); + + /// + /// The 'UnableToResolveType' diagnostic. + /// + /// +/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. + /// + public static DiagnosticEvent UnableToResolveType(string arg0, string arg1, string arg2) => Diagnostic.UnableToResolveType.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'StubsAreDeprecated' diagnostic. + /// + /// +/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. + /// + public static DiagnosticEvent StubsAreDeprecated(string arg0) => Diagnostic.StubsAreDeprecated.Event((object?[])[arg0]); + + /// + /// The 'WrongClassName' diagnostic. + /// + /// +/// Unable to compile "{arg0}" (wrong name: "{arg1}") + /// + public static DiagnosticEvent WrongClassName(string arg0, string arg1) => Diagnostic.WrongClassName.Event((object?[])[arg0, arg1]); + + /// + /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. + /// + /// +/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") + /// + public static DiagnosticEvent ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2) => Diagnostic.ReflectionCallerClassRequiresCallerID.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'LegacyAssemblyAttributesFound' diagnostic. + /// + /// +/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. + /// + public static DiagnosticEvent LegacyAssemblyAttributesFound() => Diagnostic.LegacyAssemblyAttributesFound.Event((object?[])[]); + + /// + /// The 'UnableToCreateLambdaFactory' diagnostic. + /// + /// +/// Unable to create static lambda factory. + /// + public static DiagnosticEvent UnableToCreateLambdaFactory() => Diagnostic.UnableToCreateLambdaFactory.Event((object?[])[]); + + /// + /// The 'UnknownWarning' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent UnknownWarning(string arg0) => Diagnostic.UnknownWarning.Event((object?[])[arg0]); + + /// + /// The 'DuplicateIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// + public static DiagnosticEvent DuplicateIkvmLangProperty(string arg0, string arg1) => Diagnostic.DuplicateIkvmLangProperty.Event((object?[])[arg0, arg1]); + + /// + /// The 'MalformedIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// + public static DiagnosticEvent MalformedIkvmLangProperty(string arg0, string arg1) => Diagnostic.MalformedIkvmLangProperty.Event((object?[])[arg0, arg1]); + + /// + /// The 'GenericCompilerWarning' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericCompilerWarning(string arg0) => Diagnostic.GenericCompilerWarning.Event((object?[])[arg0]); + + /// + /// The 'GenericClassLoadingWarning' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericClassLoadingWarning(string arg0) => Diagnostic.GenericClassLoadingWarning.Event((object?[])[arg0]); + + /// + /// The 'GenericVerifierWarning' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericVerifierWarning(string arg0) => Diagnostic.GenericVerifierWarning.Event((object?[])[arg0]); + + /// + /// The 'GenericRuntimeWarning' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericRuntimeWarning(string arg0) => Diagnostic.GenericRuntimeWarning.Event((object?[])[arg0]); + + /// + /// The 'GenericJniWarning' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericJniWarning(string arg0) => Diagnostic.GenericJniWarning.Event((object?[])[arg0]); + + /// + /// The 'UnableToCreateProxy' diagnostic. + /// + /// +/// Unable to create proxy "{arg0}". ("{arg1}") + /// + public static DiagnosticEvent UnableToCreateProxy(string arg0, string arg1) => Diagnostic.UnableToCreateProxy.Event((object?[])[arg0, arg1]); + + /// + /// The 'DuplicateProxy' diagnostic. + /// + /// +/// Duplicate proxy "{arg0}". + /// + public static DiagnosticEvent DuplicateProxy(string arg0) => Diagnostic.DuplicateProxy.Event((object?[])[arg0]); + + /// + /// The 'MapXmlUnableToResolveOpCode' diagnostic. + /// + /// +/// Unable to resolve opcode in remap file: {arg0}. + /// + public static DiagnosticEvent MapXmlUnableToResolveOpCode(string arg0) => Diagnostic.MapXmlUnableToResolveOpCode.Event((object?[])[arg0]); + + /// + /// The 'MapXmlError' diagnostic. + /// + /// +/// Error in remap file: {arg0}. + /// + public static DiagnosticEvent MapXmlError(string arg0) => Diagnostic.MapXmlError.Event((object?[])[arg0]); + + /// + /// The 'InputFileNotFound' diagnostic. + /// + /// +/// Source file '{arg0}' not found. + /// + public static DiagnosticEvent InputFileNotFound(string arg0) => Diagnostic.InputFileNotFound.Event((object?[])[arg0]); + + /// + /// The 'UnknownFileType' diagnostic. + /// + /// +/// Unknown file type: {arg0}. + /// + public static DiagnosticEvent UnknownFileType(string arg0) => Diagnostic.UnknownFileType.Event((object?[])[arg0]); + + /// + /// The 'UnknownElementInMapFile' diagnostic. + /// + /// +/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. + /// + public static DiagnosticEvent UnknownElementInMapFile(string arg0, string arg1, string arg2) => Diagnostic.UnknownElementInMapFile.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'UnknownAttributeInMapFile' diagnostic. + /// + /// +/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. + /// + public static DiagnosticEvent UnknownAttributeInMapFile(string arg0, string arg1, string arg2) => Diagnostic.UnknownAttributeInMapFile.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'InvalidMemberNameInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. + /// + public static DiagnosticEvent InvalidMemberNameInMapFile(string arg0, string arg1, string arg2) => Diagnostic.InvalidMemberNameInMapFile.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'InvalidMemberSignatureInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. + /// + public static DiagnosticEvent InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3) => Diagnostic.InvalidMemberSignatureInMapFile.Event((object?[])[arg0, arg1, arg2, arg3]); + + /// + /// The 'InvalidPropertyNameInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. + /// + public static DiagnosticEvent InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3) => Diagnostic.InvalidPropertyNameInMapFile.Event((object?[])[arg0, arg1, arg2, arg3]); + + /// + /// The 'InvalidPropertySignatureInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. + /// + public static DiagnosticEvent InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3) => Diagnostic.InvalidPropertySignatureInMapFile.Event((object?[])[arg0, arg1, arg2, arg3]); + + /// + /// The 'NonPrimaryAssemblyReference' diagnostic. + /// + /// +/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. + /// + public static DiagnosticEvent NonPrimaryAssemblyReference(string arg0, string arg1) => Diagnostic.NonPrimaryAssemblyReference.Event((object?[])[arg0, arg1]); + + /// + /// The 'MissingType' diagnostic. + /// + /// +/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. + /// + public static DiagnosticEvent MissingType(string arg0, string arg1) => Diagnostic.MissingType.Event((object?[])[arg0, arg1]); + + /// + /// The 'MissingReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. + /// + public static DiagnosticEvent MissingReference(string arg0, string arg1) => Diagnostic.MissingReference.Event((object?[])[arg0, arg1]); + + /// + /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. + /// + /// +/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") + /// + public static DiagnosticEvent CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2) => Diagnostic.CallerSensitiveOnUnsupportedMethod.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. + /// + /// +/// {arg0} does not implement default interface method {arg1}. + /// + public static DiagnosticEvent RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1) => Diagnostic.RemappedTypeMissingDefaultInterfaceMethod.Event((object?[])[arg0, arg1]); + + /// + /// The 'GenericCompilerError' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericCompilerError(string arg0) => Diagnostic.GenericCompilerError.Event((object?[])[arg0]); + + /// + /// The 'GenericClassLoadingError' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericClassLoadingError(string arg0) => Diagnostic.GenericClassLoadingError.Event((object?[])[arg0]); + + /// + /// The 'GenericVerifierError' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericVerifierError(string arg0) => Diagnostic.GenericVerifierError.Event((object?[])[arg0]); + + /// + /// The 'GenericRuntimeError' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericRuntimeError(string arg0) => Diagnostic.GenericRuntimeError.Event((object?[])[arg0]); + + /// + /// The 'GenericJniError' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericJniError(string arg0) => Diagnostic.GenericJniError.Event((object?[])[arg0]); + + /// + /// The 'ExportingImportsNotSupported' diagnostic. + /// + /// +/// Exporting previously imported assemblies is not supported. + /// + public static DiagnosticEvent ExportingImportsNotSupported() => Diagnostic.ExportingImportsNotSupported.Event((object?[])[]); + + /// + /// The 'ResponseFileDepthExceeded' diagnostic. + /// + /// +/// Response file nesting depth exceeded. + /// + public static DiagnosticEvent ResponseFileDepthExceeded() => Diagnostic.ResponseFileDepthExceeded.Event((object?[])[]); + + /// + /// The 'ErrorReadingFile' diagnostic. + /// + /// +/// Unable to read file: {arg0}. ({arg1}) + /// + public static DiagnosticEvent ErrorReadingFile(string arg0, string arg1) => Diagnostic.ErrorReadingFile.Event((object?[])[arg0, arg1]); + + /// + /// The 'NoTargetsFound' diagnostic. + /// + /// +/// No targets found + /// + public static DiagnosticEvent NoTargetsFound() => Diagnostic.NoTargetsFound.Event((object?[])[]); + + /// + /// The 'FileFormatLimitationExceeded' diagnostic. + /// + /// +/// File format limitation exceeded: {arg0}. + /// + public static DiagnosticEvent FileFormatLimitationExceeded(string arg0) => Diagnostic.FileFormatLimitationExceeded.Event((object?[])[arg0]); + + /// + /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. + /// + /// +/// You cannot specify both a key file and container. + /// + public static DiagnosticEvent CannotSpecifyBothKeyFileAndContainer() => Diagnostic.CannotSpecifyBothKeyFileAndContainer.Event((object?[])[]); + + /// + /// The 'DelaySignRequiresKey' diagnostic. + /// + /// +/// You cannot delay sign without a key file or container. + /// + public static DiagnosticEvent DelaySignRequiresKey() => Diagnostic.DelaySignRequiresKey.Event((object?[])[]); + + /// + /// The 'InvalidStrongNameKeyPair' diagnostic. + /// + /// +/// Invalid key {arg0} specified. ("{arg1}") + /// + public static DiagnosticEvent InvalidStrongNameKeyPair(string arg0, string arg1) => Diagnostic.InvalidStrongNameKeyPair.Event((object?[])[arg0, arg1]); + + /// + /// The 'ReferenceNotFound' diagnostic. + /// + /// +/// Reference not found: {arg0} + /// + public static DiagnosticEvent ReferenceNotFound(string arg0) => Diagnostic.ReferenceNotFound.Event((object?[])[arg0]); + + /// + /// The 'OptionsMustPreceedChildLevels' diagnostic. + /// + /// +/// You can only specify options before any child levels. + /// + public static DiagnosticEvent OptionsMustPreceedChildLevels() => Diagnostic.OptionsMustPreceedChildLevels.Event((object?[])[]); + + /// + /// The 'UnrecognizedTargetType' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -target option. + /// + public static DiagnosticEvent UnrecognizedTargetType(string arg0) => Diagnostic.UnrecognizedTargetType.Event((object?[])[arg0]); + + /// + /// The 'UnrecognizedPlatform' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -platform option. + /// + public static DiagnosticEvent UnrecognizedPlatform(string arg0) => Diagnostic.UnrecognizedPlatform.Event((object?[])[arg0]); + + /// + /// The 'UnrecognizedApartment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -apartment option. + /// + public static DiagnosticEvent UnrecognizedApartment(string arg0) => Diagnostic.UnrecognizedApartment.Event((object?[])[arg0]); + + /// + /// The 'MissingFileSpecification' diagnostic. + /// + /// +/// Missing file specification for '{arg0}' option. + /// + public static DiagnosticEvent MissingFileSpecification(string arg0) => Diagnostic.MissingFileSpecification.Event((object?[])[arg0]); + + /// + /// The 'PathTooLong' diagnostic. + /// + /// +/// Path too long: {arg0}. + /// + public static DiagnosticEvent PathTooLong(string arg0) => Diagnostic.PathTooLong.Event((object?[])[arg0]); + + /// + /// The 'PathNotFound' diagnostic. + /// + /// +/// Path not found: {arg0}. + /// + public static DiagnosticEvent PathNotFound(string arg0) => Diagnostic.PathNotFound.Event((object?[])[arg0]); + + /// + /// The 'InvalidPath' diagnostic. + /// + /// +/// Invalid path: {arg0}. + /// + public static DiagnosticEvent InvalidPath(string arg0) => Diagnostic.InvalidPath.Event((object?[])[arg0]); + + /// + /// The 'InvalidOptionSyntax' diagnostic. + /// + /// +/// Invalid option: {arg0}. + /// + public static DiagnosticEvent InvalidOptionSyntax(string arg0) => Diagnostic.InvalidOptionSyntax.Event((object?[])[arg0]); + + /// + /// The 'ExternalResourceNotFound' diagnostic. + /// + /// +/// External resource file does not exist: {arg0}. + /// + public static DiagnosticEvent ExternalResourceNotFound(string arg0) => Diagnostic.ExternalResourceNotFound.Event((object?[])[arg0]); + + /// + /// The 'ExternalResourceNameInvalid' diagnostic. + /// + /// +/// External resource file may not include path specification: {arg0}. + /// + public static DiagnosticEvent ExternalResourceNameInvalid(string arg0) => Diagnostic.ExternalResourceNameInvalid.Event((object?[])[arg0]); + + /// + /// The 'InvalidVersionFormat' diagnostic. + /// + /// +/// Invalid version specified: {arg0}. + /// + public static DiagnosticEvent InvalidVersionFormat(string arg0) => Diagnostic.InvalidVersionFormat.Event((object?[])[arg0]); + + /// + /// The 'InvalidFileAlignment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -filealign option. + /// + public static DiagnosticEvent InvalidFileAlignment(string arg0) => Diagnostic.InvalidFileAlignment.Event((object?[])[arg0]); + + /// + /// The 'ErrorWritingFile' diagnostic. + /// + /// +/// Unable to write file: {arg0}. ({arg1}) + /// + public static DiagnosticEvent ErrorWritingFile(string arg0, string arg1) => Diagnostic.ErrorWritingFile.Event((object?[])[arg0, arg1]); + + /// + /// The 'UnrecognizedOption' diagnostic. + /// + /// +/// Unrecognized option: {arg0}. + /// + public static DiagnosticEvent UnrecognizedOption(string arg0) => Diagnostic.UnrecognizedOption.Event((object?[])[arg0]); + + /// + /// The 'NoOutputFileSpecified' diagnostic. + /// + /// +/// No output file specified. + /// + public static DiagnosticEvent NoOutputFileSpecified() => Diagnostic.NoOutputFileSpecified.Event((object?[])[]); + + /// + /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. + /// + /// +/// Incompatible options: -target:module and -sharedclassloader cannot be combined. + /// + public static DiagnosticEvent SharedClassLoaderCannotBeUsedOnModuleTarget() => Diagnostic.SharedClassLoaderCannotBeUsedOnModuleTarget.Event((object?[])[]); + + /// + /// The 'RuntimeNotFound' diagnostic. + /// + /// +/// Unable to load runtime assembly. + /// + public static DiagnosticEvent RuntimeNotFound() => Diagnostic.RuntimeNotFound.Event((object?[])[]); + + /// + /// The 'MainClassRequiresExe' diagnostic. + /// + /// +/// Main class cannot be specified for library or module. + /// + public static DiagnosticEvent MainClassRequiresExe() => Diagnostic.MainClassRequiresExe.Event((object?[])[]); + + /// + /// The 'ExeRequiresMainClass' diagnostic. + /// + /// +/// No main method found. + /// + public static DiagnosticEvent ExeRequiresMainClass() => Diagnostic.ExeRequiresMainClass.Event((object?[])[]); + + /// + /// The 'PropertiesRequireExe' diagnostic. + /// + /// +/// Properties cannot be specified for library or module. + /// + public static DiagnosticEvent PropertiesRequireExe() => Diagnostic.PropertiesRequireExe.Event((object?[])[]); + + /// + /// The 'ModuleCannotHaveClassLoader' diagnostic. + /// + /// +/// Cannot specify assembly class loader for modules. + /// + public static DiagnosticEvent ModuleCannotHaveClassLoader() => Diagnostic.ModuleCannotHaveClassLoader.Event((object?[])[]); + + /// + /// The 'ErrorParsingMapFile' diagnostic. + /// + /// +/// Unable to parse remap file: {arg0}. ({arg1}) + /// + public static DiagnosticEvent ErrorParsingMapFile(string arg0, string arg1) => Diagnostic.ErrorParsingMapFile.Event((object?[])[arg0, arg1]); + + /// + /// The 'BootstrapClassesMissing' diagnostic. + /// + /// +/// Bootstrap classes missing and core assembly not found. + /// + public static DiagnosticEvent BootstrapClassesMissing() => Diagnostic.BootstrapClassesMissing.Event((object?[])[]); + + /// + /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. + /// + /// +/// All referenced assemblies must be strong named, to be able to sign the output assembly. + /// + public static DiagnosticEvent StrongNameRequiresStrongNamedRefs() => Diagnostic.StrongNameRequiresStrongNamedRefs.Event((object?[])[]); + + /// + /// The 'MainClassNotFound' diagnostic. + /// + /// +/// Main class not found. + /// + public static DiagnosticEvent MainClassNotFound() => Diagnostic.MainClassNotFound.Event((object?[])[]); + + /// + /// The 'MainMethodNotFound' diagnostic. + /// + /// +/// Main method not found. + /// + public static DiagnosticEvent MainMethodNotFound() => Diagnostic.MainMethodNotFound.Event((object?[])[]); + + /// + /// The 'UnsupportedMainMethod' diagnostic. + /// + /// +/// Redirected main method not supported. + /// + public static DiagnosticEvent UnsupportedMainMethod() => Diagnostic.UnsupportedMainMethod.Event((object?[])[]); + + /// + /// The 'ExternalMainNotAccessible' diagnostic. + /// + /// +/// External main method must be public and in a public class. + /// + public static DiagnosticEvent ExternalMainNotAccessible() => Diagnostic.ExternalMainNotAccessible.Event((object?[])[]); + + /// + /// The 'ClassLoaderNotFound' diagnostic. + /// + /// +/// Custom assembly class loader class not found. + /// + public static DiagnosticEvent ClassLoaderNotFound() => Diagnostic.ClassLoaderNotFound.Event((object?[])[]); + + /// + /// The 'ClassLoaderNotAccessible' diagnostic. + /// + /// +/// Custom assembly class loader class is not accessible. + /// + public static DiagnosticEvent ClassLoaderNotAccessible() => Diagnostic.ClassLoaderNotAccessible.Event((object?[])[]); + + /// + /// The 'ClassLoaderIsAbstract' diagnostic. + /// + /// +/// Custom assembly class loader class is abstract. + /// + public static DiagnosticEvent ClassLoaderIsAbstract() => Diagnostic.ClassLoaderIsAbstract.Event((object?[])[]); + + /// + /// The 'ClassLoaderNotClassLoader' diagnostic. + /// + /// +/// Custom assembly class loader class does not extend java.lang.ClassLoader. + /// + public static DiagnosticEvent ClassLoaderNotClassLoader() => Diagnostic.ClassLoaderNotClassLoader.Event((object?[])[]); + + /// + /// The 'ClassLoaderConstructorMissing' diagnostic. + /// + /// +/// Custom assembly class loader constructor is missing. + /// + public static DiagnosticEvent ClassLoaderConstructorMissing() => Diagnostic.ClassLoaderConstructorMissing.Event((object?[])[]); + + /// + /// The 'MapFileTypeNotFound' diagnostic. + /// + /// +/// Type '{arg0}' referenced in remap file was not found. + /// + public static DiagnosticEvent MapFileTypeNotFound(string arg0) => Diagnostic.MapFileTypeNotFound.Event((object?[])[arg0]); + + /// + /// The 'MapFileClassNotFound' diagnostic. + /// + /// +/// Class '{arg0}' referenced in remap file was not found. + /// + public static DiagnosticEvent MapFileClassNotFound(string arg0) => Diagnostic.MapFileClassNotFound.Event((object?[])[arg0]); + + /// + /// The 'MaximumErrorCountReached' diagnostic. + /// + /// +/// Maximum error count reached. + /// + public static DiagnosticEvent MaximumErrorCountReached() => Diagnostic.MaximumErrorCountReached.Event((object?[])[]); + + /// + /// The 'LinkageError' diagnostic. + /// + /// +/// Link error: {arg0} + /// + public static DiagnosticEvent LinkageError(string arg0) => Diagnostic.LinkageError.Event((object?[])[arg0]); + + /// + /// The 'RuntimeMismatch' diagnostic. + /// + /// +/// Referenced assembly {arg0} was compiled with an incompatible IKVM.Runtime version. Current runtime: {arg1}. Referenced assembly runtime: {arg2} + /// + public static DiagnosticEvent RuntimeMismatch(string arg0, string arg1, string arg2) => Diagnostic.RuntimeMismatch.Event((object?[])[arg0, arg1, arg2]); + + /// + /// The 'RuntimeMismatchStrongName' diagnostic. + /// + /// +/// + /// + public static DiagnosticEvent RuntimeMismatchStrongName() => Diagnostic.RuntimeMismatchStrongName.Event((object?[])[]); + + /// + /// The 'CoreClassesMissing' diagnostic. + /// + /// +/// Failed to find core classes in core library. + /// + public static DiagnosticEvent CoreClassesMissing() => Diagnostic.CoreClassesMissing.Event((object?[])[]); + + /// + /// The 'CriticalClassNotFound' diagnostic. + /// + /// +/// Unable to load critical class '{arg0}'. + /// + public static DiagnosticEvent CriticalClassNotFound(string arg0) => Diagnostic.CriticalClassNotFound.Event((object?[])[arg0]); + + /// + /// The 'AssemblyContainsDuplicateClassNames' diagnostic. + /// + /// +/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) + /// + public static DiagnosticEvent AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3) => Diagnostic.AssemblyContainsDuplicateClassNames.Event((object?[])[arg0, arg1, arg2, arg3]); + + /// + /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. + /// + /// +/// CallerID.getCallerID() requires a HasCallerID annotation. + /// + public static DiagnosticEvent CallerIDRequiresHasCallerIDAnnotation() => Diagnostic.CallerIDRequiresHasCallerIDAnnotation.Event((object?[])[]); + + /// + /// The 'UnableToResolveInterface' diagnostic. + /// + /// +/// Unable to resolve interface '{arg0}' on type '{arg1}'. + /// + public static DiagnosticEvent UnableToResolveInterface(string arg0, string arg1) => Diagnostic.UnableToResolveInterface.Event((object?[])[arg0, arg1]); + + /// + /// The 'MissingBaseType' diagnostic. + /// + /// +/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. + /// + public static DiagnosticEvent MissingBaseType(string arg0, string arg1, string arg2, string arg3) => Diagnostic.MissingBaseType.Event((object?[])[arg0, arg1, arg2, arg3]); + + /// + /// The 'MissingBaseTypeReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. + /// + public static DiagnosticEvent MissingBaseTypeReference(string arg0, string arg1) => Diagnostic.MissingBaseTypeReference.Event((object?[])[arg0, arg1]); + + /// + /// The 'FileNotFound' diagnostic. + /// + /// +/// File not found: {arg0}. + /// + public static DiagnosticEvent FileNotFound(string arg0) => Diagnostic.FileNotFound.Event((object?[])[arg0]); + + /// + /// The 'RuntimeMethodMissing' diagnostic. + /// + /// +/// Runtime method '{arg0}' not found. + /// + public static DiagnosticEvent RuntimeMethodMissing(string arg0) => Diagnostic.RuntimeMethodMissing.Event((object?[])[arg0]); + + /// + /// The 'MapFileFieldNotFound' diagnostic. + /// + /// +/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. + /// + public static DiagnosticEvent MapFileFieldNotFound(string arg0, string arg1) => Diagnostic.MapFileFieldNotFound.Event((object?[])[arg0, arg1]); + + /// + /// The 'GhostInterfaceMethodMissing' diagnostic. + /// + /// +/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) + /// + public static DiagnosticEvent GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3) => Diagnostic.GhostInterfaceMethodMissing.Event((object?[])[arg0, arg1, arg2, arg3]); + + /// + /// The 'ModuleInitializerMethodRequirements' diagnostic. + /// + /// +/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. + /// + public static DiagnosticEvent ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3) => Diagnostic.ModuleInitializerMethodRequirements.Event((object?[])[arg1, arg2, arg3]); + + /// + /// The 'InvalidZip' diagnostic. + /// + /// +/// Invalid zip: {name}. + /// + public static DiagnosticEvent InvalidZip(string name) => Diagnostic.InvalidZip.Event((object?[])[name]); + + /// + /// The 'GenericRuntimeTrace' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericRuntimeTrace(string arg0) => Diagnostic.GenericRuntimeTrace.Event((object?[])[arg0]); + + /// + /// The 'GenericJniTrace' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericJniTrace(string arg0) => Diagnostic.GenericJniTrace.Event((object?[])[arg0]); + + /// + /// The 'GenericCompilerTrace' diagnostic. + /// + /// +/// {arg0} + /// + public static DiagnosticEvent GenericCompilerTrace(string arg0) => Diagnostic.GenericCompilerTrace.Event((object?[])[arg0]); + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.tt b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.tt new file mode 100644 index 0000000000..967613846d --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEvent.g.tt @@ -0,0 +1,59 @@ +<#@ template debug="false" hostspecific="true" language="C#" compilerOptions="/unsafe" #> +<#@ include file="Diagnostic.t4" #> +<#@ assembly name="System.CodeDom" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Memory" #> +<#@ assembly name="System.Buffers" #> +<#@ assembly name="Newtonsoft.Json" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Buffers" #> +<#@ import namespace="System.CodeDom" #> +<#@ import namespace="System.CodeDom.Compiler" #> +<#@ import namespace="System.Diagnostics" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Runtime.CompilerServices" #> +<#@ import namespace="System.Runtime.InteropServices" #> +<#@ import namespace="Newtonsoft.Json" #> +<#@ import namespace="Newtonsoft.Json.Linq" #> +<#@ output extension=".cs" #> +#nullable enable + +using System.Text; + +namespace IKVM.CoreLib.Diagnostics +{ + + partial struct DiagnosticEvent + { + +<# +foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnostic.json")))) +{ + var desc = kvp.Value.Description; + if (string.IsNullOrWhiteSpace(desc)) + desc = $"The '{kvp.Key}' diagnostic."; + + var argDecl = new List(); + foreach (var arg in kvp.Value.Args) + argDecl.Add($"{arg.Type} {arg.Name}"); + + var argList = new List(); + foreach (var arg in kvp.Value.Args) + argList.Add($"{arg.Name}"); +#> + /// + /// <#= desc #> + /// + /// +<#= Util.ToCommentString(kvp.Value.Message ?? "") #> + /// + public static DiagnosticEvent <#= kvp.Key #>(<#= string.Join(", ", argDecl) #>) => Diagnostic.<#= kvp.Key #>.Event((object?[])[<#= string.Join(", ", argList) #>]); + +<# +} +#> + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.cs new file mode 100644 index 0000000000..5f179adc5e --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.cs @@ -0,0 +1,18 @@ +namespace IKVM.CoreLib.Diagnostics +{ + + /// + /// Base that packages messages into an event type. + /// + internal abstract partial class DiagnosticEventHandler : IDiagnosticHandler + { + + /// + public abstract bool IsEnabled(Diagnostic diagnostic); + + /// + public abstract void Report(in DiagnosticEvent @event); + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs new file mode 100644 index 0000000000..eaaa092ec4 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.cs @@ -0,0 +1,1123 @@ +#nullable enable + +namespace IKVM.CoreLib.Diagnostics +{ + + internal abstract partial class DiagnosticEventHandler + { + + /// + /// The 'MainMethodFound' diagnostic. + /// + /// +/// Found main method in class "{arg0}". + /// + public void MainMethodFound(string arg0) => Report(Diagnostic.MainMethodFound.Event([arg0])); + + /// + /// The 'OutputFileIs' diagnostic. + /// + /// +/// Output file is "{arg0}". + /// + public void OutputFileIs(string arg0) => Report(Diagnostic.OutputFileIs.Event([arg0])); + + /// + /// The 'AutoAddRef' diagnostic. + /// + /// +/// Automatically adding reference to "{arg0}". + /// + public void AutoAddRef(string arg0) => Report(Diagnostic.AutoAddRef.Event([arg0])); + + /// + /// The 'MainMethodFromManifest' diagnostic. + /// + /// +/// Using main class "{arg0}" based on jar manifest. + /// + public void MainMethodFromManifest(string arg0) => Report(Diagnostic.MainMethodFromManifest.Event([arg0])); + + /// + /// The 'GenericCompilerInfo' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericCompilerInfo(string arg0) => Report(Diagnostic.GenericCompilerInfo.Event([arg0])); + + /// + /// The 'GenericClassLoadingInfo' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericClassLoadingInfo(string arg0) => Report(Diagnostic.GenericClassLoadingInfo.Event([arg0])); + + /// + /// The 'GenericVerifierInfo' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericVerifierInfo(string arg0) => Report(Diagnostic.GenericVerifierInfo.Event([arg0])); + + /// + /// The 'GenericRuntimeInfo' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericRuntimeInfo(string arg0) => Report(Diagnostic.GenericRuntimeInfo.Event([arg0])); + + /// + /// The 'GenericJniInfo' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericJniInfo(string arg0) => Report(Diagnostic.GenericJniInfo.Event([arg0])); + + /// + /// The 'ClassNotFound' diagnostic. + /// + /// +/// Class "{arg0}" not found. + /// + public void ClassNotFound(string arg0) => Report(Diagnostic.ClassNotFound.Event([arg0])); + + /// + /// The 'ClassFormatError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (class format error "{arg1}") + /// + public void ClassFormatError(string arg0, string arg1) => Report(Diagnostic.ClassFormatError.Event([arg0, arg1])); + + /// + /// The 'DuplicateClassName' diagnostic. + /// + /// +/// Duplicate class name: "{arg0}". + /// + public void DuplicateClassName(string arg0) => Report(Diagnostic.DuplicateClassName.Event([arg0])); + + /// + /// The 'IllegalAccessError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (illegal access error "{arg1}") + /// + public void IllegalAccessError(string arg0, string arg1) => Report(Diagnostic.IllegalAccessError.Event([arg0, arg1])); + + /// + /// The 'VerificationError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (verification error "{arg1}") + /// + public void VerificationError(string arg0, string arg1) => Report(Diagnostic.VerificationError.Event([arg0, arg1])); + + /// + /// The 'NoClassDefFoundError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (missing class "{arg1}") + /// + public void NoClassDefFoundError(string arg0, string arg1) => Report(Diagnostic.NoClassDefFoundError.Event([arg0, arg1])); + + /// + /// The 'GenericUnableToCompileError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") + /// + public void GenericUnableToCompileError(string arg0, string arg1, string arg2) => Report(Diagnostic.GenericUnableToCompileError.Event([arg0, arg1, arg2])); + + /// + /// The 'DuplicateResourceName' diagnostic. + /// + /// +/// Skipping resource (name clash): "{arg0}" + /// + public void DuplicateResourceName(string arg0) => Report(Diagnostic.DuplicateResourceName.Event([arg0])); + + /// + /// The 'SkippingReferencedClass' diagnostic. + /// + /// +/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") + /// + public void SkippingReferencedClass(string arg0, string arg1) => Report(Diagnostic.SkippingReferencedClass.Event([arg0, arg1])); + + /// + /// The 'NoJniRuntime' diagnostic. + /// + /// +/// Unable to load runtime JNI assembly. + /// + public void NoJniRuntime() => Report(Diagnostic.NoJniRuntime.Event([])); + + /// + /// The 'EmittedNoClassDefFoundError' diagnostic. + /// + /// +/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). + /// + public void EmittedNoClassDefFoundError(string arg0, string arg1) => Report(Diagnostic.EmittedNoClassDefFoundError.Event([arg0, arg1])); + + /// + /// The 'EmittedIllegalAccessError' diagnostic. + /// + /// +/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") + /// + public void EmittedIllegalAccessError(string arg0, string arg1) => Report(Diagnostic.EmittedIllegalAccessError.Event([arg0, arg1])); + + /// + /// The 'EmittedInstantiationError' diagnostic. + /// + /// +/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") + /// + public void EmittedInstantiationError(string arg0, string arg1) => Report(Diagnostic.EmittedInstantiationError.Event([arg0, arg1])); + + /// + /// The 'EmittedIncompatibleClassChangeError' diagnostic. + /// + /// +/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") + /// + public void EmittedIncompatibleClassChangeError(string arg0, string arg1) => Report(Diagnostic.EmittedIncompatibleClassChangeError.Event([arg0, arg1])); + + /// + /// The 'EmittedNoSuchFieldError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") + /// + public void EmittedNoSuchFieldError(string arg0, string arg1) => Report(Diagnostic.EmittedNoSuchFieldError.Event([arg0, arg1])); + + /// + /// The 'EmittedAbstractMethodError' diagnostic. + /// + /// +/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") + /// + public void EmittedAbstractMethodError(string arg0, string arg1) => Report(Diagnostic.EmittedAbstractMethodError.Event([arg0, arg1])); + + /// + /// The 'EmittedNoSuchMethodError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") + /// + public void EmittedNoSuchMethodError(string arg0, string arg1) => Report(Diagnostic.EmittedNoSuchMethodError.Event([arg0, arg1])); + + /// + /// The 'EmittedLinkageError' diagnostic. + /// + /// +/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") + /// + public void EmittedLinkageError(string arg0, string arg1) => Report(Diagnostic.EmittedLinkageError.Event([arg0, arg1])); + + /// + /// The 'EmittedVerificationError' diagnostic. + /// + /// +/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") + /// + public void EmittedVerificationError(string arg0, string arg1) => Report(Diagnostic.EmittedVerificationError.Event([arg0, arg1])); + + /// + /// The 'EmittedClassFormatError' diagnostic. + /// + /// +/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") + /// + public void EmittedClassFormatError(string arg0, string arg1) => Report(Diagnostic.EmittedClassFormatError.Event([arg0, arg1])); + + /// + /// The 'InvalidCustomAttribute' diagnostic. + /// + /// +/// Error emitting "{arg0}" custom attribute. ("{arg1}") + /// + public void InvalidCustomAttribute(string arg0, string arg1) => Report(Diagnostic.InvalidCustomAttribute.Event([arg0, arg1])); + + /// + /// The 'IgnoredCustomAttribute' diagnostic. + /// + /// +/// Custom attribute "{arg0}" was ignored. ("{arg1}") + /// + public void IgnoredCustomAttribute(string arg0, string arg1) => Report(Diagnostic.IgnoredCustomAttribute.Event([arg0, arg1])); + + /// + /// The 'AssumeAssemblyVersionMatch' diagnostic. + /// + /// +/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy + /// + public void AssumeAssemblyVersionMatch(string arg0, string arg1) => Report(Diagnostic.AssumeAssemblyVersionMatch.Event([arg0, arg1])); + + /// + /// The 'InvalidDirectoryInLibOptionPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in -lib option is not valid. + /// + public void InvalidDirectoryInLibOptionPath(string arg0) => Report(Diagnostic.InvalidDirectoryInLibOptionPath.Event([arg0])); + + /// + /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in LIB environment is not valid. + /// + public void InvalidDirectoryInLibEnvironmentPath(string arg0) => Report(Diagnostic.InvalidDirectoryInLibEnvironmentPath.Event([arg0])); + + /// + /// The 'LegacySearchRule' diagnostic. + /// + /// +/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. + /// + public void LegacySearchRule(string arg0) => Report(Diagnostic.LegacySearchRule.Event([arg0])); + + /// + /// The 'AssemblyLocationIgnored' diagnostic. + /// + /// +/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". + /// + public void AssemblyLocationIgnored(string arg0, string arg1, string arg2) => Report(Diagnostic.AssemblyLocationIgnored.Event([arg0, arg1, arg2])); + + /// + /// The 'InterfaceMethodCantBeInternal' diagnostic. + /// + /// +/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") + /// + public void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2) => Report(Diagnostic.InterfaceMethodCantBeInternal.Event([arg0, arg1, arg2])); + + /// + /// The 'DuplicateAssemblyReference' diagnostic. + /// + /// +/// Duplicate assembly reference "{arg0}" + /// + public void DuplicateAssemblyReference(string arg0) => Report(Diagnostic.DuplicateAssemblyReference.Event([arg0])); + + /// + /// The 'UnableToResolveType' diagnostic. + /// + /// +/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. + /// + public void UnableToResolveType(string arg0, string arg1, string arg2) => Report(Diagnostic.UnableToResolveType.Event([arg0, arg1, arg2])); + + /// + /// The 'StubsAreDeprecated' diagnostic. + /// + /// +/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. + /// + public void StubsAreDeprecated(string arg0) => Report(Diagnostic.StubsAreDeprecated.Event([arg0])); + + /// + /// The 'WrongClassName' diagnostic. + /// + /// +/// Unable to compile "{arg0}" (wrong name: "{arg1}") + /// + public void WrongClassName(string arg0, string arg1) => Report(Diagnostic.WrongClassName.Event([arg0, arg1])); + + /// + /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. + /// + /// +/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") + /// + public void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2) => Report(Diagnostic.ReflectionCallerClassRequiresCallerID.Event([arg0, arg1, arg2])); + + /// + /// The 'LegacyAssemblyAttributesFound' diagnostic. + /// + /// +/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. + /// + public void LegacyAssemblyAttributesFound() => Report(Diagnostic.LegacyAssemblyAttributesFound.Event([])); + + /// + /// The 'UnableToCreateLambdaFactory' diagnostic. + /// + /// +/// Unable to create static lambda factory. + /// + public void UnableToCreateLambdaFactory() => Report(Diagnostic.UnableToCreateLambdaFactory.Event([])); + + /// + /// The 'UnknownWarning' diagnostic. + /// + /// +/// {arg0} + /// + public void UnknownWarning(string arg0) => Report(Diagnostic.UnknownWarning.Event([arg0])); + + /// + /// The 'DuplicateIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// + public void DuplicateIkvmLangProperty(string arg0, string arg1) => Report(Diagnostic.DuplicateIkvmLangProperty.Event([arg0, arg1])); + + /// + /// The 'MalformedIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// + public void MalformedIkvmLangProperty(string arg0, string arg1) => Report(Diagnostic.MalformedIkvmLangProperty.Event([arg0, arg1])); + + /// + /// The 'GenericCompilerWarning' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericCompilerWarning(string arg0) => Report(Diagnostic.GenericCompilerWarning.Event([arg0])); + + /// + /// The 'GenericClassLoadingWarning' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericClassLoadingWarning(string arg0) => Report(Diagnostic.GenericClassLoadingWarning.Event([arg0])); + + /// + /// The 'GenericVerifierWarning' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericVerifierWarning(string arg0) => Report(Diagnostic.GenericVerifierWarning.Event([arg0])); + + /// + /// The 'GenericRuntimeWarning' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericRuntimeWarning(string arg0) => Report(Diagnostic.GenericRuntimeWarning.Event([arg0])); + + /// + /// The 'GenericJniWarning' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericJniWarning(string arg0) => Report(Diagnostic.GenericJniWarning.Event([arg0])); + + /// + /// The 'UnableToCreateProxy' diagnostic. + /// + /// +/// Unable to create proxy "{arg0}". ("{arg1}") + /// + public void UnableToCreateProxy(string arg0, string arg1) => Report(Diagnostic.UnableToCreateProxy.Event([arg0, arg1])); + + /// + /// The 'DuplicateProxy' diagnostic. + /// + /// +/// Duplicate proxy "{arg0}". + /// + public void DuplicateProxy(string arg0) => Report(Diagnostic.DuplicateProxy.Event([arg0])); + + /// + /// The 'MapXmlUnableToResolveOpCode' diagnostic. + /// + /// +/// Unable to resolve opcode in remap file: {arg0}. + /// + public void MapXmlUnableToResolveOpCode(string arg0) => Report(Diagnostic.MapXmlUnableToResolveOpCode.Event([arg0])); + + /// + /// The 'MapXmlError' diagnostic. + /// + /// +/// Error in remap file: {arg0}. + /// + public void MapXmlError(string arg0) => Report(Diagnostic.MapXmlError.Event([arg0])); + + /// + /// The 'InputFileNotFound' diagnostic. + /// + /// +/// Source file '{arg0}' not found. + /// + public void InputFileNotFound(string arg0) => Report(Diagnostic.InputFileNotFound.Event([arg0])); + + /// + /// The 'UnknownFileType' diagnostic. + /// + /// +/// Unknown file type: {arg0}. + /// + public void UnknownFileType(string arg0) => Report(Diagnostic.UnknownFileType.Event([arg0])); + + /// + /// The 'UnknownElementInMapFile' diagnostic. + /// + /// +/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. + /// + public void UnknownElementInMapFile(string arg0, string arg1, string arg2) => Report(Diagnostic.UnknownElementInMapFile.Event([arg0, arg1, arg2])); + + /// + /// The 'UnknownAttributeInMapFile' diagnostic. + /// + /// +/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. + /// + public void UnknownAttributeInMapFile(string arg0, string arg1, string arg2) => Report(Diagnostic.UnknownAttributeInMapFile.Event([arg0, arg1, arg2])); + + /// + /// The 'InvalidMemberNameInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. + /// + public void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2) => Report(Diagnostic.InvalidMemberNameInMapFile.Event([arg0, arg1, arg2])); + + /// + /// The 'InvalidMemberSignatureInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. + /// + public void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3) => Report(Diagnostic.InvalidMemberSignatureInMapFile.Event([arg0, arg1, arg2, arg3])); + + /// + /// The 'InvalidPropertyNameInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. + /// + public void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3) => Report(Diagnostic.InvalidPropertyNameInMapFile.Event([arg0, arg1, arg2, arg3])); + + /// + /// The 'InvalidPropertySignatureInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. + /// + public void InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3) => Report(Diagnostic.InvalidPropertySignatureInMapFile.Event([arg0, arg1, arg2, arg3])); + + /// + /// The 'NonPrimaryAssemblyReference' diagnostic. + /// + /// +/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. + /// + public void NonPrimaryAssemblyReference(string arg0, string arg1) => Report(Diagnostic.NonPrimaryAssemblyReference.Event([arg0, arg1])); + + /// + /// The 'MissingType' diagnostic. + /// + /// +/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. + /// + public void MissingType(string arg0, string arg1) => Report(Diagnostic.MissingType.Event([arg0, arg1])); + + /// + /// The 'MissingReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. + /// + public void MissingReference(string arg0, string arg1) => Report(Diagnostic.MissingReference.Event([arg0, arg1])); + + /// + /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. + /// + /// +/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") + /// + public void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2) => Report(Diagnostic.CallerSensitiveOnUnsupportedMethod.Event([arg0, arg1, arg2])); + + /// + /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. + /// + /// +/// {arg0} does not implement default interface method {arg1}. + /// + public void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1) => Report(Diagnostic.RemappedTypeMissingDefaultInterfaceMethod.Event([arg0, arg1])); + + /// + /// The 'GenericCompilerError' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericCompilerError(string arg0) => Report(Diagnostic.GenericCompilerError.Event([arg0])); + + /// + /// The 'GenericClassLoadingError' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericClassLoadingError(string arg0) => Report(Diagnostic.GenericClassLoadingError.Event([arg0])); + + /// + /// The 'GenericVerifierError' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericVerifierError(string arg0) => Report(Diagnostic.GenericVerifierError.Event([arg0])); + + /// + /// The 'GenericRuntimeError' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericRuntimeError(string arg0) => Report(Diagnostic.GenericRuntimeError.Event([arg0])); + + /// + /// The 'GenericJniError' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericJniError(string arg0) => Report(Diagnostic.GenericJniError.Event([arg0])); + + /// + /// The 'ExportingImportsNotSupported' diagnostic. + /// + /// +/// Exporting previously imported assemblies is not supported. + /// + public void ExportingImportsNotSupported() => Report(Diagnostic.ExportingImportsNotSupported.Event([])); + + /// + /// The 'ResponseFileDepthExceeded' diagnostic. + /// + /// +/// Response file nesting depth exceeded. + /// + public void ResponseFileDepthExceeded() => Report(Diagnostic.ResponseFileDepthExceeded.Event([])); + + /// + /// The 'ErrorReadingFile' diagnostic. + /// + /// +/// Unable to read file: {arg0}. ({arg1}) + /// + public void ErrorReadingFile(string arg0, string arg1) => Report(Diagnostic.ErrorReadingFile.Event([arg0, arg1])); + + /// + /// The 'NoTargetsFound' diagnostic. + /// + /// +/// No targets found + /// + public void NoTargetsFound() => Report(Diagnostic.NoTargetsFound.Event([])); + + /// + /// The 'FileFormatLimitationExceeded' diagnostic. + /// + /// +/// File format limitation exceeded: {arg0}. + /// + public void FileFormatLimitationExceeded(string arg0) => Report(Diagnostic.FileFormatLimitationExceeded.Event([arg0])); + + /// + /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. + /// + /// +/// You cannot specify both a key file and container. + /// + public void CannotSpecifyBothKeyFileAndContainer() => Report(Diagnostic.CannotSpecifyBothKeyFileAndContainer.Event([])); + + /// + /// The 'DelaySignRequiresKey' diagnostic. + /// + /// +/// You cannot delay sign without a key file or container. + /// + public void DelaySignRequiresKey() => Report(Diagnostic.DelaySignRequiresKey.Event([])); + + /// + /// The 'InvalidStrongNameKeyPair' diagnostic. + /// + /// +/// Invalid key {arg0} specified. ("{arg1}") + /// + public void InvalidStrongNameKeyPair(string arg0, string arg1) => Report(Diagnostic.InvalidStrongNameKeyPair.Event([arg0, arg1])); + + /// + /// The 'ReferenceNotFound' diagnostic. + /// + /// +/// Reference not found: {arg0} + /// + public void ReferenceNotFound(string arg0) => Report(Diagnostic.ReferenceNotFound.Event([arg0])); + + /// + /// The 'OptionsMustPreceedChildLevels' diagnostic. + /// + /// +/// You can only specify options before any child levels. + /// + public void OptionsMustPreceedChildLevels() => Report(Diagnostic.OptionsMustPreceedChildLevels.Event([])); + + /// + /// The 'UnrecognizedTargetType' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -target option. + /// + public void UnrecognizedTargetType(string arg0) => Report(Diagnostic.UnrecognizedTargetType.Event([arg0])); + + /// + /// The 'UnrecognizedPlatform' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -platform option. + /// + public void UnrecognizedPlatform(string arg0) => Report(Diagnostic.UnrecognizedPlatform.Event([arg0])); + + /// + /// The 'UnrecognizedApartment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -apartment option. + /// + public void UnrecognizedApartment(string arg0) => Report(Diagnostic.UnrecognizedApartment.Event([arg0])); + + /// + /// The 'MissingFileSpecification' diagnostic. + /// + /// +/// Missing file specification for '{arg0}' option. + /// + public void MissingFileSpecification(string arg0) => Report(Diagnostic.MissingFileSpecification.Event([arg0])); + + /// + /// The 'PathTooLong' diagnostic. + /// + /// +/// Path too long: {arg0}. + /// + public void PathTooLong(string arg0) => Report(Diagnostic.PathTooLong.Event([arg0])); + + /// + /// The 'PathNotFound' diagnostic. + /// + /// +/// Path not found: {arg0}. + /// + public void PathNotFound(string arg0) => Report(Diagnostic.PathNotFound.Event([arg0])); + + /// + /// The 'InvalidPath' diagnostic. + /// + /// +/// Invalid path: {arg0}. + /// + public void InvalidPath(string arg0) => Report(Diagnostic.InvalidPath.Event([arg0])); + + /// + /// The 'InvalidOptionSyntax' diagnostic. + /// + /// +/// Invalid option: {arg0}. + /// + public void InvalidOptionSyntax(string arg0) => Report(Diagnostic.InvalidOptionSyntax.Event([arg0])); + + /// + /// The 'ExternalResourceNotFound' diagnostic. + /// + /// +/// External resource file does not exist: {arg0}. + /// + public void ExternalResourceNotFound(string arg0) => Report(Diagnostic.ExternalResourceNotFound.Event([arg0])); + + /// + /// The 'ExternalResourceNameInvalid' diagnostic. + /// + /// +/// External resource file may not include path specification: {arg0}. + /// + public void ExternalResourceNameInvalid(string arg0) => Report(Diagnostic.ExternalResourceNameInvalid.Event([arg0])); + + /// + /// The 'InvalidVersionFormat' diagnostic. + /// + /// +/// Invalid version specified: {arg0}. + /// + public void InvalidVersionFormat(string arg0) => Report(Diagnostic.InvalidVersionFormat.Event([arg0])); + + /// + /// The 'InvalidFileAlignment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -filealign option. + /// + public void InvalidFileAlignment(string arg0) => Report(Diagnostic.InvalidFileAlignment.Event([arg0])); + + /// + /// The 'ErrorWritingFile' diagnostic. + /// + /// +/// Unable to write file: {arg0}. ({arg1}) + /// + public void ErrorWritingFile(string arg0, string arg1) => Report(Diagnostic.ErrorWritingFile.Event([arg0, arg1])); + + /// + /// The 'UnrecognizedOption' diagnostic. + /// + /// +/// Unrecognized option: {arg0}. + /// + public void UnrecognizedOption(string arg0) => Report(Diagnostic.UnrecognizedOption.Event([arg0])); + + /// + /// The 'NoOutputFileSpecified' diagnostic. + /// + /// +/// No output file specified. + /// + public void NoOutputFileSpecified() => Report(Diagnostic.NoOutputFileSpecified.Event([])); + + /// + /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. + /// + /// +/// Incompatible options: -target:module and -sharedclassloader cannot be combined. + /// + public void SharedClassLoaderCannotBeUsedOnModuleTarget() => Report(Diagnostic.SharedClassLoaderCannotBeUsedOnModuleTarget.Event([])); + + /// + /// The 'RuntimeNotFound' diagnostic. + /// + /// +/// Unable to load runtime assembly. + /// + public void RuntimeNotFound() => Report(Diagnostic.RuntimeNotFound.Event([])); + + /// + /// The 'MainClassRequiresExe' diagnostic. + /// + /// +/// Main class cannot be specified for library or module. + /// + public void MainClassRequiresExe() => Report(Diagnostic.MainClassRequiresExe.Event([])); + + /// + /// The 'ExeRequiresMainClass' diagnostic. + /// + /// +/// No main method found. + /// + public void ExeRequiresMainClass() => Report(Diagnostic.ExeRequiresMainClass.Event([])); + + /// + /// The 'PropertiesRequireExe' diagnostic. + /// + /// +/// Properties cannot be specified for library or module. + /// + public void PropertiesRequireExe() => Report(Diagnostic.PropertiesRequireExe.Event([])); + + /// + /// The 'ModuleCannotHaveClassLoader' diagnostic. + /// + /// +/// Cannot specify assembly class loader for modules. + /// + public void ModuleCannotHaveClassLoader() => Report(Diagnostic.ModuleCannotHaveClassLoader.Event([])); + + /// + /// The 'ErrorParsingMapFile' diagnostic. + /// + /// +/// Unable to parse remap file: {arg0}. ({arg1}) + /// + public void ErrorParsingMapFile(string arg0, string arg1) => Report(Diagnostic.ErrorParsingMapFile.Event([arg0, arg1])); + + /// + /// The 'BootstrapClassesMissing' diagnostic. + /// + /// +/// Bootstrap classes missing and core assembly not found. + /// + public void BootstrapClassesMissing() => Report(Diagnostic.BootstrapClassesMissing.Event([])); + + /// + /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. + /// + /// +/// All referenced assemblies must be strong named, to be able to sign the output assembly. + /// + public void StrongNameRequiresStrongNamedRefs() => Report(Diagnostic.StrongNameRequiresStrongNamedRefs.Event([])); + + /// + /// The 'MainClassNotFound' diagnostic. + /// + /// +/// Main class not found. + /// + public void MainClassNotFound() => Report(Diagnostic.MainClassNotFound.Event([])); + + /// + /// The 'MainMethodNotFound' diagnostic. + /// + /// +/// Main method not found. + /// + public void MainMethodNotFound() => Report(Diagnostic.MainMethodNotFound.Event([])); + + /// + /// The 'UnsupportedMainMethod' diagnostic. + /// + /// +/// Redirected main method not supported. + /// + public void UnsupportedMainMethod() => Report(Diagnostic.UnsupportedMainMethod.Event([])); + + /// + /// The 'ExternalMainNotAccessible' diagnostic. + /// + /// +/// External main method must be public and in a public class. + /// + public void ExternalMainNotAccessible() => Report(Diagnostic.ExternalMainNotAccessible.Event([])); + + /// + /// The 'ClassLoaderNotFound' diagnostic. + /// + /// +/// Custom assembly class loader class not found. + /// + public void ClassLoaderNotFound() => Report(Diagnostic.ClassLoaderNotFound.Event([])); + + /// + /// The 'ClassLoaderNotAccessible' diagnostic. + /// + /// +/// Custom assembly class loader class is not accessible. + /// + public void ClassLoaderNotAccessible() => Report(Diagnostic.ClassLoaderNotAccessible.Event([])); + + /// + /// The 'ClassLoaderIsAbstract' diagnostic. + /// + /// +/// Custom assembly class loader class is abstract. + /// + public void ClassLoaderIsAbstract() => Report(Diagnostic.ClassLoaderIsAbstract.Event([])); + + /// + /// The 'ClassLoaderNotClassLoader' diagnostic. + /// + /// +/// Custom assembly class loader class does not extend java.lang.ClassLoader. + /// + public void ClassLoaderNotClassLoader() => Report(Diagnostic.ClassLoaderNotClassLoader.Event([])); + + /// + /// The 'ClassLoaderConstructorMissing' diagnostic. + /// + /// +/// Custom assembly class loader constructor is missing. + /// + public void ClassLoaderConstructorMissing() => Report(Diagnostic.ClassLoaderConstructorMissing.Event([])); + + /// + /// The 'MapFileTypeNotFound' diagnostic. + /// + /// +/// Type '{arg0}' referenced in remap file was not found. + /// + public void MapFileTypeNotFound(string arg0) => Report(Diagnostic.MapFileTypeNotFound.Event([arg0])); + + /// + /// The 'MapFileClassNotFound' diagnostic. + /// + /// +/// Class '{arg0}' referenced in remap file was not found. + /// + public void MapFileClassNotFound(string arg0) => Report(Diagnostic.MapFileClassNotFound.Event([arg0])); + + /// + /// The 'MaximumErrorCountReached' diagnostic. + /// + /// +/// Maximum error count reached. + /// + public void MaximumErrorCountReached() => Report(Diagnostic.MaximumErrorCountReached.Event([])); + + /// + /// The 'LinkageError' diagnostic. + /// + /// +/// Link error: {arg0} + /// + public void LinkageError(string arg0) => Report(Diagnostic.LinkageError.Event([arg0])); + + /// + /// The 'RuntimeMismatch' diagnostic. + /// + /// +/// Referenced assembly {arg0} was compiled with an incompatible IKVM.Runtime version. Current runtime: {arg1}. Referenced assembly runtime: {arg2} + /// + public void RuntimeMismatch(string arg0, string arg1, string arg2) => Report(Diagnostic.RuntimeMismatch.Event([arg0, arg1, arg2])); + + /// + /// The 'RuntimeMismatchStrongName' diagnostic. + /// + /// +/// + /// + public void RuntimeMismatchStrongName() => Report(Diagnostic.RuntimeMismatchStrongName.Event([])); + + /// + /// The 'CoreClassesMissing' diagnostic. + /// + /// +/// Failed to find core classes in core library. + /// + public void CoreClassesMissing() => Report(Diagnostic.CoreClassesMissing.Event([])); + + /// + /// The 'CriticalClassNotFound' diagnostic. + /// + /// +/// Unable to load critical class '{arg0}'. + /// + public void CriticalClassNotFound(string arg0) => Report(Diagnostic.CriticalClassNotFound.Event([arg0])); + + /// + /// The 'AssemblyContainsDuplicateClassNames' diagnostic. + /// + /// +/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) + /// + public void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3) => Report(Diagnostic.AssemblyContainsDuplicateClassNames.Event([arg0, arg1, arg2, arg3])); + + /// + /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. + /// + /// +/// CallerID.getCallerID() requires a HasCallerID annotation. + /// + public void CallerIDRequiresHasCallerIDAnnotation() => Report(Diagnostic.CallerIDRequiresHasCallerIDAnnotation.Event([])); + + /// + /// The 'UnableToResolveInterface' diagnostic. + /// + /// +/// Unable to resolve interface '{arg0}' on type '{arg1}'. + /// + public void UnableToResolveInterface(string arg0, string arg1) => Report(Diagnostic.UnableToResolveInterface.Event([arg0, arg1])); + + /// + /// The 'MissingBaseType' diagnostic. + /// + /// +/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. + /// + public void MissingBaseType(string arg0, string arg1, string arg2, string arg3) => Report(Diagnostic.MissingBaseType.Event([arg0, arg1, arg2, arg3])); + + /// + /// The 'MissingBaseTypeReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. + /// + public void MissingBaseTypeReference(string arg0, string arg1) => Report(Diagnostic.MissingBaseTypeReference.Event([arg0, arg1])); + + /// + /// The 'FileNotFound' diagnostic. + /// + /// +/// File not found: {arg0}. + /// + public void FileNotFound(string arg0) => Report(Diagnostic.FileNotFound.Event([arg0])); + + /// + /// The 'RuntimeMethodMissing' diagnostic. + /// + /// +/// Runtime method '{arg0}' not found. + /// + public void RuntimeMethodMissing(string arg0) => Report(Diagnostic.RuntimeMethodMissing.Event([arg0])); + + /// + /// The 'MapFileFieldNotFound' diagnostic. + /// + /// +/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. + /// + public void MapFileFieldNotFound(string arg0, string arg1) => Report(Diagnostic.MapFileFieldNotFound.Event([arg0, arg1])); + + /// + /// The 'GhostInterfaceMethodMissing' diagnostic. + /// + /// +/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) + /// + public void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3) => Report(Diagnostic.GhostInterfaceMethodMissing.Event([arg0, arg1, arg2, arg3])); + + /// + /// The 'ModuleInitializerMethodRequirements' diagnostic. + /// + /// +/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. + /// + public void ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3) => Report(Diagnostic.ModuleInitializerMethodRequirements.Event([arg1, arg2, arg3])); + + /// + /// The 'InvalidZip' diagnostic. + /// + /// +/// Invalid zip: {name}. + /// + public void InvalidZip(string name) => Report(Diagnostic.InvalidZip.Event([name])); + + /// + /// The 'GenericRuntimeTrace' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericRuntimeTrace(string arg0) => Report(Diagnostic.GenericRuntimeTrace.Event([arg0])); + + /// + /// The 'GenericJniTrace' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericJniTrace(string arg0) => Report(Diagnostic.GenericJniTrace.Event([arg0])); + + /// + /// The 'GenericCompilerTrace' diagnostic. + /// + /// +/// {arg0} + /// + public void GenericCompilerTrace(string arg0) => Report(Diagnostic.GenericCompilerTrace.Event([arg0])); + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.tt b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.tt new file mode 100644 index 0000000000..f696877cb9 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticEventHandler.g.tt @@ -0,0 +1,57 @@ +<#@ template debug="false" hostspecific="true" language="C#" compilerOptions="/unsafe" #> +<#@ include file="Diagnostic.t4" #> +<#@ assembly name="System.CodeDom" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Memory" #> +<#@ assembly name="System.Buffers" #> +<#@ assembly name="Newtonsoft.Json" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Buffers" #> +<#@ import namespace="System.CodeDom" #> +<#@ import namespace="System.CodeDom.Compiler" #> +<#@ import namespace="System.Diagnostics" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Runtime.CompilerServices" #> +<#@ import namespace="System.Runtime.InteropServices" #> +<#@ import namespace="Newtonsoft.Json" #> +<#@ import namespace="Newtonsoft.Json.Linq" #> +<#@ output extension=".cs" #> +#nullable enable + +namespace IKVM.CoreLib.Diagnostics +{ + + internal abstract partial class DiagnosticEventHandler + { + +<# +foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnostic.json")))) +{ + var desc = kvp.Value.Description; + if (string.IsNullOrWhiteSpace(desc)) + desc = $"The '{kvp.Key}' diagnostic."; + + var argDecl = new List(); + foreach (var arg in kvp.Value.Args) + argDecl.Add($"{arg.Type} {arg.Name}"); + + var argList = new List(); + foreach (var arg in kvp.Value.Args) + argList.Add($"{arg.Name}"); +#> + /// + /// <#= desc #> + /// + /// +<#= Util.ToCommentString(kvp.Value.Message ?? "") #> + /// + public void <#= kvp.Key #>(<#= string.Join(", ", argDecl) #>) => Report(Diagnostic.<#= kvp.Key #>.Event([<#= string.Join(", ", argList) #>])); + +<# +} +#> + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/DiagnosticLevel.cs b/src/IKVM.CoreLib/Diagnostics/DiagnosticLevel.cs new file mode 100644 index 0000000000..767dfcf1f4 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/DiagnosticLevel.cs @@ -0,0 +1,17 @@ +namespace IKVM.CoreLib.Diagnostics +{ + + /// + /// Represents the level of security of a diagnostic event. + enum DiagnosticLevel + { + + Trace, + Informational, + Warning, + Error, + Fatal, + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/IDiagnosticEventHandler.cs b/src/IKVM.CoreLib/Diagnostics/IDiagnosticEventHandler.cs new file mode 100644 index 0000000000..8768497ef7 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/IDiagnosticEventHandler.cs @@ -0,0 +1,25 @@ +namespace IKVM.CoreLib.Diagnostics +{ + + /// + /// Exposes a method to accept diagnostic events. + /// + interface IDiagnosticEventHandler + { + + /// + /// Returns true if the specified is enabled. + /// + /// + /// + bool IsEnabled(Diagnostic diagnostic); + + /// + /// Reports a diagnostic event. + /// + /// + void Report(in DiagnosticEvent @event); + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.cs b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.cs new file mode 100644 index 0000000000..2838efdda6 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.cs @@ -0,0 +1,19 @@ +namespace IKVM.CoreLib.Diagnostics +{ + + /// + /// Exposes methods to accept diagnostic invocations. + /// + partial interface IDiagnosticHandler + { + + /// + /// Returns true if the specified is enabled. + /// + /// + /// + bool IsEnabled(Diagnostic diagnostic); + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs new file mode 100644 index 0000000000..6d358b0b28 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.cs @@ -0,0 +1,1123 @@ +#nullable enable + +namespace IKVM.CoreLib.Diagnostics +{ + + partial interface IDiagnosticHandler + { + + /// + /// The 'MainMethodFound' diagnostic. + /// + /// +/// Found main method in class "{arg0}". + /// + void MainMethodFound(string arg0); + + /// + /// The 'OutputFileIs' diagnostic. + /// + /// +/// Output file is "{arg0}". + /// + void OutputFileIs(string arg0); + + /// + /// The 'AutoAddRef' diagnostic. + /// + /// +/// Automatically adding reference to "{arg0}". + /// + void AutoAddRef(string arg0); + + /// + /// The 'MainMethodFromManifest' diagnostic. + /// + /// +/// Using main class "{arg0}" based on jar manifest. + /// + void MainMethodFromManifest(string arg0); + + /// + /// The 'GenericCompilerInfo' diagnostic. + /// + /// +/// {arg0} + /// + void GenericCompilerInfo(string arg0); + + /// + /// The 'GenericClassLoadingInfo' diagnostic. + /// + /// +/// {arg0} + /// + void GenericClassLoadingInfo(string arg0); + + /// + /// The 'GenericVerifierInfo' diagnostic. + /// + /// +/// {arg0} + /// + void GenericVerifierInfo(string arg0); + + /// + /// The 'GenericRuntimeInfo' diagnostic. + /// + /// +/// {arg0} + /// + void GenericRuntimeInfo(string arg0); + + /// + /// The 'GenericJniInfo' diagnostic. + /// + /// +/// {arg0} + /// + void GenericJniInfo(string arg0); + + /// + /// The 'ClassNotFound' diagnostic. + /// + /// +/// Class "{arg0}" not found. + /// + void ClassNotFound(string arg0); + + /// + /// The 'ClassFormatError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (class format error "{arg1}") + /// + void ClassFormatError(string arg0, string arg1); + + /// + /// The 'DuplicateClassName' diagnostic. + /// + /// +/// Duplicate class name: "{arg0}". + /// + void DuplicateClassName(string arg0); + + /// + /// The 'IllegalAccessError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (illegal access error "{arg1}") + /// + void IllegalAccessError(string arg0, string arg1); + + /// + /// The 'VerificationError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (verification error "{arg1}") + /// + void VerificationError(string arg0, string arg1); + + /// + /// The 'NoClassDefFoundError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (missing class "{arg1}") + /// + void NoClassDefFoundError(string arg0, string arg1); + + /// + /// The 'GenericUnableToCompileError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") + /// + void GenericUnableToCompileError(string arg0, string arg1, string arg2); + + /// + /// The 'DuplicateResourceName' diagnostic. + /// + /// +/// Skipping resource (name clash): "{arg0}" + /// + void DuplicateResourceName(string arg0); + + /// + /// The 'SkippingReferencedClass' diagnostic. + /// + /// +/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") + /// + void SkippingReferencedClass(string arg0, string arg1); + + /// + /// The 'NoJniRuntime' diagnostic. + /// + /// +/// Unable to load runtime JNI assembly. + /// + void NoJniRuntime(); + + /// + /// The 'EmittedNoClassDefFoundError' diagnostic. + /// + /// +/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). + /// + void EmittedNoClassDefFoundError(string arg0, string arg1); + + /// + /// The 'EmittedIllegalAccessError' diagnostic. + /// + /// +/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") + /// + void EmittedIllegalAccessError(string arg0, string arg1); + + /// + /// The 'EmittedInstantiationError' diagnostic. + /// + /// +/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") + /// + void EmittedInstantiationError(string arg0, string arg1); + + /// + /// The 'EmittedIncompatibleClassChangeError' diagnostic. + /// + /// +/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") + /// + void EmittedIncompatibleClassChangeError(string arg0, string arg1); + + /// + /// The 'EmittedNoSuchFieldError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") + /// + void EmittedNoSuchFieldError(string arg0, string arg1); + + /// + /// The 'EmittedAbstractMethodError' diagnostic. + /// + /// +/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") + /// + void EmittedAbstractMethodError(string arg0, string arg1); + + /// + /// The 'EmittedNoSuchMethodError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") + /// + void EmittedNoSuchMethodError(string arg0, string arg1); + + /// + /// The 'EmittedLinkageError' diagnostic. + /// + /// +/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") + /// + void EmittedLinkageError(string arg0, string arg1); + + /// + /// The 'EmittedVerificationError' diagnostic. + /// + /// +/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") + /// + void EmittedVerificationError(string arg0, string arg1); + + /// + /// The 'EmittedClassFormatError' diagnostic. + /// + /// +/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") + /// + void EmittedClassFormatError(string arg0, string arg1); + + /// + /// The 'InvalidCustomAttribute' diagnostic. + /// + /// +/// Error emitting "{arg0}" custom attribute. ("{arg1}") + /// + void InvalidCustomAttribute(string arg0, string arg1); + + /// + /// The 'IgnoredCustomAttribute' diagnostic. + /// + /// +/// Custom attribute "{arg0}" was ignored. ("{arg1}") + /// + void IgnoredCustomAttribute(string arg0, string arg1); + + /// + /// The 'AssumeAssemblyVersionMatch' diagnostic. + /// + /// +/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy + /// + void AssumeAssemblyVersionMatch(string arg0, string arg1); + + /// + /// The 'InvalidDirectoryInLibOptionPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in -lib option is not valid. + /// + void InvalidDirectoryInLibOptionPath(string arg0); + + /// + /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in LIB environment is not valid. + /// + void InvalidDirectoryInLibEnvironmentPath(string arg0); + + /// + /// The 'LegacySearchRule' diagnostic. + /// + /// +/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. + /// + void LegacySearchRule(string arg0); + + /// + /// The 'AssemblyLocationIgnored' diagnostic. + /// + /// +/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". + /// + void AssemblyLocationIgnored(string arg0, string arg1, string arg2); + + /// + /// The 'InterfaceMethodCantBeInternal' diagnostic. + /// + /// +/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") + /// + void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2); + + /// + /// The 'DuplicateAssemblyReference' diagnostic. + /// + /// +/// Duplicate assembly reference "{arg0}" + /// + void DuplicateAssemblyReference(string arg0); + + /// + /// The 'UnableToResolveType' diagnostic. + /// + /// +/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. + /// + void UnableToResolveType(string arg0, string arg1, string arg2); + + /// + /// The 'StubsAreDeprecated' diagnostic. + /// + /// +/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. + /// + void StubsAreDeprecated(string arg0); + + /// + /// The 'WrongClassName' diagnostic. + /// + /// +/// Unable to compile "{arg0}" (wrong name: "{arg1}") + /// + void WrongClassName(string arg0, string arg1); + + /// + /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. + /// + /// +/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") + /// + void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2); + + /// + /// The 'LegacyAssemblyAttributesFound' diagnostic. + /// + /// +/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. + /// + void LegacyAssemblyAttributesFound(); + + /// + /// The 'UnableToCreateLambdaFactory' diagnostic. + /// + /// +/// Unable to create static lambda factory. + /// + void UnableToCreateLambdaFactory(); + + /// + /// The 'UnknownWarning' diagnostic. + /// + /// +/// {arg0} + /// + void UnknownWarning(string arg0); + + /// + /// The 'DuplicateIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// + void DuplicateIkvmLangProperty(string arg0, string arg1); + + /// + /// The 'MalformedIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// + void MalformedIkvmLangProperty(string arg0, string arg1); + + /// + /// The 'GenericCompilerWarning' diagnostic. + /// + /// +/// {arg0} + /// + void GenericCompilerWarning(string arg0); + + /// + /// The 'GenericClassLoadingWarning' diagnostic. + /// + /// +/// {arg0} + /// + void GenericClassLoadingWarning(string arg0); + + /// + /// The 'GenericVerifierWarning' diagnostic. + /// + /// +/// {arg0} + /// + void GenericVerifierWarning(string arg0); + + /// + /// The 'GenericRuntimeWarning' diagnostic. + /// + /// +/// {arg0} + /// + void GenericRuntimeWarning(string arg0); + + /// + /// The 'GenericJniWarning' diagnostic. + /// + /// +/// {arg0} + /// + void GenericJniWarning(string arg0); + + /// + /// The 'UnableToCreateProxy' diagnostic. + /// + /// +/// Unable to create proxy "{arg0}". ("{arg1}") + /// + void UnableToCreateProxy(string arg0, string arg1); + + /// + /// The 'DuplicateProxy' diagnostic. + /// + /// +/// Duplicate proxy "{arg0}". + /// + void DuplicateProxy(string arg0); + + /// + /// The 'MapXmlUnableToResolveOpCode' diagnostic. + /// + /// +/// Unable to resolve opcode in remap file: {arg0}. + /// + void MapXmlUnableToResolveOpCode(string arg0); + + /// + /// The 'MapXmlError' diagnostic. + /// + /// +/// Error in remap file: {arg0}. + /// + void MapXmlError(string arg0); + + /// + /// The 'InputFileNotFound' diagnostic. + /// + /// +/// Source file '{arg0}' not found. + /// + void InputFileNotFound(string arg0); + + /// + /// The 'UnknownFileType' diagnostic. + /// + /// +/// Unknown file type: {arg0}. + /// + void UnknownFileType(string arg0); + + /// + /// The 'UnknownElementInMapFile' diagnostic. + /// + /// +/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. + /// + void UnknownElementInMapFile(string arg0, string arg1, string arg2); + + /// + /// The 'UnknownAttributeInMapFile' diagnostic. + /// + /// +/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. + /// + void UnknownAttributeInMapFile(string arg0, string arg1, string arg2); + + /// + /// The 'InvalidMemberNameInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. + /// + void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2); + + /// + /// The 'InvalidMemberSignatureInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. + /// + void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3); + + /// + /// The 'InvalidPropertyNameInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. + /// + void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3); + + /// + /// The 'InvalidPropertySignatureInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. + /// + void InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3); + + /// + /// The 'NonPrimaryAssemblyReference' diagnostic. + /// + /// +/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. + /// + void NonPrimaryAssemblyReference(string arg0, string arg1); + + /// + /// The 'MissingType' diagnostic. + /// + /// +/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. + /// + void MissingType(string arg0, string arg1); + + /// + /// The 'MissingReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. + /// + void MissingReference(string arg0, string arg1); + + /// + /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. + /// + /// +/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") + /// + void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2); + + /// + /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. + /// + /// +/// {arg0} does not implement default interface method {arg1}. + /// + void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1); + + /// + /// The 'GenericCompilerError' diagnostic. + /// + /// +/// {arg0} + /// + void GenericCompilerError(string arg0); + + /// + /// The 'GenericClassLoadingError' diagnostic. + /// + /// +/// {arg0} + /// + void GenericClassLoadingError(string arg0); + + /// + /// The 'GenericVerifierError' diagnostic. + /// + /// +/// {arg0} + /// + void GenericVerifierError(string arg0); + + /// + /// The 'GenericRuntimeError' diagnostic. + /// + /// +/// {arg0} + /// + void GenericRuntimeError(string arg0); + + /// + /// The 'GenericJniError' diagnostic. + /// + /// +/// {arg0} + /// + void GenericJniError(string arg0); + + /// + /// The 'ExportingImportsNotSupported' diagnostic. + /// + /// +/// Exporting previously imported assemblies is not supported. + /// + void ExportingImportsNotSupported(); + + /// + /// The 'ResponseFileDepthExceeded' diagnostic. + /// + /// +/// Response file nesting depth exceeded. + /// + void ResponseFileDepthExceeded(); + + /// + /// The 'ErrorReadingFile' diagnostic. + /// + /// +/// Unable to read file: {arg0}. ({arg1}) + /// + void ErrorReadingFile(string arg0, string arg1); + + /// + /// The 'NoTargetsFound' diagnostic. + /// + /// +/// No targets found + /// + void NoTargetsFound(); + + /// + /// The 'FileFormatLimitationExceeded' diagnostic. + /// + /// +/// File format limitation exceeded: {arg0}. + /// + void FileFormatLimitationExceeded(string arg0); + + /// + /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. + /// + /// +/// You cannot specify both a key file and container. + /// + void CannotSpecifyBothKeyFileAndContainer(); + + /// + /// The 'DelaySignRequiresKey' diagnostic. + /// + /// +/// You cannot delay sign without a key file or container. + /// + void DelaySignRequiresKey(); + + /// + /// The 'InvalidStrongNameKeyPair' diagnostic. + /// + /// +/// Invalid key {arg0} specified. ("{arg1}") + /// + void InvalidStrongNameKeyPair(string arg0, string arg1); + + /// + /// The 'ReferenceNotFound' diagnostic. + /// + /// +/// Reference not found: {arg0} + /// + void ReferenceNotFound(string arg0); + + /// + /// The 'OptionsMustPreceedChildLevels' diagnostic. + /// + /// +/// You can only specify options before any child levels. + /// + void OptionsMustPreceedChildLevels(); + + /// + /// The 'UnrecognizedTargetType' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -target option. + /// + void UnrecognizedTargetType(string arg0); + + /// + /// The 'UnrecognizedPlatform' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -platform option. + /// + void UnrecognizedPlatform(string arg0); + + /// + /// The 'UnrecognizedApartment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -apartment option. + /// + void UnrecognizedApartment(string arg0); + + /// + /// The 'MissingFileSpecification' diagnostic. + /// + /// +/// Missing file specification for '{arg0}' option. + /// + void MissingFileSpecification(string arg0); + + /// + /// The 'PathTooLong' diagnostic. + /// + /// +/// Path too long: {arg0}. + /// + void PathTooLong(string arg0); + + /// + /// The 'PathNotFound' diagnostic. + /// + /// +/// Path not found: {arg0}. + /// + void PathNotFound(string arg0); + + /// + /// The 'InvalidPath' diagnostic. + /// + /// +/// Invalid path: {arg0}. + /// + void InvalidPath(string arg0); + + /// + /// The 'InvalidOptionSyntax' diagnostic. + /// + /// +/// Invalid option: {arg0}. + /// + void InvalidOptionSyntax(string arg0); + + /// + /// The 'ExternalResourceNotFound' diagnostic. + /// + /// +/// External resource file does not exist: {arg0}. + /// + void ExternalResourceNotFound(string arg0); + + /// + /// The 'ExternalResourceNameInvalid' diagnostic. + /// + /// +/// External resource file may not include path specification: {arg0}. + /// + void ExternalResourceNameInvalid(string arg0); + + /// + /// The 'InvalidVersionFormat' diagnostic. + /// + /// +/// Invalid version specified: {arg0}. + /// + void InvalidVersionFormat(string arg0); + + /// + /// The 'InvalidFileAlignment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -filealign option. + /// + void InvalidFileAlignment(string arg0); + + /// + /// The 'ErrorWritingFile' diagnostic. + /// + /// +/// Unable to write file: {arg0}. ({arg1}) + /// + void ErrorWritingFile(string arg0, string arg1); + + /// + /// The 'UnrecognizedOption' diagnostic. + /// + /// +/// Unrecognized option: {arg0}. + /// + void UnrecognizedOption(string arg0); + + /// + /// The 'NoOutputFileSpecified' diagnostic. + /// + /// +/// No output file specified. + /// + void NoOutputFileSpecified(); + + /// + /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. + /// + /// +/// Incompatible options: -target:module and -sharedclassloader cannot be combined. + /// + void SharedClassLoaderCannotBeUsedOnModuleTarget(); + + /// + /// The 'RuntimeNotFound' diagnostic. + /// + /// +/// Unable to load runtime assembly. + /// + void RuntimeNotFound(); + + /// + /// The 'MainClassRequiresExe' diagnostic. + /// + /// +/// Main class cannot be specified for library or module. + /// + void MainClassRequiresExe(); + + /// + /// The 'ExeRequiresMainClass' diagnostic. + /// + /// +/// No main method found. + /// + void ExeRequiresMainClass(); + + /// + /// The 'PropertiesRequireExe' diagnostic. + /// + /// +/// Properties cannot be specified for library or module. + /// + void PropertiesRequireExe(); + + /// + /// The 'ModuleCannotHaveClassLoader' diagnostic. + /// + /// +/// Cannot specify assembly class loader for modules. + /// + void ModuleCannotHaveClassLoader(); + + /// + /// The 'ErrorParsingMapFile' diagnostic. + /// + /// +/// Unable to parse remap file: {arg0}. ({arg1}) + /// + void ErrorParsingMapFile(string arg0, string arg1); + + /// + /// The 'BootstrapClassesMissing' diagnostic. + /// + /// +/// Bootstrap classes missing and core assembly not found. + /// + void BootstrapClassesMissing(); + + /// + /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. + /// + /// +/// All referenced assemblies must be strong named, to be able to sign the output assembly. + /// + void StrongNameRequiresStrongNamedRefs(); + + /// + /// The 'MainClassNotFound' diagnostic. + /// + /// +/// Main class not found. + /// + void MainClassNotFound(); + + /// + /// The 'MainMethodNotFound' diagnostic. + /// + /// +/// Main method not found. + /// + void MainMethodNotFound(); + + /// + /// The 'UnsupportedMainMethod' diagnostic. + /// + /// +/// Redirected main method not supported. + /// + void UnsupportedMainMethod(); + + /// + /// The 'ExternalMainNotAccessible' diagnostic. + /// + /// +/// External main method must be public and in a public class. + /// + void ExternalMainNotAccessible(); + + /// + /// The 'ClassLoaderNotFound' diagnostic. + /// + /// +/// Custom assembly class loader class not found. + /// + void ClassLoaderNotFound(); + + /// + /// The 'ClassLoaderNotAccessible' diagnostic. + /// + /// +/// Custom assembly class loader class is not accessible. + /// + void ClassLoaderNotAccessible(); + + /// + /// The 'ClassLoaderIsAbstract' diagnostic. + /// + /// +/// Custom assembly class loader class is abstract. + /// + void ClassLoaderIsAbstract(); + + /// + /// The 'ClassLoaderNotClassLoader' diagnostic. + /// + /// +/// Custom assembly class loader class does not extend java.lang.ClassLoader. + /// + void ClassLoaderNotClassLoader(); + + /// + /// The 'ClassLoaderConstructorMissing' diagnostic. + /// + /// +/// Custom assembly class loader constructor is missing. + /// + void ClassLoaderConstructorMissing(); + + /// + /// The 'MapFileTypeNotFound' diagnostic. + /// + /// +/// Type '{arg0}' referenced in remap file was not found. + /// + void MapFileTypeNotFound(string arg0); + + /// + /// The 'MapFileClassNotFound' diagnostic. + /// + /// +/// Class '{arg0}' referenced in remap file was not found. + /// + void MapFileClassNotFound(string arg0); + + /// + /// The 'MaximumErrorCountReached' diagnostic. + /// + /// +/// Maximum error count reached. + /// + void MaximumErrorCountReached(); + + /// + /// The 'LinkageError' diagnostic. + /// + /// +/// Link error: {arg0} + /// + void LinkageError(string arg0); + + /// + /// The 'RuntimeMismatch' diagnostic. + /// + /// +/// Referenced assembly {arg0} was compiled with an incompatible IKVM.Runtime version. Current runtime: {arg1}. Referenced assembly runtime: {arg2} + /// + void RuntimeMismatch(string arg0, string arg1, string arg2); + + /// + /// The 'RuntimeMismatchStrongName' diagnostic. + /// + /// +/// + /// + void RuntimeMismatchStrongName(); + + /// + /// The 'CoreClassesMissing' diagnostic. + /// + /// +/// Failed to find core classes in core library. + /// + void CoreClassesMissing(); + + /// + /// The 'CriticalClassNotFound' diagnostic. + /// + /// +/// Unable to load critical class '{arg0}'. + /// + void CriticalClassNotFound(string arg0); + + /// + /// The 'AssemblyContainsDuplicateClassNames' diagnostic. + /// + /// +/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) + /// + void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3); + + /// + /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. + /// + /// +/// CallerID.getCallerID() requires a HasCallerID annotation. + /// + void CallerIDRequiresHasCallerIDAnnotation(); + + /// + /// The 'UnableToResolveInterface' diagnostic. + /// + /// +/// Unable to resolve interface '{arg0}' on type '{arg1}'. + /// + void UnableToResolveInterface(string arg0, string arg1); + + /// + /// The 'MissingBaseType' diagnostic. + /// + /// +/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. + /// + void MissingBaseType(string arg0, string arg1, string arg2, string arg3); + + /// + /// The 'MissingBaseTypeReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. + /// + void MissingBaseTypeReference(string arg0, string arg1); + + /// + /// The 'FileNotFound' diagnostic. + /// + /// +/// File not found: {arg0}. + /// + void FileNotFound(string arg0); + + /// + /// The 'RuntimeMethodMissing' diagnostic. + /// + /// +/// Runtime method '{arg0}' not found. + /// + void RuntimeMethodMissing(string arg0); + + /// + /// The 'MapFileFieldNotFound' diagnostic. + /// + /// +/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. + /// + void MapFileFieldNotFound(string arg0, string arg1); + + /// + /// The 'GhostInterfaceMethodMissing' diagnostic. + /// + /// +/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) + /// + void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3); + + /// + /// The 'ModuleInitializerMethodRequirements' diagnostic. + /// + /// +/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. + /// + void ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3); + + /// + /// The 'InvalidZip' diagnostic. + /// + /// +/// Invalid zip: {name}. + /// + void InvalidZip(string name); + + /// + /// The 'GenericRuntimeTrace' diagnostic. + /// + /// +/// {arg0} + /// + void GenericRuntimeTrace(string arg0); + + /// + /// The 'GenericJniTrace' diagnostic. + /// + /// +/// {arg0} + /// + void GenericJniTrace(string arg0); + + /// + /// The 'GenericCompilerTrace' diagnostic. + /// + /// +/// {arg0} + /// + void GenericCompilerTrace(string arg0); + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.tt b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.tt new file mode 100644 index 0000000000..947391123f --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/IDiagnosticHandler.g.tt @@ -0,0 +1,53 @@ +<#@ template debug="false" hostspecific="true" language="C#" compilerOptions="/unsafe" #> +<#@ include file="Diagnostic.t4" #> +<#@ assembly name="System.CodeDom" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Memory" #> +<#@ assembly name="System.Buffers" #> +<#@ assembly name="Newtonsoft.Json" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Buffers" #> +<#@ import namespace="System.CodeDom" #> +<#@ import namespace="System.CodeDom.Compiler" #> +<#@ import namespace="System.Diagnostics" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Runtime.CompilerServices" #> +<#@ import namespace="System.Runtime.InteropServices" #> +<#@ import namespace="Newtonsoft.Json" #> +<#@ import namespace="Newtonsoft.Json.Linq" #> +<#@ output extension=".cs" #> +#nullable enable + +namespace IKVM.CoreLib.Diagnostics +{ + + partial interface IDiagnosticHandler + { + +<# +foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("Diagnostic.json")))) +{ + var desc = kvp.Value.Description; + if (string.IsNullOrWhiteSpace(desc)) + desc = $"The '{kvp.Key}' diagnostic."; + + var argList = new List(); + for (int i = 0; i < kvp.Value.Args.Count; i++) + argList.Add($"{kvp.Value.Args[i].Type} {kvp.Value.Args[i].Name}"); +#> + /// + /// <#= desc #> + /// + /// +<#= Util.ToCommentString(kvp.Value.Message ?? "") #> + /// + void <#= kvp.Key #>(<#= string.Join(", ", argList) #>); + +<# +} +#> + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.cs b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.cs new file mode 100644 index 0000000000..30dfc194fe --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.cs @@ -0,0 +1,82 @@ +using System; +using System.Diagnostics.Tracing; + +namespace IKVM.CoreLib.Diagnostics.Tracing +{ + + /// + /// Provides a to receive emitted IKVM diagnostic messages. + /// + [EventSource(Name = "IKVM")] + unsafe partial class DiagnosticEventSource : EventSource, IDiagnosticHandler + { + + /// + /// Gets the default instance of this event source. + /// + public static readonly DiagnosticEventSource Instance = new DiagnosticEventSource(); + + /// + /// Initializes a new instance. + /// + DiagnosticEventSource() : base(EventSourceSettings.EtwSelfDescribingEventFormat | EventSourceSettings.ThrowOnEventWriteErrors) + { + + } + + /// + [NonEvent] + bool IDiagnosticHandler.IsEnabled(Diagnostic diagnostic) + { + return IsEnabled(ToLevel(diagnostic.Level), EventKeywords.All); + } + + /// + /// Translates a to a . + /// + /// + /// + /// + [NonEvent] + EventLevel ToLevel(DiagnosticLevel level) + { + return level switch + { + DiagnosticLevel.Trace => EventLevel.Verbose, + DiagnosticLevel.Informational => EventLevel.Informational, + DiagnosticLevel.Warning => EventLevel.Warning, + DiagnosticLevel.Error => EventLevel.Error, + DiagnosticLevel.Fatal => EventLevel.Critical, + _ => throw new NotImplementedException() + }; + } + + [NonEvent] + void WriteEvent(int eventId, string arg0, string arg1, string arg2, string arg3) + { + arg0 ??= ""; + arg1 ??= ""; + arg2 ??= ""; + arg3 ??= ""; + + fixed (char* arg0Ptr = arg0) + fixed (char* arg1Ptr = arg1) + fixed (char* arg2Ptr = arg2) + fixed (char* arg3Ptr = arg3) + { + var ptr = stackalloc EventData[4]; + ptr[0].DataPointer = (IntPtr)arg0Ptr; + ptr[0].Size = (arg0.Length + 1) * 2; + ptr[1].DataPointer = (IntPtr)arg1Ptr; + ptr[1].Size = (arg1.Length + 1) * 2; + ptr[2].DataPointer = (IntPtr)arg2Ptr; + ptr[2].Size = (arg2.Length + 1) * 2; + ptr[3].DataPointer = (IntPtr)arg3Ptr; + ptr[3].Size = (arg3.Length + 1) * 2; + WriteEventCore(eventId, 4, ptr); + } + } + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs new file mode 100644 index 0000000000..7303095dab --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.cs @@ -0,0 +1,1276 @@ +#nullable enable + +using System.Diagnostics.Tracing; + +namespace IKVM.CoreLib.Diagnostics.Tracing +{ + + public partial class DiagnosticEventSource + { + + /// + /// The 'MainMethodFound' diagnostic. + /// + /// +/// Found main method in class "{arg0}". + /// + [Event(1, Message = "Found main method in class \"{0}\".", Level = EventLevel.Informational)] + public void MainMethodFound(string arg0) => WriteEvent(1, arg0); + + /// + /// The 'OutputFileIs' diagnostic. + /// + /// +/// Output file is "{arg0}". + /// + [Event(2, Message = "Output file is \"{0}\".", Level = EventLevel.Informational)] + public void OutputFileIs(string arg0) => WriteEvent(2, arg0); + + /// + /// The 'AutoAddRef' diagnostic. + /// + /// +/// Automatically adding reference to "{arg0}". + /// + [Event(3, Message = "Automatically adding reference to \"{0}\".", Level = EventLevel.Informational)] + public void AutoAddRef(string arg0) => WriteEvent(3, arg0); + + /// + /// The 'MainMethodFromManifest' diagnostic. + /// + /// +/// Using main class "{arg0}" based on jar manifest. + /// + [Event(4, Message = "Using main class \"{0}\" based on jar manifest.", Level = EventLevel.Informational)] + public void MainMethodFromManifest(string arg0) => WriteEvent(4, arg0); + + /// + /// The 'GenericCompilerInfo' diagnostic. + /// + /// +/// {arg0} + /// + [Event(5, Message = "{0}", Level = EventLevel.Informational)] + public void GenericCompilerInfo(string arg0) => WriteEvent(5, arg0); + + /// + /// The 'GenericClassLoadingInfo' diagnostic. + /// + /// +/// {arg0} + /// + [Event(6, Message = "{0}", Level = EventLevel.Informational)] + public void GenericClassLoadingInfo(string arg0) => WriteEvent(6, arg0); + + /// + /// The 'GenericVerifierInfo' diagnostic. + /// + /// +/// {arg0} + /// + [Event(7, Message = "{0}", Level = EventLevel.Informational)] + public void GenericVerifierInfo(string arg0) => WriteEvent(7, arg0); + + /// + /// The 'GenericRuntimeInfo' diagnostic. + /// + /// +/// {arg0} + /// + [Event(8, Message = "{0}", Level = EventLevel.Informational)] + public void GenericRuntimeInfo(string arg0) => WriteEvent(8, arg0); + + /// + /// The 'GenericJniInfo' diagnostic. + /// + /// +/// {arg0} + /// + [Event(9, Message = "{0}", Level = EventLevel.Informational)] + public void GenericJniInfo(string arg0) => WriteEvent(9, arg0); + + /// + /// The 'ClassNotFound' diagnostic. + /// + /// +/// Class "{arg0}" not found. + /// + [Event(100, Message = "Class \"{0}\" not found.", Level = EventLevel.Warning)] + public void ClassNotFound(string arg0) => WriteEvent(100, arg0); + + /// + /// The 'ClassFormatError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (class format error "{arg1}") + /// + [Event(101, Message = "Unable to compile class \"{0}\". (class format error \"{1}\")", Level = EventLevel.Warning)] + public void ClassFormatError(string arg0, string arg1) => WriteEvent(101, arg0, arg1); + + /// + /// The 'DuplicateClassName' diagnostic. + /// + /// +/// Duplicate class name: "{arg0}". + /// + [Event(102, Message = "Duplicate class name: \"{0}\".", Level = EventLevel.Warning)] + public void DuplicateClassName(string arg0) => WriteEvent(102, arg0); + + /// + /// The 'IllegalAccessError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (illegal access error "{arg1}") + /// + [Event(103, Message = "Unable to compile class \"{0}\". (illegal access error \"{1}\")", Level = EventLevel.Warning)] + public void IllegalAccessError(string arg0, string arg1) => WriteEvent(103, arg0, arg1); + + /// + /// The 'VerificationError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (verification error "{arg1}") + /// + [Event(104, Message = "Unable to compile class \"{0}\". (verification error \"{1}\")", Level = EventLevel.Warning)] + public void VerificationError(string arg0, string arg1) => WriteEvent(104, arg0, arg1); + + /// + /// The 'NoClassDefFoundError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". (missing class "{arg1}") + /// + [Event(105, Message = "Unable to compile class \"{0}\". (missing class \"{1}\")", Level = EventLevel.Warning)] + public void NoClassDefFoundError(string arg0, string arg1) => WriteEvent(105, arg0, arg1); + + /// + /// The 'GenericUnableToCompileError' diagnostic. + /// + /// +/// Unable to compile class "{arg0}". ("{arg1}": "{arg2}") + /// + [Event(106, Message = "Unable to compile class \"{0}\". (\"{1}\": \"{2}\")", Level = EventLevel.Warning)] + public void GenericUnableToCompileError(string arg0, string arg1, string arg2) => WriteEvent(106, arg0, arg1, arg2); + + /// + /// The 'DuplicateResourceName' diagnostic. + /// + /// +/// Skipping resource (name clash): "{arg0}" + /// + [Event(107, Message = "Skipping resource (name clash): \"{0}\"", Level = EventLevel.Warning)] + public void DuplicateResourceName(string arg0) => WriteEvent(107, arg0); + + /// + /// The 'SkippingReferencedClass' diagnostic. + /// + /// +/// Skipping class: "{arg0}". (class is already available in referenced assembly "{arg1}") + /// + [Event(109, Message = "Skipping class: \"{0}\". (class is already available in referenced assembly \"{1}\")", Level = EventLevel.Warning)] + public void SkippingReferencedClass(string arg0, string arg1) => WriteEvent(109, arg0, arg1); + + /// + /// The 'NoJniRuntime' diagnostic. + /// + /// +/// Unable to load runtime JNI assembly. + /// + [Event(110, Message = "Unable to load runtime JNI assembly.", Level = EventLevel.Warning)] + public void NoJniRuntime() => WriteEvent(110); + + /// + /// The 'EmittedNoClassDefFoundError' diagnostic. + /// + /// +/// Emitted java.lang.NoClassDefFoundError in "{arg0}". ("{arg1}"). + /// + [Event(111, Message = "Emitted java.lang.NoClassDefFoundError in \"{0}\". (\"{1}\").", Level = EventLevel.Warning)] + public void EmittedNoClassDefFoundError(string arg0, string arg1) => WriteEvent(111, arg0, arg1); + + /// + /// The 'EmittedIllegalAccessError' diagnostic. + /// + /// +/// Emitted java.lang.IllegalAccessError in "{arg0}". ("{arg1}") + /// + [Event(112, Message = "Emitted java.lang.IllegalAccessError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedIllegalAccessError(string arg0, string arg1) => WriteEvent(112, arg0, arg1); + + /// + /// The 'EmittedInstantiationError' diagnostic. + /// + /// +/// Emitted java.lang.InstantiationError in "{arg0}". ("{arg1}") + /// + [Event(113, Message = "Emitted java.lang.InstantiationError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedInstantiationError(string arg0, string arg1) => WriteEvent(113, arg0, arg1); + + /// + /// The 'EmittedIncompatibleClassChangeError' diagnostic. + /// + /// +/// Emitted java.lang.IncompatibleClassChangeError in "{arg0}". ("{arg1}") + /// + [Event(114, Message = "Emitted java.lang.IncompatibleClassChangeError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedIncompatibleClassChangeError(string arg0, string arg1) => WriteEvent(114, arg0, arg1); + + /// + /// The 'EmittedNoSuchFieldError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchFieldError in "{arg0}". ("{arg1}") + /// + [Event(115, Message = "Emitted java.lang.NoSuchFieldError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedNoSuchFieldError(string arg0, string arg1) => WriteEvent(115, arg0, arg1); + + /// + /// The 'EmittedAbstractMethodError' diagnostic. + /// + /// +/// Emitted java.lang.AbstractMethodError in "{arg0}". ("{arg1}") + /// + [Event(116, Message = "Emitted java.lang.AbstractMethodError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedAbstractMethodError(string arg0, string arg1) => WriteEvent(116, arg0, arg1); + + /// + /// The 'EmittedNoSuchMethodError' diagnostic. + /// + /// +/// Emitted java.lang.NoSuchMethodError in "{arg0}". ("{arg1}") + /// + [Event(117, Message = "Emitted java.lang.NoSuchMethodError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedNoSuchMethodError(string arg0, string arg1) => WriteEvent(117, arg0, arg1); + + /// + /// The 'EmittedLinkageError' diagnostic. + /// + /// +/// Emitted java.lang.LinkageError in "{arg0}". ("{arg1}") + /// + [Event(118, Message = "Emitted java.lang.LinkageError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedLinkageError(string arg0, string arg1) => WriteEvent(118, arg0, arg1); + + /// + /// The 'EmittedVerificationError' diagnostic. + /// + /// +/// Emitted java.lang.VerificationError in "{arg0}". ("{arg1}") + /// + [Event(119, Message = "Emitted java.lang.VerificationError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedVerificationError(string arg0, string arg1) => WriteEvent(119, arg0, arg1); + + /// + /// The 'EmittedClassFormatError' diagnostic. + /// + /// +/// Emitted java.lang.ClassFormatError in "{arg0}". ("{arg1}") + /// + [Event(120, Message = "Emitted java.lang.ClassFormatError in \"{0}\". (\"{1}\")", Level = EventLevel.Warning)] + public void EmittedClassFormatError(string arg0, string arg1) => WriteEvent(120, arg0, arg1); + + /// + /// The 'InvalidCustomAttribute' diagnostic. + /// + /// +/// Error emitting "{arg0}" custom attribute. ("{arg1}") + /// + [Event(121, Message = "Error emitting \"{0}\" custom attribute. (\"{1}\")", Level = EventLevel.Warning)] + public void InvalidCustomAttribute(string arg0, string arg1) => WriteEvent(121, arg0, arg1); + + /// + /// The 'IgnoredCustomAttribute' diagnostic. + /// + /// +/// Custom attribute "{arg0}" was ignored. ("{arg1}") + /// + [Event(122, Message = "Custom attribute \"{0}\" was ignored. (\"{1}\")", Level = EventLevel.Warning)] + public void IgnoredCustomAttribute(string arg0, string arg1) => WriteEvent(122, arg0, arg1); + + /// + /// The 'AssumeAssemblyVersionMatch' diagnostic. + /// + /// +/// Assuming assembly reference "{arg0}" matches "{arg1}", you may need to supply runtime policy + /// + [Event(123, Message = "Assuming assembly reference \"{0}\" matches \"{1}\", you may need to supply runtime p" + + "olicy", Level = EventLevel.Warning)] + public void AssumeAssemblyVersionMatch(string arg0, string arg1) => WriteEvent(123, arg0, arg1); + + /// + /// The 'InvalidDirectoryInLibOptionPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in -lib option is not valid. + /// + [Event(124, Message = "Directory \"{0}\" specified in -lib option is not valid.", Level = EventLevel.Warning)] + public void InvalidDirectoryInLibOptionPath(string arg0) => WriteEvent(124, arg0); + + /// + /// The 'InvalidDirectoryInLibEnvironmentPath' diagnostic. + /// + /// +/// Directory "{arg0}" specified in LIB environment is not valid. + /// + [Event(125, Message = "Directory \"{0}\" specified in LIB environment is not valid.", Level = EventLevel.Warning)] + public void InvalidDirectoryInLibEnvironmentPath(string arg0) => WriteEvent(125, arg0); + + /// + /// The 'LegacySearchRule' diagnostic. + /// + /// +/// Found assembly "{arg0}" using legacy search rule, please append '.dll' to the reference. + /// + [Event(126, Message = "Found assembly \"{0}\" using legacy search rule, please append \'.dll\' to the refere" + + "nce.", Level = EventLevel.Warning)] + public void LegacySearchRule(string arg0) => WriteEvent(126, arg0); + + /// + /// The 'AssemblyLocationIgnored' diagnostic. + /// + /// +/// Assembly "{arg0}" is ignored as previously loaded assembly "{arg1}" has the same identity "{arg2}". + /// + [Event(127, Message = "Assembly \"{0}\" is ignored as previously loaded assembly \"{1}\" has the same identi" + + "ty \"{2}\".", Level = EventLevel.Warning)] + public void AssemblyLocationIgnored(string arg0, string arg1, string arg2) => WriteEvent(127, arg0, arg1, arg2); + + /// + /// The 'InterfaceMethodCantBeInternal' diagnostic. + /// + /// +/// Ignoring @ikvm.lang.Internal annotation on interface method. ("{arg0}.{arg1}{arg2}") + /// + [Event(128, Message = "Ignoring @ikvm.lang.Internal annotation on interface method. (\"{0}.{1}{2}\")", Level = EventLevel.Warning)] + public void InterfaceMethodCantBeInternal(string arg0, string arg1, string arg2) => WriteEvent(128, arg0, arg1, arg2); + + /// + /// The 'DuplicateAssemblyReference' diagnostic. + /// + /// +/// Duplicate assembly reference "{arg0}" + /// + [Event(132, Message = "Duplicate assembly reference \"{0}\"", Level = EventLevel.Warning)] + public void DuplicateAssemblyReference(string arg0) => WriteEvent(132, arg0); + + /// + /// The 'UnableToResolveType' diagnostic. + /// + /// +/// Reference in "{arg0}" to type "{arg1}" claims it is defined in "{arg2}", but it could not be found. + /// + [Event(133, Message = "Reference in \"{0}\" to type \"{1}\" claims it is defined in \"{2}\", but it could not " + + "be found.", Level = EventLevel.Warning)] + public void UnableToResolveType(string arg0, string arg1, string arg2) => WriteEvent(133, arg0, arg1, arg2); + + /// + /// The 'StubsAreDeprecated' diagnostic. + /// + /// +/// Compiling stubs is deprecated. Please add a reference to assembly "{arg0}" instead. + /// + [Event(134, Message = "Compiling stubs is deprecated. Please add a reference to assembly \"{0}\" instead.", Level = EventLevel.Warning)] + public void StubsAreDeprecated(string arg0) => WriteEvent(134, arg0); + + /// + /// The 'WrongClassName' diagnostic. + /// + /// +/// Unable to compile "{arg0}" (wrong name: "{arg1}") + /// + [Event(135, Message = "Unable to compile \"{0}\" (wrong name: \"{1}\")", Level = EventLevel.Warning)] + public void WrongClassName(string arg0, string arg1) => WriteEvent(135, arg0, arg1); + + /// + /// The 'ReflectionCallerClassRequiresCallerID' diagnostic. + /// + /// +/// Reflection.getCallerClass() called from non-CallerID method. ("{arg0}.{arg1}{arg2}") + /// + [Event(136, Message = "Reflection.getCallerClass() called from non-CallerID method. (\"{0}.{1}{2}\")", Level = EventLevel.Warning)] + public void ReflectionCallerClassRequiresCallerID(string arg0, string arg1, string arg2) => WriteEvent(136, arg0, arg1, arg2); + + /// + /// The 'LegacyAssemblyAttributesFound' diagnostic. + /// + /// +/// Legacy assembly attributes container found. Please use the -assemblyattributes: option. + /// + [Event(137, Message = "Legacy assembly attributes container found. Please use the -assemblyattributes: option.", Level = EventLevel.Warning)] + public void LegacyAssemblyAttributesFound() => WriteEvent(137); + + /// + /// The 'UnableToCreateLambdaFactory' diagnostic. + /// + /// +/// Unable to create static lambda factory. + /// + [Event(138, Message = "Unable to create static lambda factory.", Level = EventLevel.Warning)] + public void UnableToCreateLambdaFactory() => WriteEvent(138); + + /// + /// The 'UnknownWarning' diagnostic. + /// + /// +/// {arg0} + /// + [Event(999, Message = "{0}", Level = EventLevel.Warning)] + public void UnknownWarning(string arg0) => WriteEvent(999, arg0); + + /// + /// The 'DuplicateIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// + [Event(139, Message = "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}.", Level = EventLevel.Warning)] + public void DuplicateIkvmLangProperty(string arg0, string arg1) => WriteEvent(139, arg0, arg1); + + /// + /// The 'MalformedIkvmLangProperty' diagnostic. + /// + /// +/// Ignoring duplicate ikvm.lang.Property annotation on {arg0}.{arg1}. + /// + [Event(140, Message = "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}.", Level = EventLevel.Warning)] + public void MalformedIkvmLangProperty(string arg0, string arg1) => WriteEvent(140, arg0, arg1); + + /// + /// The 'GenericCompilerWarning' diagnostic. + /// + /// +/// {arg0} + /// + [Event(141, Message = "{0}", Level = EventLevel.Warning)] + public void GenericCompilerWarning(string arg0) => WriteEvent(141, arg0); + + /// + /// The 'GenericClassLoadingWarning' diagnostic. + /// + /// +/// {arg0} + /// + [Event(142, Message = "{0}", Level = EventLevel.Warning)] + public void GenericClassLoadingWarning(string arg0) => WriteEvent(142, arg0); + + /// + /// The 'GenericVerifierWarning' diagnostic. + /// + /// +/// {arg0} + /// + [Event(143, Message = "{0}", Level = EventLevel.Warning)] + public void GenericVerifierWarning(string arg0) => WriteEvent(143, arg0); + + /// + /// The 'GenericRuntimeWarning' diagnostic. + /// + /// +/// {arg0} + /// + [Event(144, Message = "{0}", Level = EventLevel.Warning)] + public void GenericRuntimeWarning(string arg0) => WriteEvent(144, arg0); + + /// + /// The 'GenericJniWarning' diagnostic. + /// + /// +/// {arg0} + /// + [Event(145, Message = "{0}", Level = EventLevel.Warning)] + public void GenericJniWarning(string arg0) => WriteEvent(145, arg0); + + /// + /// The 'UnableToCreateProxy' diagnostic. + /// + /// +/// Unable to create proxy "{arg0}". ("{arg1}") + /// + [Event(4001, Message = "Unable to create proxy \"{0}\". (\"{1}\")", Level = EventLevel.Error)] + public void UnableToCreateProxy(string arg0, string arg1) => WriteEvent(4001, arg0, arg1); + + /// + /// The 'DuplicateProxy' diagnostic. + /// + /// +/// Duplicate proxy "{arg0}". + /// + [Event(4002, Message = "Duplicate proxy \"{0}\".", Level = EventLevel.Error)] + public void DuplicateProxy(string arg0) => WriteEvent(4002, arg0); + + /// + /// The 'MapXmlUnableToResolveOpCode' diagnostic. + /// + /// +/// Unable to resolve opcode in remap file: {arg0}. + /// + [Event(4003, Message = "Unable to resolve opcode in remap file: {0}.", Level = EventLevel.Error)] + public void MapXmlUnableToResolveOpCode(string arg0) => WriteEvent(4003, arg0); + + /// + /// The 'MapXmlError' diagnostic. + /// + /// +/// Error in remap file: {arg0}. + /// + [Event(4004, Message = "Error in remap file: {0}.", Level = EventLevel.Error)] + public void MapXmlError(string arg0) => WriteEvent(4004, arg0); + + /// + /// The 'InputFileNotFound' diagnostic. + /// + /// +/// Source file '{arg0}' not found. + /// + [Event(4005, Message = "Source file \'{0}\' not found.", Level = EventLevel.Error)] + public void InputFileNotFound(string arg0) => WriteEvent(4005, arg0); + + /// + /// The 'UnknownFileType' diagnostic. + /// + /// +/// Unknown file type: {arg0}. + /// + [Event(4006, Message = "Unknown file type: {0}.", Level = EventLevel.Error)] + public void UnknownFileType(string arg0) => WriteEvent(4006, arg0); + + /// + /// The 'UnknownElementInMapFile' diagnostic. + /// + /// +/// Unknown element {arg0} in remap file, line {arg1}, column {arg2}. + /// + [Event(4007, Message = "Unknown element {0} in remap file, line {1}, column {2}.", Level = EventLevel.Error)] + public void UnknownElementInMapFile(string arg0, string arg1, string arg2) => WriteEvent(4007, arg0, arg1, arg2); + + /// + /// The 'UnknownAttributeInMapFile' diagnostic. + /// + /// +/// Unknown attribute {arg0} in remap file, line {arg1}, column {arg2}. + /// + [Event(4008, Message = "Unknown attribute {0} in remap file, line {1}, column {2}.", Level = EventLevel.Error)] + public void UnknownAttributeInMapFile(string arg0, string arg1, string arg2) => WriteEvent(4008, arg0, arg1, arg2); + + /// + /// The 'InvalidMemberNameInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} name '{arg1}' in remap file in class {arg2}. + /// + [Event(4009, Message = "Invalid {0} name \'{1}\' in remap file in class {2}.", Level = EventLevel.Error)] + public void InvalidMemberNameInMapFile(string arg0, string arg1, string arg2) => WriteEvent(4009, arg0, arg1, arg2); + + /// + /// The 'InvalidMemberSignatureInMapFile' diagnostic. + /// + /// +/// Invalid {arg0} signature '{arg3}' in remap file for {arg0} {arg1}.{arg2}. + /// + [Event(4010, Message = "Invalid {0} signature \'{3}\' in remap file for {0} {1}.{2}.", Level = EventLevel.Error)] + public void InvalidMemberSignatureInMapFile(string arg0, string arg1, string arg2, string arg3) => WriteEvent(4010, arg0, arg1, arg2, arg3); + + /// + /// The 'InvalidPropertyNameInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} name '{arg3}' in remap file for property {arg1}.{arg2}. + /// + [Event(4011, Message = "Invalid property {0} name \'{3}\' in remap file for property {1}.{2}.", Level = EventLevel.Error)] + public void InvalidPropertyNameInMapFile(string arg0, string arg1, string arg2, string arg3) => WriteEvent(4011, arg0, arg1, arg2, arg3); + + /// + /// The 'InvalidPropertySignatureInMapFile' diagnostic. + /// + /// +/// Invalid property {arg0} signature '{arg3}' in remap file for property {arg1}.{arg2}. + /// + [Event(4012, Message = "Invalid property {0} signature \'{3}\' in remap file for property {1}.{2}.", Level = EventLevel.Error)] + public void InvalidPropertySignatureInMapFile(string arg0, string arg1, string arg2, string arg3) => WriteEvent(4012, arg0, arg1, arg2, arg3); + + /// + /// The 'NonPrimaryAssemblyReference' diagnostic. + /// + /// +/// Referenced assembly "{arg0}" is not the primary assembly of a shared class loader group, please reference primary assembly "{arg1}" instead. + /// + [Event(4013, Message = "Referenced assembly \"{0}\" is not the primary assembly of a shared class loader gr" + + "oup, please reference primary assembly \"{1}\" instead.", Level = EventLevel.Error)] + public void NonPrimaryAssemblyReference(string arg0, string arg1) => WriteEvent(4013, arg0, arg1); + + /// + /// The 'MissingType' diagnostic. + /// + /// +/// Reference to type "{arg0}" claims it is defined in "{arg1}", but it could not be found. + /// + [Event(4014, Message = "Reference to type \"{0}\" claims it is defined in \"{1}\", but it could not be found." + + "", Level = EventLevel.Error)] + public void MissingType(string arg0, string arg1) => WriteEvent(4014, arg0, arg1); + + /// + /// The 'MissingReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is notResponseFileDepthExceeded referenced. You must add a reference to assembly '{arg1}'. + /// + [Event(4015, Message = "The type \'{0}\' is defined in an assembly that is notResponseFileDepthExceeded ref" + + "erenced. You must add a reference to assembly \'{1}\'.", Level = EventLevel.Error)] + public void MissingReference(string arg0, string arg1) => WriteEvent(4015, arg0, arg1); + + /// + /// The 'CallerSensitiveOnUnsupportedMethod' diagnostic. + /// + /// +/// CallerSensitive annotation on unsupported method. ("{arg0}.{arg1}{arg2}") + /// + [Event(4016, Message = "CallerSensitive annotation on unsupported method. (\"{0}.{1}{2}\")", Level = EventLevel.Error)] + public void CallerSensitiveOnUnsupportedMethod(string arg0, string arg1, string arg2) => WriteEvent(4016, arg0, arg1, arg2); + + /// + /// The 'RemappedTypeMissingDefaultInterfaceMethod' diagnostic. + /// + /// +/// {arg0} does not implement default interface method {arg1}. + /// + [Event(4017, Message = "{0} does not implement default interface method {1}.", Level = EventLevel.Error)] + public void RemappedTypeMissingDefaultInterfaceMethod(string arg0, string arg1) => WriteEvent(4017, arg0, arg1); + + /// + /// The 'GenericCompilerError' diagnostic. + /// + /// +/// {arg0} + /// + [Event(4018, Message = "{0}", Level = EventLevel.Error)] + public void GenericCompilerError(string arg0) => WriteEvent(4018, arg0); + + /// + /// The 'GenericClassLoadingError' diagnostic. + /// + /// +/// {arg0} + /// + [Event(4019, Message = "{0}", Level = EventLevel.Error)] + public void GenericClassLoadingError(string arg0) => WriteEvent(4019, arg0); + + /// + /// The 'GenericVerifierError' diagnostic. + /// + /// +/// {arg0} + /// + [Event(4020, Message = "{0}", Level = EventLevel.Error)] + public void GenericVerifierError(string arg0) => WriteEvent(4020, arg0); + + /// + /// The 'GenericRuntimeError' diagnostic. + /// + /// +/// {arg0} + /// + [Event(4021, Message = "{0}", Level = EventLevel.Error)] + public void GenericRuntimeError(string arg0) => WriteEvent(4021, arg0); + + /// + /// The 'GenericJniError' diagnostic. + /// + /// +/// {arg0} + /// + [Event(4022, Message = "{0}", Level = EventLevel.Error)] + public void GenericJniError(string arg0) => WriteEvent(4022, arg0); + + /// + /// The 'ExportingImportsNotSupported' diagnostic. + /// + /// +/// Exporting previously imported assemblies is not supported. + /// + [Event(4023, Message = "Exporting previously imported assemblies is not supported.", Level = EventLevel.Error)] + public void ExportingImportsNotSupported() => WriteEvent(4023); + + /// + /// The 'ResponseFileDepthExceeded' diagnostic. + /// + /// +/// Response file nesting depth exceeded. + /// + [Event(5000, Message = "Response file nesting depth exceeded.", Level = EventLevel.Critical)] + public void ResponseFileDepthExceeded() => WriteEvent(5000); + + /// + /// The 'ErrorReadingFile' diagnostic. + /// + /// +/// Unable to read file: {arg0}. ({arg1}) + /// + [Event(5001, Message = "Unable to read file: {0}. ({1})", Level = EventLevel.Critical)] + public void ErrorReadingFile(string arg0, string arg1) => WriteEvent(5001, arg0, arg1); + + /// + /// The 'NoTargetsFound' diagnostic. + /// + /// +/// No targets found + /// + [Event(5002, Message = "No targets found", Level = EventLevel.Critical)] + public void NoTargetsFound() => WriteEvent(5002); + + /// + /// The 'FileFormatLimitationExceeded' diagnostic. + /// + /// +/// File format limitation exceeded: {arg0}. + /// + [Event(5003, Message = "File format limitation exceeded: {0}.", Level = EventLevel.Critical)] + public void FileFormatLimitationExceeded(string arg0) => WriteEvent(5003, arg0); + + /// + /// The 'CannotSpecifyBothKeyFileAndContainer' diagnostic. + /// + /// +/// You cannot specify both a key file and container. + /// + [Event(5004, Message = "You cannot specify both a key file and container.", Level = EventLevel.Critical)] + public void CannotSpecifyBothKeyFileAndContainer() => WriteEvent(5004); + + /// + /// The 'DelaySignRequiresKey' diagnostic. + /// + /// +/// You cannot delay sign without a key file or container. + /// + [Event(5005, Message = "You cannot delay sign without a key file or container.", Level = EventLevel.Critical)] + public void DelaySignRequiresKey() => WriteEvent(5005); + + /// + /// The 'InvalidStrongNameKeyPair' diagnostic. + /// + /// +/// Invalid key {arg0} specified. ("{arg1}") + /// + [Event(5006, Message = "Invalid key {0} specified. (\"{1}\")", Level = EventLevel.Critical)] + public void InvalidStrongNameKeyPair(string arg0, string arg1) => WriteEvent(5006, arg0, arg1); + + /// + /// The 'ReferenceNotFound' diagnostic. + /// + /// +/// Reference not found: {arg0} + /// + [Event(5007, Message = "Reference not found: {0}", Level = EventLevel.Critical)] + public void ReferenceNotFound(string arg0) => WriteEvent(5007, arg0); + + /// + /// The 'OptionsMustPreceedChildLevels' diagnostic. + /// + /// +/// You can only specify options before any child levels. + /// + [Event(5008, Message = "You can only specify options before any child levels.", Level = EventLevel.Critical)] + public void OptionsMustPreceedChildLevels() => WriteEvent(5008); + + /// + /// The 'UnrecognizedTargetType' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -target option. + /// + [Event(5009, Message = "Invalid value \'{0}\' for -target option.", Level = EventLevel.Critical)] + public void UnrecognizedTargetType(string arg0) => WriteEvent(5009, arg0); + + /// + /// The 'UnrecognizedPlatform' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -platform option. + /// + [Event(5010, Message = "Invalid value \'{0}\' for -platform option.", Level = EventLevel.Critical)] + public void UnrecognizedPlatform(string arg0) => WriteEvent(5010, arg0); + + /// + /// The 'UnrecognizedApartment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -apartment option. + /// + [Event(5011, Message = "Invalid value \'{0}\' for -apartment option.", Level = EventLevel.Critical)] + public void UnrecognizedApartment(string arg0) => WriteEvent(5011, arg0); + + /// + /// The 'MissingFileSpecification' diagnostic. + /// + /// +/// Missing file specification for '{arg0}' option. + /// + [Event(5012, Message = "Missing file specification for \'{0}\' option.", Level = EventLevel.Critical)] + public void MissingFileSpecification(string arg0) => WriteEvent(5012, arg0); + + /// + /// The 'PathTooLong' diagnostic. + /// + /// +/// Path too long: {arg0}. + /// + [Event(5013, Message = "Path too long: {0}.", Level = EventLevel.Critical)] + public void PathTooLong(string arg0) => WriteEvent(5013, arg0); + + /// + /// The 'PathNotFound' diagnostic. + /// + /// +/// Path not found: {arg0}. + /// + [Event(5014, Message = "Path not found: {0}.", Level = EventLevel.Critical)] + public void PathNotFound(string arg0) => WriteEvent(5014, arg0); + + /// + /// The 'InvalidPath' diagnostic. + /// + /// +/// Invalid path: {arg0}. + /// + [Event(5015, Message = "Invalid path: {0}.", Level = EventLevel.Critical)] + public void InvalidPath(string arg0) => WriteEvent(5015, arg0); + + /// + /// The 'InvalidOptionSyntax' diagnostic. + /// + /// +/// Invalid option: {arg0}. + /// + [Event(5016, Message = "Invalid option: {0}.", Level = EventLevel.Critical)] + public void InvalidOptionSyntax(string arg0) => WriteEvent(5016, arg0); + + /// + /// The 'ExternalResourceNotFound' diagnostic. + /// + /// +/// External resource file does not exist: {arg0}. + /// + [Event(5017, Message = "External resource file does not exist: {0}.", Level = EventLevel.Critical)] + public void ExternalResourceNotFound(string arg0) => WriteEvent(5017, arg0); + + /// + /// The 'ExternalResourceNameInvalid' diagnostic. + /// + /// +/// External resource file may not include path specification: {arg0}. + /// + [Event(5018, Message = "External resource file may not include path specification: {0}.", Level = EventLevel.Critical)] + public void ExternalResourceNameInvalid(string arg0) => WriteEvent(5018, arg0); + + /// + /// The 'InvalidVersionFormat' diagnostic. + /// + /// +/// Invalid version specified: {arg0}. + /// + [Event(5019, Message = "Invalid version specified: {0}.", Level = EventLevel.Critical)] + public void InvalidVersionFormat(string arg0) => WriteEvent(5019, arg0); + + /// + /// The 'InvalidFileAlignment' diagnostic. + /// + /// +/// Invalid value '{arg0}' for -filealign option. + /// + [Event(5020, Message = "Invalid value \'{0}\' for -filealign option.", Level = EventLevel.Critical)] + public void InvalidFileAlignment(string arg0) => WriteEvent(5020, arg0); + + /// + /// The 'ErrorWritingFile' diagnostic. + /// + /// +/// Unable to write file: {arg0}. ({arg1}) + /// + [Event(5021, Message = "Unable to write file: {0}. ({1})", Level = EventLevel.Critical)] + public void ErrorWritingFile(string arg0, string arg1) => WriteEvent(5021, arg0, arg1); + + /// + /// The 'UnrecognizedOption' diagnostic. + /// + /// +/// Unrecognized option: {arg0}. + /// + [Event(5022, Message = "Unrecognized option: {0}.", Level = EventLevel.Critical)] + public void UnrecognizedOption(string arg0) => WriteEvent(5022, arg0); + + /// + /// The 'NoOutputFileSpecified' diagnostic. + /// + /// +/// No output file specified. + /// + [Event(5023, Message = "No output file specified.", Level = EventLevel.Critical)] + public void NoOutputFileSpecified() => WriteEvent(5023); + + /// + /// The 'SharedClassLoaderCannotBeUsedOnModuleTarget' diagnostic. + /// + /// +/// Incompatible options: -target:module and -sharedclassloader cannot be combined. + /// + [Event(5024, Message = "Incompatible options: -target:module and -sharedclassloader cannot be combined.", Level = EventLevel.Critical)] + public void SharedClassLoaderCannotBeUsedOnModuleTarget() => WriteEvent(5024); + + /// + /// The 'RuntimeNotFound' diagnostic. + /// + /// +/// Unable to load runtime assembly. + /// + [Event(5025, Message = "Unable to load runtime assembly.", Level = EventLevel.Critical)] + public void RuntimeNotFound() => WriteEvent(5025); + + /// + /// The 'MainClassRequiresExe' diagnostic. + /// + /// +/// Main class cannot be specified for library or module. + /// + [Event(5026, Message = "Main class cannot be specified for library or module.", Level = EventLevel.Critical)] + public void MainClassRequiresExe() => WriteEvent(5026); + + /// + /// The 'ExeRequiresMainClass' diagnostic. + /// + /// +/// No main method found. + /// + [Event(5027, Message = "No main method found.", Level = EventLevel.Critical)] + public void ExeRequiresMainClass() => WriteEvent(5027); + + /// + /// The 'PropertiesRequireExe' diagnostic. + /// + /// +/// Properties cannot be specified for library or module. + /// + [Event(5028, Message = "Properties cannot be specified for library or module.", Level = EventLevel.Critical)] + public void PropertiesRequireExe() => WriteEvent(5028); + + /// + /// The 'ModuleCannotHaveClassLoader' diagnostic. + /// + /// +/// Cannot specify assembly class loader for modules. + /// + [Event(5029, Message = "Cannot specify assembly class loader for modules.", Level = EventLevel.Critical)] + public void ModuleCannotHaveClassLoader() => WriteEvent(5029); + + /// + /// The 'ErrorParsingMapFile' diagnostic. + /// + /// +/// Unable to parse remap file: {arg0}. ({arg1}) + /// + [Event(5030, Message = "Unable to parse remap file: {0}. ({1})", Level = EventLevel.Critical)] + public void ErrorParsingMapFile(string arg0, string arg1) => WriteEvent(5030, arg0, arg1); + + /// + /// The 'BootstrapClassesMissing' diagnostic. + /// + /// +/// Bootstrap classes missing and core assembly not found. + /// + [Event(5031, Message = "Bootstrap classes missing and core assembly not found.", Level = EventLevel.Critical)] + public void BootstrapClassesMissing() => WriteEvent(5031); + + /// + /// The 'StrongNameRequiresStrongNamedRefs' diagnostic. + /// + /// +/// All referenced assemblies must be strong named, to be able to sign the output assembly. + /// + [Event(5032, Message = "All referenced assemblies must be strong named, to be able to sign the output ass" + + "embly.", Level = EventLevel.Critical)] + public void StrongNameRequiresStrongNamedRefs() => WriteEvent(5032); + + /// + /// The 'MainClassNotFound' diagnostic. + /// + /// +/// Main class not found. + /// + [Event(5033, Message = "Main class not found.", Level = EventLevel.Critical)] + public void MainClassNotFound() => WriteEvent(5033); + + /// + /// The 'MainMethodNotFound' diagnostic. + /// + /// +/// Main method not found. + /// + [Event(5034, Message = "Main method not found.", Level = EventLevel.Critical)] + public void MainMethodNotFound() => WriteEvent(5034); + + /// + /// The 'UnsupportedMainMethod' diagnostic. + /// + /// +/// Redirected main method not supported. + /// + [Event(5035, Message = "Redirected main method not supported.", Level = EventLevel.Critical)] + public void UnsupportedMainMethod() => WriteEvent(5035); + + /// + /// The 'ExternalMainNotAccessible' diagnostic. + /// + /// +/// External main method must be public and in a public class. + /// + [Event(5036, Message = "External main method must be public and in a public class.", Level = EventLevel.Critical)] + public void ExternalMainNotAccessible() => WriteEvent(5036); + + /// + /// The 'ClassLoaderNotFound' diagnostic. + /// + /// +/// Custom assembly class loader class not found. + /// + [Event(5037, Message = "Custom assembly class loader class not found.", Level = EventLevel.Critical)] + public void ClassLoaderNotFound() => WriteEvent(5037); + + /// + /// The 'ClassLoaderNotAccessible' diagnostic. + /// + /// +/// Custom assembly class loader class is not accessible. + /// + [Event(5038, Message = "Custom assembly class loader class is not accessible.", Level = EventLevel.Critical)] + public void ClassLoaderNotAccessible() => WriteEvent(5038); + + /// + /// The 'ClassLoaderIsAbstract' diagnostic. + /// + /// +/// Custom assembly class loader class is abstract. + /// + [Event(5039, Message = "Custom assembly class loader class is abstract.", Level = EventLevel.Critical)] + public void ClassLoaderIsAbstract() => WriteEvent(5039); + + /// + /// The 'ClassLoaderNotClassLoader' diagnostic. + /// + /// +/// Custom assembly class loader class does not extend java.lang.ClassLoader. + /// + [Event(5040, Message = "Custom assembly class loader class does not extend java.lang.ClassLoader.", Level = EventLevel.Critical)] + public void ClassLoaderNotClassLoader() => WriteEvent(5040); + + /// + /// The 'ClassLoaderConstructorMissing' diagnostic. + /// + /// +/// Custom assembly class loader constructor is missing. + /// + [Event(5041, Message = "Custom assembly class loader constructor is missing.", Level = EventLevel.Critical)] + public void ClassLoaderConstructorMissing() => WriteEvent(5041); + + /// + /// The 'MapFileTypeNotFound' diagnostic. + /// + /// +/// Type '{arg0}' referenced in remap file was not found. + /// + [Event(5042, Message = "Type \'{0}\' referenced in remap file was not found.", Level = EventLevel.Critical)] + public void MapFileTypeNotFound(string arg0) => WriteEvent(5042, arg0); + + /// + /// The 'MapFileClassNotFound' diagnostic. + /// + /// +/// Class '{arg0}' referenced in remap file was not found. + /// + [Event(5043, Message = "Class \'{0}\' referenced in remap file was not found.", Level = EventLevel.Critical)] + public void MapFileClassNotFound(string arg0) => WriteEvent(5043, arg0); + + /// + /// The 'MaximumErrorCountReached' diagnostic. + /// + /// +/// Maximum error count reached. + /// + [Event(5044, Message = "Maximum error count reached.", Level = EventLevel.Critical)] + public void MaximumErrorCountReached() => WriteEvent(5044); + + /// + /// The 'LinkageError' diagnostic. + /// + /// +/// Link error: {arg0} + /// + [Event(5045, Message = "Link error: {0}", Level = EventLevel.Critical)] + public void LinkageError(string arg0) => WriteEvent(5045, arg0); + + /// + /// The 'RuntimeMismatch' diagnostic. + /// + /// +/// Referenced assembly {arg0} was compiled with an incompatible IKVM.Runtime version. Current runtime: {arg1}. Referenced assembly runtime: {arg2} + /// + [Event(5046, Message = "Referenced assembly {0} was compiled with an incompatible IKVM.Runtime version. C" + + "urrent runtime: {1}. Referenced assembly runtime: {2}", Level = EventLevel.Critical)] + public void RuntimeMismatch(string arg0, string arg1, string arg2) => WriteEvent(5046, arg0, arg1, arg2); + + /// + /// The 'RuntimeMismatchStrongName' diagnostic. + /// + /// +/// + /// + [Event(5047, Message = "", Level = EventLevel.Critical)] + public void RuntimeMismatchStrongName() => WriteEvent(5047); + + /// + /// The 'CoreClassesMissing' diagnostic. + /// + /// +/// Failed to find core classes in core library. + /// + [Event(5048, Message = "Failed to find core classes in core library.", Level = EventLevel.Critical)] + public void CoreClassesMissing() => WriteEvent(5048); + + /// + /// The 'CriticalClassNotFound' diagnostic. + /// + /// +/// Unable to load critical class '{arg0}'. + /// + [Event(5049, Message = "Unable to load critical class \'{0}\'.", Level = EventLevel.Critical)] + public void CriticalClassNotFound(string arg0) => WriteEvent(5049, arg0); + + /// + /// The 'AssemblyContainsDuplicateClassNames' diagnostic. + /// + /// +/// Type '{arg0}' and '{arg1}' both map to the same name '{arg2}'. ({arg3}) + /// + [Event(5050, Message = "Type \'{0}\' and \'{1}\' both map to the same name \'{2}\'. ({3})", Level = EventLevel.Critical)] + public void AssemblyContainsDuplicateClassNames(string arg0, string arg1, string arg2, string arg3) => WriteEvent(5050, arg0, arg1, arg2, arg3); + + /// + /// The 'CallerIDRequiresHasCallerIDAnnotation' diagnostic. + /// + /// +/// CallerID.getCallerID() requires a HasCallerID annotation. + /// + [Event(5051, Message = "CallerID.getCallerID() requires a HasCallerID annotation.", Level = EventLevel.Critical)] + public void CallerIDRequiresHasCallerIDAnnotation() => WriteEvent(5051); + + /// + /// The 'UnableToResolveInterface' diagnostic. + /// + /// +/// Unable to resolve interface '{arg0}' on type '{arg1}'. + /// + [Event(5052, Message = "Unable to resolve interface \'{0}\' on type \'{1}\'.", Level = EventLevel.Critical)] + public void UnableToResolveInterface(string arg0, string arg1) => WriteEvent(5052, arg0, arg1); + + /// + /// The 'MissingBaseType' diagnostic. + /// + /// +/// The base class or interface '{arg0}' in assembly '{arg1}' referenced by type '{arg2}' in '{arg3}' could not be resolved. + /// + [Event(5053, Message = "The base class or interface \'{0}\' in assembly \'{1}\' referenced by type \'{2}\' in \'" + + "{3}\' could not be resolved.", Level = EventLevel.Critical)] + public void MissingBaseType(string arg0, string arg1, string arg2, string arg3) => WriteEvent(5053, arg0, arg1, arg2, arg3); + + /// + /// The 'MissingBaseTypeReference' diagnostic. + /// + /// +/// The type '{arg0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{arg1}'. + /// + [Event(5054, Message = "The type \'{0}\' is defined in an assembly that is not referenced. You must add a r" + + "eference to assembly \'{1}\'.", Level = EventLevel.Critical)] + public void MissingBaseTypeReference(string arg0, string arg1) => WriteEvent(5054, arg0, arg1); + + /// + /// The 'FileNotFound' diagnostic. + /// + /// +/// File not found: {arg0}. + /// + [Event(5055, Message = "File not found: {0}.", Level = EventLevel.Critical)] + public void FileNotFound(string arg0) => WriteEvent(5055, arg0); + + /// + /// The 'RuntimeMethodMissing' diagnostic. + /// + /// +/// Runtime method '{arg0}' not found. + /// + [Event(5056, Message = "Runtime method \'{0}\' not found.", Level = EventLevel.Critical)] + public void RuntimeMethodMissing(string arg0) => WriteEvent(5056, arg0); + + /// + /// The 'MapFileFieldNotFound' diagnostic. + /// + /// +/// Field '{arg0}' referenced in remap file was not found in class '{arg1}'. + /// + [Event(5057, Message = "Field \'{0}\' referenced in remap file was not found in class \'{1}\'.", Level = EventLevel.Critical)] + public void MapFileFieldNotFound(string arg0, string arg1) => WriteEvent(5057, arg0, arg1); + + /// + /// The 'GhostInterfaceMethodMissing' diagnostic. + /// + /// +/// Remapped class '{arg0}' does not implement ghost interface method. ({arg1}.{arg2}{arg3}) + /// + [Event(5058, Message = "Remapped class \'{0}\' does not implement ghost interface method. ({1}.{2}{3})", Level = EventLevel.Critical)] + public void GhostInterfaceMethodMissing(string arg0, string arg1, string arg2, string arg3) => WriteEvent(5058, arg0, arg1, arg2, arg3); + + /// + /// The 'ModuleInitializerMethodRequirements' diagnostic. + /// + /// +/// Method '{arg1}.{arg2}{arg3}' does not meet the requirements of a module initializer. + /// + [Event(5059, Message = "Method \'{0}.{1}{2}\' does not meet the requirements of a module initializer.", Level = EventLevel.Critical)] + public void ModuleInitializerMethodRequirements(string arg1, string arg2, string arg3) => WriteEvent(5059, arg1, arg2, arg3); + + /// + /// The 'InvalidZip' diagnostic. + /// + /// +/// Invalid zip: {name}. + /// + [Event(5060, Message = "Invalid zip: {0}.", Level = EventLevel.Critical)] + public void InvalidZip(string name) => WriteEvent(5060, name); + + /// + /// The 'GenericRuntimeTrace' diagnostic. + /// + /// +/// {arg0} + /// + [Event(6000, Message = "{0}", Level = EventLevel.Verbose)] + public void GenericRuntimeTrace(string arg0) => WriteEvent(6000, arg0); + + /// + /// The 'GenericJniTrace' diagnostic. + /// + /// +/// {arg0} + /// + [Event(6001, Message = "{0}", Level = EventLevel.Verbose)] + public void GenericJniTrace(string arg0) => WriteEvent(6001, arg0); + + /// + /// The 'GenericCompilerTrace' diagnostic. + /// + /// +/// {arg0} + /// + [Event(6002, Message = "{0}", Level = EventLevel.Verbose)] + public void GenericCompilerTrace(string arg0) => WriteEvent(6002, arg0); + + } + +} diff --git a/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt new file mode 100644 index 0000000000..f40d2df5c5 --- /dev/null +++ b/src/IKVM.CoreLib/Diagnostics/Tracing/DiagnosticEventSource.g.tt @@ -0,0 +1,72 @@ +<#@ template debug="false" hostspecific="true" language="C#" compilerOptions="/unsafe" #> +<#@ include file="..\Diagnostic.t4" #> +<#@ assembly name="System.CodeDom" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Memory" #> +<#@ assembly name="System.Buffers" #> +<#@ assembly name="Newtonsoft.Json" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Buffers" #> +<#@ import namespace="System.CodeDom" #> +<#@ import namespace="System.CodeDom.Compiler" #> +<#@ import namespace="System.Diagnostics" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Runtime.CompilerServices" #> +<#@ import namespace="System.Runtime.InteropServices" #> +<#@ import namespace="Newtonsoft.Json" #> +<#@ import namespace="Newtonsoft.Json.Linq" #> +<#@ output extension=".cs" #> +#nullable enable + +using System.Diagnostics.Tracing; + +namespace IKVM.CoreLib.Diagnostics.Tracing +{ + + public partial class DiagnosticEventSource + { + +<# +foreach (var kvp in DiagnosticFile.Read(Host.ResolvePath(Path.Combine("..", "Diagnostic.json")))) +{ + var desc = kvp.Value.Description; + if (string.IsNullOrWhiteSpace(desc)) + desc = $"The '{kvp.Key}' diagnostic."; + + var level = kvp.Value.Level; + if (level == "Fatal") + level = "Critical"; + if (level == "Trace") + level = "Verbose"; + + var message = new List(); + foreach (var segment in CompositeFormat.Parse(kvp.Value.Message ?? "").Segments) + message.Add(segment.Literal != null ? segment.Literal : $"{{{kvp.Value.Args.FindIndex(i => i.Name == segment.Arg)}}}"); + + var argDecl = new List(); + foreach (var arg in kvp.Value.Args) + argDecl.Add($"{arg.Type} {arg.Name}"); + + var argList = new List(); + argList.Add(kvp.Value.Id.ToString()); + foreach (var arg in kvp.Value.Args) + argList.Add($"{arg.Name}"); + +#> + /// + /// <#= desc #> + /// + /// +<#= Util.ToCommentString(kvp.Value.Message) #> + /// + [Event(<#= kvp.Value.Id #>, Message = <#= Util.ToStringLiteral(string.Join("", message)) #>, Level = EventLevel.<#= level #>)] + public void <#= kvp.Key #>(<#= string.Join(", ", argDecl) #>) => WriteEvent(<#= string.Join(", ", argList) #>); + +<# +} +#> + } + +} diff --git a/src/IKVM.CoreLib/IKVM.CoreLib.csproj b/src/IKVM.CoreLib/IKVM.CoreLib.csproj new file mode 100644 index 0000000000..36523d0b22 --- /dev/null +++ b/src/IKVM.CoreLib/IKVM.CoreLib.csproj @@ -0,0 +1,74 @@ + + + Library + net472;net6.0;net8.0 + enable + true + + + + + + + + + + + + + + + DiagnosticEvent.g.cs + TextTemplatingFileGenerator + + + TextTemplatingFileGenerator + Diagnostic.g.cs + + + DiagnosticEventHandler.g.cs + TextTemplatingFileGenerator + + + TextTemplatingFileGenerator + IDiagnosticHandler.g.cs + + + DiagnosticEventSource.g.cs + TextTemplatingFileGenerator + + + + + + + + + + DiagnosticEvent.g.tt + True + True + + + True + True + Diagnostic.g.tt + + + DiagnosticEventHandler.g.tt + True + True + + + True + True + IDiagnosticHandler.g.tt + + + DiagnosticEventSource.g.tt + True + True + + + + diff --git a/src/IKVM.CoreLib/System/Index.cs b/src/IKVM.CoreLib/System/Index.cs new file mode 100644 index 0000000000..f29a3ab473 --- /dev/null +++ b/src/IKVM.CoreLib/System/Index.cs @@ -0,0 +1,151 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NETSTANDARD2_1 || NET +#else +using System.Runtime.CompilerServices; + +namespace System; + +/// Represent a type can be used to index a collection either from the start or the end. +/// +/// Index is used by the C# compiler to support the new index syntax +/// +/// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ; +/// int lastElement = someArray[^1]; // lastElement = 5 +/// +/// +readonly struct Index : IEquatable +{ + private readonly int _value; + + /// Construct an Index using a value and indicating if the index is from the start or from the end. + /// The index value. it has to be zero or positive number. + /// Indicating if the index is from the start or from the end. + /// + /// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element. + /// +#if !NET35 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public Index(int value, bool fromEnd = false) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + if (fromEnd) + _value = ~value; + else + _value = value; + } + + // The following private constructors mainly created for perf reason to avoid the checks + private Index(int value) + { + _value = value; + } + + /// Create an Index pointing at first element. + public static Index Start => new Index(0); + + /// Create an Index pointing at beyond last element. + public static Index End => new Index(~0); + + /// Create an Index from the start at the position indicated by the value. + /// The index value from the start. +#if !NET35 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public static Index FromStart(int value) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + return new Index(value); + } + + /// Create an Index from the end at the position indicated by the value. + /// The index value from the end. +#if !NET35 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public static Index FromEnd(int value) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + return new Index(~value); + } + + /// Returns the index value. + public int Value + { + get + { + if (_value < 0) + return ~_value; + else + return _value; + } + } + + /// Indicates whether the index is from the start or the end. + public bool IsFromEnd => _value < 0; + + /// Calculate the offset from the start using the giving collection length. + /// The length of the collection that the Index will be used with. length has to be a positive value + /// + /// For performance reason, we don't validate the input length parameter and the returned offset value against negative values. + /// we don't validate either the returned offset is greater than the input length. + /// It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and + /// then used to index a collection will get out of range exception which will be same affect as the validation. + /// +#if !NET35 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public int GetOffset(int length) + { + int offset = _value; + if (IsFromEnd) + { + // offset = length - (~value) + // offset = length + (~(~value) + 1) + // offset = length + value + 1 + + offset += length + 1; + } + return offset; + } + + /// Indicates whether the current Index object is equal to another object of the same type. + /// An object to compare with this object + public override bool Equals(object? value) => value is Index && _value == ((Index)value)._value; + + /// Indicates whether the current Index object is equal to another Index object. + /// An object to compare with this object + public bool Equals(Index other) => _value == other._value; + + /// Returns the hash code for this instance. + public override int GetHashCode() => _value; + + /// Converts integer number to an Index. + public static implicit operator Index(int value) => FromStart(value); + + /// Converts the value of the current Index object to its equivalent string representation. + public override string ToString() + { + if (IsFromEnd) + return "^" + ((uint)Value).ToString(); + + return ((uint)Value).ToString(); + } +} + +#endif diff --git a/src/IKVM.CoreLib/System/Range.cs b/src/IKVM.CoreLib/System/Range.cs new file mode 100644 index 0000000000..eeda47db4d --- /dev/null +++ b/src/IKVM.CoreLib/System/Range.cs @@ -0,0 +1,94 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NETSTANDARD2_1 || NET +#else +using System.Runtime.CompilerServices; + +namespace System; + +/// Represent a range has start and end indexes. +/// +/// Range is used by the C# compiler to support the range syntax. +/// +/// int[] someArray = new int[5] { 1, 2, 3, 4, 5 }; +/// int[] subArray1 = someArray[0..2]; // { 1, 2 } +/// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 } +/// +/// +readonly struct Range : IEquatable +{ + /// Represent the inclusive start index of the Range. + public Index Start { get; } + + /// Represent the exclusive end index of the Range. + public Index End { get; } + + /// Construct a Range object using the start and end indexes. + /// Represent the inclusive start index of the range. + /// Represent the exclusive end index of the range. + public Range(Index start, Index end) + { + Start = start; + End = end; + } + + /// Indicates whether the current Range object is equal to another object of the same type. + /// An object to compare with this object + public override bool Equals(object? value) => + value is Range r && + r.Start.Equals(Start) && + r.End.Equals(End); + + /// Indicates whether the current Range object is equal to another Range object. + /// An object to compare with this object + public bool Equals(Range other) => other.Start.Equals(Start) && other.End.Equals(End); + + /// Returns the hash code for this instance. + public override int GetHashCode() + { + return Start.GetHashCode() * 31 + End.GetHashCode(); + } + + /// Converts the value of the current Range object to its equivalent string representation. + public override string ToString() + { + return Start + ".." + End; + } + + /// Create a Range object starting from start index to the end of the collection. + public static Range StartAt(Index start) => new Range(start, Index.End); + + /// Create a Range object starting from first element in the collection to the end Index. + public static Range EndAt(Index end) => new Range(Index.Start, end); + + /// Create a Range object starting from first element to the end. + public static Range All => new Range(Index.Start, Index.End); + + /// Calculate the start offset and length of range object using a collection length. + /// The length of the collection that the range will be used with. length has to be a positive value. + /// + /// For performance reason, we don't validate the input length parameter against negative values. + /// It is expected Range will be used with collections which always have non negative length/count. + /// We validate the range is inside the length scope though. + /// +#if !NET35 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + [CLSCompliant(false)] + public (int Offset, int Length) GetOffsetAndLength(int length) + { + int start = Start.GetOffset(length); + int end = End.GetOffset(length); + + if ((uint)end > (uint)length || (uint)start > (uint)end) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + return (start, end - start); + } +} + +#endif diff --git a/src/IKVM.CoreLib/System/Runtime/CompilerServices/IsExternalInit.cs b/src/IKVM.CoreLib/System/Runtime/CompilerServices/IsExternalInit.cs new file mode 100644 index 0000000000..e251a1ef91 --- /dev/null +++ b/src/IKVM.CoreLib/System/Runtime/CompilerServices/IsExternalInit.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET45 || NET451 || NET452 || NET6 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48 + +using System.ComponentModel; + +// ReSharper disable once CheckNamespace +namespace System.Runtime.CompilerServices +{ + /// + /// Reserved to be used by the compiler for tracking metadata. + /// This class should not be used by developers in source code. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class IsExternalInit + { + } +} + +#endif diff --git a/src/IKVM.Runtime-ref/IKVM.Runtime-ref.csproj b/src/IKVM.Runtime-ref/IKVM.Runtime-ref.csproj index 919af962fb..c315a05186 100644 --- a/src/IKVM.Runtime-ref/IKVM.Runtime-ref.csproj +++ b/src/IKVM.Runtime-ref/IKVM.Runtime-ref.csproj @@ -13,6 +13,7 @@ + diff --git a/src/IKVM.Runtime/Annotation.cs b/src/IKVM.Runtime/Annotation.cs index 55b3c7e33e..dec264adf4 100644 --- a/src/IKVM.Runtime/Annotation.cs +++ b/src/IKVM.Runtime/Annotation.cs @@ -26,6 +26,8 @@ Jeroen Frijters using IKVM.Attributes; + + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -98,7 +100,7 @@ internal static Annotation Load(RuntimeJavaType owner, object[] def) if (ClassFile.IsValidFieldSig(annotationClass)) { - RuntimeJavaType tw = owner.GetClassLoader().RetTypeWrapperFromSig(annotationClass.Replace('/', '.'), LoadMode.Link); + var tw = owner.ClassLoader.RetTypeWrapperFromSig(annotationClass.Replace('/', '.'), LoadMode.Link); // Java allows inaccessible annotations to be used, so when the annotation isn't visible // we fall back to using the DynamicAnnotationAttribute. if (!tw.IsUnloadable && tw.IsAccessibleFrom(owner)) @@ -106,7 +108,8 @@ internal static Annotation Load(RuntimeJavaType owner, object[] def) return tw.Annotation; } } - Tracer.Warning(Tracer.Compiler, "Unable to load annotation class {0}", annotationClass); + + owner.Diagnostics.GenericCompilerWarning($"Unable to load annotation class {annotationClass}"); #if IMPORTER return new RuntimeManagedByteCodeJavaType.CompiledAnnotation(owner.Context, owner.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute")); #else diff --git a/src/IKVM.Runtime/Assertions.cs b/src/IKVM.Runtime/Assertions.cs index 2d27f273e9..64e3d12f16 100644 --- a/src/IKVM.Runtime/Assertions.cs +++ b/src/IKVM.Runtime/Assertions.cs @@ -130,7 +130,7 @@ internal static bool IsEnabled(RuntimeJavaType tw) } while (len > 0); } - return tw.GetClassLoader() == tw.Context.ClassLoaderFactory.GetBootstrapClassLoader() ? sysAsserts : userAsserts; + return tw.ClassLoader == tw.Context.ClassLoaderFactory.GetBootstrapClassLoader() ? sysAsserts : userAsserts; } private static int Count(OptionNode n) diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs index a8da1548c4..d38c6b8452 100644 --- a/src/IKVM.Runtime/AttributeHelper.cs +++ b/src/IKVM.Runtime/AttributeHelper.cs @@ -28,6 +28,7 @@ Jeroen Frijters using System.Runtime.CompilerServices; using IKVM.Attributes; +using IKVM.CoreLib.Diagnostics; using IKVM.ByteCode.Buffers; using IKVM.ByteCode.Decoding; using IKVM.ByteCode.Encoding; @@ -199,7 +200,7 @@ object ParseValue(RuntimeClassLoader loader, RuntimeJavaType tw, string val) } else if (tw.IsUnloadable) { - throw new FatalCompilerErrorException(Message.MapFileTypeNotFound, tw.Name); + throw new FatalCompilerErrorException(Diagnostic.MapFileTypeNotFound.Event([tw.Name])); } else if (tw.TypeAsTBD.IsEnum) { diff --git a/src/IKVM.Runtime/BootstrapClassLoader.cs b/src/IKVM.Runtime/BootstrapClassLoader.cs index 324562d7c1..43653d49d3 100644 --- a/src/IKVM.Runtime/BootstrapClassLoader.cs +++ b/src/IKVM.Runtime/BootstrapClassLoader.cs @@ -24,6 +24,7 @@ Jeroen Frijters using System; using System.Collections.Generic; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -43,7 +44,7 @@ sealed class BootstrapClassLoader : RuntimeAssemblyClassLoader /// Initializes a new instance. /// internal BootstrapClassLoader(RuntimeContext context) : - base(context, context.Resolver.ResolveBaseAssembly(), new string[] { typeof(object).Assembly.FullName, typeof(Uri).Assembly.FullName }) + base(context, context.Resolver.ResolveBaseAssembly(), [typeof(object).Assembly.FullName, typeof(Uri).Assembly.FullName]) { #if FIRST_PASS == false && IMPORTER == false && EXPORTER == false RegisterNativeLibrary(LibJava.Instance.Handle); diff --git a/src/IKVM.Runtime/ByteCodeHelperMethods.cs b/src/IKVM.Runtime/ByteCodeHelperMethods.cs index c424a33e93..8cd03badb9 100644 --- a/src/IKVM.Runtime/ByteCodeHelperMethods.cs +++ b/src/IKVM.Runtime/ByteCodeHelperMethods.cs @@ -23,7 +23,7 @@ Jeroen Frijters */ using System; -using IKVM.Runtime; +using IKVM.CoreLib.Diagnostics; #if IMPORTER using IKVM.Reflection; @@ -179,7 +179,7 @@ static MethodInfo GetHelper(Type type, string method, Type[] parameters) var mi = parameters == null ? type.GetMethod(method) : type.GetMethod(method, parameters); if (mi == null) #if IMPORTER - throw new FatalCompilerErrorException(Message.RuntimeMethodMissing, method); + throw new FatalCompilerErrorException(Diagnostic.RuntimeMethodMissing.Event([method])); #else throw new InternalException("Missing ByteCodeHelper method in runtime."); #endif diff --git a/src/IKVM.Runtime/ClassFile.ConstantPoolItemClass.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemClass.cs index 06c0e92ab1..b7a207aed1 100644 --- a/src/IKVM.Runtime/ClassFile.ConstantPoolItemClass.cs +++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemClass.cs @@ -167,13 +167,13 @@ internal override void Link(RuntimeJavaType thisType, LoadMode mode) { if (typeWrapper == Context.VerifierJavaTypeFactory.Null) { - var tw = thisType.GetClassLoader().LoadClass(name, mode | LoadMode.WarnClassNotFound); + var tw = thisType.ClassLoader.LoadClass(name, mode | LoadMode.WarnClassNotFound); #if !IMPORTER && !FIRST_PASS if (!tw.IsUnloadable) { try { - thisType.GetClassLoader().CheckPackageAccess(tw, thisType.ClassObject.pd); + thisType.ClassLoader.CheckPackageAccess(tw, thisType.ClassObject.pd); } catch (java.lang.SecurityException) { diff --git a/src/IKVM.Runtime/ClassFile.ConstantPoolItemFieldref.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemFieldref.cs index 4ff50358ce..4a52b5cf7c 100644 --- a/src/IKVM.Runtime/ClassFile.ConstantPoolItemFieldref.cs +++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemFieldref.cs @@ -87,7 +87,7 @@ internal override void Link(RuntimeJavaType thisType, LoadMode mode) fw.Link(mode); } } - RuntimeClassLoader classLoader = thisType.GetClassLoader(); + RuntimeClassLoader classLoader = thisType.ClassLoader; RuntimeJavaType fld = classLoader.FieldTypeWrapperFromSig(this.Signature, mode); lock (this) { diff --git a/src/IKVM.Runtime/ClassFile.ConstantPoolItemInvokeDynamic.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemInvokeDynamic.cs index 35ad95e918..0da5ef78a1 100644 --- a/src/IKVM.Runtime/ClassFile.ConstantPoolItemInvokeDynamic.cs +++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemInvokeDynamic.cs @@ -74,7 +74,7 @@ internal override void Link(RuntimeJavaType thisType, LoadMode mode) } } - var classLoader = thisType.GetClassLoader(); + var classLoader = thisType.ClassLoader; var args = classLoader.ArgJavaTypeListFromSig(descriptor, mode); var ret = classLoader.RetTypeWrapperFromSig(descriptor, mode); diff --git a/src/IKVM.Runtime/ClassFile.ConstantPoolItemMI.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMI.cs index 10f2574b5d..fa8b36218f 100644 --- a/src/IKVM.Runtime/ClassFile.ConstantPoolItemMI.cs +++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMI.cs @@ -79,7 +79,7 @@ internal override void Link(RuntimeJavaType thisType, LoadMode mode) return; } } - RuntimeClassLoader classLoader = thisType.GetClassLoader(); + RuntimeClassLoader classLoader = thisType.ClassLoader; RuntimeJavaType[] args = classLoader.ArgJavaTypeListFromSig(this.Signature, mode); RuntimeJavaType ret = classLoader.RetTypeWrapperFromSig(this.Signature, mode); lock (this) diff --git a/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodType.cs b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodType.cs index b17327c9e6..edf4cee7cf 100644 --- a/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodType.cs +++ b/src/IKVM.Runtime/ClassFile.ConstantPoolItemMethodType.cs @@ -69,7 +69,7 @@ internal override void Link(RuntimeJavaType thisType, LoadMode mode) } } - var classLoader = thisType.GetClassLoader(); + var classLoader = thisType.ClassLoader; var args = classLoader.ArgJavaTypeListFromSig(descriptor, mode); var ret = classLoader.RetTypeWrapperFromSig(descriptor, mode); diff --git a/src/IKVM.Runtime/ClassFile.Field.cs b/src/IKVM.Runtime/ClassFile.Field.cs index fb6dc3ab99..83d561f4f7 100644 --- a/src/IKVM.Runtime/ClassFile.Field.cs +++ b/src/IKVM.Runtime/ClassFile.Field.cs @@ -26,6 +26,7 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.ByteCode; using IKVM.ByteCode.Decoding; +using IKVM.CoreLib.Diagnostics; namespace IKVM.Runtime { @@ -154,7 +155,7 @@ private void DecodePropertyAnnotation(ClassFile classFile, object[] annot) { if (propertyGetterSetter != null) { - Tracer.Error(Tracer.ClassLoading, "Ignoring duplicate ikvm.lang.Property annotation on {0}.{1}", classFile.Name, this.Name); + classFile.diagnostics.GenericClassLoadingError($"Ignoring duplicate ikvm.lang.Property annotation on {classFile.Name}.{this.Name}"); return; } @@ -185,7 +186,7 @@ private void DecodePropertyAnnotation(ClassFile classFile, object[] annot) if (propertyGetterSetter == null || propertyGetterSetter[0] == null) { propertyGetterSetter = null; - Tracer.Error(Tracer.ClassLoading, "Ignoring malformed ikvm.lang.Property annotation on {0}.{1}", classFile.Name, this.Name); + classFile.diagnostics.GenericClassLoadingError($"Ignoring malformed ikvm.lang.Property annotation on {classFile.Name}.{Name}"); return; } } diff --git a/src/IKVM.Runtime/ClassFile.Method.cs b/src/IKVM.Runtime/ClassFile.Method.cs index 140e0b1d3b..c84b8900c6 100644 --- a/src/IKVM.Runtime/ClassFile.Method.cs +++ b/src/IKVM.Runtime/ClassFile.Method.cs @@ -24,6 +24,8 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.ByteCode; using IKVM.ByteCode.Decoding; +using IKVM.CoreLib.Diagnostics; + #if IMPORTER using IKVM.Tools.Importer; @@ -181,7 +183,7 @@ internal Method(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions opt { if (classFile.IsInterface) { - classFile.context.StaticCompiler.IssueMessage(Message.InterfaceMethodCantBeInternal, classFile.Name, Name, Signature); + classFile.diagnostics.InterfaceMethodCantBeInternal(classFile.Name, Name, Signature); } else { @@ -206,7 +208,7 @@ internal Method(ClassFile classFile, string[] utf8_cp, ClassFileParseOptions opt { if (classFile.IsInterface || IsConstructor || IsClassInitializer || IsPrivate || IsStatic == false) { - classFile.context.StaticCompiler.IssueMessage(Message.ModuleInitializerMethodRequirements, classFile.Name, Name, Signature); + classFile.diagnostics.ModuleInitializerMethodRequirements(classFile.Name, Name, Signature); } else { diff --git a/src/IKVM.Runtime/ClassFile.cs b/src/IKVM.Runtime/ClassFile.cs index 2031b302b4..15e6759b04 100644 --- a/src/IKVM.Runtime/ClassFile.cs +++ b/src/IKVM.Runtime/ClassFile.cs @@ -28,6 +28,7 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.ByteCode; using IKVM.ByteCode.Decoding; +using IKVM.CoreLib.Diagnostics; namespace IKVM.Runtime { @@ -45,6 +46,7 @@ sealed partial class ClassFile : IDisposable const ushort FLAG_MODULE_INITIALIZER = 0x8000; readonly RuntimeContext context; + readonly IDiagnosticHandler diagnostics; readonly IKVM.ByteCode.Decoding.ClassFile clazz; readonly ConstantPoolItem[] constantpool; @@ -126,9 +128,10 @@ static string GetClassName(IKVM.ByteCode.Decoding.ClassFile reader, out bool iss /// /// /// - internal ClassFile(RuntimeContext context, IKVM.ByteCode.Decoding.ClassFile clazz, string inputClassName, ClassFileParseOptions options, object[] constantPoolPatches) + internal ClassFile(RuntimeContext context, IDiagnosticHandler diagnostics, IKVM.ByteCode.Decoding.ClassFile clazz, string inputClassName, ClassFileParseOptions options, object[] constantPoolPatches) { this.context = context ?? throw new ArgumentNullException(nameof(context)); + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); this.clazz = clazz ?? throw new ArgumentNullException(nameof(clazz)); try diff --git a/src/IKVM.Runtime/DefineMethodHelper.cs b/src/IKVM.Runtime/DefineMethodHelper.cs index 6f5697ad7b..f04b221f46 100644 --- a/src/IKVM.Runtime/DefineMethodHelper.cs +++ b/src/IKVM.Runtime/DefineMethodHelper.cs @@ -56,7 +56,7 @@ internal int ParameterCount internal MethodBuilder DefineMethod(RuntimeByteCodeJavaType context, TypeBuilder tb, string name, MethodAttributes attribs) { - return DefineMethod(context.GetClassLoader().GetTypeWrapperFactory(), tb, name, attribs, null, false); + return DefineMethod(context.ClassLoader.GetTypeWrapperFactory(), tb, name, attribs, null, false); } internal MethodBuilder DefineMethod(RuntimeJavaTypeFactory context, TypeBuilder tb, string name, MethodAttributes attribs) @@ -96,7 +96,7 @@ internal MethodBuilder DefineMethod(RuntimeJavaTypeFactory context, TypeBuilder internal MethodBuilder DefineConstructor(RuntimeByteCodeJavaType context, TypeBuilder tb, MethodAttributes attribs) { - return DefineConstructor(context.GetClassLoader().GetTypeWrapperFactory(), tb, attribs); + return DefineConstructor(context.ClassLoader.GetTypeWrapperFactory(), tb, attribs); } internal MethodBuilder DefineConstructor(RuntimeJavaTypeFactory context, TypeBuilder tb, MethodAttributes attribs) diff --git a/src/IKVM.Runtime/DynamicCallerIDProvider.cs b/src/IKVM.Runtime/DynamicCallerIDProvider.cs index 324cd7c1e0..a1ead52906 100644 --- a/src/IKVM.Runtime/DynamicCallerIDProvider.cs +++ b/src/IKVM.Runtime/DynamicCallerIDProvider.cs @@ -67,7 +67,7 @@ internal static ikvm.@internal.CallerID CreateCallerID(RuntimeJavaType tw) #if FIRST_PASS throw new NotImplementedException(); #else - return ikvm.@internal.CallerID.create(tw.ClassObject, tw.GetClassLoader().GetJavaClassLoader()); + return ikvm.@internal.CallerID.create(tw.ClassObject, tw.ClassLoader.GetJavaClassLoader()); #endif } diff --git a/src/IKVM.Runtime/DynamicClassLoader.cs b/src/IKVM.Runtime/DynamicClassLoader.cs index b583d11e63..ce807570ae 100644 --- a/src/IKVM.Runtime/DynamicClassLoader.cs +++ b/src/IKVM.Runtime/DynamicClassLoader.cs @@ -23,11 +23,12 @@ Jeroen Frijters */ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Collections.Concurrent; + using static System.Diagnostics.DebuggableAttribute; +using IKVM.CoreLib.Diagnostics; #if IMPORTER @@ -124,7 +125,7 @@ public DynamicClassLoader GetOrCreate(RuntimeClassLoader loader) { #if IMPORTER // importer uses only one class loader, and we can just return a single dynamic class loader - return new DynamicClassLoader(context, ((CompilerClassLoader)loader).CreateModuleBuilder(), false); + return new DynamicClassLoader(context, loader.Diagnostics, ((CompilerClassLoader)loader).CreateModuleBuilder(), false); #else // each assembly class loader gets its own dynamic class loader if (loader is RuntimeAssemblyClassLoader acl) @@ -138,12 +139,12 @@ public DynamicClassLoader GetOrCreate(RuntimeClassLoader loader) #if NETFRAMEWORK n.KeyPair = DynamicClassLoader.ForgedKeyPair.Instance; #endif - return new DynamicClassLoader(context, DynamicClassLoader.CreateModuleBuilder(context, n), true); + return new DynamicClassLoader(context, loader.Diagnostics, DynamicClassLoader.CreateModuleBuilder(context, n), true); } } } - return instance ??= new DynamicClassLoader(context, DynamicClassLoader.CreateModuleBuilder(context), false); + return instance ??= new DynamicClassLoader(context, loader.Diagnostics, DynamicClassLoader.CreateModuleBuilder(context), false); #endif } @@ -179,9 +180,7 @@ public static string TypeNameMangleImpl(ConcurrentDictionary /// + /// /// /// - internal DynamicClassLoader(RuntimeContext context, ModuleBuilder moduleBuilder, bool hasInternalAccess) + internal DynamicClassLoader(RuntimeContext context, IDiagnosticHandler diagnostics, ModuleBuilder moduleBuilder, bool hasInternalAccess) { this.context = context ?? throw new ArgumentNullException(nameof(context)); + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); this.moduleBuilder = moduleBuilder; this.hasInternalAccess = hasInternalAccess; } @@ -410,7 +412,7 @@ internal void FinishAll() { more = true; done.Add(tw, tw); - Tracer.Info(Tracer.Runtime, "Finishing {0}", tw.TypeAsTBD.FullName); + diagnostics.GenericRuntimeTrace($"Finishing: {tw.TypeAsTBD.FullName}"); tw.Finish(); } } diff --git a/src/IKVM.Runtime/IKVM.Runtime.csproj b/src/IKVM.Runtime/IKVM.Runtime.csproj index a7980b19a4..3fd313ba4f 100644 --- a/src/IKVM.Runtime/IKVM.Runtime.csproj +++ b/src/IKVM.Runtime/IKVM.Runtime.csproj @@ -13,6 +13,7 @@ + diff --git a/src/IKVM.Runtime/JNI/JNIEnv.cs b/src/IKVM.Runtime/JNI/JNIEnv.cs index 9a339b68ec..be813a7e4a 100644 --- a/src/IKVM.Runtime/JNI/JNIEnv.cs +++ b/src/IKVM.Runtime/JNI/JNIEnv.cs @@ -31,6 +31,7 @@ Jeroen Frijters using System.Runtime.Serialization; using IKVM.ByteCode.Text; +using IKVM.CoreLib.Diagnostics; using IKVM.Runtime.Extensions; namespace IKVM.Runtime.JNI @@ -445,7 +446,7 @@ internal static void FatalError(JNIEnv* pEnv, byte* msg) { Console.Error.WriteLine("FATAL ERROR in native method: {0}", msg == null ? "(null)" : DecodeMUTF8Argument(msg, nameof(msg))); Console.Error.WriteLine(new StackTrace(1, true)); - Environment.Exit(1); + System.Environment.Exit(1); } /// @@ -2763,14 +2764,14 @@ internal static jint RegisterNatives(JNIEnv* pEnv, nint clazz, JNINativeMethod* { try { - RuntimeJavaType wrapper = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)); + var wrapper = RuntimeJavaType.FromClass((java.lang.Class)pEnv->UnwrapRef(clazz)); wrapper.Finish(); for (int i = 0; i < nMethods; i++) { var methodName = DecodeMUTF8(methods[i].name); var methodSig = DecodeMUTF8(methods[i].signature); - Tracer.Info(Tracer.Jni, "Registering native method: {0}.{1}{2}, fnPtr = 0x{3:X}", wrapper.Name, methodName, methodSig, ((IntPtr)methods[i].fnPtr).ToInt64()); + JVM.Context.Diagnostics.GenericJniInfo($"Registering native method: {wrapper.Name}.{methodName}{methodSig}, fnPtr = 0x{((IntPtr)methods[i].fnPtr).ToInt64():X}"); FieldInfo fi = null; // don't allow dotted names! @@ -2779,7 +2780,7 @@ internal static jint RegisterNatives(JNIEnv* pEnv, nint clazz, JNINativeMethod* if (fi == null) { - Tracer.Error(Tracer.Jni, "Failed to register native method: {0}.{1}{2}", wrapper.Name, methodName, methodSig); + JVM.Context.Diagnostics.GenericJniError($"Failed to register native method: {wrapper.Name}.{methodName}{methodSig}"); throw new java.lang.NoSuchMethodError(methodName); } @@ -2811,7 +2812,7 @@ internal static jint UnregisterNatives(JNIEnv* pEnv, nint clazz) string name = fi.Name; if (name.StartsWith(METHOD_PTR_FIELD_PREFIX)) { - Tracer.Info(Tracer.Jni, "Unregistering native method: {0}.{1}", wrapper.Name, name.Substring(METHOD_PTR_FIELD_PREFIX.Length)); + JVM.Context.Diagnostics.GenericJniInfo($"Unregistering native method: {wrapper.Name}.{name.Substring(METHOD_PTR_FIELD_PREFIX.Length)}"); fi.SetValue(null, IntPtr.Zero); } } diff --git a/src/IKVM.Runtime/JNI/JNIFrame.cs b/src/IKVM.Runtime/JNI/JNIFrame.cs index 786462e188..8876997219 100644 --- a/src/IKVM.Runtime/JNI/JNIFrame.cs +++ b/src/IKVM.Runtime/JNI/JNIFrame.cs @@ -25,35 +25,6 @@ Jeroen Frijters using System.Diagnostics; using System.Text; -using IKVM.Runtime.Accessors.Java.Lang; - -using jarray = System.IntPtr; -using jboolean = System.SByte; -using jbooleanArray = System.IntPtr; -using jbyte = System.SByte; -using jbyteArray = System.IntPtr; -using jchar = System.UInt16; -using jcharArray = System.IntPtr; -using jclass = System.IntPtr; -using jdouble = System.Double; -using jdoubleArray = System.IntPtr; -using jfieldID = System.IntPtr; -using jfloat = System.Single; -using jfloatArray = System.IntPtr; -using jint = System.Int32; -using jintArray = System.IntPtr; -using jlong = System.Int64; -using jlongArray = System.IntPtr; -using jmethodID = System.IntPtr; -using jobject = System.IntPtr; -using jobjectArray = System.IntPtr; -using jshort = System.Int16; -using jshortArray = System.IntPtr; -using jsize = System.Int32; -using jstring = System.IntPtr; -using jthrowable = System.IntPtr; -using jweak = System.IntPtr; - namespace IKVM.Runtime.JNI { @@ -113,7 +84,7 @@ public static nint GetFuncPtr(object callerID, string clazz, string name, string var mangledSig = JniMangle(sig.Substring(1, sig.IndexOf(')') - 1)); var methodName = $"Java_{mangledClass}_{mangledName}"; var longMethodName = $"Java_{mangledClass}_{mangledName}__{mangledSig}"; - Tracer.Info(Tracer.Jni, "Linking native method: {0}.{1}{2}, classLoader = {3}, methodName = {4}, longMethodName = {5}, argl = {6}", clazz, name, sig, loader, methodName, longMethodName, argl); + JVM.Context.Diagnostics.GenericJniInfo($"Linking native method: {clazz}.{name}{sig}, classLoader = {loader}, methodName = {methodName}, longMethodName = {longMethodName}, argl = {argl}"); lock (JNINativeLoader.SyncRoot) { @@ -121,20 +92,20 @@ public static nint GetFuncPtr(object callerID, string clazz, string name, string { if (LibJvm.Instance.JVM_FindLibraryEntry(p, NativeLibrary.MangleExportName(methodName, argl)) is nint h1 and not 0) { - Tracer.Info(Tracer.Jni, "Native method {0}.{1}{2} found in library 0x{3:X} (short)", clazz, name, sig, p); + JVM.Context.Diagnostics.GenericJniInfo($"Native method {clazz}.{name}{sig} found in library 0x{p:X} (short)"); return h1; } if (LibJvm.Instance.JVM_FindLibraryEntry(p, NativeLibrary.MangleExportName(longMethodName, argl)) is nint h2 and not 0) { - Tracer.Info(Tracer.Jni, "Native method {0}.{1}{2} found in library 0x{3:X} (long)", clazz, name, sig, p); + JVM.Context.Diagnostics.GenericJniInfo($"Native method {clazz}.{name}{sig} found in library 0x{p:X} (long)"); return h2; } } } var msg = $"{clazz}.{name}{sig}"; - Tracer.Error(Tracer.Jni, "UnsatisfiedLinkError: {0}", msg); + JVM.Context.Diagnostics.GenericJniError($"UnsatisfiedLinkError: {msg}"); throw new java.lang.UnsatisfiedLinkError(msg); #endif } diff --git a/src/IKVM.Runtime/JNI/JNINativeLoader.cs b/src/IKVM.Runtime/JNI/JNINativeLoader.cs index 4a7ebf1852..33650b8da1 100644 --- a/src/IKVM.Runtime/JNI/JNINativeLoader.cs +++ b/src/IKVM.Runtime/JNI/JNINativeLoader.cs @@ -25,6 +25,8 @@ Jeroen Frijters using System.Collections.Generic; using System.Runtime.InteropServices; +using IKVM.CoreLib.Diagnostics; + namespace IKVM.Runtime.JNI { @@ -50,7 +52,7 @@ static unsafe class JNINativeLoader /// public static long LoadLibrary(string filename, RuntimeJavaType fromClass) { - Tracer.Info(Tracer.Jni, "loadLibrary: '{0}' fromClass '{1}'", filename, fromClass); + JVM.Context.Diagnostics.GenericJniInfo($"loadLibrary: '{filename}' fromClass '{fromClass}'"); lock (SyncRoot) { @@ -61,17 +63,17 @@ public static long LoadLibrary(string filename, RuntimeJavaType fromClass) // attempt to load the native library if ((p = LibJvm.Instance.JVM_LoadLibrary(filename)) == 0) { - Tracer.Info(Tracer.Jni, "Failed to load library: path = '{0}', message = {2}", filename, "NULL handle returned."); + JVM.Context.Diagnostics.GenericJniInfo($"Failed to load library: path = '{filename}', message = {"NULL handle returned."}"); return 0; } // find whether the native library was already loaded - foreach (var h in fromClass.GetClassLoader().GetNativeLibraries()) + foreach (var h in fromClass.ClassLoader.GetNativeLibraries()) { if (h == p) { LibJvm.Instance.JVM_UnloadLibrary(p); - Tracer.Warning(Tracer.Jni, "Library was already loaded, returning same reference.", filename); + JVM.Context.Diagnostics.GenericJniWarning("Library was already loaded, returning same reference"); return p; } } @@ -80,25 +82,25 @@ public static long LoadLibrary(string filename, RuntimeJavaType fromClass) if (loaded.Contains(p)) { var msg = $"Native library '{filename}' already loaded in another classloader."; - Tracer.Error(Tracer.Jni, "UnsatisfiedLinkError: {0}", msg); + JVM.Context.Diagnostics.GenericJniError($"UnsatisfiedLinkError: {msg}"); throw new java.lang.UnsatisfiedLinkError(msg); } - Tracer.Info(Tracer.Jni, "Library loaded: {0}, handle = 0x{1:X}", filename, p); + JVM.Context.Diagnostics.GenericJniInfo($"Library loaded: {filename}, handle = 0x{p:X}"); try { var onload = LibJvm.Instance.JVM_FindLibraryEntry(p, NativeLibrary.MangleExportName("JNI_OnLoad", sizeof(nint) + sizeof(nint))); if (onload != 0) { - Tracer.Info(Tracer.Jni, "Calling JNI_OnLoad on: {0}", filename); + JVM.Context.Diagnostics.GenericJniInfo($"Calling JNI_OnLoad on: {filename}"); var f = new JNIFrame(); int v; var w = f.Enter(ikvm.@internal.CallerID.create(fromClass.ClassObject, fromClass.ClassObject.getClassLoader())); try { v = Marshal.GetDelegateForFunctionPointer(onload)(JavaVM.pJavaVM, null); - Tracer.Info(Tracer.Jni, "JNI_OnLoad returned: 0x{0:X8}", v); + JVM.Context.Diagnostics.GenericJniInfo($"JNI_OnLoad returned: 0x{v:X8}"); } finally { @@ -108,7 +110,7 @@ public static long LoadLibrary(string filename, RuntimeJavaType fromClass) if (JNIVM.IsSupportedJNIVersion(v) == false) { var msg = $"Unsupported JNI version 0x{v:X} required by {filename}"; - Tracer.Error(Tracer.Jni, "UnsatisfiedLinkError: {0}", msg); + JVM.Context.Diagnostics.GenericJniError($"UnsatisfiedLinkError: {msg}"); throw new java.lang.UnsatisfiedLinkError(msg); } } @@ -120,17 +122,17 @@ public static long LoadLibrary(string filename, RuntimeJavaType fromClass) // record addition of native library loaded.Add(p); - fromClass.GetClassLoader().RegisterNativeLibrary(p); + fromClass.ClassLoader.RegisterNativeLibrary(p); return p; } catch (DllNotFoundException e) { - Tracer.Info(Tracer.Jni, "Failed to load library: path = '{0}', error = {1}, message = {2}", filename, "DllNotFoundException", e.Message); + JVM.Context.Diagnostics.GenericJniInfo($"Failed to load library: path = '{filename}', error = DllNotFoundException, message = {e.Message}"); return 0; } catch (Exception e) { - Tracer.Info(Tracer.Jni, "Failed to load library: path = '{0}', error = {1}, message = {2}", filename, "Exception", e.Message); + JVM.Context.Diagnostics.GenericJniInfo($"Failed to load library: path = '{filename}', error = Exception, message = {e.Message}"); LibJvm.Instance.JVM_UnloadLibrary(p); throw; } @@ -148,14 +150,14 @@ public static void UnloadLibrary(long handle, RuntimeJavaType fromClass) lock (SyncRoot) { - Tracer.Info(Tracer.Jni, "Unloading library: handle = 0x{0:X}, class = {1}", handle, fromClass); + JVM.Context.Diagnostics.GenericJniInfo($"Unloading library: handle = 0x{handle:X}, class = {fromClass}"); try { var onunload = LibJvm.Instance.JVM_FindLibraryEntry(p, NativeLibrary.MangleExportName("JNI_OnUnload", sizeof(nint) + sizeof(nint))); if (onunload != 0) { - Tracer.Info(Tracer.Jni, "Calling JNI_OnUnload on: handle = 0x{0:X}", handle); + JVM.Context.Diagnostics.GenericJniInfo($"Calling JNI_OnUnload on: handle = 0x{handle:X}"); var f = new JNIFrame(); var w = f.Enter(ikvm.@internal.CallerID.create(fromClass.ClassObject, fromClass.ClassObject.getClassLoader())); @@ -176,7 +178,7 @@ public static void UnloadLibrary(long handle, RuntimeJavaType fromClass) // remove record of native library loaded.Remove(p); - fromClass.GetClassLoader().UnregisterNativeLibrary(p); + fromClass.ClassLoader.UnregisterNativeLibrary(p); LibJvm.Instance.JVM_UnloadLibrary(p); } } diff --git a/src/IKVM.Runtime/JVM.Internal.cs b/src/IKVM.Runtime/JVM.Internal.cs index 3527d5fb2e..4e6889482d 100644 --- a/src/IKVM.Runtime/JVM.Internal.cs +++ b/src/IKVM.Runtime/JVM.Internal.cs @@ -1,5 +1,6 @@ using System; +using IKVM.CoreLib.Diagnostics.Tracing; using IKVM.Runtime.Accessors; using IKVM.Runtime.Accessors.Java.Lang; using IKVM.Runtime.Vfs; @@ -34,7 +35,7 @@ internal static class Internal #if FIRST_PASS == false && IMPORTER == false && EXPORTER == false internal static readonly RuntimeContextOptions contextOptions = new RuntimeContextOptions(); - internal static readonly RuntimeContext context = new RuntimeContext(contextOptions, new Resolver(), false); + internal static readonly RuntimeContext context = new RuntimeContext(contextOptions, DiagnosticEventSource.Instance, new Resolver(), false); internal static readonly VfsTable vfs = VfsTable.BuildDefaultTable(new VfsRuntimeContext(context), Properties.HomePath); internal static readonly Lazy systemThreadGroup = new Lazy(() => ThreadGroupAccessor.Init()); internal static readonly Lazy mainThreadGroup = new Lazy(() => ThreadGroupAccessor.Init(null, SystemThreadGroup, "main")); diff --git a/src/IKVM.Runtime/JVM.cs b/src/IKVM.Runtime/JVM.cs index 159f7aadf5..f287af1c92 100644 --- a/src/IKVM.Runtime/JVM.cs +++ b/src/IKVM.Runtime/JVM.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading; +using IKVM.CoreLib.Diagnostics.Tracing; using IKVM.Runtime.Vfs; namespace IKVM.Runtime diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/internal/CallerID.cs b/src/IKVM.Runtime/Java/Externs/ikvm/internal/CallerID.cs index f8c0ae3108..e1867c5112 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/internal/CallerID.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/internal/CallerID.cs @@ -46,7 +46,7 @@ static class CallerID #if FIRST_PASS throw new NotImplementedException(); #else - return JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(obj.GetType().DeclaringType).GetClassLoader().GetJavaClassLoader(); + return JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(obj.GetType().DeclaringType).ClassLoader.GetJavaClassLoader(); #endif } diff --git a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AssemblyClassLoader.cs b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AssemblyClassLoader.cs index daa44364c3..8626051a86 100644 --- a/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AssemblyClassLoader.cs +++ b/src/IKVM.Runtime/Java/Externs/ikvm/runtime/AssemblyClassLoader.cs @@ -24,6 +24,7 @@ Jeroen Frijters using System; using System.Reflection; +using IKVM.CoreLib.Diagnostics; using IKVM.Runtime; using IKVM.Runtime.Accessors.Java.Lang; @@ -64,26 +65,27 @@ public static void setWrapper(global::java.lang.ClassLoader _this, Assembly asse var tw = wrapper.LoadClass(name); if (tw == null) { - Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this); + JVM.Context.Diagnostics.GenericClassLoadingInfo($"Failed to load class \"{name}\" from {_this}"); global::java.lang.Throwable.suppressFillInStackTrace = true; throw new global::java.lang.ClassNotFoundException(name); } - Tracer.Info(Tracer.ClassLoading, "Loaded class \"{0}\" from {1}", name, _this); + + JVM.Context.Diagnostics.GenericClassLoadingInfo($"Loaded class \"{name}\" from {_this}"); return tw.ClassObject; } catch (ClassNotFoundException x) { - Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this); + JVM.Context.Diagnostics.GenericClassLoadingInfo($"Failed to load class \"{name}\" from {_this}: {x.Message}"); throw new global::java.lang.ClassNotFoundException(x.Message); } catch (ClassLoadingException x) { - Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this); + JVM.Context.Diagnostics.GenericClassLoadingInfo($"Failed to load class \"{name}\" from {_this}: {x.Message}"); throw x.InnerException; } catch (RetargetableJavaException x) { - Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this); + JVM.Context.Diagnostics.GenericClassLoadingInfo($"Failed to load class \"{name}\" from {_this}: {x.Message}"); throw x.ToJava(); } #endif diff --git a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs index dc5a184f58..34a9554256 100644 --- a/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs +++ b/src/IKVM.Runtime/Java/Externs/java/io/ObjectStreamClass.cs @@ -281,7 +281,7 @@ internal FastFieldReflector(global::java.io.ObjectStreamField[] fields) RuntimeJavaType fieldType = fw.FieldTypeWrapper; try { - fieldType = fieldType.EnsureLoadable(tw.GetClassLoader()); + fieldType = fieldType.EnsureLoadable(tw.ClassLoader); fieldType.Finish(); } catch (RetargetableJavaException x) diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs index 96da4f118b..e0ae4ff524 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/Class.cs @@ -282,7 +282,7 @@ public static string getSigName(global::java.lang.Class thisClass) public static global::java.lang.ClassLoader getClassLoader0(global::java.lang.Class thisClass) { - return RuntimeJavaType.FromClass(thisClass).GetClassLoader().GetJavaClassLoader(); + return RuntimeJavaType.FromClass(thisClass).ClassLoader.GetJavaClassLoader(); } public static global::java.lang.Class getSuperclass(global::java.lang.Class thisClass) @@ -345,7 +345,7 @@ public static object[] getEnclosingMethod0(global::java.lang.Class thisClass) if (enc == null) return null; - return new object[] { tw.GetClassLoader().LoadClassByName(enc[0]).ClassObject, enc[1], enc[2] == null ? null : enc[2].Replace('.', '/') }; + return [tw.ClassLoader.LoadClassByName(enc[0]).ClassObject, enc[1], enc[2] == null ? null : enc[2].Replace('.', '/')]; } catch (RetargetableJavaException x) { @@ -363,7 +363,7 @@ public static object[] getEnclosingMethod0(global::java.lang.Class thisClass) if (decl == null) return null; - decl = decl.EnsureLoadable(wrapper.GetClassLoader()); + decl = decl.EnsureLoadable(wrapper.ClassLoader); if (!decl.IsAccessibleFrom(wrapper)) throw new IllegalAccessError(string.Format("tried to access class {0} from class {1}", decl.Name, wrapper.Name)); @@ -371,7 +371,7 @@ public static object[] getEnclosingMethod0(global::java.lang.Class thisClass) RuntimeJavaType[] declInner = decl.InnerClasses; for (int i = 0; i < declInner.Length; i++) { - if (declInner[i].Name == wrapper.Name && declInner[i].EnsureLoadable(decl.GetClassLoader()) == wrapper) + if (declInner[i].Name == wrapper.Name && declInner[i].EnsureLoadable(decl.ClassLoader) == wrapper) { return decl.ClassObject; } @@ -398,7 +398,7 @@ public static object[] getEnclosingMethod0(global::java.lang.Class thisClass) { // The protection domain for statically compiled code is created lazily (not at global::java.lang.Class creation time), // to work around boot strap issues. - var acl = wrapper.GetClassLoader() as RuntimeAssemblyClassLoader; + var acl = wrapper.ClassLoader as RuntimeAssemblyClassLoader; if (acl != null) pd = acl.GetProtectionDomain(); else if (wrapper is RuntimeAnonymousJavaType) @@ -511,7 +511,7 @@ public static object getDeclaredAnnotationsImpl(global::java.lang.Class thisClas { throw x.ToJava(); } - return AnnotationsToMap(wrapper.GetClassLoader(), wrapper.GetDeclaredAnnotations()); + return AnnotationsToMap(wrapper.ClassLoader, wrapper.GetDeclaredAnnotations()); #endif } @@ -663,7 +663,7 @@ public static object getDeclaredConstructors0(global::java.lang.Class thisClass, global::java.lang.Class[] innerclasses = new global::java.lang.Class[wrappers.Length]; for (int i = 0; i < innerclasses.Length; i++) { - RuntimeJavaType tw = wrappers[i].EnsureLoadable(wrapper.GetClassLoader()); + RuntimeJavaType tw = wrappers[i].EnsureLoadable(wrapper.ClassLoader); if (!tw.IsAccessibleFrom(wrapper)) { throw new IllegalAccessError(string.Format("tried to access class {0} from class {1}", tw.Name, wrapper.Name)); diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.cs b/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.cs index 22c39fa46d..0813d82b25 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/ClassLoader.cs @@ -149,7 +149,7 @@ static IKVM.ByteCode.Decoding.ClassFile ReadClass(byte[] buffer) try { var runtimeClassLoader = JVM.Context.ClassLoaderFactory.GetClassLoaderWrapper(self); - var classFile = new IKVM.Runtime.ClassFile(JVM.Context, clazz, name, runtimeClassLoader.ClassFileParseOptions, null); + var classFile = new IKVM.Runtime.ClassFile(JVM.Context, JVM.Context.Diagnostics, clazz, name, runtimeClassLoader.ClassFileParseOptions, null); if (name != null && classFile.Name != name) throw new global::java.lang.NoClassDefFoundError(name + " (wrong name: " + classFile.Name + ")"); diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs b/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs index ba034a7a9e..36c28392f6 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/SecurityManager.cs @@ -64,7 +64,7 @@ public static object currentClassLoader0(object thisSecurityManager) { var currentClass = currentLoadedClass0(thisSecurityManager); if (currentClass != null) - return RuntimeJavaType.FromClass(currentClass).GetClassLoader().GetJavaClassLoader(); + return RuntimeJavaType.FromClass(currentClass).ClassLoader.GetJavaClassLoader(); return null; } diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Executable.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Executable.cs index aaf1bfabe5..6b1d5dab78 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Executable.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Executable.cs @@ -62,7 +62,7 @@ public static byte[] getTypeAnnotationBytes0(global::java.lang.reflect.Executabl public static object declaredAnnotationsImpl(global::java.lang.reflect.Executable executable) { var mw = RuntimeJavaMethod.FromExecutable(executable); - return IKVM.Java.Externs.java.lang.Class.AnnotationsToMap(mw.DeclaringType.GetClassLoader(), mw.DeclaringType.GetMethodAnnotations(mw)); + return IKVM.Java.Externs.java.lang.Class.AnnotationsToMap(mw.DeclaringType.ClassLoader, mw.DeclaringType.GetMethodAnnotations(mw)); } public static object[][] sharedGetParameterAnnotationsImpl(global::java.lang.reflect.Executable executable) @@ -88,7 +88,7 @@ public static object[][] sharedGetParameterAnnotationsImpl(global::java.lang.ref } else if (obj is IKVM.Attributes.DynamicAnnotationAttribute) { - a = (global::java.lang.annotation.Annotation)JVM.NewAnnotation(mw.DeclaringType.GetClassLoader().GetJavaClassLoader(), ((IKVM.Attributes.DynamicAnnotationAttribute)obj).Definition); + a = (global::java.lang.annotation.Annotation)JVM.NewAnnotation(mw.DeclaringType.ClassLoader.GetJavaClassLoader(), ((IKVM.Attributes.DynamicAnnotationAttribute)obj).Definition); if (a != null) list.Add(a); } diff --git a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Field.cs b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Field.cs index c0a22aa2c7..3591c361a8 100644 --- a/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Field.cs +++ b/src/IKVM.Runtime/Java/Externs/java/lang/reflect/Field.cs @@ -32,7 +32,7 @@ static class Field public static object getDeclaredAnnotationsImpl(global::java.lang.reflect.Field thisField) { var fw = RuntimeJavaField.FromField(thisField); - return IKVM.Java.Externs.java.lang.Class.AnnotationsToMap(fw.DeclaringType.GetClassLoader(), fw.DeclaringType.GetFieldAnnotations(fw)); + return IKVM.Java.Externs.java.lang.Class.AnnotationsToMap(fw.DeclaringType.ClassLoader, fw.DeclaringType.GetFieldAnnotations(fw)); } public static byte[] getTypeAnnotationBytes0(global::java.lang.reflect.Field thisField) diff --git a/src/IKVM.Runtime/Java/Externs/sun/invoke/util/VerifyAccess.cs b/src/IKVM.Runtime/Java/Externs/sun/invoke/util/VerifyAccess.cs index 694f8e29d2..6a2efe9c4c 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/invoke/util/VerifyAccess.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/invoke/util/VerifyAccess.cs @@ -45,7 +45,7 @@ static class VerifyAccess return null; } - return tw.GetClassLoader().GetJavaClassLoader(); + return tw.ClassLoader.GetJavaClassLoader(); #endif } diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs index a2e3bfba89..20a8de6f9a 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/Unsafe.cs @@ -1673,8 +1673,8 @@ public static int pageSize(object self) try { var tw = RuntimeJavaType.FromClass(hostClass); - var cl = tw.GetClassLoader(); - var cf = new IKVM.Runtime.ClassFile(JVM.Context, ReadClass(data), "", cl.ClassFileParseOptions, cpPatches); + var cl = tw.ClassLoader; + var cf = new IKVM.Runtime.ClassFile(JVM.Context, JVM.Context.Diagnostics, ReadClass(data), "", cl.ClassFileParseOptions, cpPatches); // if this happens, the OpenJDK is probably trying to load an OpenJDK class file as a resource, // make sure the build process includes the original class file as a resource in that case diff --git a/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs b/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs index 4ba2aca74b..ad2eaaef57 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/misc/VM.cs @@ -62,7 +62,7 @@ public static void initialize() if (m.DeclaringType != null && JVM.Context.ClassLoaderFactory.GetJavaTypeFromType(m.DeclaringType) is RuntimeJavaType tw and not null) { // check that the assembly isn't java.base or the IKVM runtime - var clw = tw.GetClassLoader(); + var clw = tw.ClassLoader; if (clw is RuntimeAssemblyClassLoader acl) if (acl.GetAssembly(tw) == typeof(object).Assembly || acl.GetAssembly(tw) == typeof(VM).Assembly) continue; diff --git a/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs b/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs index 41301ab729..8a726ac707 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/net/www/protocol/ikvmres/Handler.cs @@ -50,32 +50,36 @@ public static byte[] GenerateStub(global::java.lang.Class c) public static Stream ReadResourceFromAssemblyImpl(Assembly asm, string resource) { +#if FIRST_PASS + throw new NotImplementedException(); +#else // chop off the leading slash resource = resource.Substring(1); - string mangledName = JVM.MangleResourceName(resource); - ManifestResourceInfo info = asm.GetManifestResourceInfo(mangledName); + var mangledName = JVM.MangleResourceName(resource); + var info = asm.GetManifestResourceInfo(mangledName); if (info != null && info.FileName != null) - { return asm.GetManifestResourceStream(mangledName); - } - Stream s = asm.GetManifestResourceStream(mangledName); + + var s = asm.GetManifestResourceStream(mangledName); if (s == null) { - Tracer.Warning(Tracer.ClassLoading, "Resource \"{0}\" not found in {1}", resource, asm.FullName); + JVM.Context.Diagnostics.GenericClassLoadingWarning($"Resource \"{resource}\" not found in {asm.FullName}"); throw new FileNotFoundException("resource " + resource + " not found in assembly " + asm.FullName); } + switch (s.ReadByte()) { case 0: - Tracer.Info(Tracer.ClassLoading, "Reading resource \"{0}\" from {1}", resource, asm.FullName); + JVM.Context.Diagnostics.GenericClassLoadingInfo($"Reading resource \"{resource}\" from {asm.FullName}"); return s; case 1: - Tracer.Info(Tracer.ClassLoading, "Reading compressed resource \"{0}\" from {1}", resource, asm.FullName); + JVM.Context.Diagnostics.GenericClassLoadingInfo($"Reading compressed resource \"{resource}\" from {asm.FullName}"); return new System.IO.Compression.DeflateStream(s, System.IO.Compression.CompressionMode.Decompress, false); default: - Tracer.Error(Tracer.ClassLoading, "Resource \"{0}\" in {1} has an unsupported encoding", resource, asm.FullName); + JVM.Context.Diagnostics.GenericClassLoadingError($"Resource \"{resource}\" in {asm.FullName} has an unsupported encoding"); throw new IOException("Unsupported resource encoding for resource " + resource + " found in assembly " + asm.FullName); } +#endif } public static object LoadClassFromAssembly(Assembly asm, string className) diff --git a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs index 9c4a43cc86..5c6488df91 100644 --- a/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs +++ b/src/IKVM.Runtime/Java/Externs/sun/reflect/ReflectionFactory.cs @@ -177,7 +177,7 @@ public object invoke(object obj, object[] args, global::ikvm.@internal.CallerID try { - args = ConvertArgs(mw.DeclaringType.GetClassLoader(), mw.GetParameters(), args); + args = ConvertArgs(mw.DeclaringType.ClassLoader, mw.GetParameters(), args); } catch (InvalidCastException e) { @@ -245,7 +245,7 @@ internal ConstructorAccessorImpl(RuntimeJavaMethod mw) [IKVM.Attributes.HideFromJava] public object newInstance(object[] args) { - args = ConvertArgs(mw.DeclaringType.GetClassLoader(), mw.GetParameters(), args); + args = ConvertArgs(mw.DeclaringType.ClassLoader, mw.GetParameters(), args); try { return mw.CreateInstance(args); @@ -290,7 +290,7 @@ public object newInstance(object[] args) var obj = RuntimeHelpers.GetUninitializedObject(type); #endif if (mw != null) - mw.Invoke(obj, ConvertArgs(mw.DeclaringType.GetClassLoader(), mw.GetParameters(), args)); + mw.Invoke(obj, ConvertArgs(mw.DeclaringType.ClassLoader, mw.GetParameters(), args)); return obj; } @@ -577,7 +577,7 @@ internal unsafe FastMethodAccessorImpl(RuntimeJavaMethod mw) for (int i = 0; i < parameters.Length; i++) { - parameters[i] = parameters[i].EnsureLoadable(mw.DeclaringType.GetClassLoader()); + parameters[i] = parameters[i].EnsureLoadable(mw.DeclaringType.ClassLoader); parameters[i].Finish(); } @@ -823,7 +823,7 @@ internal FastConstructorAccessorImpl(global::java.lang.reflect.Constructor const for (int i = 0; i < parameters.Length; i++) { - parameters[i] = parameters[i].EnsureLoadable(mw.DeclaringType.GetClassLoader()); + parameters[i] = parameters[i].EnsureLoadable(mw.DeclaringType.ClassLoader); parameters[i].Finish(); } @@ -2012,7 +2012,7 @@ internal ObjectField(RuntimeJavaField field, bool isFinal) protected sealed override void CheckValue(object value) { - if (value != null && !fw.FieldTypeWrapper.EnsureLoadable(fw.DeclaringType.GetClassLoader()).IsInstance(value)) + if (value != null && !fw.FieldTypeWrapper.EnsureLoadable(fw.DeclaringType.ClassLoader).IsInstance(value)) { throw SetIllegalArgumentException(value); } @@ -2054,7 +2054,7 @@ private Delegate GenerateFastGetter(Type delegateType, Type fieldType, RuntimeJa RuntimeJavaType fieldTypeWrapper; try { - fieldTypeWrapper = fw.FieldTypeWrapper.EnsureLoadable(fw.DeclaringType.GetClassLoader()); + fieldTypeWrapper = fw.FieldTypeWrapper.EnsureLoadable(fw.DeclaringType.ClassLoader); fieldTypeWrapper.Finish(); fw.DeclaringType.Finish(); } @@ -2100,7 +2100,7 @@ private Delegate GenerateFastSetter(Type delegateType, Type fieldType, RuntimeJa RuntimeJavaType fieldTypeWrapper; try { - fieldTypeWrapper = fw.FieldTypeWrapper.EnsureLoadable(fw.DeclaringType.GetClassLoader()); + fieldTypeWrapper = fw.FieldTypeWrapper.EnsureLoadable(fw.DeclaringType.ClassLoader); fieldTypeWrapper.Finish(); fw.DeclaringType.Finish(); } diff --git a/src/IKVM.Runtime/LambdaMetafactory.cs b/src/IKVM.Runtime/LambdaMetafactory.cs index c02667c77f..fd160d6cf1 100644 --- a/src/IKVM.Runtime/LambdaMetafactory.cs +++ b/src/IKVM.Runtime/LambdaMetafactory.cs @@ -26,6 +26,7 @@ Jeroen Frijters using System.Diagnostics; using IKVM.ByteCode; +using IKVM.CoreLib.Diagnostics; #if IMPORTER using IKVM.Reflection; @@ -58,10 +59,8 @@ internal static bool Emit(RuntimeByteCodeJavaType.FinishContext context, ClassFi if (lmf.getInstance == null && !lmf.EmitImpl(context, classFile, cpi, bsm, ilgen)) { #if IMPORTER - if (context.TypeWrapper.GetClassLoader().DisableDynamicBinding) - { - context.Context.StaticCompiler.IssueMessage(Message.UnableToCreateLambdaFactory); - } + if (context.TypeWrapper.ClassLoader.DisableDynamicBinding) + context.TypeWrapper.ClassLoader.Diagnostics.UnableToCreateLambdaFactory(); #endif return false; } @@ -440,7 +439,7 @@ private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaTyp FieldBuilder instField = tb.DefineField("inst", tb, FieldAttributes.Private | FieldAttributes.Static); // static constructor - MethodBuilder cctor = ReflectUtil.DefineTypeInitializer(tb, context.TypeWrapper.GetClassLoader()); + MethodBuilder cctor = ReflectUtil.DefineTypeInitializer(tb, context.TypeWrapper.ClassLoader); CodeEmitter ilgenCCtor = context.Context.CodeEmitterFactory.Create(cctor); ilgenCCtor.Emit(OpCodes.Newobj, ctor); ilgenCCtor.Emit(OpCodes.Stsfld, instField); @@ -508,7 +507,7 @@ private static MethodBuilder CreateConstructorAndDispatch(RuntimeByteCodeJavaTyp ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); - if (!context.TypeWrapper.GetClassLoader().NoAutomagicSerialization) + if (!context.TypeWrapper.ClassLoader.NoAutomagicSerialization) { // add .NET serialization interop support context.Context.Serialization.MarkSerializable(tb); @@ -737,7 +736,7 @@ private static void AddDefaultInterfaceMethods(RuntimeByteCodeJavaType.FinishCon { // we use special name to hide these from Java reflection const MethodAttributes attr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final | MethodAttributes.SpecialName; - RuntimeJavaTypeFactory factory = context.TypeWrapper.GetClassLoader().GetTypeWrapperFactory(); + RuntimeJavaTypeFactory factory = context.TypeWrapper.ClassLoader.GetTypeWrapperFactory(); foreach (RuntimeJavaMethod mw in methodList) { if (!mw.IsAbstract) diff --git a/src/IKVM.Runtime/Launcher.cs b/src/IKVM.Runtime/Launcher.cs index a86e528e13..18bfbc8286 100644 --- a/src/IKVM.Runtime/Launcher.cs +++ b/src/IKVM.Runtime/Launcher.cs @@ -413,22 +413,6 @@ public static int Run(Assembly assembly, string main, bool jar, string[] args, s continue; } - if (arg.StartsWith("-Xtrace:".AsSpan())) - { - if (arg.IndexOf(':') is int v && v > -1) - Tracer.SetTraceLevel(arg.Slice(v + 1).ToString()); - - continue; - } - - if (arg.StartsWith("-Xmethodtrace:".AsSpan())) - { - if (arg.IndexOf(':') is int v && v > -1) - Tracer.HandleMethodTrace(arg.Slice(v + 1).ToString()); - - continue; - } - if (arg.StartsWith("-Xreference:".AsSpan())) { if (arg.IndexOf(':') is int v && v > -1) @@ -678,10 +662,6 @@ static void PrintXHelp() Console.Error.WriteLine(" -Xbreak trigger a user defined breakpoint at startup"); Console.Error.WriteLine(" -Xnoglobbing Disable argument globbing"); Console.Error.WriteLine(" -Xverify Enable strict class file verification"); - Console.Error.WriteLine(" -Xtrace:"); - Console.Error.WriteLine(" Displays all tracepoints with the given name"); - Console.Error.WriteLine(" -Xmethodtrace:"); - Console.Error.WriteLine(" Builds method trace into the specified output methods"); Console.Error.WriteLine(); Console.Error.WriteLine("The -X options are non-standard and subject to change without notice."); Console.Error.WriteLine(); diff --git a/src/IKVM.Runtime/LibJVM.cs b/src/IKVM.Runtime/LibJVM.cs index db206bade8..dd3849bc8f 100644 --- a/src/IKVM.Runtime/LibJVM.cs +++ b/src/IKVM.Runtime/LibJVM.cs @@ -9,6 +9,7 @@ namespace IKVM.Runtime { + using IKVM.CoreLib.Diagnostics; #if FIRST_PASS == false && IMPORTER == false && EXPORTER == false @@ -178,7 +179,7 @@ void JVM_ThrowException(string name, string msg) { if (name == null) { - Tracer.Error(Tracer.Runtime, $"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Missing name argument."); + JVM.Context.Diagnostics.GenericJniError($"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Missing name argument."); return; } @@ -186,7 +187,7 @@ void JVM_ThrowException(string name, string msg) var exceptionClass = RuntimeClassLoader.FromCallerID(callerID).TryLoadClassByName(name.Replace('/', '.')); if (exceptionClass == null) { - Tracer.Error(Tracer.Runtime, $"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Could not find exception class {{0}}.", name); + JVM.Context.Diagnostics.GenericJniError($"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Could not find exception class {name}."); return; } @@ -194,7 +195,7 @@ void JVM_ThrowException(string name, string msg) var ctor = exceptionClass.GetMethodWrapper("", msg == null ? "()V" : "(Ljava.lang.String;)V", false); if (ctor == null) { - Tracer.Error(Tracer.Runtime, $"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Exception {{0}} missing constructor.", name); + JVM.Context.Diagnostics.GenericJniError($"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Exception {name} missing constructor."); return; } @@ -203,12 +204,12 @@ void JVM_ThrowException(string name, string msg) var ctorMember = (java.lang.reflect.Constructor)ctor.ToMethodOrConstructor(false); var exception = (Exception)ctorMember.newInstance(msg == null ? Array.Empty() : new object[] { msg }, callerID); - Tracer.Verbose(Tracer.Runtime, $"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Created exception {{0}} from libjvm.", name); + JVM.Context.Diagnostics.GenericJniTrace($"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Created exception {name} from libjvm."); JVM.SetPendingException(exception); } catch (Exception e) { - Tracer.Error(Tracer.Runtime, $"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Exception occurred creating exception {{0}}: {{1}}", name, e.Message); + JVM.Context.Diagnostics.GenericJniError($"{nameof(LibJvm)}.{nameof(JVM_ThrowException)}: Exception occurred creating exception {name}: {e.Message}"); JVM.SetPendingException(e); } } @@ -230,7 +231,7 @@ nint JVM_GetThreadInterruptEvent() } catch (Exception e) { - Tracer.Error(Tracer.Runtime, $"{nameof(LibJvm)}.{nameof(JVM_GetThreadInterruptEvent)}: Exception occurred: {{0}}", e.Message); + JVM.Context.Diagnostics.GenericJniError($"{nameof(LibJvm)}.{nameof(JVM_GetThreadInterruptEvent)}: Exception occurred: {e.Message}"); JVM.SetPendingException(new global::java.lang.InternalError(e)); return 0; } @@ -546,9 +547,9 @@ public nint JVM_LoadLibrary(string name) { try { - Tracer.Verbose(Tracer.Jni, $"{nameof(LibJvm)}.{nameof(JVM_LoadLibrary)}: {{0}}", name); + JVM.Context.Diagnostics.GenericJniTrace($"{nameof(LibJvm)}.{nameof(JVM_LoadLibrary)}: {name}"); var h = _JVM_LoadLibrary(name); - Tracer.Verbose(Tracer.Jni, $"{nameof(LibJvm)}.{nameof(JVM_LoadLibrary)}: {{0}} => {{1}}", name, h); + JVM.Context.Diagnostics.GenericJniTrace($"{nameof(LibJvm)}.{nameof(JVM_LoadLibrary)}: {name} => {h}"); return h; } finally @@ -565,9 +566,9 @@ public void JVM_UnloadLibrary(nint handle) { try { - Tracer.Verbose(Tracer.Jni, $"{nameof(LibJvm)}.{nameof(JVM_UnloadLibrary)}: start {{0}}", handle); + JVM.Context.Diagnostics.GenericJniTrace($"{nameof(LibJvm)}.{nameof(JVM_UnloadLibrary)}: start {handle}"); _JVM_UnloadLibrary(handle); - Tracer.Verbose(Tracer.Jni, $"{nameof(LibJvm)}.{nameof(JVM_UnloadLibrary)}: finish {{0}} => {{1}}", handle); + JVM.Context.Diagnostics.GenericJniTrace($"{nameof(LibJvm)}.{nameof(JVM_UnloadLibrary)}: finish {handle}"); } finally { @@ -585,9 +586,9 @@ public nint JVM_FindLibraryEntry(nint handle, string name) { try { - Tracer.Verbose(Tracer.Jni, $"{nameof(LibJvm)}.{nameof(JVM_FindLibraryEntry)}: {{0}} {{1}}", handle, name); + JVM.Context.Diagnostics.GenericJniTrace($"{nameof(LibJvm)}.{nameof(JVM_FindLibraryEntry)}: {handle} {name}"); var h = _JVM_FindLibraryEntry(handle, name); - Tracer.Verbose(Tracer.Jni, $"{nameof(LibJvm)}.{nameof(JVM_FindLibraryEntry)}: {{0}} {{1}} => {{2}}", handle, name, h); + JVM.Context.Diagnostics.GenericJniTrace($"{nameof(LibJvm)}.{nameof(JVM_FindLibraryEntry)}: {handle} {name} => {h}"); return h; } finally diff --git a/src/IKVM.Runtime/MethodAnalyzer.cs b/src/IKVM.Runtime/MethodAnalyzer.cs index 9a72cb836b..9af36c6c99 100644 --- a/src/IKVM.Runtime/MethodAnalyzer.cs +++ b/src/IKVM.Runtime/MethodAnalyzer.cs @@ -26,6 +26,8 @@ Jeroen Frijters using System.Diagnostics; using IKVM.ByteCode; +using IKVM.CoreLib.Diagnostics; + #if IMPORTER using IKVM.Tools.Importer; @@ -1613,11 +1615,11 @@ private void PatchHardErrorsAndDynamicMemberAccess(RuntimeJavaType wrapper, Runt } else if (!tw.IsAccessibleFrom(wrapper)) { - SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name); + SetHardError(wrapper.ClassLoader, ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name); } else if (tw.IsAbstract) { - SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.InstantiationError, "{0}", tw.Name); + SetHardError(wrapper.ClassLoader, ref instructions[i], HardError.InstantiationError, "{0}", tw.Name); } break; } @@ -1631,7 +1633,7 @@ private void PatchHardErrorsAndDynamicMemberAccess(RuntimeJavaType wrapper, Runt } else if (!tw.IsAccessibleFrom(wrapper)) { - SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name); + SetHardError(wrapper.ClassLoader, ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name); } break; } @@ -1648,7 +1650,7 @@ private void PatchHardErrorsAndDynamicMemberAccess(RuntimeJavaType wrapper, Runt } else if (!tw.IsAccessibleFrom(wrapper)) { - SetHardError(wrapper.GetClassLoader(), ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name); + SetHardError(wrapper.ClassLoader, ref instructions[i], HardError.IllegalAccessError, "Try to access class {0} from class {1}", tw.Name, wrapper.Name); } break; } @@ -1690,7 +1692,7 @@ void PatchLdcMethodHandle(ref ClassFile.Method.Instruction instr) } else if (!cpi.GetClassType().IsAccessibleFrom(wrapper)) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "tried to access class {0} from class {1}", cpi.Class, wrapper.Name); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IllegalAccessError, "tried to access class {0} from class {1}", cpi.Class, wrapper.Name); } else if (cpi.Kind == MethodHandleKind.InvokeVirtual && cpi.GetClassType() == context.JavaBase.TypeOfJavaLangInvokeMethodHandle && (cpi.Name == "invoke" || cpi.Name == "invokeExact")) { @@ -1714,7 +1716,7 @@ void PatchLdcMethodHandle(ref ClassFile.Method.Instruction instr) msg = cpi.Class + "." + cpi.Name + cpi.Signature; break; } - SetHardError(wrapper.GetClassLoader(), ref instr, err, msg, cpi.Class, cpi.Name, SigToString(cpi.Signature)); + SetHardError(wrapper.ClassLoader, ref instr, err, msg, cpi.Class, cpi.Name, SigToString(cpi.Signature)); } else if (!cpi.Member.IsAccessibleFrom(cpi.GetClassType(), wrapper, cpi.GetClassType())) { @@ -1724,7 +1726,7 @@ void PatchLdcMethodHandle(ref ClassFile.Method.Instruction instr) } else { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessException, "member is private: {0}.{1}/{2}/{3}, from {4}", cpi.Class, cpi.Name, SigToString(cpi.Signature), cpi.Kind, wrapper.Name); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IllegalAccessException, "member is private: {0}.{1}/{2}/{3}, from {4}", cpi.Class, cpi.Name, SigToString(cpi.Signature), cpi.Kind, wrapper.Name); } } } @@ -2473,7 +2475,7 @@ private static void UpdateTryBlockExit(ExceptionTableEntry exception, int target private void ConditionalPatchNoClassDefFoundError(ref ClassFile.Method.Instruction instruction, RuntimeJavaType tw) { - RuntimeClassLoader loader = wrapper.GetClassLoader(); + RuntimeClassLoader loader = wrapper.ClassLoader; if (loader.DisableDynamicBinding) { SetHardError(loader, ref instruction, HardError.NoClassDefFoundError, "{0}", tw.Name); @@ -2484,38 +2486,39 @@ private void SetHardError(RuntimeClassLoader classLoader, ref ClassFile.Method.I { string text = string.Format(message, args); #if IMPORTER - Message msg; + Diagnostic msg; switch (hardError) { case HardError.NoClassDefFoundError: - msg = Message.EmittedNoClassDefFoundError; + classLoader.Diagnostics.EmittedNoClassDefFoundError(classFile.Name + "." + method.Name + method.Signature, text); break; case HardError.IllegalAccessError: - msg = Message.EmittedIllegalAccessError; + classLoader.Diagnostics.EmittedIllegalAccessError(classFile.Name + "." + method.Name + method.Signature, text); break; case HardError.InstantiationError: - msg = Message.EmittedIllegalAccessError; + classLoader.Diagnostics.EmittedInstantiationError(classFile.Name + "." + method.Name + method.Signature, text); break; case HardError.IncompatibleClassChangeError: + classLoader.Diagnostics.EmittedIncompatibleClassChangeError(classFile.Name + "." + method.Name + method.Signature, text); + break; case HardError.IllegalAccessException: - msg = Message.EmittedIncompatibleClassChangeError; + classLoader.Diagnostics.EmittedIllegalAccessError(classFile.Name + "." + method.Name + method.Signature, text); break; case HardError.NoSuchFieldError: - msg = Message.EmittedNoSuchFieldError; + classLoader.Diagnostics.EmittedNoSuchFieldError(classFile.Name + "." + method.Name + method.Signature, text); break; case HardError.AbstractMethodError: - msg = Message.EmittedAbstractMethodError; + classLoader.Diagnostics.EmittedAbstractMethodError(classFile.Name + "." + method.Name + method.Signature, text); break; case HardError.NoSuchMethodError: - msg = Message.EmittedNoSuchMethodError; + classLoader.Diagnostics.EmittedNoSuchMethodError(classFile.Name + "." + method.Name + method.Signature, text); break; case HardError.LinkageError: - msg = Message.EmittedLinkageError; + classLoader.Diagnostics.EmittedLinkageError(classFile.Name + "." + method.Name + method.Signature, text); break; default: throw new InvalidOperationException(); } - classLoader.IssueMessage(msg, classFile.Name + "." + method.Name + method.Signature, text); #endif instruction.SetHardError(hardError, AllocErrorMessage(text)); } @@ -2567,9 +2570,9 @@ private void PatchInvoke(RuntimeJavaType wrapper, ref ClassFile.Method.Instructi if (cpi.GetClassType().IsUnloadable) { - if (wrapper.GetClassLoader().DisableDynamicBinding) + if (wrapper.ClassLoader.DisableDynamicBinding) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoClassDefFoundError, "{0}", cpi.GetClassType().Name); + SetHardError(wrapper.ClassLoader, ref instr, HardError.NoClassDefFoundError, "{0}", cpi.GetClassType().Name); } else { @@ -2601,11 +2604,11 @@ private void PatchInvoke(RuntimeJavaType wrapper, ref ClassFile.Method.Instructi } else if (invoke == NormalizedByteCode.__invokeinterface && !cpi.GetClassType().IsInterface) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "invokeinterface on non-interface"); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IncompatibleClassChangeError, "invokeinterface on non-interface"); } else if (cpi.GetClassType().IsInterface && invoke != NormalizedByteCode.__invokeinterface && ((invoke != NormalizedByteCode.__invokestatic && invoke != NormalizedByteCode.__invokespecial) || classFile.MajorVersion < 52)) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, + SetHardError(wrapper.ClassLoader, ref instr, HardError.IncompatibleClassChangeError, classFile.MajorVersion < 52 ? "interface method must be invoked using invokeinterface" : "interface method must be invoked using invokeinterface, invokespecial or invokestatic"); @@ -2618,17 +2621,17 @@ private void PatchInvoke(RuntimeJavaType wrapper, ref ClassFile.Method.Instructi string errmsg = CheckLoaderConstraints(cpi, targetMethod); if (errmsg != null) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.LinkageError, "{0}", errmsg); + SetHardError(wrapper.ClassLoader, ref instr, HardError.LinkageError, "{0}", errmsg); } else if (targetMethod.IsStatic == (invoke == NormalizedByteCode.__invokestatic)) { if (targetMethod.IsAbstract && invoke == NormalizedByteCode.__invokespecial && (targetMethod.GetMethod() == null || targetMethod.GetMethod().IsAbstract)) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.AbstractMethodError, "{0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature); + SetHardError(wrapper.ClassLoader, ref instr, HardError.AbstractMethodError, "{0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature); } else if (invoke == NormalizedByteCode.__invokeinterface && targetMethod.IsPrivate) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "private interface method requires invokespecial, not invokeinterface: method {0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IncompatibleClassChangeError, "private interface method requires invokespecial, not invokeinterface: method {0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature); } else if (targetMethod.IsAccessibleFrom(cpi.GetClassType(), wrapper, thisType)) { @@ -2665,17 +2668,17 @@ private void PatchInvoke(RuntimeJavaType wrapper, ref ClassFile.Method.Instructi instr.PatchOpCode(NormalizedByteCode.__clone_array); return; } - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "tried to access method {0}.{1}{2} from class {3}", ToSlash(targetMethod.DeclaringType.Name), cpi.Name, ToSlash(cpi.Signature), ToSlash(wrapper.Name)); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IllegalAccessError, "tried to access method {0}.{1}{2} from class {3}", ToSlash(targetMethod.DeclaringType.Name), cpi.Name, ToSlash(cpi.Signature), ToSlash(wrapper.Name)); } } else { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "static call to non-static method (or v.v.)"); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IncompatibleClassChangeError, "static call to non-static method (or v.v.)"); } } else { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoSuchMethodError, "{0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature); + SetHardError(wrapper.ClassLoader, ref instr, HardError.NoSuchMethodError, "{0}.{1}{2}", cpi.Class, cpi.Name, cpi.Signature); } } } @@ -2769,9 +2772,9 @@ private void PatchFieldAccess(RuntimeJavaType wrapper, RuntimeJavaMethod mw, ref } else if (cpi.GetClassType().IsUnloadable) { - if (wrapper.GetClassLoader().DisableDynamicBinding) + if (wrapper.ClassLoader.DisableDynamicBinding) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoClassDefFoundError, "{0}", cpi.GetClassType().Name); + SetHardError(wrapper.ClassLoader, ref instr, HardError.NoClassDefFoundError, "{0}", cpi.GetClassType().Name); } else { @@ -2800,7 +2803,7 @@ private void PatchFieldAccess(RuntimeJavaType wrapper, RuntimeJavaMethod mw, ref RuntimeJavaField field = cpi.GetField(); if (field == null) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.NoSuchFieldError, "{0}.{1}", cpi.Class, cpi.Name); + SetHardError(wrapper.ClassLoader, ref instr, HardError.NoSuchFieldError, "{0}.{1}", cpi.Class, cpi.Name); return; } if (false && cpi.GetFieldType() != field.FieldTypeWrapper && !cpi.GetFieldType().IsUnloadable & !field.FieldTypeWrapper.IsUnloadable) @@ -2808,24 +2811,24 @@ private void PatchFieldAccess(RuntimeJavaType wrapper, RuntimeJavaMethod mw, ref #if IMPORTER StaticCompiler.LinkageError("Field \"{2}.{3}\" is of type \"{0}\" instead of type \"{1}\" as expected by \"{4}\"", field.FieldTypeWrapper, cpi.GetFieldType(), cpi.GetClassType().Name, cpi.Name, wrapper.Name); #endif - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.LinkageError, "Loader constraints violated: {0}.{1}", field.DeclaringType.Name, field.Name); + SetHardError(wrapper.ClassLoader, ref instr, HardError.LinkageError, "Loader constraints violated: {0}.{1}", field.DeclaringType.Name, field.Name); return; } if (field.IsStatic != isStatic) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IncompatibleClassChangeError, "Static field access to non-static field (or v.v.)"); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IncompatibleClassChangeError, "Static field access to non-static field (or v.v.)"); return; } if (!field.IsAccessibleFrom(cpi.GetClassType(), wrapper, thisType)) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "Try to access field {0}.{1} from class {2}", field.DeclaringType.Name, field.Name, wrapper.Name); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IllegalAccessError, "Try to access field {0}.{1} from class {2}", field.DeclaringType.Name, field.Name, wrapper.Name); return; } // are we trying to mutate a final field? (they are read-only from outside of the defining class) if (write && field.IsFinal - && ((isStatic ? wrapper != cpi.GetClassType() : wrapper != thisType) || (wrapper.GetClassLoader().StrictFinalFieldSemantics && (isStatic ? (mw != null && mw.Name != "") : (mw == null || mw.Name != ""))))) + && ((isStatic ? wrapper != cpi.GetClassType() : wrapper != thisType) || (wrapper.ClassLoader.StrictFinalFieldSemantics && (isStatic ? (mw != null && mw.Name != "") : (mw == null || mw.Name != ""))))) { - SetHardError(wrapper.GetClassLoader(), ref instr, HardError.IllegalAccessError, "Field {0}.{1} is final", field.DeclaringType.Name, field.Name); + SetHardError(wrapper.ClassLoader, ref instr, HardError.IllegalAccessError, "Field {0}.{1} is final", field.DeclaringType.Name, field.Name); return; } } @@ -2868,7 +2871,7 @@ private string CheckLoaderConstraints(ClassFile.ConstantPoolItemMI cpi, RuntimeJ #if NETFRAMEWORK if (cpi.GetRetType() != mw.ReturnType && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable) #else - if (cpi.GetRetType() != mw.ReturnType && cpi.GetRetType().Name != mw.ReturnType.Name && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable) + if (cpi.GetRetType() != mw.ReturnType && cpi.GetRetType().Name != mw.ReturnType.Name && !cpi.GetRetType().IsUnloadable && !mw.ReturnType.IsUnloadable) #endif { #if IMPORTER @@ -2883,7 +2886,7 @@ private string CheckLoaderConstraints(ClassFile.ConstantPoolItemMI cpi, RuntimeJ #if NETFRAMEWORK if (here[i] != there[i] && !here[i].IsUnloadable && !there[i].IsUnloadable) #else - if (here[i] != there[i] && here[i].Name != there[i].Name && !here[i].IsUnloadable && !there[i].IsUnloadable) + if (here[i] != there[i] && here[i].Name != there[i].Name && !here[i].IsUnloadable && !there[i].IsUnloadable) #endif { #if IMPORTER diff --git a/src/IKVM.Runtime/ReflectUtil.cs b/src/IKVM.Runtime/ReflectUtil.cs index f5ae01f505..e219ae4c2d 100644 --- a/src/IKVM.Runtime/ReflectUtil.cs +++ b/src/IKVM.Runtime/ReflectUtil.cs @@ -208,9 +208,8 @@ private static bool MatchTypes(Type[] t1, Type[] t2) internal static Type GetMissingType(Type type) { while (type.HasElementType) - { type = type.GetElementType(); - } + if (type.__IsMissing) { return type; @@ -219,15 +218,14 @@ internal static Type GetMissingType(Type type) { if (type.IsGenericType) { - foreach (Type arg in type.GetGenericArguments()) + foreach (var arg in type.GetGenericArguments()) { - Type t1 = GetMissingType(arg); + var t1 = GetMissingType(arg); if (t1.__IsMissing) - { return t1; - } } } + throw new NotImplementedException(type.FullName); } else diff --git a/src/IKVM.Runtime/RuntimeAnonymousJavaType.cs b/src/IKVM.Runtime/RuntimeAnonymousJavaType.cs index 401112efa3..9f05717537 100644 --- a/src/IKVM.Runtime/RuntimeAnonymousJavaType.cs +++ b/src/IKVM.Runtime/RuntimeAnonymousJavaType.cs @@ -61,10 +61,7 @@ private static string GetName(RuntimeContext context, Type type) return context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).Name + type.Name.Replace(NestedTypeName.IntrinsifiedAnonymousClass, "$$Lambda$"); } - internal override RuntimeClassLoader GetClassLoader() - { - return Context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).GetClassLoader(); - } + internal override RuntimeClassLoader ClassLoader => Context.ClassLoaderFactory.GetJavaTypeFromType(type.DeclaringType).ClassLoader; internal override Type TypeAsTBD { diff --git a/src/IKVM.Runtime/RuntimeArrayJavaType.cs b/src/IKVM.Runtime/RuntimeArrayJavaType.cs index 1031bb2d27..ed204a85fc 100644 --- a/src/IKVM.Runtime/RuntimeArrayJavaType.cs +++ b/src/IKVM.Runtime/RuntimeArrayJavaType.cs @@ -64,10 +64,7 @@ internal override RuntimeJavaType BaseTypeWrapper get { return Context.JavaBase.TypeOfJavaLangObject; } } - internal override RuntimeClassLoader GetClassLoader() - { - return ultimateElementTypeWrapper.GetClassLoader(); - } + internal override RuntimeClassLoader ClassLoader => ultimateElementTypeWrapper.ClassLoader; internal static MethodInfo GetCloneMethod(RuntimeContext context) { diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs index 3cba3e77d8..247a9e4980 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoader.cs @@ -27,12 +27,12 @@ Jeroen Frijters using System.Diagnostics; using System.Threading; using System.Runtime.Serialization; +using System.Runtime.CompilerServices; +using IKVM.CoreLib.Diagnostics; using IKVM.Attributes; using IKVM.Runtime.Syntax; -using System.Runtime.CompilerServices; - #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -76,7 +76,7 @@ internal class RuntimeAssemblyClassLoader : RuntimeClassLoader sealed class AssemblyLoader { - readonly RuntimeContext context; + readonly RuntimeAssemblyClassLoader loader; readonly Assembly assembly; bool[] isJavaModule; @@ -92,19 +92,19 @@ sealed class AssemblyLoader /// /// Initializes a new instance. /// - /// + /// /// - internal AssemblyLoader(RuntimeContext context, Assembly assembly) + internal AssemblyLoader(RuntimeAssemblyClassLoader loader, Assembly assembly) { - this.context = context; - this.assembly = assembly; + this.loader = loader ?? throw new ArgumentNullException(nameof(loader)); + this.assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); modules = assembly.GetModules(false); isJavaModule = new bool[modules.Length]; for (int i = 0; i < modules.Length; i++) { - var attr = context.AttributeHelper.GetJavaModuleAttributes(modules[i]); + var attr = loader.Context.AttributeHelper.GetJavaModuleAttributes(modules[i]); if (attr.Length > 0) { isJavaModule[i] = true; @@ -190,7 +190,7 @@ Type GetType(string name) // context and the requested type references a type in another assembly // that cannot be found in the ReflectionOnly context // TODO figure out what other exceptions Assembly.GetType() can throw - Tracer.Info(Tracer.Runtime, e.Message); + loader.Diagnostics.GenericRuntimeInfo(e.Message); } return null; @@ -218,7 +218,7 @@ Type GetType(Module module, string name) // context and the requested type references a type in another assembly // that cannot be found in the ReflectionOnly context // TODO figure out what other exceptions Assembly.GetType() can throw - Tracer.Info(Tracer.Runtime, e.Message); + loader.Diagnostics.GenericRuntimeInfo(e.Message); } return null; @@ -241,7 +241,7 @@ Type GetJavaType(Module module, string name) } if (t != null - && !context.AttributeHelper.IsHideFromJava(t) + && !loader.Context.AttributeHelper.IsHideFromJava(t) && !t.IsArray && !t.IsPointer && !t.IsByRef) @@ -251,7 +251,7 @@ Type GetJavaType(Module module, string name) { // we can end up here because we replace the $ with a plus sign // (or client code did a Class.forName() on an invalid name) - Tracer.Info(Tracer.Runtime, x.Message); + loader.Diagnostics.GenericRuntimeInfo(x.Message); } return null; @@ -267,9 +267,9 @@ internal RuntimeJavaType DoLoad(string name) if (type != null) { // check the name to make sure that the canonical name was used - if (RuntimeManagedByteCodeJavaType.GetName(context, type) == name) + if (RuntimeManagedByteCodeJavaType.GetName(loader.Context, type) == name) { - return context.ManagedByteCodeJavaTypeFactory.newInstance(name, type); + return loader.Context.ManagedByteCodeJavaTypeFactory.newInstance(name, type); } } } @@ -286,9 +286,9 @@ internal RuntimeJavaType DoLoad(string name) if (type != null && RuntimeManagedJavaType.IsAllowedOutside(type)) { // check the name to make sure that the canonical name was used - if (RuntimeManagedJavaType.GetName(context, type) == name) + if (RuntimeManagedJavaType.GetName(loader.Context, type) == name) { - return RuntimeManagedJavaType.Create(context, type, name); + return RuntimeManagedJavaType.Create(loader.Context, type, name); } } } @@ -356,10 +356,10 @@ internal RuntimeJavaType DoLoad(string name) isJavaType = true; // types which should be hidden from Java should not have Java names - if (context.AttributeHelper.IsHideFromJava(type)) + if (loader.Context.AttributeHelper.IsHideFromJava(type)) return null; - return RuntimeManagedByteCodeJavaType.GetName(context, type); + return RuntimeManagedByteCodeJavaType.GetName(loader.Context, type); } else { @@ -369,7 +369,7 @@ internal RuntimeJavaType DoLoad(string name) if (RuntimeManagedJavaType.IsAllowedOutside(type) == false) return null; - return RuntimeManagedJavaType.GetName(context, type); + return RuntimeManagedJavaType.GetName(loader.Context, type); } } @@ -382,21 +382,21 @@ internal RuntimeJavaType CreateJavaTypeForAssemblyType(Type type) if (isJavaType) { // since this type was compiled from Java source, we have to look for our attributes - return context.ManagedByteCodeJavaTypeFactory.newInstance(name, type); + return loader.Context.ManagedByteCodeJavaTypeFactory.newInstance(name, type); } else { // since this type was not compiled from Java source, we don't need to // look for our attributes, but we do need to filter unrepresentable // stuff (and transform some other stuff) - return RuntimeManagedJavaType.Create(context, type, name); + return RuntimeManagedJavaType.Create(loader.Context, type, name); } } internal bool InternalsVisibleTo(AssemblyName otherName) { if (internalsVisibleTo == null) - Interlocked.CompareExchange(ref internalsVisibleTo, context.AttributeHelper.GetInternalsVisibleToAttributes(assembly), null); + Interlocked.CompareExchange(ref internalsVisibleTo, loader.Context.AttributeHelper.GetInternalsVisibleToAttributes(assembly), null); foreach (var name in internalsVisibleTo) { @@ -447,12 +447,13 @@ internal RuntimeAssemblyClassLoader(RuntimeContext context, Assembly assembly) : /// /// Initializes a new instance. /// + /// /// /// internal RuntimeAssemblyClassLoader(RuntimeContext context, Assembly assembly, string[] fixedReferences) : base(context, CodeGenOptions.None, null) { - this.assemblyLoader = new AssemblyLoader(context, assembly); + this.assemblyLoader = new AssemblyLoader(this, assembly); this.references = fixedReferences; } @@ -557,7 +558,7 @@ void LazyInitExports() internal Assembly GetAssembly(RuntimeJavaType wrapper) { - Debug.Assert(wrapper.GetClassLoader() == this); + Debug.Assert(wrapper.ClassLoader == this); while (wrapper.IsFakeNestedType) wrapper = wrapper.DeclaringTypeWrapper; @@ -665,7 +666,7 @@ AssemblyLoader GetLoaderForExportedAssembly(Assembly assembly) if (loader == null) { - loader = new AssemblyLoader(Context, assembly); + loader = new AssemblyLoader(this, assembly); lock (exportedLoaders) { @@ -703,8 +704,8 @@ internal virtual RuntimeJavaType GetJavaTypeFromAssemblyType(Type type) if (type.IsGenericType && !type.IsGenericTypeDefinition) { // in the case of "magic" implementation generic type instances we'll end up here as well, - // but then wrapper.GetClassLoader() will return this anyway - javaType = javaType.GetClassLoader().RegisterInitiatingLoader(javaType); + // but then wrapper.ClassLoader will return this anyway + javaType = javaType.ClassLoader.RegisterInitiatingLoader(javaType); } else { @@ -715,7 +716,7 @@ internal virtual RuntimeJavaType GetJavaTypeFromAssemblyType(Type type) if (javaType.TypeAsTBD != type && (!javaType.IsRemapped || javaType.TypeAsBaseType != type)) { #if IMPORTER - throw new FatalCompilerErrorException(Message.AssemblyContainsDuplicateClassNames, type.FullName, javaType.TypeAsTBD.FullName, javaType.Name, type.Assembly.FullName); + throw new FatalCompilerErrorException(Diagnostic.AssemblyContainsDuplicateClassNames.Event([type.FullName, javaType.TypeAsTBD.FullName, javaType.Name, type.Assembly.FullName])); #else throw new InternalException($"\nType \"{type.FullName}\" and \"{javaType.TypeAsTBD.FullName}\" both map to the same name \"{javaType.Name}\"."); #endif @@ -943,7 +944,7 @@ static java.net.URL MakeResourceURL(Assembly asm, string name) if (found == false && unmangledName.EndsWith(".class", StringComparison.Ordinal) && unmangledName.IndexOf('.') == unmangledName.Length - 6) { var tw = FindLoadedClass(unmangledName.Substring(0, unmangledName.Length - 6).Replace('/', '.')); - if (tw != null && tw.GetClassLoader() == this && !tw.IsArray && !tw.IsDynamic) + if (tw != null && tw.ClassLoader == this && !tw.IsArray && !tw.IsDynamic) yield return new java.io.File(Path.Combine(VfsTable.GetAssemblyClassesPath(JVM.Vfs.Context, assemblyLoader.Assembly, JVM.Properties.HomePath), unmangledName)).toURI().toURL(); } #endif @@ -1095,7 +1096,7 @@ protected override RuntimeJavaType FindLoadedClassLazy(string name) internal override bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJavaType friend) { - var other = friend.GetClassLoader(); + var other = friend.ClassLoader; if (this == other) { #if IMPORTER || EXPORTER @@ -1155,7 +1156,7 @@ internal List> GetPackageInfo() Type GetCustomClassLoaderType() { - LoadCustomClassLoaderRedirects(Context); + LoadCustomClassLoaderRedirects(this); var assembly = assemblyLoader.Assembly; var assemblyName = assembly.FullName; @@ -1177,7 +1178,7 @@ Type GetCustomClassLoaderType() } catch (Exception x) { - Tracer.Error(Tracer.Runtime, "Unable to load custom class loader {0} specified in app.config for assembly {1}: {2}", kv.Value, assembly, x); + Diagnostics.GenericRuntimeError($"Unable to load custom class loader {kv.Value} specified in app.config for assembly {assembly}: {x}"); } break; @@ -1223,7 +1224,7 @@ void InitializeJavaClassLoader(JavaClassLoaderConstructionInProgress jclcip, Typ jclcip.javaClassLoader = newJavaClassLoader; Context.ClassLoaderFactory.SetWrapperForClassLoader(jclcip.javaClassLoader, this); DoPrivileged(new CustomClassLoaderCtorCaller(customClassLoaderCtor, jclcip.javaClassLoader, assembly)); - Tracer.Info(Tracer.Runtime, "Created custom assembly class loader {0} for assembly {1}", customClassLoaderClass.FullName, assembly); + Diagnostics.GenericRuntimeInfo($"Created custom assembly class loader {customClassLoaderClass.FullName} for assembly {assembly}"); } else { @@ -1233,7 +1234,7 @@ void InitializeJavaClassLoader(JavaClassLoaderConstructionInProgress jclcip, Typ } catch (Exception x) { - Tracer.Error(Tracer.Runtime, "Unable to create custom assembly class loader {0} for {1}: {2}", customClassLoaderClass.FullName, assembly, x); + Diagnostics.GenericRuntimeError($"Unable to create custom assembly class loader {customClassLoaderClass.FullName} for {assembly}: {x}"); } } @@ -1260,9 +1261,9 @@ static object GetUninitializedObject(Type type) #endif } - static void LoadCustomClassLoaderRedirects(RuntimeContext context) + static void LoadCustomClassLoaderRedirects(RuntimeClassLoader loader) { - if (context.AssemblyClassLoaderFactory.customClassLoaderRedirects == null) + if (loader.Context.AssemblyClassLoaderFactory.customClassLoaderRedirects == null) { var dict = new Dictionary(); @@ -1279,11 +1280,11 @@ static void LoadCustomClassLoaderRedirects(RuntimeContext context) } catch (Exception x) { - Tracer.Error(Tracer.Runtime, "Error while reading custom class loader redirects: {0}", x); + loader.Diagnostics.GenericRuntimeError($"Error while reading custom class loader redirects: {x}"); } finally { - Interlocked.CompareExchange(ref context.AssemblyClassLoaderFactory.customClassLoaderRedirects, dict, null); + Interlocked.CompareExchange(ref loader.Context.AssemblyClassLoaderFactory.customClassLoaderRedirects, dict, null); } } } diff --git a/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs index b3caabcd22..4f219c5f30 100644 --- a/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeAssemblyClassLoaderFactory.cs @@ -21,9 +21,9 @@ Jeroen Frijters jeroen@frijters.net */ +using System; using System.Collections.Generic; using System.Runtime.CompilerServices; -using System; #if IMPORTER || EXPORTER using IKVM.Reflection; diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs index 4b8c105073..b14c6846e5 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.FinishContext.cs @@ -28,6 +28,8 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.ByteCode; using IKVM.ByteCode.Decoding; +using IKVM.CoreLib.Diagnostics; + #if IMPORTER using IKVM.Reflection; @@ -323,9 +325,9 @@ internal Type FinishImpl() else { #if IMPORTER - if (methods[i].GetParameters().Length > MethodHandleUtil.MaxArity && methods[i].RequiresNonVirtualDispatcher && wrapper.GetClassLoader().EmitNoRefEmitHelpers) + if (methods[i].GetParameters().Length > MethodHandleUtil.MaxArity && methods[i].RequiresNonVirtualDispatcher && wrapper.ClassLoader.EmitNoRefEmitHelpers) { - wrapper.GetClassLoader().GetTypeWrapperFactory().DefineDelegate(methods[i].GetParameters().Length, methods[i].ReturnType == context.PrimitiveJavaTypeFactory.VOID); + wrapper.ClassLoader.GetTypeWrapperFactory().DefineDelegate(methods[i].GetParameters().Length, methods[i].ReturnType == context.PrimitiveJavaTypeFactory.VOID); } #endif if (m.IsAbstract) @@ -348,7 +350,6 @@ internal Type FinishImpl() if (stub) { var ilGenerator = context.CodeEmitterFactory.Create(mb); - new TraceHelper(context).EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature); ilGenerator.EmitThrow("java.lang.AbstractMethodError", classFile.Name + "." + m.Name + m.Signature); ilGenerator.DoEmit(); } @@ -370,7 +371,6 @@ internal Type FinishImpl() try { var ilGenerator = context.CodeEmitterFactory.Create(mb); - new TraceHelper(context).EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature); #if IMPORTER // do we have an implementation in map.xml? if (wrapper.EmitMapXmlMethodPrologueAndOrBody(ilGenerator, classFile, m)) @@ -489,10 +489,10 @@ internal Type FinishImpl() } else { - if (wrapper.classLoader.NoJNI) + if (wrapper.ClassLoader.NoJNI) { // since NoJniStubs can only be set when we're statically compiling, it is safe to use the "compiler" trace switch - Tracer.Warning(Tracer.Compiler, "Native method not implemented: {0}.{1}.{2}", classFile.Name, m.Name, m.Signature); + wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Native method not implemented: {classFile.Name}.{m.Name}.{m.Signature}"); ilGenerator.EmitThrow("java.lang.UnsatisfiedLinkError", "Native method not implemented (compiled with -nojni): " + classFile.Name + "." + m.Name + m.Signature); } else @@ -529,7 +529,6 @@ internal Type FinishImpl() ilGenerator.EmitNullCheck(); } - new TraceHelper(context).EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature); #if IMPORTER // do we have an implementation in map.xml? if (wrapper.EmitMapXmlMethodPrologueAndOrBody(ilGenerator, classFile, m)) @@ -635,7 +634,7 @@ internal Type FinishImpl() if (!wrapper.IsAbstract && wrapper.HasUnsupportedAbstractMethods) AddUnsupportedAbstractMethods(); - if (!wrapper.GetClassLoader().NoAutomagicSerialization) + if (!wrapper.ClassLoader.NoAutomagicSerialization) wrapper.automagicSerializationCtor = context.Serialization.AddAutomagicSerialization(wrapper, typeBuilder); } @@ -675,8 +674,8 @@ internal Type FinishImpl() var annotation = Annotation.Load(wrapper, def); if (annotation != null) { - annotation.Apply(wrapper.GetClassLoader(), mb, def); - annotation.ApplyReturnValue(wrapper.GetClassLoader(), mb, ref returnParameter, def); + annotation.Apply(wrapper.ClassLoader, mb, def); + annotation.ApplyReturnValue(wrapper.ClassLoader, mb, ref returnParameter, def); } } } @@ -705,11 +704,11 @@ internal Type FinishImpl() var prop = fields[i] as RuntimeByteCodePropertyJavaField; if (prop != null) { - annotation.Apply(wrapper.GetClassLoader(), prop.GetPropertyBuilder(), def); + annotation.Apply(wrapper.ClassLoader, prop.GetPropertyBuilder(), def); } else { - annotation.Apply(wrapper.GetClassLoader(), (FieldBuilder)fields[i].GetField(), def); + annotation.Apply(wrapper.ClassLoader, (FieldBuilder)fields[i].GetField(), def); } } } @@ -723,7 +722,7 @@ internal Type FinishImpl() { var annotation = Annotation.Load(wrapper, def); if (annotation != null) - annotation.Apply(wrapper.GetClassLoader(), typeBuilder, def); + annotation.Apply(wrapper.ClassLoader, typeBuilder, def); } } @@ -1012,10 +1011,10 @@ private void AddMethodParameterInfo(ClassFile.Method m, RuntimeJavaMethod mw, Me parameterNames = null; ParameterBuilder[] parameterBuilders = null; - if (wrapper.GetClassLoader().EmitSymbols + if (wrapper.ClassLoader.EmitSymbols #if IMPORTER || (classFile.IsPublic && (m.IsPublic || m.IsProtected)) - || (m.MethodParameters != null && !wrapper.GetClassLoader().NoParameterReflection) + || (m.MethodParameters != null && !wrapper.ClassLoader.NoParameterReflection) #endif ) { @@ -1056,7 +1055,7 @@ private void AddMethodParameterInfo(ClassFile.Method m, RuntimeJavaMethod mw, Me { var annotation = Annotation.Load(wrapper, def); if (annotation != null) - annotation.Apply(wrapper.GetClassLoader(), parameterBuilders[j], def); + annotation.Apply(wrapper.ClassLoader, parameterBuilders[j], def); } } } @@ -1129,7 +1128,7 @@ private void CreateDefaultMethodInterop(ref TypeBuilder tbDefaultMethods, Method tbDefaultMethods = DefineNestedInteropType(NestedTypeName.DefaultMethods); } - var mb = mw.GetDefineMethodHelper().DefineMethod(wrapper.GetClassLoader().GetTypeWrapperFactory(), tbDefaultMethods, mw.Name, MethodAttributes.Public | MethodAttributes.Static, wrapper.TypeAsSignatureType, true); + var mb = mw.GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(), tbDefaultMethods, mw.Name, MethodAttributes.Public | MethodAttributes.Static, wrapper.TypeAsSignatureType, true); var ilgen = context.CodeEmitterFactory.Create(mb); if (wrapper.IsGhost) { @@ -1174,7 +1173,7 @@ private void AddInheritedDefaultInterfaceMethods(RuntimeJavaMethod[] methods) if (classFile.IsInterface) { // if we're an interface with a default miranda method, we need to create a new default method that forwards to the original - mb = methods[i].GetDefineMethodHelper().DefineMethod(wrapper.GetClassLoader().GetTypeWrapperFactory(), + mb = methods[i].GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(), typeBuilder, NamePrefix.DefaultMethod + mb.Name, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, typeBuilder, false); } EmitCallDefaultInterfaceMethod(mb, mmw.BaseMethod); @@ -1856,43 +1855,6 @@ internal void Generate(RuntimeByteCodeJavaType.FinishContext context, CodeEmitte } } - class TraceHelper - { - - readonly RuntimeContext context; - - /// - /// Initializes a new instance. - /// - /// - public TraceHelper(RuntimeContext context) - { - this.context = context ?? throw new ArgumentNullException(nameof(context)); - } - -#if IMPORTER - MethodInfo MethodIsTracedMethod => context.Resolver.ResolveRuntimeType(typeof(Tracer).FullName).GetMethod("IsTracedMethod"); -#endif - MethodInfo MethodMethodInfo => context.Resolver.ResolveRuntimeType(typeof(Tracer).FullName).GetMethod("MethodInfo"); - - internal void EmitMethodTrace(CodeEmitter ilgen, string tracemessage) - { - if (Tracer.IsTracedMethod(tracemessage)) - { - var label = ilgen.DefineLabel(); -#if IMPORTER - // TODO this should be a boolean field test instead of a call to Tracer.IsTracedMessage - ilgen.Emit(OpCodes.Ldstr, tracemessage); - ilgen.Emit(OpCodes.Call, MethodIsTracedMethod); - ilgen.EmitBrfalse(label); -#endif - ilgen.Emit(OpCodes.Ldstr, tracemessage); - ilgen.Emit(OpCodes.Call, MethodMethodInfo); - ilgen.MarkLabel(label); - } - } - } - #if IMPORTER void EmitCallerIDStub(RuntimeJavaMethod mw, string[] parameterNames) @@ -1979,7 +1941,7 @@ void ImplementInterfaces(RuntimeJavaType[] interfaces, List int if (!wrapper.IsInterface) { // look for "magic" interfaces that imply a .NET interface - if (iface.GetClassLoader() == context.JavaBase.TypeOfJavaLangObject.GetClassLoader()) + if (iface.ClassLoader == context.JavaBase.TypeOfJavaLangObject.ClassLoader) { if (iface.Name == "java.lang.Iterable" && !wrapper.ImplementsInterface(context.ClassLoaderFactory.GetJavaTypeFromType(context.Resolver.ResolveCoreType(typeof(System.Collections.IEnumerable).FullName)))) { @@ -2093,7 +2055,7 @@ void CompileConstructorBody(FinishContext context, CodeEmitter ilGenerator, int { var methods = wrapper.GetMethods(); var m = classFile.Methods[methodIndex]; - new TraceHelper(context.context).EmitMethodTrace(ilGenerator, classFile.Name + "." + m.Name + m.Signature); + #if IMPORTER // do we have an implementation in map.xml? if (wrapper.EmitMapXmlMethodPrologueAndOrBody(ilGenerator, classFile, m)) diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs index ea07b61031..1d35dbfbb3 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.JavaTypeImpl.cs @@ -24,9 +24,9 @@ Jeroen Frijters using System; using System.Collections.Generic; using System.Diagnostics; +using System.Collections.Concurrent; using IKVM.Attributes; -using System.Collections.Concurrent; #if IMPORTER using IKVM.Reflection; @@ -73,7 +73,7 @@ private sealed partial class JavaTypeImpl : DynamicImpl internal JavaTypeImpl(RuntimeJavaType host, ClassFile f, RuntimeByteCodeJavaType wrapper) { - Tracer.Info(Tracer.Compiler, "constructing JavaTypeImpl for " + f.Name); + wrapper.ClassLoader.Diagnostics.GenericCompilerInfo("constructing JavaTypeImpl for " + f.Name); this.host = host; this.classFile = f; this.wrapper = (RuntimeDynamicOrImportJavaType)wrapper; @@ -225,7 +225,7 @@ bool SupportsCallerID(ClassFile.Method method) { // If we end up here, we either have to add support or add them to the white-list in the above clause // to allow them to fall back to dynamic stack walking. - wrapper.Context.StaticCompiler.IssueMessage(Message.CallerSensitiveOnUnsupportedMethod, classFile.Name, method.Name, method.Signature); + wrapper.ClassLoader.Diagnostics.CallerSensitiveOnUnsupportedMethod(classFile.Name, method.Name, method.Signature); return false; } } @@ -301,7 +301,7 @@ internal void CreateStep2() { if (!CheckInnerOuterNames(f.Name, enclosingClassName)) { - Tracer.Warning(Tracer.Compiler, "Incorrect {0} attribute on {1}", outerClass.outerClass.IsNotNil ? "InnerClasses" : "EnclosingMethod", f.Name); + wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Incorrect {(outerClass.outerClass.IsNotNil ? "InnerClasses" : "EnclosingMethod")} attribute on {f.Name}"); } else { @@ -311,7 +311,7 @@ internal void CreateStep2() } catch (RetargetableJavaException x) { - Tracer.Warning(Tracer.Compiler, "Unable to load outer class {0} for inner class {1} ({2}: {3})", enclosingClassName, f.Name, x.GetType().Name, x.Message); + wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Unable to load outer class {enclosingClassName} for inner class {f.Name} ({x.GetType().Name}: {x.Message})"); } if (enclosingClassWrapper != null) @@ -321,7 +321,7 @@ internal void CreateStep2() // class live in the same class loader (when doing a multi target compilation, // it is possible to split the two classes across assemblies) var oimpl = enclosingClassWrapper.impl as JavaTypeImpl; - if (oimpl != null && enclosingClassWrapper.GetClassLoader() == wrapper.GetClassLoader()) + if (oimpl != null && enclosingClassWrapper.ClassLoader == wrapper.ClassLoader) { var outerClassFile = oimpl.classFile; var outerInnerClasses = outerClassFile.InnerClasses; @@ -364,7 +364,7 @@ internal void CreateStep2() } else { - Tracer.Warning(Tracer.Compiler, "Non-reciprocal inner class {0}", f.Name); + wrapper.ClassLoader.Diagnostics.GenericCompilerWarning($"Non-reciprocal inner class {f.Name}"); } } } @@ -484,7 +484,7 @@ internal void CreateStep2() try { - exists = wrapper.GetClassLoader().TryLoadClassByName(name) != null; + exists = wrapper.ClassLoader.TryLoadClassByName(name) != null; } catch (RetargetableJavaException) { @@ -975,7 +975,7 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) } int fieldIndex = GetFieldIndex(fw); #if IMPORTER - if (wrapper.GetClassLoader().RemoveUnusedFields + if (wrapper.ClassLoader.RemoveUnusedFields && fw.IsPrivate && fw.IsStatic && fw.IsFinal @@ -984,7 +984,7 @@ internal override FieldInfo LinkField(RuntimeJavaField fw) && !classFile.IsReferenced(classFile.Fields[fieldIndex])) { // unused, so we skip it - Tracer.Info(Tracer.Compiler, "Unused field {0}::{1}", wrapper.Name, fw.Name); + wrapper.ClassLoader.Diagnostics.GenericCompilerInfo($"Unused field {wrapper.Name}::{fw.Name}"); return null; } @@ -1228,7 +1228,7 @@ FinishedTypeImpl FinishCore() throw new InvalidOperationException("Recursive finish attempt for " + wrapper.Name); finishInProgress = true; - Tracer.Info(Tracer.Compiler, "Finishing: {0}", wrapper.Name); + wrapper.ClassLoader.Diagnostics.GenericCompilerTrace($"Finishing: {wrapper.Name}"); Profiler.Enter("JavaTypeImpl.Finish.Core"); try @@ -1357,7 +1357,7 @@ private bool IsValidAnnotationElementType(string type) { try { - var tw = wrapper.GetClassLoader().TryLoadClassByName(type.Substring(1, type.Length - 2)); + var tw = wrapper.ClassLoader.TryLoadClassByName(type.Substring(1, type.Length - 2)); if (tw != null) { if ((tw.Modifiers & Modifiers.Annotation) != 0) @@ -1545,7 +1545,7 @@ internal void Link() Annotation annotation = Annotation.Load(o.wrapper, def); if (annotation != null && annotation.IsCustomAttribute) { - annotation.Apply(o.wrapper.GetClassLoader(), attributeTypeBuilder, def); + annotation.Apply(o.wrapper.ClassLoader, attributeTypeBuilder, def); } if (def[1].Equals("Lcli/System/AttributeUsageAttribute$Annotation;")) { @@ -2525,7 +2525,7 @@ internal override MethodBase LinkMethod(RuntimeJavaMethod mw) wrapper.Context.AttributeHelper.SetSignatureAttribute(method, m.GenericSignature); } - if (wrapper.GetClassLoader().NoParameterReflection) + if (wrapper.ClassLoader.NoParameterReflection) { // ignore MethodParameters (except to extract parameter names) } @@ -2779,7 +2779,7 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier { // the CLR doesn't allow (non-virtual) instance methods in interfaces, // so we need to turn it into a static method - mb = methods[index].GetDefineMethodHelper().DefineMethod(wrapper.GetClassLoader().GetTypeWrapperFactory(), + mb = methods[index].GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(), tb, NamePrefix.PrivateInterfaceInstanceMethod + name, attribs | MethodAttributes.Static | MethodAttributes.SpecialName, typeBuilder, false); #if IMPORTER @@ -2888,13 +2888,13 @@ MethodBuilder GenerateMethod(int index, ClassFile.Method m, ref bool setModifier { if (wrapper.IsGhost) { - RuntimeDefaultInterfaceJavaMethod.SetImpl(methods[index], methods[index].GetDefineMethodHelper().DefineMethod(wrapper.GetClassLoader().GetTypeWrapperFactory(), + RuntimeDefaultInterfaceJavaMethod.SetImpl(methods[index], methods[index].GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(), typeBuilder, NamePrefix.DefaultMethod + mb.Name, MethodAttributes.Public | MethodAttributes.SpecialName, null, false)); } else { - RuntimeDefaultInterfaceJavaMethod.SetImpl(methods[index], methods[index].GetDefineMethodHelper().DefineMethod(wrapper.GetClassLoader().GetTypeWrapperFactory(), + RuntimeDefaultInterfaceJavaMethod.SetImpl(methods[index], methods[index].GetDefineMethodHelper().DefineMethod(wrapper.ClassLoader.GetTypeWrapperFactory(), typeBuilder, NamePrefix.DefaultMethod + mb.Name, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, typeBuilder, false)); } diff --git a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs index 6e0e3f7b95..c25ce1f0c4 100644 --- a/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeByteCodeJavaType.cs @@ -26,6 +26,8 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Diagnostics; + #if IMPORTER using IKVM.Reflection; @@ -97,10 +99,10 @@ private static void CheckMissing(RuntimeJavaType prev, RuntimeJavaType tw) Type mt = ReflectUtil.GetMissingType(missing.MissingType); if (mt.Assembly.__IsMissing) { - throw new FatalCompilerErrorException(Message.MissingBaseTypeReference, mt.FullName, mt.Assembly.FullName); + throw new FatalCompilerErrorException(Diagnostic.MissingBaseTypeReference.Event([mt.FullName, mt.Assembly.FullName])); } - throw new FatalCompilerErrorException(Message.MissingBaseType, mt.FullName, mt.Assembly.FullName, - prev.TypeAsBaseType.FullName, prev.TypeAsBaseType.Module.Name); + + throw new FatalCompilerErrorException(Diagnostic.MissingBaseType.Event([mt.FullName, mt.Assembly.FullName, prev.TypeAsBaseType.FullName, prev.TypeAsBaseType.Module.Name])); } foreach (RuntimeJavaType iface in tw.Interfaces) { @@ -268,7 +270,7 @@ private void VerifyDelegate(ClassFile f) DelegateInnerClassCheck(iface != null); DelegateInnerClassCheck(iface.IsInterface); DelegateInnerClassCheck(iface.IsPublic); - DelegateInnerClassCheck(iface.GetClassLoader() == classLoader); + DelegateInnerClassCheck(iface.ClassLoader == classLoader); RuntimeJavaMethod[] methods = iface.GetMethods(); DelegateInnerClassCheck(methods.Length == 1 && methods[0].Name == "Invoke"); if (methods[0].Signature != invoke.Signature) @@ -315,10 +317,7 @@ internal sealed override RuntimeJavaType BaseTypeWrapper get { return baseTypeWrapper; } } - internal override RuntimeClassLoader GetClassLoader() - { - return classLoader; - } + internal override RuntimeClassLoader ClassLoader => classLoader; internal override Modifiers ReflectiveModifiers { @@ -839,7 +838,7 @@ object[] DecodeAnnotations(object[] definitions) if (definitions == null) return null; - var loader = GetClassLoader().GetJavaClassLoader(); + var loader = ClassLoader.GetJavaClassLoader(); var annotations = new List(); for (int i = 0; i < definitions.Length; i++) @@ -919,7 +918,7 @@ internal override object GetAnnotationDefault(RuntimeJavaMethod mw) object defVal = impl.GetMethodDefaultValue(i); if (defVal != null) { - return JVM.NewAnnotationElementValue(mw.DeclaringType.GetClassLoader().GetJavaClassLoader(), mw.ReturnType.ClassObject, defVal); + return JVM.NewAnnotationElementValue(mw.DeclaringType.ClassLoader.GetJavaClassLoader(), mw.ReturnType.ClassObject, defVal); } return null; } @@ -956,7 +955,7 @@ internal override MethodBase GetSerializationConstructor() private Type[] GetModOpt(RuntimeJavaType tw, bool mustBePublic) { - return GetModOpt(GetClassLoader().GetTypeWrapperFactory(), tw, mustBePublic); + return GetModOpt(ClassLoader.GetTypeWrapperFactory(), tw, mustBePublic); } internal static Type[] GetModOpt(RuntimeJavaTypeFactory context, RuntimeJavaType tw, bool mustBePublic) @@ -1059,15 +1058,15 @@ internal override RuntimeJavaType Host internal void EmitLevel4Warning(HardError error, string message) { #if IMPORTER - if (GetClassLoader().WarningLevelHigh) + if (ClassLoader.WarningLevelHigh) { switch (error) { case HardError.AbstractMethodError: - GetClassLoader().IssueMessage(Message.EmittedAbstractMethodError, this.Name, message); + ClassLoader.Diagnostics.EmittedAbstractMethodError(this.Name, message); break; case HardError.IncompatibleClassChangeError: - GetClassLoader().IssueMessage(Message.EmittedIncompatibleClassChangeError, this.Name, message); + ClassLoader.Diagnostics.EmittedIncompatibleClassChangeError(this.Name, message); break; default: throw new InvalidOperationException(); diff --git a/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs b/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs index caf7fe431f..ec600f9026 100644 --- a/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs +++ b/src/IKVM.Runtime/RuntimeByteCodePropertyJavaField.cs @@ -23,11 +23,14 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Diagnostics; + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; + #else using System.Reflection; using System.Reflection.Emit; @@ -63,7 +66,7 @@ RuntimeJavaMethod GetMethod(string name, string sig, bool isstatic) return mw; } - Tracer.Error(Tracer.Compiler, "Property '{0}' accessor '{1}' not found in class '{2}'", this.Name, name, this.DeclaringType.Name); + DeclaringType.ClassLoader.Diagnostics.GenericCompilerError($"Property '{Name}' accessor '{name}' not found in class '{DeclaringType.Name}'"); } return null; @@ -141,7 +144,7 @@ protected override void EmitGetImpl(CodeEmitter ilgen) internal static void EmitThrowNoSuchMethodErrorForGetter(CodeEmitter ilgen, RuntimeJavaType type, RuntimeJavaMember member) { #if IMPORTER - type.Context.StaticCompiler.IssueMessage(Message.EmittedNoSuchMethodError, "", member.DeclaringType.Name + "." + member.Name + member.Signature); + type.ClassLoader.Diagnostics.EmittedNoSuchMethodError("", member.DeclaringType.Name + "." + member.Name + member.Signature); #endif // HACK the branch around the throw is to keep the verifier happy CodeEmitterLabel label = ilgen.DefineLabel(); @@ -186,7 +189,7 @@ protected override void EmitSetImpl(CodeEmitter ilgen) internal static void EmitThrowNoSuchMethodErrorForSetter(CodeEmitter ilgen, RuntimeJavaMember member) { #if IMPORTER - member.DeclaringType.Context.StaticCompiler.IssueMessage(Message.EmittedNoSuchMethodError, "", member.DeclaringType.Name + "." + member.Name + member.Signature); + member.DeclaringType.ClassLoader.Diagnostics.EmittedNoSuchMethodError("", member.DeclaringType.Name + "." + member.Name + member.Signature); #endif // HACK the branch around the throw is to keep the verifier happy CodeEmitterLabel label = ilgen.DefineLabel(); diff --git a/src/IKVM.Runtime/RuntimeClassLoader.cs b/src/IKVM.Runtime/RuntimeClassLoader.cs index 044b4189a5..d116674cf1 100644 --- a/src/IKVM.Runtime/RuntimeClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeClassLoader.cs @@ -27,6 +27,9 @@ Jeroen Frijters using System.Diagnostics; using System.Threading; +using IKVM.Runtime.Accessors.Java.Lang; +using IKVM.CoreLib.Diagnostics; + #if NETCOREAPP using System.Runtime.Loader; #endif @@ -40,10 +43,6 @@ Jeroen Frijters using System.Reflection; using ProtectionDomain = java.security.ProtectionDomain; - -using IKVM.Runtime.Accessors.Java.Lang; - -using System.Text; #endif #if IMPORTER @@ -93,6 +92,11 @@ internal RuntimeClassLoader(RuntimeContext context, CodeGenOptions codegenoption #endif } + /// + /// Gets the events originated by this class loader should be sent to. + /// + public virtual IDiagnosticHandler Diagnostics => Context.Diagnostics; + #if IMPORTER || EXPORTER internal void SetRemappedType(Type type, RuntimeJavaType tw) @@ -371,12 +375,12 @@ internal RuntimeJavaType LoadClass(string name, LoadMode mode) #if IMPORTER if (!(name.Length > 1 && name[0] == '[') && ((mode & LoadMode.WarnClassNotFound) != 0) || WarningLevelHigh) - IssueMessage(Message.ClassNotFound, name); + Diagnostics.GenericClassLoadingError($"Class not found: {name}"); #else if (!(name.Length > 1 && name[0] == '[')) - Tracer.Error(Tracer.ClassLoading, "Class not found: {0}", name); + Diagnostics.GenericClassLoadingError($"Class not found: {name}"); #endif switch (mode & LoadMode.MaskReturn) @@ -677,7 +681,7 @@ protected virtual RuntimeJavaType LoadClassImpl(string name, LoadMode mode) if ((mode & LoadMode.SuppressExceptions) == 0) throw new ClassLoadingException(ikvm.runtime.Util.mapException(x), name); - if (Tracer.ClassLoading.TraceError) + if (Diagnostics.IsEnabled(Diagnostic.GenericClassLoadingError)) { var cl = GetJavaClassLoader(); if (cl != null) @@ -691,11 +695,11 @@ protected virtual RuntimeJavaType LoadClassImpl(string name, LoadMode mode) cl = cl.getParent(); } - Tracer.Error(Tracer.ClassLoading, "ClassLoader chain: {0}", sb); + Diagnostics.GenericClassLoadingError($"ClassLoader chain: {sb}"); } var m = ikvm.runtime.Util.mapException(x); - Tracer.Error(Tracer.ClassLoading, m.ToString() + Environment.NewLine + m.StackTrace); + Diagnostics.GenericClassLoadingError(m.ToString() + Environment.NewLine + m.StackTrace); } return null; @@ -722,7 +726,7 @@ static RuntimeJavaType CreateArrayType(string name, RuntimeJavaType elementJavaT Debug.Assert(!elementJavaType.IsUnloadable && !elementJavaType.IsVerifierType && !elementJavaType.IsArray); Debug.Assert(dimensions >= 1); - return elementJavaType.GetClassLoader().RegisterInitiatingLoader(new RuntimeArrayJavaType(elementJavaType.Context, elementJavaType, name)); + return elementJavaType.ClassLoader.RegisterInitiatingLoader(new RuntimeArrayJavaType(elementJavaType.Context, elementJavaType, name)); } #if !IMPORTER && !EXPORTER @@ -924,8 +928,8 @@ public override string ToString() internal virtual bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJavaType friend) { - Debug.Assert(wrapper.GetClassLoader() == this); - return this == friend.GetClassLoader(); + Debug.Assert(wrapper.ClassLoader == this); + return this == friend.ClassLoader; } #if !IMPORTER && !EXPORTER @@ -942,15 +946,6 @@ internal static RuntimeClassLoader FromCallerID(ikvm.@internal.CallerID callerID #endif -#if IMPORTER - internal virtual void IssueMessage(Message msgId, params string[] values) - { - // it's not ideal when we end up here (because it means we're emitting a warning that is not associated with a specific output target), - // but it happens when we're decoding something in a referenced assembly that either doesn't make sense or contains an unloadable type - Context.StaticCompiler.IssueMessage(msgId, values); - } -#endif - internal void CheckPackageAccess(RuntimeJavaType tw, ProtectionDomain pd) { #if !IMPORTER && !FIRST_PASS && !EXPORTER diff --git a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs index e50f60cba2..5950026f64 100644 --- a/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs +++ b/src/IKVM.Runtime/RuntimeClassLoaderFactory.cs @@ -25,7 +25,7 @@ Jeroen Frijters using System.Collections.Generic; using System.Diagnostics; -using IKVM.Runtime; +using IKVM.CoreLib.Diagnostics; #if NETCOREAPP using System.Runtime.Loader; @@ -111,7 +111,7 @@ internal void LoadRemappedTypes() else { #if IMPORTER - throw new FatalCompilerErrorException(Message.CoreClassesMissing); + throw new FatalCompilerErrorException(Diagnostic.CoreClassesMissing.Event([])); #else throw new InternalException("Failed to find core classes in core library."); #endif @@ -185,21 +185,18 @@ internal RuntimeJavaType GetJavaTypeFromType(Type type) #endif Debug.Assert(!type.IsPointer); Debug.Assert(!type.IsByRef); + RuntimeJavaType wrapper; lock (globalTypeToTypeWrapper) - { globalTypeToTypeWrapper.TryGetValue(type, out wrapper); - } if (wrapper != null) - { return wrapper; - } #if EXPORTER if (type.__IsMissing || type.__ContainsMissingType) { - wrapper = new RuntimeUnloadableJavaType(context, "Missing/" + type.Assembly.FullName); + wrapper = new RuntimeUnloadableJavaType(context, type); globalTypeToTypeWrapper.Add(type, wrapper); return wrapper; } @@ -275,7 +272,7 @@ internal RuntimeClassLoader GetGenericClassLoader(RuntimeJavaType wrapper) list.Add(context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly)); foreach (Type arg in type.GetGenericArguments()) { - RuntimeClassLoader loader = GetJavaTypeFromType(arg).GetClassLoader(); + RuntimeClassLoader loader = GetJavaTypeFromType(arg).ClassLoader; if (!list.Contains(loader) && loader != bootstrapClassLoader) { list.Add(loader); @@ -292,7 +289,7 @@ internal RuntimeJavaType LoadClassCritical(string name) #if IMPORTER var wrapper = GetBootstrapClassLoader().TryLoadClassByName(name); if (wrapper == null) - throw new FatalCompilerErrorException(Message.CriticalClassNotFound, name); + throw new FatalCompilerErrorException(Diagnostic.CriticalClassNotFound.Event([name])); return wrapper; #else diff --git a/src/IKVM.Runtime/RuntimeContext.cs b/src/IKVM.Runtime/RuntimeContext.cs index fd1dea7a1c..87e62e6288 100644 --- a/src/IKVM.Runtime/RuntimeContext.cs +++ b/src/IKVM.Runtime/RuntimeContext.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Concurrent; +using IKVM.CoreLib.Diagnostics; + + #if IMPORTER using IKVM.Tools.Importer; #endif @@ -23,6 +26,7 @@ class RuntimeContext { readonly RuntimeContextOptions options; + readonly IDiagnosticHandler diagnostics; readonly IManagedTypeResolver resolver; readonly bool bootstrap; readonly ConcurrentDictionary singletons = new(); @@ -72,11 +76,13 @@ class RuntimeContext /// Initializes a new instance. /// /// + /// /// /// - public RuntimeContext(RuntimeContextOptions options, IManagedTypeResolver resolver, bool bootstrap, StaticCompiler staticCompiler) + public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, IManagedTypeResolver resolver, bool bootstrap, StaticCompiler staticCompiler) { this.options = options ?? throw new ArgumentNullException(nameof(options)); + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); this.resolver = resolver ?? throw new ArgumentNullException(nameof(resolver)); this.bootstrap = bootstrap; this.staticCompiler = staticCompiler; @@ -88,17 +94,24 @@ public RuntimeContext(RuntimeContextOptions options, IManagedTypeResolver resolv /// Initializes a new instance. /// /// + /// /// /// - public RuntimeContext(RuntimeContextOptions options, IManagedTypeResolver resolver, bool bootstrap) + public RuntimeContext(RuntimeContextOptions options, IDiagnosticHandler diagnostics, IManagedTypeResolver resolver, bool bootstrap) { this.options = options ?? throw new ArgumentNullException(nameof(options)); + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); this.resolver = resolver ?? throw new ArgumentNullException(nameof(resolver)); this.bootstrap = bootstrap; } #endif + /// + /// Gets the where events should be sent. + /// + public IDiagnosticHandler Diagnostics => diagnostics; + /// /// Gets or creates a new instance in a thread safe manner. /// diff --git a/src/IKVM.Runtime/RuntimeGenericClassLoader.cs b/src/IKVM.Runtime/RuntimeGenericClassLoader.cs index 5a6b388b61..8c0712a660 100644 --- a/src/IKVM.Runtime/RuntimeGenericClassLoader.cs +++ b/src/IKVM.Runtime/RuntimeGenericClassLoader.cs @@ -66,7 +66,7 @@ protected override RuntimeJavaType FindLoadedClassLazy(string name) foreach (var loader in delegates) { var tw = loader.FindLoadedClass(name); - if (tw != null && tw.GetClassLoader() == loader) + if (tw != null && tw.ClassLoader == loader) return tw; } @@ -109,7 +109,7 @@ internal java.util.Enumeration GetResources(string name) var tw = FindLoadedClass(name.Substring(0, name.Length - 6).Replace('/', '.')); if (tw != null && !tw.IsArray && !tw.IsDynamic) { - var loader = tw.GetClassLoader(); + var loader = tw.ClassLoader; if (loader is RuntimeGenericClassLoader) v.add(new java.net.URL("ikvmres", "gen", Context.ClassLoaderFactory.GetGenericClassLoaderId(loader), "/" + name)); else if (loader is RuntimeAssemblyClassLoader acl) @@ -130,7 +130,7 @@ internal java.net.URL FindResource(string name) if (name.EndsWith(".class", StringComparison.Ordinal) && name.IndexOf('.') == name.Length - 6) { var tw = FindLoadedClass(name.Substring(0, name.Length - 6).Replace('/', '.')); - if (tw != null && tw.GetClassLoader() == this && !tw.IsArray && !tw.IsDynamic) + if (tw != null && tw.ClassLoader == this && !tw.IsArray && !tw.IsDynamic) return new java.net.URL("ikvmres", "gen", Context.ClassLoaderFactory.GetGenericClassLoaderId(this), "/" + name); } diff --git a/src/IKVM.Runtime/RuntimeJavaField.cs b/src/IKVM.Runtime/RuntimeJavaField.cs index 5bb28744f8..5b6a1ae853 100644 --- a/src/IKVM.Runtime/RuntimeJavaField.cs +++ b/src/IKVM.Runtime/RuntimeJavaField.cs @@ -78,7 +78,7 @@ internal RuntimeJavaField(RuntimeJavaType declaringType, RuntimeJavaType fieldTy DeclaringType.IsPublic && !DeclaringType.IsInterface && (IsPublic || (IsProtected && !DeclaringType.IsFinal)) && - !DeclaringType.GetClassLoader().StrictFinalFieldSemantics && + !DeclaringType.ClassLoader.StrictFinalFieldSemantics && DeclaringType.IsDynamic && this is not RuntimeConstantJavaField && this is not RuntimeByteCodePropertyJavaField) @@ -179,7 +179,7 @@ internal object ToField(bool copy, int? fieldIndex) field = new java.lang.reflect.Field( DeclaringType.ClassObject, Name, - FieldTypeWrapper.EnsureLoadable(DeclaringType.GetClassLoader()).ClassObject, + FieldTypeWrapper.EnsureLoadable(DeclaringType.ClassLoader).ClassObject, (int)(Modifiers & ReflectionFieldModifiersMask) | (IsInternal ? 0x40000000 : 0), fieldIndex ?? Array.IndexOf(DeclaringType.GetFields(), this), DeclaringType.GetGenericFieldSignature(this), @@ -377,7 +377,7 @@ internal void Link(LoadMode mode) if (fieldType != null) return; - var fld = DeclaringType.GetClassLoader().FieldTypeWrapperFromSig(Signature, mode); + var fld = DeclaringType.ClassLoader.FieldTypeWrapperFromSig(Signature, mode); lock (this) { diff --git a/src/IKVM.Runtime/RuntimeJavaMethod.cs b/src/IKVM.Runtime/RuntimeJavaMethod.cs index 14e5d49e1e..6e752c734b 100644 --- a/src/IKVM.Runtime/RuntimeJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeJavaMethod.cs @@ -27,6 +27,8 @@ Jeroen Frijters using IKVM.Attributes; using System.Linq; +using IKVM.CoreLib.Diagnostics; + #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -160,7 +162,7 @@ internal java.lang.reflect.Executable ToMethodOrConstructor(bool copy) if (method == null) { Link(); - RuntimeClassLoader loader = this.DeclaringType.GetClassLoader(); + RuntimeClassLoader loader = this.DeclaringType.ClassLoader; RuntimeJavaType[] argTypes = GetParameters(); java.lang.Class[] parameterTypes = new java.lang.Class[argTypes.Length]; for (int i = 0; i < argTypes.Length; i++) @@ -247,7 +249,7 @@ private java.lang.Class[] GetExceptions() java.lang.Class[] array = new java.lang.Class[classes.Length]; for (int i = 0; i < classes.Length; i++) { - array[i] = this.DeclaringType.GetClassLoader().LoadClassByName(classes[i]).ClassObject; + array[i] = this.DeclaringType.ClassLoader.LoadClassByName(classes[i]).ClassObject; } return array; } @@ -306,7 +308,7 @@ internal void Link(LoadMode mode) return; } } - RuntimeClassLoader loader = this.DeclaringType.GetClassLoader(); + RuntimeClassLoader loader = this.DeclaringType.ClassLoader; RuntimeJavaType ret = loader.RetTypeWrapperFromSig(Signature, mode); RuntimeJavaType[] parameters = loader.ArgJavaTypeListFromSig(Signature, mode); lock (this) @@ -345,18 +347,16 @@ internal void Link(LoadMode mode) protected virtual void DoLinkMethod() { - method = this.DeclaringType.LinkMethod(this); + method = DeclaringType.LinkMethod(this); } [Conditional("DEBUG")] internal void AssertLinked() { if (!(parameterTypeWrappers != null && returnTypeWrapper != null)) - { - Tracer.Error(Tracer.Runtime, "AssertLinked failed: " + this.DeclaringType.Name + "::" + this.Name + this.Signature); - } + DeclaringType.ClassLoader.Diagnostics.GenericRuntimeError($"AssertLinked failed: {DeclaringType.Name}::{Name}{Signature}"); - Debug.Assert(parameterTypeWrappers != null && returnTypeWrapper != null, this.DeclaringType.Name + "::" + this.Name + this.Signature); + Debug.Assert(parameterTypeWrappers != null && returnTypeWrapper != null, DeclaringType.Name + "::" + Name + Signature); } internal RuntimeJavaType ReturnType @@ -458,7 +458,7 @@ internal Type GetDelegateType() { var type = DeclaringType.TypeAsBaseType.Assembly.GetType(ReturnType == DeclaringType.Context.PrimitiveJavaTypeFactory.VOID ? "__<>NVIV`" + paramTypes.Length : "__<>NVI`" + (paramTypes.Length + 1)); if (type == null) - type = DeclaringType.GetClassLoader().GetTypeWrapperFactory().DefineDelegate(paramTypes.Length, ReturnType == DeclaringType.Context.PrimitiveJavaTypeFactory.VOID); + type = DeclaringType.ClassLoader.GetTypeWrapperFactory().DefineDelegate(paramTypes.Length, ReturnType == DeclaringType.Context.PrimitiveJavaTypeFactory.VOID); var types = new Type[paramTypes.Length + (ReturnType == DeclaringType.Context.PrimitiveJavaTypeFactory.VOID ? 0 : 1)]; for (int i = 0; i < paramTypes.Length; i++) diff --git a/src/IKVM.Runtime/RuntimeJavaType.cs b/src/IKVM.Runtime/RuntimeJavaType.cs index c79d8cabdc..16e5adf8fe 100644 --- a/src/IKVM.Runtime/RuntimeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeJavaType.cs @@ -26,6 +26,7 @@ Jeroen Frijters using System.Diagnostics; using IKVM.Attributes; +using IKVM.CoreLib.Diagnostics; #if IMPORTER || EXPORTER using IKVM.Reflection; @@ -88,6 +89,11 @@ internal RuntimeJavaType(RuntimeContext context, TypeFlags flags, Modifiers modi /// public RuntimeContext Context => context; + /// + /// Gets the where events related to this type should be sent. + /// + public virtual IDiagnosticHandler Diagnostics => Context.Diagnostics; + #if EMITTERS internal void EmitClassLiteral(CodeEmitter ilgen) @@ -685,7 +691,10 @@ internal bool IsInterfaceOrInterfaceArray } } - internal abstract RuntimeClassLoader GetClassLoader(); + /// + /// Gets the associated . + /// + internal abstract RuntimeClassLoader ClassLoader { get; } /// /// Searches for the with the specified name and signature. @@ -878,7 +887,7 @@ internal bool IsAccessibleFrom(RuntimeJavaType wrapper) internal bool InternalsVisibleTo(RuntimeJavaType wrapper) { - return GetClassLoader().InternalsVisibleToImpl(this, wrapper); + return ClassLoader.InternalsVisibleToImpl(this, wrapper); } internal virtual bool IsPackageAccessibleFrom(RuntimeJavaType wrapper) @@ -886,15 +895,15 @@ internal virtual bool IsPackageAccessibleFrom(RuntimeJavaType wrapper) if (MatchingPackageNames(name, wrapper.name)) { #if IMPORTER - CompilerClassLoader ccl = GetClassLoader() as CompilerClassLoader; + CompilerClassLoader ccl = ClassLoader as CompilerClassLoader; if (ccl != null) { // this is a hack for multi target -sharedclassloader compilation // (during compilation we have multiple CompilerClassLoader instances to represent the single shared runtime class loader) - return ccl.IsEquivalentTo(wrapper.GetClassLoader()); + return ccl.IsEquivalentTo(wrapper.ClassLoader); } #endif - return GetClassLoader() == wrapper.GetClassLoader(); + return ClassLoader == wrapper.ClassLoader; } else { @@ -1030,11 +1039,11 @@ internal RuntimeJavaType ElementTypeWrapper case '[': // NOTE this call to LoadClassByDottedNameFast can never fail and will not trigger a class load // (because the ultimate element type was already loaded when this type was created) - return GetClassLoader().TryLoadClassByName(name.Substring(1)); + return ClassLoader.TryLoadClassByName(name.Substring(1)); case 'L': // NOTE this call to LoadClassByDottedNameFast can never fail and will not trigger a class load // (because the ultimate element type was already loaded when this type was created) - return GetClassLoader().TryLoadClassByName(name.Substring(2, name.Length - 3)); + return ClassLoader.TryLoadClassByName(name.Substring(2, name.Length - 3)); case 'Z': return context.PrimitiveJavaTypeFactory.BOOLEAN; case 'B': @@ -1061,7 +1070,7 @@ internal RuntimeJavaType MakeArrayType(int rank) { Debug.Assert(rank != 0); // NOTE this call to LoadClassByDottedNameFast can never fail and will not trigger a class load - return GetClassLoader().TryLoadClassByName(new String('[', rank) + this.SigName); + return ClassLoader.TryLoadClassByName(new String('[', rank) + this.SigName); } internal bool ImplementsInterface(RuntimeJavaType interfaceWrapper) @@ -1514,7 +1523,7 @@ internal virtual object GetAnnotationDefault(RuntimeJavaMethod mw) object[] attr = mb.GetCustomAttributes(typeof(AnnotationDefaultAttribute), false); if (attr.Length == 1) { - return JVM.NewAnnotationElementValue(mw.DeclaringType.GetClassLoader().GetJavaClassLoader(), mw.ReturnType.ClassObject, ((AnnotationDefaultAttribute)attr[0]).Value); + return JVM.NewAnnotationElementValue(mw.DeclaringType.ClassLoader.GetJavaClassLoader(), mw.ReturnType.ClassObject, ((AnnotationDefaultAttribute)attr[0]).Value); } } return null; diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs index 01add0e311..d9ca623897 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.DelegateConstructorJavaMethod.cs @@ -62,7 +62,7 @@ sealed class DelegateConstructorJavaMethod : RuntimeJavaMethod /// /// internal DelegateConstructorJavaMethod(RuntimeJavaType tw, MethodBase method) : - this(tw, tw.GetClassLoader().LoadClassByName(tw.Name + RuntimeManagedJavaType.DelegateInterfaceSuffix), tw.Context.AttributeHelper.GetModifiers(method, false)) + this(tw, tw.ClassLoader.LoadClassByName(tw.Name + RuntimeManagedJavaType.DelegateInterfaceSuffix), tw.Context.AttributeHelper.GetModifiers(method, false)) { constructor = (ConstructorInfo)method; } diff --git a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs index 5e39d3bafb..d479188d63 100644 --- a/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedByteCodeJavaType.cs @@ -25,6 +25,7 @@ Jeroen Frijters using System.Collections.Generic; using System.Diagnostics; +using IKVM.CoreLib.Diagnostics; using IKVM.Attributes; using IKVM.Runtime.Syntax; using IKVM.ByteCode; @@ -207,10 +208,7 @@ internal override RuntimeJavaType BaseTypeWrapper } } - internal override RuntimeClassLoader GetClassLoader() - { - return Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); - } + internal override RuntimeClassLoader ClassLoader => Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); static ExModifiers GetModifiers(RuntimeContext context, Type type) { @@ -317,7 +315,7 @@ private RuntimeJavaType[] GetInterfaces() if (interfaceWrappers[i] == null) { #if IMPORTER - throw new FatalCompilerErrorException(Message.UnableToResolveInterface, interfaceNames[i], this); + throw new FatalCompilerErrorException(Diagnostic.UnableToResolveInterface.Event([interfaceNames[i], this])); #else throw new InternalException($"Unable to resolve interface {interfaceNames[i]} on type {this}"); #endif @@ -372,7 +370,7 @@ internal override RuntimeJavaType[] InnerClasses } foreach (string s in Context.AttributeHelper.GetNonNestedInnerClasses(type)) { - wrappers.Add(GetClassLoader().LoadClassByName(s)); + wrappers.Add(ClassLoader.LoadClassByName(s)); } return wrappers.ToArray(); @@ -395,8 +393,9 @@ internal override RuntimeJavaType DeclaringTypeWrapper string decl = Context.AttributeHelper.GetNonNestedOuterClasses(type); if (decl != null) { - return GetClassLoader().LoadClassByName(decl); + return ClassLoader.LoadClassByName(decl); } + return null; } } @@ -492,7 +491,7 @@ private void SigTypePatchUp(string sigtype, ref RuntimeJavaType type) // as object (not as arrays of object) if (type.IsArray) { - type = GetClassLoader().FieldTypeWrapperFromSig(sigtype, LoadMode.LoadOrThrow); + type = ClassLoader.FieldTypeWrapperFromSig(sigtype, LoadMode.LoadOrThrow); } else if (type.IsPrimitive) { @@ -517,7 +516,7 @@ private void SigTypePatchUp(string sigtype, ref RuntimeJavaType type) } try { - RuntimeJavaType tw = GetClassLoader().TryLoadClassByName(sigtype); + RuntimeJavaType tw = ClassLoader.TryLoadClassByName(sigtype); if (tw != null && tw.IsRemapped) { type = tw; @@ -609,7 +608,7 @@ private void GetNameSigFromMethodBase(MethodBase method, out string name, out st retType = method is ConstructorInfo ? Context.PrimitiveJavaTypeFactory.VOID : GetParameterTypeWrapper(Context, ((MethodInfo)method).ReturnParameter); var parameters = method.GetParameters(); int len = parameters.Length; - if (len > 0 && IsCallerID(Context, parameters[len - 1].ParameterType) && GetClassLoader() == Context.ClassLoaderFactory.GetBootstrapClassLoader() && IsCallerSensitive(method)) + if (len > 0 && IsCallerID(Context, parameters[len - 1].ParameterType) && ClassLoader == Context.ClassLoaderFactory.GetBootstrapClassLoader() && IsCallerSensitive(method)) { len--; flags |= MemberFlags.CallerID; diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs index 56b62ea80c..09e8475a88 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaType.cs @@ -24,12 +24,14 @@ Jeroen Frijters using System; using System.Collections.Generic; +using IKVM.CoreLib.Diagnostics; + #if IMPORTER || EXPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; -using System.Net.Mime; + #else using System.Reflection; using System.Reflection.Emit; @@ -393,11 +395,11 @@ RuntimeJavaType[] GetInnerClasses() AttributeUsageAttribute attr = GetAttributeUsage(); if ((attr.ValidOn & AttributeTargets.ReturnValue) != 0) { - list.Add(GetClassLoader().RegisterInitiatingLoader(new ReturnValueAnnotationJavaType(Context, this))); + list.Add(ClassLoader.RegisterInitiatingLoader(new ReturnValueAnnotationJavaType(Context, this))); } if (attr.AllowMultiple) { - list.Add(GetClassLoader().RegisterInitiatingLoader(new MultipleAnnotationJavaType(Context, this))); + list.Add(ClassLoader.RegisterInitiatingLoader(new MultipleAnnotationJavaType(Context, this))); } return list.ToArray(); } @@ -543,9 +545,9 @@ internal override void Apply(RuntimeClassLoader loader, TypeBuilder tb, object a // we have to handle this explicitly, because if we apply an illegal StructLayoutAttribute, // TypeBuilder.CreateType() will later on throw an exception. #if IMPORTER - loader.IssueMessage(Message.IgnoredCustomAttribute, type.FullName, "Type '" + tb.FullName + "' does not extend cli.System.Object"); + loader.Diagnostics.IgnoredCustomAttribute(type.FullName, $"Type '{tb.FullName}' does not extend cli.System.Object"); #else - Tracer.Error(Tracer.Runtime, "StructLayoutAttribute cannot be applied to {0}, because it does not directly extend cli.System.Object", tb.FullName); + loader.Diagnostics.GenericRuntimeError($"StructLayoutAttribute cannot be applied to {tb.FullName}, because it does not directly extend cli.System.Object"); #endif return; } @@ -590,7 +592,7 @@ internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, obje } else { - loader.IssueMessage(Message.InvalidCustomAttribute, type.FullName, "The version '" + str + "' is invalid."); + loader.Diagnostics.InvalidCustomAttribute(type.FullName, "The version '" + str + "' is invalid."); } } else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyCultureAttribute).FullName)) @@ -605,7 +607,7 @@ internal override void Apply(RuntimeClassLoader loader, AssemblyBuilder ab, obje || type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyKeyFileAttribute).FullName) || type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyKeyNameAttribute).FullName)) { - loader.IssueMessage(Message.IgnoredCustomAttribute, type.FullName, "Please use the corresponding compiler switch."); + loader.Diagnostics.IgnoredCustomAttribute(type.FullName, "Please use the corresponding compiler switch."); } else if (type == loader.Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyAlgorithmIdAttribute).FullName)) { diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaTypeBase.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaTypeBase.cs index c69931b6ac..feec0c7a77 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaTypeBase.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.AttributeAnnotationJavaTypeBase.cs @@ -45,10 +45,7 @@ internal AttributeAnnotationJavaTypeBase(RuntimeContext context, string name) : } - internal sealed override RuntimeClassLoader GetClassLoader() - { - return DeclaringTypeWrapper.GetClassLoader(); - } + internal sealed override RuntimeClassLoader ClassLoader => DeclaringTypeWrapper.ClassLoader; internal sealed override RuntimeJavaType[] Interfaces => new RuntimeJavaType[] { Context.ClassLoaderFactory.GetBootstrapClassLoader().LoadClassByName("java.lang.annotation.Annotation") }; diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs index 6566529b88..87e804711a 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.DelegateInnerClassJavaType.cs @@ -89,10 +89,7 @@ internal DelegateInnerClassJavaType(RuntimeContext context, string name, Type de internal override RuntimeJavaType DeclaringTypeWrapper => Context.ClassLoaderFactory.GetJavaTypeFromType(fakeType.GetGenericArguments()[0]); - internal override RuntimeClassLoader GetClassLoader() - { - return DeclaringTypeWrapper.GetClassLoader(); - } + internal override RuntimeClassLoader ClassLoader => DeclaringTypeWrapper.ClassLoader; internal override Type TypeAsTBD => fakeType; diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs index c67eae2fe0..95830d7a77 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.EnumEnumJavaType.cs @@ -183,10 +183,7 @@ protected override void LazyPublishMembers() internal override RuntimeJavaType DeclaringTypeWrapper => Context.ClassLoaderFactory.GetJavaTypeFromType(fakeType.GetGenericArguments()[0]); - internal override RuntimeClassLoader GetClassLoader() - { - return DeclaringTypeWrapper.GetClassLoader(); - } + internal override RuntimeClassLoader ClassLoader => DeclaringTypeWrapper.ClassLoader; internal override Type TypeAsTBD => fakeType; diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.OpenGenericJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.OpenGenericJavaType.cs index 7bfa8baf22..bde1900458 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.OpenGenericJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.OpenGenericJavaType.cs @@ -75,15 +75,12 @@ internal OpenGenericJavaType(RuntimeContext context, Type type, string name) : internal override Type TypeAsTBD => type; - internal override RuntimeClassLoader GetClassLoader() - { - return Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); - } + internal override RuntimeClassLoader ClassLoader => Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); protected override void LazyPublishMembers() { - SetFields(Array.Empty()); - SetMethods(Array.Empty()); + SetFields([]); + SetMethods([]); } } diff --git a/src/IKVM.Runtime/RuntimeManagedJavaType.cs b/src/IKVM.Runtime/RuntimeManagedJavaType.cs index a1fe3634f4..04a159d570 100644 --- a/src/IKVM.Runtime/RuntimeManagedJavaType.cs +++ b/src/IKVM.Runtime/RuntimeManagedJavaType.cs @@ -316,7 +316,7 @@ internal static RuntimeJavaType Create(RuntimeContext context, Type type, string internal override RuntimeJavaType BaseTypeWrapper => baseTypeWrapper ??= Context.ManagedJavaTypeFactory.GetBaseJavaType(type); - internal override RuntimeClassLoader GetClassLoader() => type.IsGenericType ? Context.ClassLoaderFactory.GetGenericClassLoader(this) : Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); + internal override RuntimeClassLoader ClassLoader => type.IsGenericType ? Context.ClassLoaderFactory.GetGenericClassLoader(this) : Context.AssemblyClassLoaderFactory.FromAssembly(type.Assembly); internal static string GetDelegateInvokeStubName(Type delegateType) { @@ -748,13 +748,13 @@ RuntimeJavaType[] GetInnerClasses() list.Add(Context.ClassLoaderFactory.GetJavaTypeFromType(nestedTypes[i])); if (IsDelegate(Context, type)) - list.Add(GetClassLoader().RegisterInitiatingLoader(new DelegateInnerClassJavaType(Context, Name + DelegateInterfaceSuffix, type))); + list.Add(ClassLoader.RegisterInitiatingLoader(new DelegateInnerClassJavaType(Context, Name + DelegateInterfaceSuffix, type))); if (IsAttribute(Context, type)) - list.Add(GetClassLoader().RegisterInitiatingLoader(new AttributeAnnotationJavaType(Context, Name + AttributeAnnotationSuffix, type))); + list.Add(ClassLoader.RegisterInitiatingLoader(new AttributeAnnotationJavaType(Context, Name + AttributeAnnotationSuffix, type))); if (type.IsEnum && type.IsVisible) - list.Add(GetClassLoader().RegisterInitiatingLoader(new EnumEnumJavaType(Context, Name + EnumEnumSuffix, type))); + list.Add(ClassLoader.RegisterInitiatingLoader(new EnumEnumJavaType(Context, Name + EnumEnumSuffix, type))); return list.ToArray(); } diff --git a/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs b/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs index 2537101ecd..1603b19752 100644 --- a/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs +++ b/src/IKVM.Runtime/RuntimePrimitiveJavaType.cs @@ -108,7 +108,7 @@ internal static bool IsPrimitiveType(RuntimeContext context, Type type) internal override string SigName => sigName; - internal override RuntimeClassLoader GetClassLoader() => Context.ClassLoaderFactory.GetBootstrapClassLoader(); + internal override RuntimeClassLoader ClassLoader => Context.ClassLoaderFactory.GetBootstrapClassLoader(); internal override Type TypeAsTBD => type; diff --git a/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs b/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs index 95474ea48b..05961e1edc 100644 --- a/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs +++ b/src/IKVM.Runtime/RuntimeUnloadableJavaType.cs @@ -82,10 +82,7 @@ internal RuntimeUnloadableJavaType(RuntimeContext context, string name, Type cus internal override RuntimeJavaType BaseTypeWrapper => null; - internal override RuntimeClassLoader GetClassLoader() - { - return null; - } + internal override RuntimeClassLoader ClassLoader => null; internal override RuntimeJavaType EnsureLoadable(RuntimeClassLoader loader) { diff --git a/src/IKVM.Runtime/RuntimeVerifierJavaType.cs b/src/IKVM.Runtime/RuntimeVerifierJavaType.cs index e73f1fd50f..998f9c82c4 100644 --- a/src/IKVM.Runtime/RuntimeVerifierJavaType.cs +++ b/src/IKVM.Runtime/RuntimeVerifierJavaType.cs @@ -195,10 +195,7 @@ internal override RuntimeJavaType BaseTypeWrapper get { return null; } } - internal override RuntimeClassLoader GetClassLoader() - { - return null; - } + internal override RuntimeClassLoader ClassLoader => null; protected override void LazyPublishMembers() { diff --git a/src/IKVM.Runtime/StubGen/StubGenerator.cs b/src/IKVM.Runtime/StubGen/StubGenerator.cs index 01bd58815d..bb91ff5a47 100644 --- a/src/IKVM.Runtime/StubGen/StubGenerator.cs +++ b/src/IKVM.Runtime/StubGen/StubGenerator.cs @@ -1189,7 +1189,7 @@ CustomAttributeData GetAnnotationDefault(MethodBase mb) string GetAssemblyName(RuntimeJavaType tw) { - var loader = tw.GetClassLoader(); + var loader = tw.ClassLoader; var acl = loader as RuntimeAssemblyClassLoader; if (acl != null) return acl.GetAssembly(tw).FullName; diff --git a/src/IKVM.Runtime/System/Index.cs b/src/IKVM.Runtime/System/Index.cs index 566d892d32..f29a3ab473 100644 --- a/src/IKVM.Runtime/System/Index.cs +++ b/src/IKVM.Runtime/System/Index.cs @@ -3,9 +3,6 @@ // See the LICENSE file in the project root for more information. #if NETSTANDARD2_1 || NET -using System.Runtime.CompilerServices; - -[assembly: TypeForwardedTo(typeof(System.Index))] #else using System.Runtime.CompilerServices; @@ -19,7 +16,7 @@ namespace System; /// int lastElement = someArray[^1]; // lastElement = 5 /// /// -public readonly struct Index : IEquatable +readonly struct Index : IEquatable { private readonly int _value; diff --git a/src/IKVM.Runtime/System/Range.cs b/src/IKVM.Runtime/System/Range.cs index 7d536244c0..eeda47db4d 100644 --- a/src/IKVM.Runtime/System/Range.cs +++ b/src/IKVM.Runtime/System/Range.cs @@ -3,9 +3,6 @@ // See the LICENSE file in the project root for more information. #if NETSTANDARD2_1 || NET -using System.Runtime.CompilerServices; - -[assembly: TypeForwardedTo(typeof(global::System.Range))] #else using System.Runtime.CompilerServices; @@ -20,7 +17,7 @@ namespace System; /// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 } /// /// -public readonly struct Range : IEquatable +readonly struct Range : IEquatable { /// Represent the inclusive start index of the Range. public Index Start { get; } diff --git a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs index eb8231736f..bb0d5d136b 100644 --- a/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs +++ b/src/IKVM.Runtime/Util/Java/Lang/Invoke/NativeInvokerBytecodeGenerator.cs @@ -332,10 +332,7 @@ public AnonymousClass(RuntimeContext context) : } - internal override RuntimeClassLoader GetClassLoader() - { - return Context.ClassLoaderFactory.GetBootstrapClassLoader(); - } + internal override RuntimeClassLoader ClassLoader => Context.ClassLoaderFactory.GetBootstrapClassLoader(); internal override Type TypeAsTBD { diff --git a/src/IKVM.Runtime/compiler.cs b/src/IKVM.Runtime/compiler.cs index d141799c86..98591bf474 100644 --- a/src/IKVM.Runtime/compiler.cs +++ b/src/IKVM.Runtime/compiler.cs @@ -26,6 +26,7 @@ Jeroen Frijters using System.Diagnostics; using System.Diagnostics.SymbolStore; +using IKVM.CoreLib.Diagnostics; using IKVM.Attributes; using IKVM.ByteCode; @@ -44,6 +45,7 @@ Jeroen Frijters using LocalVariableTableEntry = IKVM.Runtime.ClassFile.Method.LocalVariableTableEntry; using Instruction = IKVM.Runtime.ClassFile.Method.Instruction; using InstructionFlags = IKVM.Runtime.ClassFile.Method.InstructionFlags; +using System.Runtime.CompilerServices; namespace IKVM.Runtime { @@ -564,7 +566,7 @@ internal void Store(int i) internal static void Compile(RuntimeByteCodeJavaType.FinishContext finish, RuntimeJavaType host, RuntimeByteCodeJavaType clazz, RuntimeJavaMethod mw, ClassFile classFile, ClassFile.Method m, CodeEmitter ilGenerator, ref bool nonleaf) { - var classLoader = clazz.GetClassLoader(); + var classLoader = clazz.ClassLoader; if (classLoader.EmitSymbols) { if (classFile.SourcePath != null) @@ -608,9 +610,9 @@ internal static void Compile(RuntimeByteCodeJavaType.FinishContext finish, Runti catch (VerifyError x) { #if IMPORTER - classLoader.IssueMessage(Message.EmittedVerificationError, classFile.Name + "." + m.Name + m.Signature, x.Message); + classLoader.Diagnostics.EmittedVerificationError(classFile.Name + "." + m.Name + m.Signature, x.Message); #endif - Tracer.Error(Tracer.Verifier, x.ToString()); + classLoader.Diagnostics.GenericVerifierError(x.ToString()); clazz.SetHasVerifyError(); // because in Java the method is only verified if it is actually called, // we generate code here to throw the VerificationError @@ -620,9 +622,9 @@ internal static void Compile(RuntimeByteCodeJavaType.FinishContext finish, Runti catch (ClassFormatError x) { #if IMPORTER - classLoader.IssueMessage(Message.EmittedClassFormatError, classFile.Name + "." + m.Name + m.Signature, x.Message); + classLoader.Diagnostics.EmittedClassFormatError(classFile.Name + "." + m.Name + m.Signature, x.Message); #endif - Tracer.Error(Tracer.Verifier, x.ToString()); + classLoader.Diagnostics.GenericVerifierError(x.ToString()); clazz.SetHasClassFormatError(); ilGenerator.EmitThrow("java.lang.ClassFormatError", x.Message); return; @@ -875,12 +877,12 @@ internal void AddExitHack(object bc) void Compile(Block block, int startIndex) { - InstructionFlags[] flags = ComputePartialReachability(startIndex, true); - ExceptionTableEntry[] exceptions = GetExceptionTableFor(flags); - int exceptionIndex = 0; - Instruction[] code = m.Instructions; - Stack blockStack = new Stack(); - bool instructionIsForwardReachable = true; + var flags = ComputePartialReachability(startIndex, true); + var exceptions = GetExceptionTableFor(flags); + var exceptionIndex = 0; + var code = m.Instructions; + var blockStack = new Stack(); + var instructionIsForwardReachable = true; if (startIndex != 0) { for (int i = 0; i < flags.Length; i++) @@ -892,13 +894,15 @@ void Compile(Block block, int startIndex) instructionIsForwardReachable = false; ilGenerator.EmitBr(block.GetLabel(startIndex)); } + break; } } } + for (int i = 0; i < code.Length; i++) { - Instruction instr = code[i]; + var instr = code[i]; if (scopeBegin != null) { @@ -2559,8 +2563,9 @@ void Compile(Block block, int startIndex) { finish.Context.ClassLoaderFactory.LoadClassCritical("java.lang.IncompatibleClassChangeError").GetMethodWrapper("", "()V", false).EmitNewobj(ilGenerator); } - string message = harderrors[instr.HardErrorMessageId]; - Tracer.Error(Tracer.Compiler, "{0}: {1}\n\tat {2}.{3}{4}", exceptionType.Name, message, classFile.Name, m.Name, m.Signature); + + var message = harderrors[instr.HardErrorMessageId]; + clazz.ClassLoader.Diagnostics.GenericCompilerError($"{exceptionType.Name}: {message}\n\tat {classFile.Name}.{m.Name}{m.Signature}"); ilGenerator.Emit(OpCodes.Ldstr, message); RuntimeJavaMethod method = exceptionType.GetMethodWrapper("", "(Ljava.lang.String;)V", false); method.Link(); @@ -2575,6 +2580,7 @@ void Compile(Block block, int startIndex) default: throw new NotImplementedException(instr.NormalizedOpCode.ToString()); } + // mark next instruction as inuse switch (ByteCodeMetaData.GetFlowControl(instr.NormalizedOpCode)) { @@ -2739,7 +2745,7 @@ internal static void Emit(Compiler compiler, ClassFile.ConstantPoolItemInvokeDyn var tb = compiler.finish.DefineIndyCallSiteType(); var fb = tb.DefineField("value", typeofIndyCallSite, FieldAttributes.Static | FieldAttributes.Assembly); - var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, compiler.clazz.GetClassLoader())); + var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, compiler.clazz.ClassLoader)); ilgen.Emit(OpCodes.Ldnull); ilgen.Emit(OpCodes.Ldftn, CreateBootstrapStub(compiler, cpi, delegateType, tb, fb, methodGetTarget)); ilgen.Emit(OpCodes.Newobj, compiler.finish.Context.MethodHandleUtil.GetDelegateConstructor(delegateType)); @@ -3097,7 +3103,7 @@ static FieldBuilder CreateField(Compiler compiler, MethodTypeConstantHandle hand { var tb = compiler.finish.DefineMethodTypeConstantType(handle); var field = tb.DefineField("value", compiler.finish.Context.JavaBase.TypeOfJavaLangInvokeMethodType.TypeAsSignatureType, FieldAttributes.Assembly | FieldAttributes.Static | FieldAttributes.InitOnly); - var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, compiler.clazz.GetClassLoader())); + var ilgen = compiler.finish.Context.CodeEmitterFactory.Create(ReflectUtil.DefineTypeInitializer(tb, compiler.clazz.ClassLoader)); var delegateType = compiler.finish.Context.MethodHandleUtil.CreateDelegateTypeForLoadConstant(args, ret); ilgen.Emit(OpCodes.Call, compiler.finish.Context.ByteCodeHelperMethods.LoadMethodType.MakeGenericMethod(delegateType)); ilgen.Emit(OpCodes.Stsfld, field); diff --git a/src/IKVM.Runtime/intrinsics.cs b/src/IKVM.Runtime/intrinsics.cs index 6a197ef6b9..c390600878 100644 --- a/src/IKVM.Runtime/intrinsics.cs +++ b/src/IKVM.Runtime/intrinsics.cs @@ -25,6 +25,8 @@ Jeroen Frijters using System; using System.Collections.Generic; +using IKVM.CoreLib.Diagnostics; + #if IMPORTER using IKVM.Reflection; using IKVM.Reflection.Emit; @@ -148,7 +150,7 @@ static void EmitArrayIndexScale(EmitIntrinsicContext eic, RuntimeJavaType tw) internal static bool IsIntrinsic(RuntimeJavaMethod mw) { - return intrinsics.ContainsKey(new IntrinsicKey(mw)) && mw.DeclaringType.GetClassLoader() == mw.DeclaringType.Context.JavaBase.TypeOfJavaLangObject.GetClassLoader(); + return intrinsics.ContainsKey(new IntrinsicKey(mw)) && mw.DeclaringType.ClassLoader == mw.DeclaringType.Context.JavaBase.TypeOfJavaLangObject.ClassLoader; } internal static bool Emit(EmitIntrinsicContext context) @@ -208,7 +210,7 @@ private static bool Class_desiredAssertionStatus(EmitIntrinsicContext eic) && eic.Match(-1, NormalizedByteCode.__ldc)) { RuntimeJavaType classLiteral = eic.GetClassLiteral(-1); - if (!classLiteral.IsUnloadable && classLiteral.GetClassLoader().RemoveAsserts) + if (!classLiteral.IsUnloadable && classLiteral.ClassLoader.RemoveAsserts) { eic.Emitter.Emit(OpCodes.Pop); eic.Emitter.EmitLdc_I4(0); @@ -353,7 +355,7 @@ static bool Reflection_getCallerClass(EmitIntrinsicContext eic) } else { - eic.Context.TypeWrapper.Context.StaticCompiler.IssueMessage(Message.ReflectionCallerClassRequiresCallerID, eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature); + eic.Context.TypeWrapper.ClassLoader.Diagnostics.ReflectionCallerClassRequiresCallerID(eic.ClassFile.Name, eic.Caller.Name, eic.Caller.Signature); } return false; } @@ -372,7 +374,7 @@ private static bool CallerID_getCallerID(EmitIntrinsicContext eic) } else { - throw new FatalCompilerErrorException(Message.CallerIDRequiresHasCallerIDAnnotation); + throw new FatalCompilerErrorException(Diagnostic.CallerIDRequiresHasCallerIDAnnotation.Event([])); } } @@ -1009,7 +1011,7 @@ internal static MethodInfo MakeExchange(RuntimeContext context, Type type) static void EmitConsumeUnsafe(EmitIntrinsicContext eic) { #if IMPORTER - if (eic.Caller.DeclaringType.GetClassLoader() == eic.Context.TypeWrapper.Context.JavaBase.TypeOfJavaLangObject.GetClassLoader()) + if (eic.Caller.DeclaringType.ClassLoader == eic.Context.TypeWrapper.Context.JavaBase.TypeOfJavaLangObject.ClassLoader) { // we're compiling the core library (which is obviously trusted), so we don't need to check // if we really have an Unsafe instance @@ -1024,7 +1026,7 @@ static void EmitConsumeUnsafe(EmitIntrinsicContext eic) static RuntimeJavaField GetUnsafeField(EmitIntrinsicContext eic, ClassFile.ConstantPoolItemFieldref field) { - if (eic.Caller.DeclaringType.GetClassLoader() != eic.Method.DeclaringType.Context.JavaBase.TypeOfJavaLangObject.GetClassLoader()) + if (eic.Caller.DeclaringType.ClassLoader != eic.Method.DeclaringType.Context.JavaBase.TypeOfJavaLangObject.ClassLoader) { // this code does not solve the general problem and assumes non-hostile, well behaved static initializers // so we only support the core class library diff --git a/src/IKVM.Runtime/tracer.cs b/src/IKVM.Runtime/tracer.cs deleted file mode 100644 index 145cb2eaac..0000000000 --- a/src/IKVM.Runtime/tracer.cs +++ /dev/null @@ -1,232 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006 Jeroen Frijters - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Diagnostics; -using System.Text.RegularExpressions; -using System.Threading; - -namespace IKVM.Runtime -{ - - public static class Tracer - { - - public readonly static TraceSwitch Compiler = new TraceSwitch("compiler", "Static Compiler"); - public readonly static TraceSwitch FxBug = new TraceSwitch("fxbug", ".NET Framework bug related events"); - public readonly static TraceSwitch ClassLoading = new TraceSwitch("classloading", "Class loading"); - public readonly static TraceSwitch Verifier = new TraceSwitch("verifier", "Bytecode Verifier"); - public readonly static TraceSwitch Runtime = new TraceSwitch("runtime", "Miscellaneous runtime events"); - public readonly static TraceSwitch Jni = new TraceSwitch("jni", "JNI"); - - readonly static Dictionary allTraceSwitches = new Dictionary(); - readonly static List methodtraces = new List(); - - sealed class MyTextWriterTraceListener : TextWriterTraceListener - { - - /// - /// Initializes a new instance. - /// - /// - internal MyTextWriterTraceListener(System.IO.TextWriter tw) : - base(tw) - { - - } - - public override void Fail(string message) - { - WriteLine($"Assert.Fail: {message}"); - WriteLine(new StackTrace(true).ToString()); - base.Fail(message); - } - - public override void Fail(string message, string detailMessage) - { - WriteLine($"Assert.Fail: {message}.\n{detailMessage}"); - WriteLine(new StackTrace(true).ToString()); - base.Fail(message, detailMessage); - } - - } - - /// - /// Initializes the static instance. - /// - static Tracer() - { - try - { - Init(); - } - catch (System.Security.SecurityException) - { - - } - } - - private static void Init() - { - allTraceSwitches[Compiler.DisplayName] = Compiler; - allTraceSwitches[FxBug.DisplayName] = FxBug; - allTraceSwitches[ClassLoading.DisplayName] = ClassLoading; - allTraceSwitches[Verifier.DisplayName] = Verifier; - allTraceSwitches[Runtime.DisplayName] = Runtime; - allTraceSwitches[Jni.DisplayName] = Jni; - -#if NETFRAMEWORK - - try - { - Trace.AutoFlush = true; - -#if !EXPORTER - /* If the app config file gives some method trace - add it */ - var trace = ConfigurationManager.AppSettings["Traced Methods"]; - if (trace != null) - methodtraces.Add(trace); -#endif - } - catch (ConfigurationException) - { - // app.config is malformed, ignore - } -#endif - } - - [Conditional("DEBUG")] - public static void EnableTraceForDebug() - { - SetTraceLevel("*", TraceLevel.Verbose); - } - - /// - /// Enables trace output to to the console. - /// - public static void EnableTraceConsoleListener() - { - //Trace.Listeners.Add(new MyTextWriterTraceListener(Console.Error)); - } - - public static void HandleMethodTrace(string name) - { - methodtraces.Add(name); - } - - public static bool IsTracedMethod(string name) - { - foreach (var trace in methodtraces) - { - try - { - if (Regex.IsMatch(name, trace)) - return true; - } - catch (Exception x) - { - Tracer.Warning(Tracer.Compiler, $"Regular Expression match failure: {trace}:{x}"); - } - } - - return false; - } - - public static void SetTraceLevel(string name) - { - var trace = name.Split('='); - var level = TraceLevel.Verbose; - - if (trace.Length == 2) - level = (TraceLevel)Enum.Parse(typeof(TraceLevel), trace[1], true); - - SetTraceLevel(trace[0], level); - } - - public static void SetTraceLevel(string name, TraceLevel level) - { - if (name == "*") - { - foreach (var ts in allTraceSwitches.Values) - ts.Level = level; - } - else - { - if (allTraceSwitches.TryGetValue(name, out var ts)) - { - ts.Level = level; - } - else - { - Console.Error.WriteLine("Warning: Invalid traceswitch name: {0}", name); - } - } - } - - static void WriteLine(string message, object[] p) - { - if (p.Length > 0) - message = string.Format(message, p); - - Trace.WriteLine($"[{DateTime.Now:HH':'mm':'ss'.'fffff} {Thread.CurrentThread.Name}] {message}"); - } - - [Conditional("TRACE")] - public static void Verbose(TraceSwitch traceSwitch, string message, params object[] p) - { - if (traceSwitch.TraceVerbose) - WriteLine(message, p); - } - - [Conditional("TRACE")] - public static void Info(TraceSwitch traceSwitch, string message, params object[] p) - { - if (traceSwitch.TraceInfo) - WriteLine(message, p); - } - - [Conditional("TRACE")] - public static void MethodInfo(string message) - { - Trace.WriteLine($"[{DateTime.Now:HH':'mm':'ss'.'fffff} {Thread.CurrentThread.Name}] {message}"); - } - - [Conditional("TRACE")] - public static void Warning(TraceSwitch traceSwitch, string message, params object[] p) - { - if (traceSwitch.TraceWarning) - WriteLine(message, p); - } - - [Conditional("TRACE")] - public static void Error(TraceSwitch traceSwitch, string message, params object[] p) - { - if (traceSwitch.TraceError) - WriteLine(message, p); - } - - } - -} diff --git a/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj b/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj index 4af39ee6f5..bf56d51345 100644 --- a/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj +++ b/src/IKVM.Tools.Exporter/IKVM.Tools.Exporter.csproj @@ -12,6 +12,7 @@ + @@ -32,7 +33,6 @@ - diff --git a/src/IKVM.Tools.Exporter/IkvmExporterInternal.cs b/src/IKVM.Tools.Exporter/IkvmExporterInternal.cs index 5c183d22fb..61083684a6 100644 --- a/src/IKVM.Tools.Exporter/IkvmExporterInternal.cs +++ b/src/IKVM.Tools.Exporter/IkvmExporterInternal.cs @@ -5,8 +5,8 @@ using System.Linq; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; -using System.Security.Cryptography.Xml; +using IKVM.CoreLib.Diagnostics; using IKVM.Reflection; using IKVM.Runtime; using IKVM.Tools.Importer; @@ -22,6 +22,35 @@ namespace IKVM.Tools.Exporter static class IkvmExporterInternal { + /// + /// Handles diagnostic messages from IKVM. + /// + class DiagnosticHandler : DiagnosticEventHandler + { + + readonly IkvmExporterOptions options; + + /// + /// Initializes a new instance. + /// + /// + public DiagnosticHandler(IkvmExporterOptions options) + { + this.options = options ?? throw new ArgumentNullException(nameof(options)); + } + + public override bool IsEnabled(Diagnostic diagnostic) + { + return IkvmExporterInternal.IsDiagnosticEnabled(options, diagnostic); + } + + public override void Report(in DiagnosticEvent @event) + { + IkvmExporterInternal.ReportEvent(options, @event); + } + + } + class ManagedResolver : IManagedTypeResolver { @@ -94,8 +123,7 @@ public Type ResolveRuntimeType(string typeName) /// public static int Execute(IkvmExporterOptions options) { - IKVM.Runtime.Tracer.EnableTraceConsoleListener(); - IKVM.Runtime.Tracer.EnableTraceForDebug(); + var diagnostics = new DiagnosticHandler(options); var references = new List(); if (options.References != null) @@ -123,7 +151,7 @@ public static int Execute(IkvmExporterOptions options) var coreLibName = FindCoreLibName(references, libpaths); if (coreLibName == null) { - Console.Error.WriteLine("Error: core library not found"); + diagnostics.CoreClassesMissing(); return 1; } @@ -139,7 +167,7 @@ public static int Execute(IkvmExporterOptions options) Assembly[] dummy = null; if (assemblyResolver.ResolveReference(cache, ref dummy, reference) == false) { - Console.Error.WriteLine("Error: reference not found {0}", reference); + diagnostics.ReferenceNotFound(reference); return 1; } } @@ -149,9 +177,14 @@ public static int Execute(IkvmExporterOptions options) { file = new FileInfo(options.Assembly); } + catch (FileNotFoundException) + { + diagnostics.InputFileNotFound(options.Assembly); + return 1; + } catch (Exception x) { - Console.Error.WriteLine("Error: unable to load \"{0}\"\n {1}", options.Assembly, x.Message); + diagnostics.ErrorReadingFile(options.Assembly, x.ToString()); return 1; } @@ -171,7 +204,7 @@ public static int Execute(IkvmExporterOptions options) if (assembly == null) { rc = 1; - Console.Error.WriteLine("Error: Assembly \"{0}\" not found", options.Assembly); + diagnostics.ReferenceNotFound(options.Assembly); } else { @@ -186,12 +219,12 @@ public static int Execute(IkvmExporterOptions options) if (runtimeAssembly == null || runtimeAssembly.__IsMissing) { - Console.Error.WriteLine("Error: IKVM.Runtime not found."); + diagnostics.RuntimeNotFound(); return 1; } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), new ManagedResolver(compiler, null), true, compiler); + context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedResolver(compiler, null), true, compiler); context.ClassLoaderFactory.SetBootstrapClassLoader(new RuntimeBootstrapClassLoader(context)); } else @@ -207,22 +240,25 @@ public static int Execute(IkvmExporterOptions options) if (runtimeAssembly == null || runtimeAssembly.__IsMissing) { - Console.Error.WriteLine("Error: IKVM.Runtime not found."); + diagnostics.RuntimeNotFound(); return 1; } if (baseAssembly == null || runtimeAssembly.__IsMissing) { - Console.Error.WriteLine("Error: IKVM.Java not found."); + diagnostics.CoreClassesMissing(); return 1; } compiler = new StaticCompiler(universe, assemblyResolver, runtimeAssembly); - context = new RuntimeContext(new RuntimeContextOptions(), new ManagedResolver(compiler, baseAssembly), false, compiler); + context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedResolver(compiler, baseAssembly), false, compiler); } if (context.AttributeHelper.IsJavaModule(assembly.ManifestModule)) - Console.Error.WriteLine("Warning: Running ikvmstub on ikvmc compiled assemblies is not supported."); + { + diagnostics.ExportingImportsNotSupported(); + return 1; + } if (options.Output == null) options.Output = assembly.GetName().Name + ".jar"; @@ -256,21 +292,19 @@ public static int Execute(IkvmExporterOptions options) } } } - catch (System.Exception x) + catch (Exception x) { - Console.Error.WriteLine(x); - if (options.ContinueOnError == false) - Console.Error.WriteLine("Warning: Assembly reflection encountered an error. Resultant JAR may be incomplete."); + diagnostics.UnknownWarning($"Assembly reflection encountered an error. Resultant JAR may be incomplete. ({x.Message})"); rc = 1; } } } - catch (InvalidDataException x) + catch (InvalidDataException e) { rc = 1; - Console.Error.WriteLine("Error: {0}", x.Message); + diagnostics.InvalidZip(options.Output); } } @@ -353,14 +387,14 @@ static void LoadSharedClassLoaderAssemblies(StaticCompiler compiler, Assembly as { if (assembly.GetManifestResourceInfo("ikvm.exports") != null) { - using (Stream stream = assembly.GetManifestResourceStream("ikvm.exports")) + using (var stream = assembly.GetManifestResourceStream("ikvm.exports")) { - BinaryReader rdr = new BinaryReader(stream); - int assemblyCount = rdr.ReadInt32(); + var rdr = new BinaryReader(stream); + var assemblyCount = rdr.ReadInt32(); for (int i = 0; i < assemblyCount; i++) { - string name = rdr.ReadString(); - int typeCount = rdr.ReadInt32(); + var name = rdr.ReadString(); + var typeCount = rdr.ReadInt32(); if (typeCount > 0) { for (int j = 0; j < typeCount; j++) @@ -467,24 +501,25 @@ private static bool IsNonVectorArray(RuntimeJavaType tw) return !tw.IsArray && tw.TypeAsBaseType.IsArray; } - private static void AddToExportListIfNeeded(RuntimeJavaType tw) + private static void AddToExportListIfNeeded(RuntimeJavaType javaType) { - while (tw.IsArray) - tw = tw.ElementTypeWrapper; + while (javaType.IsArray) + javaType = javaType.ElementTypeWrapper; - if (tw.IsUnloadable && tw.Name.StartsWith("Missing/")) + if (javaType.IsUnloadable && javaType is RuntimeUnloadableJavaType unloadableJavaType) { - Console.Error.WriteLine("Error: unable to find assembly '{0}'", tw.Name.Substring(8)); + javaType.Diagnostics.MissingType(unloadableJavaType.MissingType.Name, unloadableJavaType.MissingType.Assembly.FullName); Environment.Exit(1); return; } - if (tw is RuntimeStubJavaType) + + if (javaType is RuntimeStubJavaType) { // skip } - else if ((tw.TypeAsTBD != null && tw.TypeAsTBD.IsGenericType) || IsNonVectorArray(tw) || !tw.IsPublic) + else if ((javaType.TypeAsTBD != null && javaType.TypeAsTBD.IsGenericType) || IsNonVectorArray(javaType) || !javaType.IsPublic) { - AddToExportList(tw); + AddToExportList(javaType); } } @@ -530,6 +565,54 @@ private static void ProcessClass(RuntimeJavaType tw) } } + /// + /// Returns true if the specified diagnostic is enabled. + /// + /// + /// + internal static bool IsDiagnosticEnabled(IkvmExporterOptions options, Diagnostic diagnostic) + { + return diagnostic.Level is not DiagnosticLevel.Trace and not DiagnosticLevel.Informational; + } + + /// + /// Handles a . + /// + /// + /// + internal static void ReportEvent(IkvmExporterOptions options, in DiagnosticEvent evt) + { + if (evt.Diagnostic.Level is DiagnosticLevel.Trace or DiagnosticLevel.Informational) + return; + + // choose output channel + var dst = evt.Diagnostic.Level is DiagnosticLevel.Fatal or DiagnosticLevel.Error or DiagnosticLevel.Warning ? Console.Error : Console.Out; + + // write tag + dst.Write(evt.Diagnostic.Level switch + { + DiagnosticLevel.Trace => "trace", + DiagnosticLevel.Informational => "info", + DiagnosticLevel.Warning => "warning", + DiagnosticLevel.Error => "error", + DiagnosticLevel.Fatal => "error", + _ => throw new InvalidOperationException(), + }); + + // write event ID + dst.Write($"IKVM{evt.Diagnostic.Id:D4}: "); + + // write message +#if NET8_0_OR_GREATER + dst.Write(string.Format(null, evt.Diagnostic.Message, evt.Args)); +#else + dst.Write(string.Format(null, evt.Diagnostic.Message, evt.Args.ToArray())); +#endif + + // end of line + dst.WriteLine(); + } + } } diff --git a/src/IKVM.Tools.Exporter/RuntimeStubJavaType.cs b/src/IKVM.Tools.Exporter/RuntimeStubJavaType.cs index b97da24f1d..a1c8780731 100644 --- a/src/IKVM.Tools.Exporter/RuntimeStubJavaType.cs +++ b/src/IKVM.Tools.Exporter/RuntimeStubJavaType.cs @@ -58,10 +58,7 @@ internal override RuntimeJavaType BaseTypeWrapper get { return baseWrapper; } } - internal override RuntimeClassLoader GetClassLoader() - { - return Context.ClassLoaderFactory.GetBootstrapClassLoader(); - } + internal override RuntimeClassLoader ClassLoader => Context.ClassLoaderFactory.GetBootstrapClassLoader(); internal override Type TypeAsTBD { diff --git a/src/IKVM.Tools.Exporter/StaticCompiler.cs b/src/IKVM.Tools.Exporter/StaticCompiler.cs index 57f27fbfd1..0fe5e51b09 100644 --- a/src/IKVM.Tools.Exporter/StaticCompiler.cs +++ b/src/IKVM.Tools.Exporter/StaticCompiler.cs @@ -23,6 +23,7 @@ Jeroen Frijters */ using System; +using IKVM.CoreLib.Diagnostics; using IKVM.Reflection; using IKVM.Tools.Importer; diff --git a/src/IKVM.Tools.Importer/CompilerClassLoader.cs b/src/IKVM.Tools.Importer/CompilerClassLoader.cs index b03d8b4388..6c3f3d44f6 100644 --- a/src/IKVM.Tools.Importer/CompilerClassLoader.cs +++ b/src/IKVM.Tools.Importer/CompilerClassLoader.cs @@ -35,6 +35,7 @@ Jeroen Frijters using IKVM.Attributes; using IKVM.ByteCode; +using IKVM.CoreLib.Diagnostics; using IKVM.Reflection; using IKVM.Reflection.Emit; using IKVM.Runtime; @@ -49,6 +50,7 @@ sealed class CompilerClassLoader : RuntimeClassLoader const string DEFAULT_RUNTIME_ARGS_PREFIX = "-J"; + readonly IDiagnosticHandler diagnostics; Dictionary classes; Dictionary remapped = new Dictionary(); string assemblyName; @@ -58,6 +60,7 @@ sealed class CompilerClassLoader : RuntimeClassLoader AssemblyBuilder assemblyBuilder; MapXml.Attribute[] assemblyAttributes; CompilerOptions options; + private readonly StaticCompiler compiler; RuntimeAssemblyClassLoader[] referencedAssemblies; Dictionary nameMappings = new Dictionary(); Packages packages; @@ -82,15 +85,20 @@ sealed class CompilerClassLoader : RuntimeClassLoader /// Initializes a new instance. /// /// + /// + /// /// /// /// /// /// /// - internal CompilerClassLoader(RuntimeContext context, RuntimeAssemblyClassLoader[] referencedAssemblies, CompilerOptions options, FileInfo assemblyPath, bool targetIsModule, string assemblyName, Dictionary classes) : + /// + public CompilerClassLoader(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, RuntimeAssemblyClassLoader[] referencedAssemblies, CompilerOptions options, FileInfo assemblyPath, bool targetIsModule, string assemblyName, Dictionary classes) : base(context, options.codegenoptions, null) { + this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler)); + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); this.referencedAssemblies = referencedAssemblies; this.options = options; this.classes = classes; @@ -98,9 +106,12 @@ internal CompilerClassLoader(RuntimeContext context, RuntimeAssemblyClassLoader[ this.assemblyFile = assemblyPath.Name; this.assemblyDir = assemblyPath.DirectoryName; this.targetIsModule = targetIsModule; - Tracer.Info(Tracer.Compiler, "Instantiate CompilerClassLoader for {0}", assemblyName); + Diagnostics.GenericCompilerInfo($"Instantiate CompilerClassLoader for {assemblyName}"); } + /// + public override IDiagnosticHandler Diagnostics => diagnostics; + internal bool ReserveName(string javaName) { return !classes.ContainsKey(javaName) && GetTypeWrapperFactory().ReserveName(javaName); @@ -250,7 +261,7 @@ private RuntimeJavaType PeerLoad(string name) { var tw = TryLoadClassByName(name); // HACK we don't want to load classes referenced by peers, hence the "== this" check - if (tw != null && tw.GetClassLoader() == this) + if (tw != null && tw.ClassLoader == this) { return tw; } @@ -288,31 +299,31 @@ RuntimeJavaType GetTypeWrapperCompilerHook(string name) try { - f = new IKVM.Runtime.ClassFile(Context, IKVM.ByteCode.Decoding.ClassFile.Read(itemRef.GetData()), name, ClassFileParseOptions, null); + f = new IKVM.Runtime.ClassFile(Context, Diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(itemRef.GetData()), name, ClassFileParseOptions, null); } catch (UnsupportedClassVersionException e) { - Context.StaticCompiler.SuppressWarning(options, Message.ClassNotFound, name); - Context.StaticCompiler.IssueMessage(options, Message.ClassFormatError, name, e.Message); + Context.StaticCompiler.SuppressWarning(options, Diagnostic.ClassNotFound, name); + Diagnostics.ClassFormatError(name, e.Message); return null; } catch (ByteCodeException e) { - Context.StaticCompiler.SuppressWarning(options, Message.ClassNotFound, name); - Context.StaticCompiler.IssueMessage(options, Message.ClassFormatError, name, e.Message); + Context.StaticCompiler.SuppressWarning(options, Diagnostic.ClassNotFound, name); + Diagnostics.ClassFormatError(name, e.Message); return null; } catch (ClassFormatError e) { - Context.StaticCompiler.SuppressWarning(options, Message.ClassNotFound, name); - Context.StaticCompiler.IssueMessage(options, Message.ClassFormatError, name, e.Message); + Context.StaticCompiler.SuppressWarning(options, Diagnostic.ClassNotFound, name); + Diagnostics.ClassFormatError(name, e.Message); return null; } if (f.Name != name) { - Context.StaticCompiler.SuppressWarning(options, Message.ClassNotFound, name); - Context.StaticCompiler.IssueMessage(options, Message.WrongClassName, name, f.Name); + Context.StaticCompiler.SuppressWarning(options, Diagnostic.ClassNotFound, name); + Diagnostics.WrongClassName(name, f.Name); return null; } @@ -396,31 +407,31 @@ RuntimeJavaType GetTypeWrapperCompilerHook(string name) } catch (ClassFormatError x) { - Context.StaticCompiler.IssueMessage(options, Message.ClassFormatError, name, x.Message); + Diagnostics.ClassFormatError(name, x.Message); } catch (IllegalAccessError x) { - Context.StaticCompiler.IssueMessage(options, Message.IllegalAccessError, name, x.Message); + Diagnostics.IllegalAccessError(name, x.Message); } catch (VerifyError x) { - Context.StaticCompiler.IssueMessage(options, Message.VerificationError, name, x.Message); + Diagnostics.VerificationError(name, x.Message); } catch (NoClassDefFoundError x) { if ((options.codegenoptions & CodeGenOptions.DisableDynamicBinding) != 0) { - Context.StaticCompiler.IssueMessage(options, Message.NoClassDefFoundError, name, x.Message); + Diagnostics.NoClassDefFoundError(name, x.Message); } - Context.StaticCompiler.IssueMessage(options, Message.ClassNotFound, x.Message); + Diagnostics.ClassNotFound(x.Message); } catch (RetargetableJavaException x) { - Context.StaticCompiler.IssueMessage(options, Message.GenericUnableToCompileError, name, x.GetType().Name, x.Message); + Diagnostics.GenericUnableToCompileError(name, x.GetType().Name, x.Message); } - Context.StaticCompiler.SuppressWarning(options, Message.ClassNotFound, name); + Context.StaticCompiler.SuppressWarning(options, Diagnostic.ClassNotFound, name); return null; } else @@ -452,8 +463,8 @@ internal bool IsEquivalentTo(RuntimeClassLoader other) internal override bool InternalsVisibleToImpl(RuntimeJavaType wrapper, RuntimeJavaType friend) { - Debug.Assert(wrapper.GetClassLoader() == this); - RuntimeClassLoader other = friend.GetClassLoader(); + Debug.Assert(wrapper.ClassLoader == this); + RuntimeClassLoader other = friend.ClassLoader; // TODO ideally we should also respect InternalsVisibleToAttribute.Annotation here if (this == other || internalsVisibleTo.Contains(other)) { @@ -619,23 +630,24 @@ void Save() if (targetIsModule) { - Tracer.Info(Tracer.Compiler, "CompilerClassLoader saving {0} in {1}", assemblyFile, assemblyDir); + Diagnostics.GenericCompilerInfo($"CompilerClassLoader saving {assemblyFile} in {assemblyDir}"); + try { GetTypeWrapperFactory().ModuleBuilder.__Save(options.pekind, options.imageFileMachine); } catch (IOException x) { - throw new FatalCompilerErrorException(Message.ErrorWritingFile, GetTypeWrapperFactory().ModuleBuilder.FullyQualifiedName, x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorWritingFile.Event([GetTypeWrapperFactory().ModuleBuilder.FullyQualifiedName, x.Message])); } catch (UnauthorizedAccessException x) { - throw new FatalCompilerErrorException(Message.ErrorWritingFile, GetTypeWrapperFactory().ModuleBuilder.FullyQualifiedName, x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorWritingFile.Event([GetTypeWrapperFactory().ModuleBuilder.FullyQualifiedName, x.Message])); } } else { - Tracer.Info(Tracer.Compiler, "CompilerClassLoader saving {0} in {1}", assemblyFile, assemblyDir); + Diagnostics.GenericCompilerInfo($"CompilerClassLoader saving {assemblyFile} in {assemblyDir}"); try { @@ -643,11 +655,11 @@ void Save() } catch (IOException x) { - throw new FatalCompilerErrorException(Message.ErrorWritingFile, Path.Combine(assemblyDir, assemblyFile), x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorWritingFile.Event([Path.Combine(assemblyDir, assemblyFile), x.Message])); } catch (UnauthorizedAccessException x) { - throw new FatalCompilerErrorException(Message.ErrorWritingFile, Path.Combine(assemblyDir, assemblyFile), x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorWritingFile.Event([Path.Combine(assemblyDir, assemblyFile), x.Message])); } } } @@ -705,7 +717,7 @@ void WriteExportMap() AddWildcardExports(exportedNamesPerAssembly); foreach (var tw in dynamicallyImportedTypes) - AddExportMapEntry(exportedNamesPerAssembly, (CompilerClassLoader)tw.GetClassLoader(), tw.Name); + AddExportMapEntry(exportedNamesPerAssembly, (CompilerClassLoader)tw.ClassLoader, tw.Name); if (options.sharedclassloader == null) { @@ -757,7 +769,7 @@ void WriteExportMap() void WriteResources() { - Tracer.Info(Tracer.Compiler, "CompilerClassLoader adding resources..."); + Diagnostics.GenericCompilerInfo("CompilerClassLoader adding resources..."); // BUG we need to call GetTypeWrapperFactory() to make sure that the assemblyBuilder is created (when building an empty target) var moduleBuilder = GetTypeWrapperFactory().ModuleBuilder; @@ -861,10 +873,7 @@ private sealed class RemapperTypeWrapper : RuntimeJavaType private RuntimeJavaType baseTypeWrapper; private RuntimeJavaType[] interfaceWrappers; - internal override RuntimeClassLoader GetClassLoader() - { - return classLoader; - } + internal override RuntimeClassLoader ClassLoader => classLoader; internal override bool IsRemapped { @@ -1013,7 +1022,7 @@ internal void LoadInterfaces(IKVM.Tools.Importer.MapXml.Class c) { if (GetMethodWrapper(mw.Name, mw.Signature, true) == null) { - DeclaringTypeWrapper.Context.StaticCompiler.IssueMessage(Message.RemappedTypeMissingDefaultInterfaceMethod, Name, iface.Name + "." + mw.Name + mw.Signature); + classLoader.Diagnostics.RemappedTypeMissingDefaultInterfaceMethod(Name, iface.Name + "." + mw.Name + mw.Signature); } } } @@ -1085,7 +1094,7 @@ internal override MethodBase DoLink() { MethodAttributes attr = MapMethodAccessModifiers(m.Modifiers); RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType; - Type[] paramTypes = typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig); + Type[] paramTypes = typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig); MethodBuilder cbCore = null; @@ -1096,10 +1105,10 @@ internal override MethodBase DoLink() { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in m.Attributes) { - DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), mbHelper, custattr); + DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mbHelper, custattr); } } - SetParameters(DeclaringType.GetClassLoader(), mbHelper, m.Parameters); + SetParameters(DeclaringType.ClassLoader, mbHelper, m.Parameters); DeclaringType.Context.AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers, false); DeclaringType.Context.AttributeHelper.SetNameSig(mbHelper, "", m.Sig); AddDeclaredExceptions(DeclaringType.Context, mbHelper, m.Throws); @@ -1111,10 +1120,10 @@ internal override MethodBase DoLink() { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in m.Attributes) { - DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), cbCore, custattr); + DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, cbCore, custattr); } } - SetParameters(DeclaringType.GetClassLoader(), cbCore, m.Parameters); + SetParameters(DeclaringType.ClassLoader, cbCore, m.Parameters); AddDeclaredExceptions(DeclaringType.Context, cbCore, m.Throws); } return cbCore; @@ -1135,7 +1144,7 @@ internal override void Finish() if (m.Body != null) { // TODO do we need return type conversion here? - m.Body.Emit(DeclaringType.GetClassLoader(), ilgen); + m.Body.Emit(DeclaringType.ClassLoader, ilgen); } else { @@ -1161,7 +1170,7 @@ internal override void Finish() ilgen.Emit(OpCodes.Ret); } ilgen.DoEmit(); - if (this.DeclaringType.GetClassLoader().EmitStackTraceInfo) + if (this.DeclaringType.ClassLoader.EmitStackTraceInfo) { ilgen.EmitLineNumberTable(cbCore); } @@ -1172,11 +1181,11 @@ internal override void Finish() CodeEmitter ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mbHelper); if (m.Redirect != null) { - m.Redirect.Emit(DeclaringType.GetClassLoader(), ilgen); + m.Redirect.Emit(DeclaringType.ClassLoader, ilgen); } else if (m.AlternateBody != null) { - m.AlternateBody.Emit(DeclaringType.GetClassLoader(), ilgen); + m.AlternateBody.Emit(DeclaringType.ClassLoader, ilgen); } else if (m.Body != null) { @@ -1199,7 +1208,7 @@ internal override void Finish() ilgen.Emit(OpCodes.Ret); } ilgen.DoEmit(); - if (this.DeclaringType.GetClassLoader().EmitStackTraceInfo) + if (this.DeclaringType.ClassLoader.EmitStackTraceInfo) { ilgen.EmitLineNumberTable(mbHelper); } @@ -1274,7 +1283,7 @@ internal override MethodBase DoLink() { throw new InvalidOperationException(typeWrapper.Name + "." + m.Name + m.Sig); } - MethodInfo interfaceMethod = typeWrapper.shadowType.GetMethod(m.Override.Name, typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig)); + MethodInfo interfaceMethod = typeWrapper.shadowType.GetMethod(m.Override.Name, typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig)); if (interfaceMethod == null) { throw new InvalidOperationException(typeWrapper.Name + "." + m.Name + m.Sig); @@ -1318,25 +1327,25 @@ internal override MethodBase DoLink() if (specialCases != null) { CodeEmitter ilgen; - Type[] argTypes = ArrayUtil.Concat(typeWrapper.shadowType, typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig)); + Type[] argTypes = ArrayUtil.Concat(typeWrapper.shadowType, typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig)); if (typeWrapper.helperTypeBuilder == null) { typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType("__Helper", TypeAttributes.NestedPublic | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Abstract); DeclaringType.Context.AttributeHelper.HideFromJava(typeWrapper.helperTypeBuilder); } - helper = typeWrapper.helperTypeBuilder.DefineMethod(m.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeWrapper.GetClassLoader().RetTypeWrapperFromSig(m.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType, argTypes); + helper = typeWrapper.helperTypeBuilder.DefineMethod(m.Name, MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Static, typeWrapper.ClassLoader.RetTypeWrapperFromSig(m.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType, argTypes); if (m.Attributes != null) { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in m.Attributes) { - DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), helper, custattr); + DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, helper, custattr); } } - SetParameters(DeclaringType.GetClassLoader(), helper, m.Parameters); + SetParameters(DeclaringType.ClassLoader, helper, m.Parameters); ilgen = DeclaringType.Context.CodeEmitterFactory.Create(helper); foreach (IKVM.Tools.Importer.MapXml.Class c in specialCases) { - var tw = typeWrapper.GetClassLoader().LoadClassByName(c.Name); + var tw = typeWrapper.ClassLoader.LoadClassByName(c.Name); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Isinst, tw.TypeAsTBD); ilgen.Emit(OpCodes.Dup); @@ -1367,8 +1376,8 @@ internal override MethodBase DoLink() else { MethodBuilder mbCore = null; - Type[] paramTypes = typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig); - Type retType = typeWrapper.GetClassLoader().RetTypeWrapperFromSig(m.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType; + Type[] paramTypes = typeWrapper.ClassLoader.ArgTypeListFromSig(m.Sig); + Type retType = typeWrapper.ClassLoader.RetTypeWrapperFromSig(m.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType; if (typeWrapper.shadowType.IsSealed && (m.Modifiers & IKVM.Tools.Importer.MapXml.MapModifiers.Static) == 0) { @@ -1425,15 +1434,15 @@ internal override MethodBase DoLink() } } } - mbCore = GetDefineMethodHelper().DefineMethod(DeclaringType.GetClassLoader().GetTypeWrapperFactory(), typeWrapper.typeBuilder, m.Name, attr); + mbCore = GetDefineMethodHelper().DefineMethod(DeclaringType.ClassLoader.GetTypeWrapperFactory(), typeWrapper.typeBuilder, m.Name, attr); if (m.Attributes != null) { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in m.Attributes) { - DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), mbCore, custattr); + DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mbCore, custattr); } } - SetParameters(DeclaringType.GetClassLoader(), mbCore, m.Parameters); + SetParameters(DeclaringType.ClassLoader, mbCore, m.Parameters); if (overrideMethod != null && !inherited) { typeWrapper.typeBuilder.DefineMethodOverride(mbCore, overrideMethod); @@ -1461,7 +1470,7 @@ internal override MethodBase DoLink() { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in m.Attributes) { - DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), mbHelper, custattr); + DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mbHelper, custattr); } } IKVM.Tools.Importer.MapXml.Parameter[] parameters; @@ -1476,7 +1485,7 @@ internal override MethodBase DoLink() } parameters[0] = new IKVM.Tools.Importer.MapXml.Parameter(); parameters[0].Name = "this"; - SetParameters(DeclaringType.GetClassLoader(), mbHelper, parameters); + SetParameters(DeclaringType.ClassLoader, mbHelper, parameters); if (!typeWrapper.IsFinal) { DeclaringType.Context.AttributeHelper.SetEditorBrowsableNever(mbHelper); @@ -1530,7 +1539,7 @@ internal override void Finish() if (m.Body != null) { // we manually walk the instruction list, because we need to special case the ret instructions - IKVM.Tools.Importer.MapXml.CodeGenContext context = new IKVM.Tools.Importer.MapXml.CodeGenContext(DeclaringType.GetClassLoader()); + IKVM.Tools.Importer.MapXml.CodeGenContext context = new IKVM.Tools.Importer.MapXml.CodeGenContext(DeclaringType.ClassLoader); foreach (IKVM.Tools.Importer.MapXml.Instruction instr in m.Body.Instructions) { if (instr is IKVM.Tools.Importer.MapXml.Ret) @@ -1571,7 +1580,7 @@ internal override void Finish() ilgen.Emit(OpCodes.Ret); } ilgen.DoEmit(); - if (this.DeclaringType.GetClassLoader().EmitStackTraceInfo) + if (this.DeclaringType.ClassLoader.EmitStackTraceInfo) { ilgen.EmitLineNumberTable(mbCore); } @@ -1645,7 +1654,7 @@ internal override void Finish() { IKVM.Tools.Importer.MapXml.InstructionList body = m.AlternateBody == null ? m.Body : m.AlternateBody; // we manually walk the instruction list, because we need to special case the ret instructions - IKVM.Tools.Importer.MapXml.CodeGenContext context = new IKVM.Tools.Importer.MapXml.CodeGenContext(DeclaringType.GetClassLoader()); + IKVM.Tools.Importer.MapXml.CodeGenContext context = new IKVM.Tools.Importer.MapXml.CodeGenContext(DeclaringType.ClassLoader); foreach (IKVM.Tools.Importer.MapXml.Instruction instr in body.Instructions) { if (instr is IKVM.Tools.Importer.MapXml.Ret) @@ -1697,7 +1706,7 @@ internal override void Finish() ilgen.DoEmit(); - if (DeclaringType.GetClassLoader().EmitStackTraceInfo) + if (DeclaringType.ClassLoader.EmitStackTraceInfo) ilgen.EmitLineNumberTable(mbHelper); } @@ -1710,15 +1719,15 @@ internal override void Finish() // apply custom attributes from map XML if (m.Attributes != null) foreach (var custattr in m.Attributes) - DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.GetClassLoader(), mb, custattr); + DeclaringType.Context.AttributeHelper.SetCustomAttribute(DeclaringType.ClassLoader, mb, custattr); - SetParameters(DeclaringType.GetClassLoader(), mb, m.Parameters); + SetParameters(DeclaringType.ClassLoader, mb, m.Parameters); DeclaringType.Context.AttributeHelper.HideFromJava(mb); var ilgen = DeclaringType.Context.CodeEmitterFactory.Create(mb); if (m.NonVirtualAlternateBody != null) { - m.NonVirtualAlternateBody.Emit(DeclaringType.GetClassLoader(), ilgen); + m.NonVirtualAlternateBody.Emit(DeclaringType.ClassLoader, ilgen); } else { @@ -1743,7 +1752,7 @@ private void EmitRedirect(Type baseType, CodeEmitter ilgen) { var redirName = m.Redirect.Name ?? m.Name; var redirSig = m.Redirect.Sig ?? m.Sig; - var classLoader = DeclaringType.GetClassLoader(); + var classLoader = DeclaringType.ClassLoader; // type specified, or class missing, assume loading .NET type if (m.Redirect.Type != null || m.Redirect.Class == null) @@ -1819,7 +1828,7 @@ internal void Process2ndPassStep2(IKVM.Tools.Importer.MapXml.Root map) { attr |= FieldAttributes.Static; } - FieldBuilder fb = tb.DefineField(f.Name, GetClassLoader().FieldTypeWrapperFromSig(f.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType, attr); + FieldBuilder fb = tb.DefineField(f.Name, ClassLoader.FieldTypeWrapperFromSig(f.Sig, LoadMode.LoadOrThrow).TypeAsSignatureType, attr); if (f.Attributes != null) { foreach (IKVM.Tools.Importer.MapXml.Attribute custattr in f.Attributes) @@ -1840,11 +1849,11 @@ internal void Process2ndPassStep2(IKVM.Tools.Importer.MapXml.Root map) throw new NotImplementedException("remapped constant field of type: " + f.Sig); } fb.SetConstant(constant); - fields.Add(new RuntimeConstantJavaField(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig, LoadMode.LoadOrThrow), f.Name, f.Sig, (Modifiers)f.Modifiers, fb, constant, MemberFlags.None)); + fields.Add(new RuntimeConstantJavaField(this, ClassLoader.FieldTypeWrapperFromSig(f.Sig, LoadMode.LoadOrThrow), f.Name, f.Sig, (Modifiers)f.Modifiers, fb, constant, MemberFlags.None)); } else { - fields.Add(RuntimeJavaField.Create(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig, LoadMode.LoadOrThrow), fb, f.Name, f.Sig, new ExModifiers((Modifiers)f.Modifiers, false))); + fields.Add(RuntimeJavaField.Create(this, ClassLoader.FieldTypeWrapperFromSig(f.Sig, LoadMode.LoadOrThrow), fb, f.Name, f.Sig, new ExModifiers((Modifiers)f.Modifiers, false))); } } } @@ -1882,7 +1891,7 @@ internal void Process4thPass(ICollection remappedTypes) { foreach (IKVM.Tools.Importer.MapXml.Implements iface in classDef.Interfaces) { - GetClassLoader().LoadClassByName(iface.Class).Finish(); + ClassLoader.LoadClassByName(iface.Class).Finish(); } } @@ -2141,7 +2150,7 @@ internal static void AddDeclaredExceptions(RuntimeContext context, MethodBuilder internal void EmitRemappedTypes() { - Tracer.Info(Tracer.Compiler, "Emit remapped types"); + Diagnostics.GenericCompilerInfo("Emit remapped types"); assemblyAttributes = map.Assembly.Attributes; @@ -2155,8 +2164,9 @@ internal void EmitRemappedTypes() { if (classes.ContainsKey(c.Name)) { - Context.StaticCompiler.IssueMessage(Message.DuplicateClassName, c.Name); + Diagnostics.DuplicateClassName(c.Name); } + remapped.Add(c.Name, new RemapperTypeWrapper(Context, this, c, map)); hasRemappedTypes = true; } @@ -2476,7 +2486,7 @@ private static bool IsSigned(Assembly asm) return key != null && key.Length != 0; } - internal static int Compile(RuntimeContext context, StaticCompiler compiler, string runtimeAssembly, List optionsList) + internal static int Compile(IkvmImporterInternal importer, RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, string runtimeAssembly, List optionsList) { try { @@ -2486,22 +2496,20 @@ internal static int Compile(RuntimeContext context, StaticCompiler compiler, str { // runtime assembly is required if (compiler.runtimeAssembly == null) - throw new FatalCompilerErrorException(Message.RuntimeNotFound); + throw new FatalCompilerErrorException(Diagnostic.RuntimeNotFound.Event([])); // some unknown error - throw new FatalCompilerErrorException(Message.FileNotFound); + throw new FatalCompilerErrorException(Diagnostic.FileNotFound.Event([])); } - Tracer.Info(Tracer.Compiler, "Loaded runtime assembly: {0}", compiler.runtimeAssembly.FullName); - List loaders = new List(); - foreach (CompilerOptions options in optionsList) + diagnostics.GenericCompilerInfo($"Loaded runtime assembly: {compiler.runtimeAssembly.FullName}"); + + var loaders = new List(); + foreach (var options in optionsList) { - CompilerClassLoader loader = null; - int rc = CreateCompiler(context, compiler, options, out loader); + int rc = CreateCompiler(context, compiler, new IkvmImporterInternal.DiagnosticHandler(importer, options), options, out var loader); if (rc != 0) - { return rc; - } loaders.Add(loader); options.sharedclassloader?.Add(loader); @@ -2520,8 +2528,7 @@ internal static int Compile(RuntimeContext context, StaticCompiler compiler, str { if (loader.options.sharedclassloader != null) { - Type mainAssemblyType; - if (!mainAssemblyTypes.TryGetValue(loader.options.sharedclassloader[0], out mainAssemblyType)) + if (!mainAssemblyTypes.TryGetValue(loader.options.sharedclassloader[0], out var mainAssemblyType)) { var tb = loader.options.sharedclassloader[0].GetTypeWrapperFactory().ModuleBuilder.DefineType("__", TypeAttributes.NotPublic | TypeAttributes.Abstract | TypeAttributes.SpecialName); loader.Context.AttributeHelper.HideFromJava(tb); @@ -2533,46 +2540,44 @@ internal static int Compile(RuntimeContext context, StaticCompiler compiler, str ((AssemblyBuilder)loader.GetTypeWrapperFactory().ModuleBuilder.Assembly).__AddTypeForwarder(mainAssemblyType); } } + loader.CompilePass1(); } - foreach (CompilerClassLoader loader in loaders) + foreach (var loader in loaders) { loader.CompilePass2(); } if (context.Bootstrap) - foreach (CompilerClassLoader loader in loaders) + foreach (var loader in loaders) loader.EmitRemappedTypes2ndPass(); - foreach (CompilerClassLoader loader in loaders) + foreach (var loader in loaders) { int rc = loader.CompilePass3(); if (rc != 0) - { return rc; - } } - Tracer.Info(Tracer.Compiler, "CompilerClassLoader.Save..."); - foreach (CompilerClassLoader loader in loaders) - { + diagnostics.GenericCompilerInfo("CompilerClassLoader.Save..."); + + foreach (var loader in loaders) loader.PrepareSave(); - } + if (compiler.errorCount > 0) - { return 1; - } + foreach (CompilerClassLoader loader in loaders) - { loader.Save(); - } + return compiler.errorCount == 0 ? 0 : 1; } - static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, out CompilerClassLoader loader) + static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, CompilerOptions options, out CompilerClassLoader loader) { - Tracer.Info(Tracer.Compiler, "JVM.Compile path: {0}, assembly: {1}", options.path, options.assembly); + diagnostics.GenericCompilerInfo($"JVM.Compile path: {options.path}, assembly: {options.assembly}"); + AssemblyName runtimeAssemblyName = compiler.runtimeAssembly.GetName(); bool allReferencesAreStrongNamed = IsSigned(compiler.runtimeAssembly); List references = new List(); @@ -2580,7 +2585,8 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi { references.Add(reference); allReferencesAreStrongNamed &= IsSigned(reference); - Tracer.Info(Tracer.Compiler, "Loaded reference assembly: {0}", reference.FullName); + diagnostics.GenericCompilerInfo($"Loaded reference assembly: {reference.FullName}"); + // if it's an IKVM compiled assembly, make sure that it was compiled // against same version of the runtime foreach (AssemblyName asmref in reference.GetReferencedAssemblies()) @@ -2592,20 +2598,22 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi // TODO we really should support binding redirects here to allow different revisions to be mixed if (asmref.FullName != runtimeAssemblyName.FullName) { - throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName); + throw new FatalCompilerErrorException(Diagnostic.RuntimeMismatch.Event([reference.Location, runtimeAssemblyName.FullName, asmref.FullName])); } } else { if (asmref.GetPublicKeyToken() != null && asmref.GetPublicKeyToken().Length != 0) { - throw new FatalCompilerErrorException(Message.RuntimeMismatch, reference.Location, runtimeAssemblyName.FullName, asmref.FullName); + throw new FatalCompilerErrorException(Diagnostic.RuntimeMismatch.Event([reference.Location, runtimeAssemblyName.FullName, asmref.FullName])); } } } } } - Tracer.Info(Tracer.Compiler, "Parsing class files"); + + diagnostics.GenericCompilerInfo("Parsing class files"); + // map the class names to jar entries Dictionary h = new Dictionary(); List classNames = new List(); @@ -2625,7 +2633,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi string className = name.Substring(0, name.Length - 6).Replace('/', '.'); if (h.ContainsKey(className)) { - compiler.IssueMessage(Message.DuplicateClassName, className); + diagnostics.DuplicateClassName(className); Jar.Item itemRef = h[className]; if ((options.classesJar != -1 && itemRef.Jar == options.jars[options.classesJar]) || jar != itemRef.Jar) { @@ -2653,7 +2661,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi { try { - var f = new IKVM.Runtime.ClassFile(context, IKVM.ByteCode.Decoding.ClassFile.Read(assemblyType.GetData()), null, ClassFileParseOptions.None, null); + using var f = new IKVM.Runtime.ClassFile(context, diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(assemblyType.GetData()), null, ClassFileParseOptions.None, null); // NOTE the "assembly" type in the unnamed package is a magic type // that acts as the placeholder for assembly attributes @@ -2663,7 +2671,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi // HACK remove "assembly" type that exists only as a placeholder for assembly attributes h.Remove(f.Name); assemblyType.Remove(); - compiler.IssueMessage(Message.LegacyAssemblyAttributesFound); + diagnostics.LegacyAssemblyAttributesFound(); } } catch (ByteCodeException) @@ -2684,14 +2692,14 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi { try { - var f = new IKVM.Runtime.ClassFile(context, IKVM.ByteCode.Decoding.ClassFile.Read(h[className].GetData()), null, ClassFileParseOptions.None, null); + using var f = new IKVM.Runtime.ClassFile(context, diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(h[className].GetData()), null, ClassFileParseOptions.None, null); if (f.Name == className) { foreach (var m in f.Methods) { if (m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") { - compiler.IssueMessage(Message.MainMethodFound, f.Name); + diagnostics.MainMethodFound(f.Name); options.mainClass = f.Name; goto break_outer; } @@ -2713,12 +2721,12 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi if (options.target != PEFileKinds.Dll && options.mainClass == null) { - throw new FatalCompilerErrorException(Message.ExeRequiresMainClass); + throw new FatalCompilerErrorException(Diagnostic.ExeRequiresMainClass.Event([])); } if (options.target == PEFileKinds.Dll && options.props.Count != 0) { - throw new FatalCompilerErrorException(Message.PropertiesRequireExe); + throw new FatalCompilerErrorException(Diagnostic.PropertiesRequireExe.Event([])); } if (options.path == null) @@ -2738,20 +2746,21 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi { options.path = IkvmImporterInternal.GetFileInfo(options.assembly + ".exe"); } - compiler.IssueMessage(Message.OutputFileIs, options.path.ToString()); + + diagnostics.OutputFileIs(options.path.ToString()); } if (options.targetIsModule) { if (options.classLoader != null) { - throw new FatalCompilerErrorException(Message.ModuleCannotHaveClassLoader); + throw new FatalCompilerErrorException(Diagnostic.ModuleCannotHaveClassLoader.Event([])); } // TODO if we're overwriting a user specified assembly name, we need to emit a warning options.assembly = options.path.Name; } - Tracer.Info(Tracer.Compiler, "Constructing compiler"); + diagnostics.GenericCompilerInfo("Constructing compiler"); var referencedAssemblies = new List(references.Count); for (int i = 0; i < references.Count; i++) { @@ -2761,16 +2770,16 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi var acl = context.AssemblyClassLoaderFactory.FromAssembly(references[i]); if (referencedAssemblies.Contains(acl)) - compiler.IssueMessage(options, Message.DuplicateAssemblyReference, acl.MainAssembly.FullName); + diagnostics.DuplicateAssemblyReference(acl.MainAssembly.FullName); referencedAssemblies.Add(acl); } - loader = new CompilerClassLoader(context, referencedAssemblies.ToArray(), options, options.path, options.targetIsModule, options.assembly, h); + loader = new CompilerClassLoader(context, compiler, diagnostics, referencedAssemblies.ToArray(), options, options.path, options.targetIsModule, options.assembly, h); loader.classesToCompile = new List(h.Keys); if (options.remapfile != null) { - Tracer.Info(Tracer.Compiler, "Loading remapped types (1) from {0}", options.remapfile); + diagnostics.GenericCompilerInfo($"Loading remapped types (1) from {options.remapfile}"); FileStream fs; try @@ -2781,7 +2790,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi } catch (Exception e) { - throw new FatalCompilerErrorException(Message.ErrorReadingFile, options.remapfile, e.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorReadingFile.Event([options.remapfile, e.Message])); } try @@ -2794,7 +2803,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi } catch (MapXml.MapXmlException x) { - throw new FatalCompilerErrorException(Message.ErrorParsingMapFile, options.remapfile, x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorParsingMapFile.Event([options.remapfile, x.Message])); } if (loader.ValidateAndSetMap(map) == false) @@ -2838,7 +2847,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi if (compiler.baseAssembly == null) { - throw new FatalCompilerErrorException(Message.BootstrapClassesMissing); + throw new FatalCompilerErrorException(Diagnostic.BootstrapClassesMissing.Event([])); } // we need to scan again for remapped types, now that we've loaded the core library @@ -2853,7 +2862,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, Compi if ((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed) { - throw new FatalCompilerErrorException(Message.StrongNameRequiresStrongNamedRefs); + throw new FatalCompilerErrorException(Diagnostic.StrongNameRequiresStrongNamedRefs.Event([])); } if (loader.map != null) @@ -2895,7 +2904,7 @@ private void CompilePass0() void CompilePass1() { - Tracer.Info(Tracer.Compiler, "Compiling class files (1)"); + Diagnostics.GenericCompilerInfo("Compiling class files (1)"); if (options.bootstrap) EmitRemappedTypes(); @@ -2915,11 +2924,11 @@ void CompilePass1() var javaType = TryLoadClassByName(s); if (javaType != null) { - var loader = javaType.GetClassLoader(); + var loader = javaType.ClassLoader; if (loader != this) { if (loader is RuntimeAssemblyClassLoader) - Context.StaticCompiler.IssueMessage(options, Message.SkippingReferencedClass, s, ((RuntimeAssemblyClassLoader)loader).GetAssembly(javaType).FullName); + Diagnostics.SkippingReferencedClass(s, ((RuntimeAssemblyClassLoader)loader).GetAssembly(javaType).FullName); continue; } @@ -2934,7 +2943,7 @@ void CompilePass1() void CompilePass2() { - Tracer.Info(Tracer.Compiler, "Compiling class files (2)"); + Diagnostics.GenericCompilerInfo("Compiling class files (2)"); foreach (var javaTypes in javaTypes) { @@ -2946,7 +2955,7 @@ void CompilePass2() int CompilePass3() { - Tracer.Info(Tracer.Compiler, "Compiling class files (3)"); + Diagnostics.GenericCompilerInfo("Compiling class files (3)"); // emits the IL required for module initialization var moduleInitBuilders = new List>(); @@ -2977,22 +2986,22 @@ int CompilePass3() } if (wrapper == null) { - throw new FatalCompilerErrorException(Message.MainClassNotFound); + throw new FatalCompilerErrorException(Diagnostic.MainClassNotFound.Event([])); } var mw = wrapper.GetMethodWrapper("main", "([Ljava.lang.String;)V", false); if (mw == null || !mw.IsStatic) - throw new FatalCompilerErrorException(Message.MainMethodNotFound); + throw new FatalCompilerErrorException(Diagnostic.MainMethodNotFound.Event([])); mw.Link(); var method = mw.GetMethod() as MethodInfo; if (method == null) - throw new FatalCompilerErrorException(Message.UnsupportedMainMethod); + throw new FatalCompilerErrorException(Diagnostic.UnsupportedMainMethod.Event([])); if (!ReflectUtil.IsFromAssembly(method.DeclaringType, assemblyBuilder) && (!method.IsPublic || !method.DeclaringType.IsPublic)) { - throw new FatalCompilerErrorException(Message.ExternalMainNotAccessible); + throw new FatalCompilerErrorException(Diagnostic.ExternalMainNotAccessible.Event([])); } var apartmentAttributeType = options.apartment switch @@ -3009,7 +3018,7 @@ int CompilePass3() if (map != null) { LoadMappedExceptions(map); - Tracer.Info(Tracer.Compiler, "Loading remapped types (2)"); + Diagnostics.GenericCompilerInfo("Loading remapped types (2)"); try { @@ -3022,7 +3031,7 @@ int CompilePass3() } } - Tracer.Info(Tracer.Compiler, "Compiling class files (2)"); + Diagnostics.GenericCompilerInfo("Compiling class files (2)"); WriteResources(); // add external resources @@ -3062,20 +3071,20 @@ int CompilePass3() } if (classLoaderType == null) - throw new FatalCompilerErrorException(Message.ClassLoaderNotFound); + throw new FatalCompilerErrorException(Diagnostic.ClassLoaderNotFound.Event([])); if (classLoaderType.IsPublic == false && ReflectUtil.IsFromAssembly(classLoaderType.TypeAsBaseType, assemblyBuilder) == false) - throw new FatalCompilerErrorException(Message.ClassLoaderNotAccessible); + throw new FatalCompilerErrorException(Diagnostic.ClassLoaderNotAccessible.Event([])); if (classLoaderType.IsAbstract) - throw new FatalCompilerErrorException(Message.ClassLoaderIsAbstract); + throw new FatalCompilerErrorException(Diagnostic.ClassLoaderIsAbstract.Event([])); if (classLoaderType.IsAssignableTo(Context.ClassLoaderFactory.LoadClassCritical("java.lang.ClassLoader")) == false) - throw new FatalCompilerErrorException(Message.ClassLoaderNotClassLoader); + throw new FatalCompilerErrorException(Diagnostic.ClassLoaderNotClassLoader.Event([])); var classLoaderInitMethod = classLoaderType.GetMethodWrapper("", "(Lcli.System.Reflection.Assembly;)V", false); if (classLoaderInitMethod == null) - throw new FatalCompilerErrorException(Message.ClassLoaderConstructorMissing); + throw new FatalCompilerErrorException(Diagnostic.ClassLoaderConstructorMissing.Event([])); // apply custom attribute specifying custom class loader var ci = Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { Context.Types.Type }, null); @@ -3184,12 +3193,12 @@ private void ValidateNameSig(string member, string clazz, string name, string si if (!IsValidName(name)) { valid = false; - Context.StaticCompiler.IssueMessage(Message.InvalidMemberNameInMapFile, member, name, clazz); + Diagnostics.InvalidMemberNameInMapFile(member, name, clazz); } if (!IsValidSig(sig, field)) { valid = false; - Context.StaticCompiler.IssueMessage(Message.InvalidMemberSignatureInMapFile, member, clazz, name, sig); + Diagnostics.InvalidMemberSignatureInMapFile(member, clazz, name, sig); } } @@ -3200,12 +3209,12 @@ void ValidatePropertyGetterSetter(string getterOrSetter, string clazz, string pr if (!IsValidName(method.Name)) { valid = false; - Context.StaticCompiler.IssueMessage(Message.InvalidPropertyNameInMapFile, getterOrSetter, clazz, property, method.Name); + Diagnostics.InvalidPropertyNameInMapFile(getterOrSetter, clazz, property, method.Name); } if (!IKVM.Runtime.ClassFile.IsValidMethodSig(method.Sig)) { valid = false; - Context.StaticCompiler.IssueMessage(Message.InvalidPropertySignatureInMapFile, getterOrSetter, clazz, property, method.Sig); + Diagnostics.InvalidPropertySignatureInMapFile(getterOrSetter, clazz, property, method.Sig); } } } @@ -3233,11 +3242,6 @@ internal Type GetTypeFromReferencedAssembly(string name) return null; } - internal override void IssueMessage(Message msgId, params string[] values) - { - Context.StaticCompiler.IssueMessage(options, msgId, values); - } - internal override bool WarningLevelHigh { get { return options.warningLevelHigh; } diff --git a/src/IKVM.Tools.Importer/FatalCompilerErrorException.cs b/src/IKVM.Tools.Importer/FatalCompilerErrorException.cs index a953792fb3..03c8e7fb79 100644 --- a/src/IKVM.Tools.Importer/FatalCompilerErrorException.cs +++ b/src/IKVM.Tools.Importer/FatalCompilerErrorException.cs @@ -1,29 +1,6 @@ -/* - Copyright (C) 2002-2014 Jeroen Frijters +using System; - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jeroen Frijters - jeroen@frijters.net - -*/ -using System; - -using IKVM.Runtime; +using IKVM.CoreLib.Diagnostics; namespace IKVM.Tools.Importer { @@ -31,140 +8,20 @@ namespace IKVM.Tools.Importer sealed class FatalCompilerErrorException : Exception { - internal FatalCompilerErrorException(Message id, params object[] args) : - base($"fatal error IKVMC{(int)id}: {(args.Length == 0 ? GetMessage(id) : string.Format(GetMessage(id), args))}") + /// + /// Initializes a new instance. + /// + /// + internal FatalCompilerErrorException(in DiagnosticEvent evt) : +#if NET8_0_OR_GREATER + base($"fatal error IKVMC{evt.Diagnostic.Id}: {string.Format(null, evt.Diagnostic.Message, evt.Args)}") +#else + base($"fatal error IKVMC{evt.Diagnostic.Id}: {string.Format(evt.Diagnostic.Message, evt.Args.ToArray())}") +#endif { } - private static string GetMessage(Message id) - { - switch (id) - { - case IKVM.Tools.Importer.Message.ResponseFileDepthExceeded: - return "Response file nesting depth exceeded"; - case IKVM.Tools.Importer.Message.ErrorReadingFile: - return "Unable to read file: {0}\n\t({1})"; - case IKVM.Tools.Importer.Message.NoTargetsFound: - return "No targets found"; - case IKVM.Tools.Importer.Message.FileFormatLimitationExceeded: - return "File format limitation exceeded: {0}"; - case IKVM.Tools.Importer.Message.CannotSpecifyBothKeyFileAndContainer: - return "You cannot specify both a key file and container"; - case IKVM.Tools.Importer.Message.DelaySignRequiresKey: - return "You cannot delay sign without a key file or container"; - case IKVM.Tools.Importer.Message.InvalidStrongNameKeyPair: - return "Invalid key {0} specified.\n\t(\"{1}\")"; - case IKVM.Tools.Importer.Message.ReferenceNotFound: - return "Reference not found: {0}"; - case IKVM.Tools.Importer.Message.OptionsMustPreceedChildLevels: - return "You can only specify options before any child levels"; - case IKVM.Tools.Importer.Message.UnrecognizedTargetType: - return "Invalid value '{0}' for -target option"; - case IKVM.Tools.Importer.Message.UnrecognizedPlatform: - return "Invalid value '{0}' for -platform option"; - case IKVM.Tools.Importer.Message.UnrecognizedApartment: - return "Invalid value '{0}' for -apartment option"; - case IKVM.Tools.Importer.Message.MissingFileSpecification: - return "Missing file specification for '{0}' option"; - case IKVM.Tools.Importer.Message.PathTooLong: - return "Path too long: {0}"; - case IKVM.Tools.Importer.Message.PathNotFound: - return "Path not found: {0}"; - case IKVM.Tools.Importer.Message.InvalidPath: - return "Invalid path: {0}"; - case IKVM.Tools.Importer.Message.InvalidOptionSyntax: - return "Invalid option: {0}"; - case IKVM.Tools.Importer.Message.ExternalResourceNotFound: - return "External resource file does not exist: {0}"; - case IKVM.Tools.Importer.Message.ExternalResourceNameInvalid: - return "External resource file may not include path specification: {0}"; - case IKVM.Tools.Importer.Message.InvalidVersionFormat: - return "Invalid version specified: {0}"; - case IKVM.Tools.Importer.Message.InvalidFileAlignment: - return "Invalid value '{0}' for -filealign option"; - case IKVM.Tools.Importer.Message.ErrorWritingFile: - return "Unable to write file: {0}\n\t({1})"; - case IKVM.Tools.Importer.Message.UnrecognizedOption: - return "Unrecognized option: {0}"; - case IKVM.Tools.Importer.Message.NoOutputFileSpecified: - return "No output file specified"; - case IKVM.Tools.Importer.Message.SharedClassLoaderCannotBeUsedOnModuleTarget: - return "Incompatible options: -target:module and -sharedclassloader cannot be combined"; - case IKVM.Tools.Importer.Message.RuntimeNotFound: - return "Unable to load runtime assembly"; - case IKVM.Tools.Importer.Message.MainClassRequiresExe: - return "Main class cannot be specified for library or module"; - case IKVM.Tools.Importer.Message.ExeRequiresMainClass: - return "No main method found"; - case IKVM.Tools.Importer.Message.PropertiesRequireExe: - return "Properties cannot be specified for library or module"; - case IKVM.Tools.Importer.Message.ModuleCannotHaveClassLoader: - return "Cannot specify assembly class loader for modules"; - case IKVM.Tools.Importer.Message.ErrorParsingMapFile: - return "Unable to parse remap file: {0}\n\t({1})"; - case IKVM.Tools.Importer.Message.BootstrapClassesMissing: - return "Bootstrap classes missing and core assembly not found"; - case IKVM.Tools.Importer.Message.StrongNameRequiresStrongNamedRefs: - return "All referenced assemblies must be strong named, to be able to sign the output assembly"; - case IKVM.Tools.Importer.Message.MainClassNotFound: - return "Main class not found"; - case IKVM.Tools.Importer.Message.MainMethodNotFound: - return "Main method not found"; - case IKVM.Tools.Importer.Message.UnsupportedMainMethod: - return "Redirected main method not supported"; - case IKVM.Tools.Importer.Message.ExternalMainNotAccessible: - return "External main method must be public and in a public class"; - case IKVM.Tools.Importer.Message.ClassLoaderNotFound: - return "Custom assembly class loader class not found"; - case IKVM.Tools.Importer.Message.ClassLoaderNotAccessible: - return "Custom assembly class loader class is not accessible"; - case IKVM.Tools.Importer.Message.ClassLoaderIsAbstract: - return "Custom assembly class loader class is abstract"; - case IKVM.Tools.Importer.Message.ClassLoaderNotClassLoader: - return "Custom assembly class loader class does not extend java.lang.ClassLoader"; - case IKVM.Tools.Importer.Message.ClassLoaderConstructorMissing: - return "Custom assembly class loader constructor is missing"; - case IKVM.Tools.Importer.Message.MapFileTypeNotFound: - return "Type '{0}' referenced in remap file was not found"; - case IKVM.Tools.Importer.Message.MapFileClassNotFound: - return "Class '{0}' referenced in remap file was not found"; - case IKVM.Tools.Importer.Message.MaximumErrorCountReached: - return "Maximum error count reached"; - case IKVM.Tools.Importer.Message.LinkageError: - return "Link error: {0}"; - case IKVM.Tools.Importer.Message.RuntimeMismatch: - return "Referenced assembly {0} was compiled with an incompatible IKVM.Runtime version\n" + - "\tCurrent runtime: {1}\n" + - "\tReferenced assembly runtime: {2}"; - case IKVM.Tools.Importer.Message.CoreClassesMissing: - return "Failed to find core classes in core library"; - case IKVM.Tools.Importer.Message.CriticalClassNotFound: - return "Unable to load critical class '{0}'"; - case IKVM.Tools.Importer.Message.AssemblyContainsDuplicateClassNames: - return "Type '{0}' and '{1}' both map to the same name '{2}'\n\t({3})"; - case IKVM.Tools.Importer.Message.CallerIDRequiresHasCallerIDAnnotation: - return "CallerID.getCallerID() requires a HasCallerID annotation"; - case IKVM.Tools.Importer.Message.UnableToResolveInterface: - return "Unable to resolve interface '{0}' on type '{1}'"; - case IKVM.Tools.Importer.Message.MissingBaseType: - return "The base class or interface '{0}' in assembly '{1}' referenced by type '{2}' in '{3}' could not be resolved"; - case IKVM.Tools.Importer.Message.MissingBaseTypeReference: - return "The type '{0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{1}'"; - case IKVM.Tools.Importer.Message.FileNotFound: - return "File not found: {0}"; - case IKVM.Tools.Importer.Message.RuntimeMethodMissing: - return "Runtime method '{0}' not found"; - case IKVM.Tools.Importer.Message.MapFileFieldNotFound: - return "Field '{0}' referenced in remap file was not found in class '{1}'"; - case IKVM.Tools.Importer.Message.GhostInterfaceMethodMissing: - return "Remapped class '{0}' does not implement ghost interface method\n\t({1}.{2}{3})"; - case Importer.Message.ModuleInitializerMethodRequirements: - return "Method '{1}.{2}{3}' does not meet the requirements of a module initializer."; - default: - return "Missing Error IKVM.Tools.Importer.Message. Please file a bug."; - } - } } } diff --git a/src/IKVM.Tools.Importer/IKVM.Tools.Importer.csproj b/src/IKVM.Tools.Importer/IKVM.Tools.Importer.csproj index a4e5e7b16e..ec8a04ab36 100644 --- a/src/IKVM.Tools.Importer/IKVM.Tools.Importer.csproj +++ b/src/IKVM.Tools.Importer/IKVM.Tools.Importer.csproj @@ -17,6 +17,7 @@ + diff --git a/src/IKVM.Tools.Importer/IkvmImporterContext.NetFramework.cs b/src/IKVM.Tools.Importer/IkvmImporterContext.NetFramework.cs index 967b6dbd7f..057412104b 100644 --- a/src/IKVM.Tools.Importer/IkvmImporterContext.NetFramework.cs +++ b/src/IKVM.Tools.Importer/IkvmImporterContext.NetFramework.cs @@ -64,7 +64,7 @@ public IkvmImporterContext(string[] args) false, System.Reflection.BindingFlags.Default, null, - new[] { args }, + [args], null, null); } diff --git a/src/IKVM.Tools.Importer/IkvmImporterInternal.cs b/src/IKVM.Tools.Importer/IkvmImporterInternal.cs index 96da26085b..a443d6544d 100644 --- a/src/IKVM.Tools.Importer/IkvmImporterInternal.cs +++ b/src/IKVM.Tools.Importer/IkvmImporterInternal.cs @@ -29,7 +29,7 @@ Jeroen Frijters using System.Threading; using IKVM.ByteCode; -using IKVM.ByteCode.Decoding; +using IKVM.CoreLib.Diagnostics; using IKVM.Reflection; using IKVM.Reflection.Emit; using IKVM.Runtime; @@ -42,6 +42,39 @@ namespace IKVM.Tools.Importer class IkvmImporterInternal { + /// + /// implementation for nested class loaders. + /// + internal class DiagnosticHandler : DiagnosticEventHandler + { + + readonly IkvmImporterInternal importer; + readonly CompilerOptions options; + + /// + /// Initializes a new instance. + /// + /// + /// + /// + public DiagnosticHandler(IkvmImporterInternal importer, CompilerOptions options) + { + this.importer = importer ?? throw new ArgumentNullException(nameof(importer)); + this.options = options ?? throw new ArgumentNullException(nameof(options)); + } + + public override bool IsEnabled(Diagnostic diagnostic) + { + return importer.IsDiagnosticEnabled(diagnostic); + } + + public override void Report(in DiagnosticEvent @event) + { + importer.ReportEvent(options, @event); + } + + } + bool nonleaf; string manifestMainClass; string defaultAssemblyName; @@ -59,7 +92,7 @@ static void AddArg(List arglist, string s, int depth) { if (depth++ > 16) { - throw new FatalCompilerErrorException(Message.ResponseFileDepthExceeded); + throw new FatalCompilerErrorException(Diagnostic.ResponseFileDepthExceeded.Event([])); } try { @@ -82,7 +115,7 @@ static void AddArg(List arglist, string s, int depth) } catch (Exception x) { - throw new FatalCompilerErrorException(Message.ErrorReadingFile, s.Substring(1), x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorReadingFile.Event([s.Substring(1), x.Message])); } } else @@ -103,8 +136,6 @@ public static int Execute(string[] args) { DateTime start = DateTime.Now; System.Threading.Thread.CurrentThread.Name = "compiler"; - Tracer.EnableTraceConsoleListener(); - Tracer.EnableTraceForDebug(); try { @@ -168,23 +199,24 @@ static int Compile(string[] args) PrintHeader(); } - var compiler = new StaticCompiler(); + var rootTarget = new CompilerOptions(); var importer = new IkvmImporterInternal(); + var diagnostics = new DiagnosticHandler(importer, rootTarget); + var compiler = new StaticCompiler(diagnostics); var targets = new List(); - var rootTarget = new CompilerOptions(); - var context = new RuntimeContext(new RuntimeContextOptions(), new ManagedResolver(compiler), argList.Contains("-bootstrap"), compiler); + var context = new RuntimeContext(new RuntimeContextOptions(), diagnostics, new ManagedResolver(compiler), argList.Contains("-bootstrap"), compiler); compiler.rootTarget = rootTarget; - importer.ParseCommandLine(context, compiler, argList.GetEnumerator(), targets, rootTarget); + importer.ParseCommandLine(context, compiler, diagnostics, argList.GetEnumerator(), targets, rootTarget); compiler.Init(nonDeterministicOutput, rootTarget.debugMode, libpaths); - resolver.Warning += (warning, message, parameters) => loader_Warning(compiler, warning, message, parameters); + resolver.Warning += (warning, message, parameters) => loader_Warning(compiler, diagnostics, warning, message, parameters); resolver.Init(compiler.Universe, nostdlib, rootTarget.unresolvedReferences, libpaths); - ResolveReferences(compiler, targets); + ResolveReferences(compiler, diagnostics, targets); ResolveStrongNameKeys(targets); if (targets.Count == 0) { - throw new FatalCompilerErrorException(Message.NoTargetsFound); + throw new FatalCompilerErrorException(Diagnostic.NoTargetsFound.Event([])); } if (compiler.errorCount != 0) { @@ -193,35 +225,35 @@ static int Compile(string[] args) try { - return CompilerClassLoader.Compile(context, compiler, runtimeAssembly, targets); + return CompilerClassLoader.Compile(importer, context, compiler, diagnostics, runtimeAssembly, targets); } catch (FileFormatLimitationExceededException x) { - throw new FatalCompilerErrorException(Message.FileFormatLimitationExceeded, x.Message); + throw new FatalCompilerErrorException(Diagnostic.FileFormatLimitationExceeded.Event([x.Message])); } } - static void loader_Warning(StaticCompiler compiler, AssemblyResolver.WarningId warning, string message, string[] parameters) + static void loader_Warning(StaticCompiler compiler, IDiagnosticHandler diagnostics, AssemblyResolver.WarningId warning, string message, string[] parameters) { switch (warning) { case AssemblyResolver.WarningId.HigherVersion: - IssueMessage(compiler, Message.AssumeAssemblyVersionMatch, parameters); + diagnostics.AssumeAssemblyVersionMatch(parameters[0], parameters[1]); break; case AssemblyResolver.WarningId.InvalidLibDirectoryOption: - IssueMessage(compiler, Message.InvalidDirectoryInLibOptionPath, parameters); + diagnostics.InvalidDirectoryInLibOptionPath(parameters[0]); break; case AssemblyResolver.WarningId.InvalidLibDirectoryEnvironment: - IssueMessage(compiler, Message.InvalidDirectoryInLibEnvironmentPath, parameters); + diagnostics.InvalidDirectoryInLibEnvironmentPath(parameters[0]); break; case AssemblyResolver.WarningId.LegacySearchRule: - IssueMessage(compiler, Message.LegacySearchRule, parameters); + diagnostics.LegacySearchRule(parameters[0]); break; case AssemblyResolver.WarningId.LocationIgnored: - IssueMessage(compiler, Message.AssemblyLocationIgnored, parameters); + diagnostics.AssemblyLocationIgnored(parameters[0], parameters[1], parameters[2]); break; default: - IssueMessage(compiler, Message.UnknownWarning, string.Format(message, parameters)); + diagnostics.UnknownWarning(string.Format(message, parameters)); break; } } @@ -231,10 +263,10 @@ static void ResolveStrongNameKeys(List targets) foreach (var options in targets) { if (options.keyfile != null && options.keycontainer != null) - throw new FatalCompilerErrorException(Message.CannotSpecifyBothKeyFileAndContainer); + throw new FatalCompilerErrorException(Diagnostic.CannotSpecifyBothKeyFileAndContainer.Event([])); if (options.keyfile == null && options.keycontainer == null && options.delaysign) - throw new FatalCompilerErrorException(Message.DelaySignRequiresKey); + throw new FatalCompilerErrorException(Diagnostic.DelaySignRequiresKey.Event([])); if (options.keyfile != null) { @@ -278,7 +310,7 @@ internal static byte[] ReadAllBytes(FileInfo path) } catch (Exception x) { - throw new FatalCompilerErrorException(Message.ErrorReadingFile, path.ToString(), x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorReadingFile.Event([path.ToString(), x.Message])); } } @@ -398,17 +430,17 @@ static void PrintHelp() Console.Error.WriteLine(" class file."); } - void ParseCommandLine(RuntimeContext context, StaticCompiler compiler, IEnumerator arglist, List targets, CompilerOptions options) + void ParseCommandLine(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, IEnumerator arglist, List targets, CompilerOptions options) { options.target = PEFileKinds.ConsoleApplication; options.guessFileKind = true; options.version = new Version(0, 0, 0, 0); options.apartment = ApartmentState.STA; options.props = new Dictionary(); - ContinueParseCommandLine(context, compiler, arglist, targets, options); + ContinueParseCommandLine(context, compiler, diagnostics, arglist, targets, options); } - void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, IEnumerator arglist, List targets, CompilerOptions options) + void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, IDiagnosticHandler diagnostics, IEnumerator arglist, List targets, CompilerOptions options) { var fileNames = new List(); while (arglist.MoveNext()) @@ -418,13 +450,14 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I { if (!nonleaf) { - ReadFiles(context, compiler, options, fileNames); + ReadFiles(context, compiler, options, diagnostics, fileNames); nonleaf = true; } - IkvmImporterInternal nestedLevel = new IkvmImporterInternal(); + + var nestedLevel = new IkvmImporterInternal(); nestedLevel.manifestMainClass = manifestMainClass; nestedLevel.defaultAssemblyName = defaultAssemblyName; - nestedLevel.ContinueParseCommandLine(context, compiler, arglist, targets, options.Copy()); + nestedLevel.ContinueParseCommandLine(context, compiler, diagnostics, arglist, targets, options.Copy()); } else if (s == "}") { @@ -432,7 +465,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I } else if (nonleaf) { - throw new FatalCompilerErrorException(Message.OptionsMustPreceedChildLevels); + throw new FatalCompilerErrorException(Diagnostic.OptionsMustPreceedChildLevels.Event([])); } else if (s[0] == '-') { @@ -440,14 +473,6 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I { options.path = GetFileInfo(s.Substring(5)); } - else if (s.StartsWith("-Xtrace:")) - { - Tracer.SetTraceLevel(s.Substring(8)); - } - else if (s.StartsWith("-Xmethodtrace:")) - { - Tracer.HandleMethodTrace(s.Substring(14)); - } else if (s.StartsWith("-assembly:")) { options.assembly = s.Substring(10); @@ -475,7 +500,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I options.guessFileKind = false; break; default: - throw new FatalCompilerErrorException(Message.UnrecognizedTargetType, s.Substring(8)); + throw new FatalCompilerErrorException(Diagnostic.UnrecognizedTargetType.Event([s.Substring(8)])); } } else if (s.StartsWith("-platform:")) @@ -507,7 +532,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I options.imageFileMachine = ImageFileMachine.UNKNOWN; break; default: - throw new FatalCompilerErrorException(Message.UnrecognizedPlatform, s.Substring(10)); + throw new FatalCompilerErrorException(Diagnostic.UnrecognizedPlatform.Event([s.Substring(10)])); } } else if (s.StartsWith("-apartment:")) @@ -524,7 +549,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I options.apartment = ApartmentState.Unknown; break; default: - throw new FatalCompilerErrorException(Message.UnrecognizedApartment, s.Substring(11)); + throw new FatalCompilerErrorException(Diagnostic.UnrecognizedApartment.Event([s.Substring(11)])); } } else if (s == "-noglobbing") @@ -567,7 +592,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I { var r = s.Substring(s.IndexOf(':') + 1); if (r == "") - throw new FatalCompilerErrorException(Message.MissingFileSpecification, s); + throw new FatalCompilerErrorException(Diagnostic.MissingFileSpecification.Event([s])); ArrayAppend(ref options.unresolvedReferences, r); } @@ -590,7 +615,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I if (exists) { var dir = new DirectoryInfo(spec); - found = Recurse(context, compiler, options, dir, dir, "*"); + found = Recurse(context, compiler, options, diagnostics, dir, dir, "*"); } else { @@ -599,35 +624,35 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I var dir = new DirectoryInfo(Path.GetDirectoryName(spec)); if (dir.Exists) { - found = Recurse(context, compiler, options, dir, dir, Path.GetFileName(spec)); + found = Recurse(context, compiler, options, diagnostics, dir, dir, Path.GetFileName(spec)); } else { - found = RecurseJar(context, compiler, options, spec); + found = RecurseJar(context, compiler, options, diagnostics, spec); } } catch (PathTooLongException) { - throw new FatalCompilerErrorException(Message.PathTooLong, spec); + throw new FatalCompilerErrorException(Diagnostic.PathTooLong.Event([spec])); } catch (DirectoryNotFoundException) { - throw new FatalCompilerErrorException(Message.PathNotFound, spec); + throw new FatalCompilerErrorException(Diagnostic.PathNotFound.Event([spec])); } catch (ArgumentException) { - throw new FatalCompilerErrorException(Message.InvalidPath, spec); + throw new FatalCompilerErrorException(Diagnostic.InvalidPath.Event([spec])); } } if (!found) - throw new FatalCompilerErrorException(Message.FileNotFound, spec); + throw new FatalCompilerErrorException(Diagnostic.FileNotFound.Event([spec])); } else if (s.StartsWith("-resource:")) { var spec = s.Substring(10).Split('='); if (spec.Length != 2) - throw new FatalCompilerErrorException(Message.InvalidOptionSyntax, s); + throw new FatalCompilerErrorException(Diagnostic.InvalidOptionSyntax.Event([s])); var fileInfo = GetFileInfo(spec[1]); var fileName = spec[0].TrimStart('/').TrimEnd('/'); @@ -637,11 +662,11 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I { var spec = s.Substring(18).Split('='); if (spec.Length != 2) - throw new FatalCompilerErrorException(Message.InvalidOptionSyntax, s); + throw new FatalCompilerErrorException(Diagnostic.InvalidOptionSyntax.Event([s])); if (!File.Exists(spec[1])) - throw new FatalCompilerErrorException(Message.ExternalResourceNotFound, spec[1]); + throw new FatalCompilerErrorException(Diagnostic.ExternalResourceNotFound.Event([spec[1]])); if (Path.GetFileName(spec[1]) != spec[1]) - throw new FatalCompilerErrorException(Message.ExternalResourceNameInvalid, spec[1]); + throw new FatalCompilerErrorException(Diagnostic.ExternalResourceNameInvalid.Event([spec[1]])); // TODO resource name clashes should be tested options.externalResources ??= new Dictionary(); @@ -659,7 +684,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I { var str = s.Substring(9); if (!TryParseVersion(s.Substring(9), out options.version)) - throw new FatalCompilerErrorException(Message.InvalidVersionFormat, str); + throw new FatalCompilerErrorException(Diagnostic.InvalidVersionFormat.Event([str])); } else if (s.StartsWith("-fileversion:")) { @@ -805,7 +830,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I else if (s.StartsWith("-filealign:")) { if (!uint.TryParse(s.Substring(11), out var filealign) || filealign < 512 || filealign > 8192 || (filealign & (filealign - 1)) != 0) - throw new FatalCompilerErrorException(Message.InvalidFileAlignment, s.Substring(11)); + throw new FatalCompilerErrorException(Diagnostic.InvalidFileAlignment.Event([s.Substring(11)])); options.fileAlignment = filealign; } @@ -841,14 +866,14 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I } catch (Exception x) { - throw new FatalCompilerErrorException(Message.ErrorWritingFile, options.writeSuppressWarningsFile, x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorWritingFile.Event([options.writeSuppressWarningsFile, x.Message])); } } else if (s.StartsWith("-proxy:")) // currently undocumented! { var proxy = s.Substring(7); if (options.proxies.Contains(proxy)) - IssueMessage(compiler, Message.DuplicateProxy, proxy); + diagnostics.DuplicateProxy(proxy); options.proxies.Add(proxy); } @@ -871,7 +896,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I } else if (s.StartsWith("-assemblyattributes:", StringComparison.Ordinal)) { - ProcessAttributeAnnotationsClass(context, ref options.assemblyAttributeAnnotations, s.Substring(20)); + ProcessAttributeAnnotationsClass(context, diagnostics, ref options.assemblyAttributeAnnotations, s.Substring(20)); } else if (s == "-w4") // undocumented option to always warn if a class isn't found { @@ -887,7 +912,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I } else { - throw new FatalCompilerErrorException(Message.UnrecognizedOption, s); + throw new FatalCompilerErrorException(Diagnostic.UnrecognizedOption.Event([s])); } } else @@ -896,7 +921,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I } if (options.targetIsModule && options.sharedclassloader != null) { - throw new FatalCompilerErrorException(Message.SharedClassLoaderCannotBeUsedOnModuleTarget); + throw new FatalCompilerErrorException(Diagnostic.SharedClassLoaderCannotBeUsedOnModuleTarget.Event([])); } } @@ -905,13 +930,13 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I return; } - ReadFiles(context, compiler, options, fileNames); + ReadFiles(context, compiler, options, diagnostics, fileNames); if (options.assembly == null) { var basename = options.path == null ? defaultAssemblyName : options.path.Name; if (basename == null) - throw new FatalCompilerErrorException(Message.NoOutputFileSpecified); + throw new FatalCompilerErrorException(Diagnostic.NoOutputFileSpecified.Event([])); int idx = basename.LastIndexOf('.'); if (idx > 0) @@ -930,7 +955,7 @@ void ContinueParseCommandLine(RuntimeContext context, StaticCompiler compiler, I if (options.mainClass == null && manifestMainClass != null && (options.guessFileKind || options.target != PEFileKinds.Dll)) { - IssueMessage(compiler, options, Message.MainMethodFromManifest, manifestMainClass); + diagnostics.MainMethodFromManifest(manifestMainClass); options.mainClass = manifestMainClass; } @@ -945,30 +970,30 @@ internal static FileInfo GetFileInfo(string path) if (fileInfo.Directory == null) { // this happens with an incorrect unc path (e.g. "\\foo\bar") - throw new FatalCompilerErrorException(Message.InvalidPath, path); + throw new FatalCompilerErrorException(Diagnostic.InvalidPath.Event([path])); } return fileInfo; } catch (ArgumentException) { - throw new FatalCompilerErrorException(Message.InvalidPath, path); + throw new FatalCompilerErrorException(Diagnostic.InvalidPath.Event([path])); } catch (NotSupportedException) { - throw new FatalCompilerErrorException(Message.InvalidPath, path); + throw new FatalCompilerErrorException(Diagnostic.InvalidPath.Event([path])); } catch (PathTooLongException) { - throw new FatalCompilerErrorException(Message.PathTooLong, path); + throw new FatalCompilerErrorException(Diagnostic.PathTooLong.Event([path])); } catch (UnauthorizedAccessException) { // this exception does not appear to be possible - throw new FatalCompilerErrorException(Message.InvalidPath, path); + throw new FatalCompilerErrorException(Diagnostic.InvalidPath.Event([path])); } } - private void ReadFiles(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, List fileNames) + void ReadFiles(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, IDiagnosticHandler diagnostics, List fileNames) { foreach (string fileName in fileNames) { @@ -990,22 +1015,28 @@ private void ReadFiles(RuntimeContext context, StaticCompiler compiler, Compiler { } } + string[] files = null; try { - string path = Path.GetDirectoryName(fileName); + var path = Path.GetDirectoryName(fileName); files = Directory.GetFiles(path == "" ? "." : path, Path.GetFileName(fileName)); } - catch { } + catch + { + + } + + if (files == null || files.Length == 0) { - IssueMessage(compiler, Message.InputFileNotFound, fileName); + diagnostics.InputFileNotFound(fileName); } else { foreach (string f in files) { - ProcessFile(context, compiler, options, null, f); + ProcessFile(context, compiler, options, diagnostics, null, f); } } } @@ -1066,20 +1097,21 @@ static void SetStrongNameKeyPair(ref StrongNameKeyPair strongNameKeyPair, FileIn } catch (Exception x) { - throw new FatalCompilerErrorException(Message.InvalidStrongNameKeyPair, keyFile != null ? "file" : "container", x.Message); + throw new FatalCompilerErrorException(Diagnostic.InvalidStrongNameKeyPair.Event([keyFile != null ? "file" : "container", x.Message])); } } - static void ResolveReferences(StaticCompiler compiler, List targets) + static void ResolveReferences(StaticCompiler compiler, IDiagnosticHandler diagnostics, List targets) { var cache = new Dictionary(); - foreach (CompilerOptions target in targets) + + foreach (var target in targets) { if (target.unresolvedReferences != null) { foreach (string reference in target.unresolvedReferences) { - foreach (CompilerOptions peer in targets) + foreach (var peer in targets) { if (peer.assembly.Equals(reference, StringComparison.OrdinalIgnoreCase)) { @@ -1089,7 +1121,7 @@ static void ResolveReferences(StaticCompiler compiler, List tar } if (!resolver.ResolveReference(cache, ref target.references, reference)) { - throw new FatalCompilerErrorException(Message.ReferenceNotFound, reference); + throw new FatalCompilerErrorException(Diagnostic.ReferenceNotFound.Event([reference])); } next_reference:; } @@ -1097,53 +1129,37 @@ static void ResolveReferences(StaticCompiler compiler, List tar } // verify that we didn't reference any secondary assemblies of a shared class loader group - foreach (CompilerOptions target in targets) + foreach (var target in targets) { if (target.references != null) { - foreach (Assembly asm in target.references) + foreach (var asm in target.references) { - Type forwarder = asm.GetType("__"); + var forwarder = asm.GetType("__"); if (forwarder != null && forwarder.Assembly != asm) - { - IssueMessage(compiler, Message.NonPrimaryAssemblyReference, asm.Location, forwarder.Assembly.GetName().Name); - } + diagnostics.NonPrimaryAssemblyReference(asm.Location, forwarder.Assembly.GetName().Name); } } } // add legacy references (from stub files) - foreach (CompilerOptions target in targets) - { - foreach (string assemblyName in target.legacyStubReferences.Keys) - { + foreach (var target in targets) + foreach (var assemblyName in target.legacyStubReferences.Keys) ArrayAppend(ref target.references, resolver.LegacyLoad(new AssemblyName(assemblyName), null)); - } - } // now pre-load the secondary assemblies of any shared class loader groups - foreach (CompilerOptions target in targets) - { + foreach (var target in targets) if (target.references != null) - { - foreach (Assembly asm in target.references) - { + foreach (var asm in target.references) RuntimeAssemblyClassLoader.PreloadExportedAssemblies(compiler, asm); - } - } - } } private static void ArrayAppend(ref T[] array, T element) { if (array == null) - { - array = new T[] { element }; - } + array = [element]; else - { array = ArrayUtil.Concat(array, element); - } } private static void ArrayAppend(ref T[] array, T[] append) @@ -1166,17 +1182,16 @@ static byte[] ReadFromZip(ZipArchiveEntry ze) using MemoryStream ms = new MemoryStream(); using Stream s = ze.Open(); s.CopyTo(ms); - return ms.ToArray(); } - static bool EmitStubWarning(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, byte[] buf) + static bool EmitStubWarning(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, IDiagnosticHandler diagnostics, byte[] buf) { IKVM.Runtime.ClassFile cf; try { - cf = new IKVM.Runtime.ClassFile(context, IKVM.ByteCode.Decoding.ClassFile.Read(buf), "", ClassFileParseOptions.None, null); + cf = new IKVM.Runtime.ClassFile(context, diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(buf), "", ClassFileParseOptions.None, null); } catch (ClassFormatError) { @@ -1199,26 +1214,26 @@ static bool EmitStubWarning(RuntimeContext context, StaticCompiler compiler, Com foreach (Match m in mc) { options.legacyStubReferences[m.Groups[1].Value] = null; - IssueMessage(compiler, options, Message.StubsAreDeprecated, m.Groups[1].Value); + diagnostics.StubsAreDeprecated(m.Groups[1].Value); } } else { options.legacyStubReferences[cf.IKVMAssemblyAttribute] = null; - IssueMessage(compiler, options, Message.StubsAreDeprecated, cf.IKVMAssemblyAttribute); + diagnostics.StubsAreDeprecated(cf.IKVMAssemblyAttribute); } return true; } - static bool IsExcludedOrStubLegacy(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, ZipArchiveEntry ze, byte[] data) + static bool IsExcludedOrStubLegacy(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, IDiagnosticHandler diagnostics, ZipArchiveEntry ze, byte[] data) { if (ze.Name.EndsWith(".class", StringComparison.OrdinalIgnoreCase)) { try { var name = IKVM.Runtime.ClassFile.GetClassName(data, 0, data.Length, out var stub); - if (options.IsExcludedClass(name) || (stub && EmitStubWarning(context, compiler, options, data))) + if (options.IsExcludedClass(name) || (stub && EmitStubWarning(context, compiler, options, diagnostics, data))) { // we use stubs to add references, but otherwise ignore them return true; @@ -1260,15 +1275,15 @@ void ProcessManifest(StaticCompiler compiler, CompilerOptions options, ZipArchiv } } - bool ProcessZipFile(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, string file, Predicate filter) + bool ProcessZipFile(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, IDiagnosticHandler diagnostics, string file, Predicate filter) { try { - using ZipArchive zf = ZipFile.OpenRead(file); + using var zf = ZipFile.OpenRead(file); bool found = false; Jar jar = null; - foreach (ZipArchiveEntry ze in zf.Entries) + foreach (var ze in zf.Entries) { if (filter != null && !filter(ze)) { @@ -1277,8 +1292,8 @@ bool ProcessZipFile(RuntimeContext context, StaticCompiler compiler, CompilerOpt else { found = true; - byte[] data = ReadFromZip(ze); - if (IsExcludedOrStubLegacy(context, compiler, options, ze, data)) + var data = ReadFromZip(ze); + if (IsExcludedOrStubLegacy(context, compiler, options, diagnostics, ze, data)) { continue; } @@ -1293,25 +1308,27 @@ bool ProcessZipFile(RuntimeContext context, StaticCompiler compiler, CompilerOpt } } } + // include empty zip file if (!found) { options.GetJar(file); } + return found; } catch (InvalidDataException x) { - throw new FatalCompilerErrorException(Message.ErrorReadingFile, file, x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorReadingFile.Event([file, x.Message])); } } - void ProcessFile(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, DirectoryInfo baseDir, string file) + void ProcessFile(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, IDiagnosticHandler diagnostics, DirectoryInfo baseDir, string file) { var fileInfo = GetFileInfo(file); if (fileInfo.Extension.Equals(".jar", StringComparison.OrdinalIgnoreCase) || fileInfo.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)) { - ProcessZipFile(context, compiler, options, file, null); + ProcessZipFile(context, compiler, options, diagnostics, file, null); } else { @@ -1325,7 +1342,7 @@ void ProcessFile(RuntimeContext context, StaticCompiler compiler, CompilerOption return; // we use stubs to add references, but otherwise ignore them - if (stub && EmitStubWarning(context, compiler, options, data)) + if (stub && EmitStubWarning(context, compiler, options, diagnostics, data)) return; options.GetClassesJar().Add(name.Replace('.', '/') + ".class", data, fileInfo); @@ -1333,13 +1350,13 @@ void ProcessFile(RuntimeContext context, StaticCompiler compiler, CompilerOption } catch (ClassFormatError x) { - IssueMessage(compiler, Message.ClassFormatError, file, x.Message); + diagnostics.ClassFormatError(file, x.Message); } } if (baseDir == null) { - IssueMessage(compiler, Message.UnknownFileType, file); + diagnostics.UnknownFileType(file); } else { @@ -1352,24 +1369,27 @@ void ProcessFile(RuntimeContext context, StaticCompiler compiler, CompilerOption } } - bool Recurse(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, DirectoryInfo baseDir, DirectoryInfo dir, string spec) + bool Recurse(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, IDiagnosticHandler diagnostics, DirectoryInfo baseDir, DirectoryInfo dir, string spec) { bool found = false; - foreach (FileInfo file in dir.GetFiles(spec)) + + foreach (var file in dir.GetFiles(spec)) { found = true; - ProcessFile(context, compiler, options, baseDir, file.FullName); + ProcessFile(context, compiler, options, diagnostics, baseDir, file.FullName); } - foreach (DirectoryInfo sub in dir.GetDirectories()) + + foreach (var sub in dir.GetDirectories()) { - found |= Recurse(context, compiler, options, baseDir, sub, spec); + found |= Recurse(context, compiler, options, diagnostics, baseDir, sub, spec); } + return found; } - bool RecurseJar(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, string path) + bool RecurseJar(RuntimeContext context, StaticCompiler compiler, CompilerOptions options, IDiagnosticHandler diagnostics, string path) { - string file = ""; + var file = ""; for (; ; ) { file = Path.Combine(Path.GetFileName(path), file); @@ -1380,14 +1400,14 @@ bool RecurseJar(RuntimeContext context, StaticCompiler compiler, CompilerOptions } else if (File.Exists(path)) { - string pathFilter = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar; - string fileFilter = "^" + Regex.Escape(Path.GetFileName(file)).Replace("\\*", ".*").Replace("\\?", ".") + "$"; - return ProcessZipFile(context, compiler, options, path, delegate (ZipArchiveEntry ze) + var pathFilter = Path.GetDirectoryName(file) + Path.DirectorySeparatorChar; + var fileFilter = "^" + Regex.Escape(Path.GetFileName(file)).Replace("\\*", ".*").Replace("\\?", ".") + "$"; + + return ProcessZipFile(context, compiler, options, diagnostics, path, delegate (ZipArchiveEntry ze) { // MONOBUG Path.GetDirectoryName() doesn't normalize / to \ on Windows - string name = ze.FullName.Replace('/', Path.DirectorySeparatorChar); - return (Path.GetDirectoryName(name) + Path.DirectorySeparatorChar).StartsWith(pathFilter) - && Regex.IsMatch(Path.GetFileName(ze.FullName), fileFilter); + var name = ze.FullName.Replace('/', Path.DirectorySeparatorChar); + return (Path.GetDirectoryName(name) + Path.DirectorySeparatorChar).StartsWith(pathFilter) && Regex.IsMatch(Path.GetFileName(ze.FullName), fileFilter); }); } } @@ -1399,9 +1419,9 @@ private static void ProcessExclusionFile(ref string[] classesToExclude, string f try { var list = classesToExclude == null ? new List() : new List(classesToExclude); - using (StreamReader file = new StreamReader(filename)) + using (var file = new StreamReader(filename)) { - String line; + string line; while ((line = file.ReadLine()) != null) { line = line.Trim(); @@ -1411,279 +1431,99 @@ private static void ProcessExclusionFile(ref string[] classesToExclude, string f } } } + classesToExclude = list.ToArray(); } catch (Exception x) { - throw new FatalCompilerErrorException(Message.ErrorReadingFile, filename, x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorReadingFile.Event([filename, x.Message])); } } - static void ProcessAttributeAnnotationsClass(RuntimeContext context, ref object[] annotations, string filename) + static void ProcessAttributeAnnotationsClass(RuntimeContext context, IDiagnosticHandler diagnostics, ref object[] annotations, string filename) { try { using var file = File.OpenRead(filename); - var cf = new IKVM.Runtime.ClassFile(context, IKVM.ByteCode.Decoding.ClassFile.Read(file), null, ClassFileParseOptions.None, null); + var cf = new IKVM.Runtime.ClassFile(context, diagnostics, IKVM.ByteCode.Decoding.ClassFile.Read(file), null, ClassFileParseOptions.None, null); ArrayAppend(ref annotations, cf.Annotations); } catch (Exception x) { - throw new FatalCompilerErrorException(Message.ErrorReadingFile, filename, x.Message); + throw new FatalCompilerErrorException(Diagnostic.ErrorReadingFile.Event([filename, x.Message])); } } - internal static void IssueMessage(StaticCompiler compiler, Message msgId, params string[] values) + /// + /// Returns true if the specified diagnostic is enabled. + /// + /// + /// + /// + bool IsDiagnosticEnabled(Diagnostic diagnostic) { - IssueMessage(compiler, compiler.rootTarget, msgId, values); + return diagnostic.Level is not DiagnosticLevel.Trace and not DiagnosticLevel.Informational; } - internal static void IssueMessage(StaticCompiler compiler, CompilerOptions options, Message msgId, params string[] values) + /// + /// Handles a . + /// + /// + /// + /// + void ReportEvent(CompilerOptions options, in DiagnosticEvent evt) { - if (compiler.errorCount != 0 && msgId < Message.StartErrors && !options.warnaserror) - { - // don't display any warnings after we've emitted an error message + if (evt.Diagnostic.Level is DiagnosticLevel.Trace or DiagnosticLevel.Informational) return; - } - string key = ((int)msgId).ToString(); + var key = evt.Diagnostic.Id.ToString(); for (int i = 0; ; i++) { if (options.suppressWarnings.ContainsKey(key)) - { return; - } - if (i == values.Length) - { + + if (i == evt.Args.Length) break; - } - key += ":" + values[i]; + + key += ":" + evt.Args[i]; } + options.suppressWarnings.Add(key, key); if (options.writeSuppressWarningsFile != null) - { File.AppendAllText(options.writeSuppressWarningsFile.FullName, "-nowarn:" + key + Environment.NewLine); - } - string msg; - switch (msgId) - { - case Message.MainMethodFound: - msg = "Found main method in class \"{0}\""; - break; - case Message.OutputFileIs: - msg = "Output file is \"{0}\""; - break; - case Message.AutoAddRef: - msg = "Automatically adding reference to \"{0}\""; - break; - case Message.MainMethodFromManifest: - msg = "Using main class \"{0}\" based on jar manifest"; - break; - case Message.ClassNotFound: - msg = "Class \"{0}\" not found"; - break; - case Message.ClassFormatError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (class format error \"{1}\")"; - break; - case Message.DuplicateClassName: - msg = "Duplicate class name: \"{0}\""; - break; - case Message.IllegalAccessError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (illegal access error \"{1}\")"; - break; - case Message.VerificationError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (verification error \"{1}\")"; - break; - case Message.NoClassDefFoundError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (missing class \"{1}\")"; - break; - case Message.GenericUnableToCompileError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (\"{1}\": \"{2}\")"; - break; - case Message.DuplicateResourceName: - msg = "Skipping resource (name clash): \"{0}\""; - break; - case Message.SkippingReferencedClass: - msg = "Skipping class: \"{0}\"" + Environment.NewLine + - " (class is already available in referenced assembly \"{1}\")"; - break; - case Message.NoJniRuntime: - msg = "Unable to load runtime JNI assembly"; - break; - case Message.EmittedNoClassDefFoundError: - msg = "Emitted java.lang.NoClassDefFoundError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedIllegalAccessError: - msg = "Emitted java.lang.IllegalAccessError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedInstantiationError: - msg = "Emitted java.lang.InstantiationError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedIncompatibleClassChangeError: - msg = "Emitted java.lang.IncompatibleClassChangeError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedNoSuchFieldError: - msg = "Emitted java.lang.NoSuchFieldError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedAbstractMethodError: - msg = "Emitted java.lang.AbstractMethodError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedNoSuchMethodError: - msg = "Emitted java.lang.NoSuchMethodError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedLinkageError: - msg = "Emitted java.lang.LinkageError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedVerificationError: - msg = "Emitted java.lang.VerificationError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedClassFormatError: - msg = "Emitted java.lang.ClassFormatError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.InvalidCustomAttribute: - msg = "Error emitting \"{0}\" custom attribute" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.IgnoredCustomAttribute: - msg = "Custom attribute \"{0}\" was ignored" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.AssumeAssemblyVersionMatch: - msg = "Assuming assembly reference \"{0}\" matches \"{1}\", you may need to supply runtime policy"; - break; - case Message.InvalidDirectoryInLibOptionPath: - msg = "Directory \"{0}\" specified in -lib option is not valid"; - break; - case Message.InvalidDirectoryInLibEnvironmentPath: - msg = "Directory \"{0}\" specified in LIB environment is not valid"; - break; - case Message.LegacySearchRule: - msg = "Found assembly \"{0}\" using legacy search rule, please append '.dll' to the reference"; - break; - case Message.AssemblyLocationIgnored: - msg = "Assembly \"{0}\" is ignored as previously loaded assembly \"{1}\" has the same identity \"{2}\""; - break; - case Message.InterfaceMethodCantBeInternal: - msg = "Ignoring @ikvm.lang.Internal annotation on interface method" + Environment.NewLine + - " (\"{0}.{1}{2}\")"; - break; - case Message.NonPrimaryAssemblyReference: - msg = "Referenced assembly \"{0}\" is not the primary assembly of a shared class loader group, please reference primary assembly \"{1}\" instead"; - break; - case Message.MissingType: - msg = "Reference to type \"{0}\" claims it is defined in \"{1}\", but it could not be found"; - break; - case Message.MissingReference: - msg = "The type '{0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{1}'"; - break; - case Message.DuplicateAssemblyReference: - msg = "Duplicate assembly reference \"{0}\""; - break; - case Message.UnableToResolveType: - msg = "Reference in \"{0}\" to type \"{1}\" claims it is defined in \"{2}\", but it could not be found"; - break; - case Message.StubsAreDeprecated: - msg = "Compiling stubs is deprecated. Please add a reference to assembly \"{0}\" instead."; - break; - case Message.WrongClassName: - msg = "Unable to compile \"{0}\" (wrong name: \"{1}\")"; - break; - case Message.ReflectionCallerClassRequiresCallerID: - msg = "Reflection.getCallerClass() called from non-CallerID method" + Environment.NewLine + - " (\"{0}.{1}{2}\")"; - break; - case Message.LegacyAssemblyAttributesFound: - msg = "Legacy assembly attributes container found. Please use the -assemblyattributes: option."; - break; - case Message.UnableToCreateLambdaFactory: - msg = "Unable to create static lambda factory."; - break; - case Message.UnableToCreateProxy: - msg = "Unable to create proxy \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.DuplicateProxy: - msg = "Duplicate proxy \"{0}\""; - break; - case Message.MapXmlUnableToResolveOpCode: - msg = "Unable to resolve opcode in remap file: {0}"; - break; - case Message.MapXmlError: - msg = "Error in remap file: {0}"; - break; - case Message.InputFileNotFound: - msg = "Source file '{0}' not found"; - break; - case Message.UnknownFileType: - msg = "Unknown file type: {0}"; - break; - case Message.UnknownElementInMapFile: - msg = "Unknown element {0} in remap file, line {1}, column {2}"; - break; - case Message.UnknownAttributeInMapFile: - msg = "Unknown attribute {0} in remap file, line {1}, column {2}"; - break; - case Message.InvalidMemberNameInMapFile: - msg = "Invalid {0} name '{1}' in remap file in class {2}"; - break; - case Message.InvalidMemberSignatureInMapFile: - msg = "Invalid {0} signature '{3}' in remap file for {0} {1}.{2}"; - break; - case Message.InvalidPropertyNameInMapFile: - msg = "Invalid property {0} name '{3}' in remap file for property {1}.{2}"; - break; - case Message.InvalidPropertySignatureInMapFile: - msg = "Invalid property {0} signature '{3}' in remap file for property {1}.{2}"; - break; - case Message.UnknownWarning: - msg = "{0}"; - break; - case Message.CallerSensitiveOnUnsupportedMethod: - msg = "CallerSensitive annotation on unsupported method" + Environment.NewLine + - " (\"{0}.{1}{2}\")"; - break; - case Message.RemappedTypeMissingDefaultInterfaceMethod: - msg = "{0} does not implement default interface method {1}"; - break; - default: - throw new InvalidProgramException(); - } - bool error = msgId >= Message.StartErrors - || (options.warnaserror && msgId >= Message.StartWarnings) - || options.errorWarnings.ContainsKey(key) - || options.errorWarnings.ContainsKey(((int)msgId).ToString()); - Console.Error.Write("{0} IKVMC{1:D4}: ", error ? "error" : msgId < Message.StartWarnings ? "note" : "warning", (int)msgId); - if (error && Message.StartWarnings <= msgId && msgId < Message.StartErrors) - { - Console.Error.Write("Warning as Error: "); - } - Console.Error.WriteLine(msg, values); - if (options != compiler.rootTarget && options.path != null) - { - Console.Error.WriteLine(" (in {0})", options.path); - } - if (error) - { - if (++compiler.errorCount == 100) - { - throw new FatalCompilerErrorException(Message.MaximumErrorCountReached); - } - } + +#if NET8_0_OR_GREATER + var msg = evt.Diagnostic.Message.Format; +#else + var msg = evt.Diagnostic.Message; +#endif + // choose output channel + var dst = evt.Diagnostic.Level is DiagnosticLevel.Fatal or DiagnosticLevel.Error or DiagnosticLevel.Warning ? Console.Error : Console.Out; + + // write tag + dst.Write(evt.Diagnostic.Level switch + { + DiagnosticLevel.Trace => "trace", + DiagnosticLevel.Informational => "info", + DiagnosticLevel.Warning when options.errorWarnings.ContainsKey(key) || options.errorWarnings.ContainsKey(evt.Diagnostic.Id.ToString()) => "error", + DiagnosticLevel.Warning => "warning", + DiagnosticLevel.Error => "error", + DiagnosticLevel.Fatal => "error", + _ => throw new InvalidOperationException(), + }); + + // write event ID + dst.Write($"IKVM{evt.Diagnostic.Id:D4}: "); + + // write message +#if NET8_0_OR_GREATER + dst.Write(string.Format(null, evt.Diagnostic.Message, evt.Args)); +#else + dst.Write(string.Format(null, evt.Diagnostic.Message, evt.Args.ToArray())); +#endif + + // end of line, potentially containing option path + dst.WriteLine(options.path != null ? $" (in {options.path})" : ""); } } diff --git a/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs b/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs index b342906e36..57aa18b150 100644 --- a/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs +++ b/src/IKVM.Tools.Importer/MapXml/Ldtoken.cs @@ -25,6 +25,7 @@ Jeroen Frijters using System; using System.Xml.Linq; +using IKVM.CoreLib.Diagnostics; using IKVM.Reflection; using IKVM.Reflection.Emit; using IKVM.Runtime; @@ -106,7 +107,7 @@ internal override void Generate(CodeGenContext context, CodeEmitter ilgen) } else { - context.ClassLoader.Context.StaticCompiler.IssueMessage(Message.MapXmlUnableToResolveOpCode, ToString()); + context.ClassLoader.Diagnostics.MapXmlUnableToResolveOpCode(ToString()); } } @@ -116,7 +117,7 @@ private bool Validate(CodeGenContext context) { if (Method != null || Field != null || Sig != null) { - context.ClassLoader.Context.StaticCompiler.IssueMessage(Message.MapXmlError, "not implemented: cannot use 'type' attribute with 'method' or 'field' attribute for ldtoken"); + context.ClassLoader.Diagnostics.MapXmlError("not implemented: cannot use 'type' attribute with 'method' or 'field' attribute for ldtoken"); return false; } return true; @@ -127,20 +128,20 @@ private bool Validate(CodeGenContext context) { if (Sig != null) { - context.ClassLoader.Context.StaticCompiler.IssueMessage(Message.MapXmlError, "cannot specify 'sig' attribute without either 'method' or 'field' attribute for ldtoken"); + context.ClassLoader.Diagnostics.MapXmlError("cannot specify 'sig' attribute without either 'method' or 'field' attribute for ldtoken"); } return true; } if (Method != null && Field != null) { - context.ClassLoader.Context.StaticCompiler.IssueMessage(Message.MapXmlError, "cannot specify both 'method' and 'field' attribute for ldtoken"); + context.ClassLoader.Diagnostics.MapXmlError("cannot specify both 'method' and 'field' attribute for ldtoken"); return false; } return true; } else { - context.ClassLoader.Context.StaticCompiler.IssueMessage(Message.MapXmlError, "must specify either 'type' or 'class' attribute for ldtoken"); + context.ClassLoader.Diagnostics.MapXmlError("must specify either 'type' or 'class' attribute for ldtoken"); return false; } } diff --git a/src/IKVM.Tools.Importer/Message.cs b/src/IKVM.Tools.Importer/Message.cs deleted file mode 100644 index dc5c93409a..0000000000 --- a/src/IKVM.Tools.Importer/Message.cs +++ /dev/null @@ -1,135 +0,0 @@ -namespace IKVM.Tools.Importer -{ - - internal enum Message - { - - // These are the informational messages - MainMethodFound = 1, - OutputFileIs = 2, - AutoAddRef = 3, - MainMethodFromManifest = 4, - // This is were the warnings start - StartWarnings = 100, - ClassNotFound = 100, - ClassFormatError = 101, - DuplicateClassName = 102, - IllegalAccessError = 103, - VerificationError = 104, - NoClassDefFoundError = 105, - GenericUnableToCompileError = 106, - DuplicateResourceName = 107, - SkippingReferencedClass = 109, - NoJniRuntime = 110, - EmittedNoClassDefFoundError = 111, - EmittedIllegalAccessError = 112, - EmittedInstantiationError = 113, - EmittedIncompatibleClassChangeError = 114, - EmittedNoSuchFieldError = 115, - EmittedAbstractMethodError = 116, - EmittedNoSuchMethodError = 117, - EmittedLinkageError = 118, - EmittedVerificationError = 119, - EmittedClassFormatError = 120, - InvalidCustomAttribute = 121, - IgnoredCustomAttribute = 122, - AssumeAssemblyVersionMatch = 123, - InvalidDirectoryInLibOptionPath = 124, - InvalidDirectoryInLibEnvironmentPath = 125, - LegacySearchRule = 126, - AssemblyLocationIgnored = 127, - InterfaceMethodCantBeInternal = 128, - DuplicateAssemblyReference = 132, - UnableToResolveType = 133, - StubsAreDeprecated = 134, - WrongClassName = 135, - ReflectionCallerClassRequiresCallerID = 136, - LegacyAssemblyAttributesFound = 137, - UnableToCreateLambdaFactory = 138, - UnknownWarning = 999, - // This is where the errors start - StartErrors = 4000, - UnableToCreateProxy = 4001, - DuplicateProxy = 4002, - MapXmlUnableToResolveOpCode = 4003, - MapXmlError = 4004, - InputFileNotFound = 4005, - UnknownFileType = 4006, - UnknownElementInMapFile = 4007, - UnknownAttributeInMapFile = 4008, - InvalidMemberNameInMapFile = 4009, - InvalidMemberSignatureInMapFile = 4010, - InvalidPropertyNameInMapFile = 4011, - InvalidPropertySignatureInMapFile = 4012, - NonPrimaryAssemblyReference = 4013, - MissingType = 4014, - MissingReference = 4015, - CallerSensitiveOnUnsupportedMethod = 4016, - RemappedTypeMissingDefaultInterfaceMethod = 4017, - // Fatal errors - ResponseFileDepthExceeded = 5000, - ErrorReadingFile = 5001, - NoTargetsFound = 5002, - FileFormatLimitationExceeded = 5003, - CannotSpecifyBothKeyFileAndContainer = 5004, - DelaySignRequiresKey = 5005, - InvalidStrongNameKeyPair = 5006, - ReferenceNotFound = 5007, - OptionsMustPreceedChildLevels = 5008, - UnrecognizedTargetType = 5009, - UnrecognizedPlatform = 5010, - UnrecognizedApartment = 5011, - MissingFileSpecification = 5012, - PathTooLong = 5013, - PathNotFound = 5014, - InvalidPath = 5015, - InvalidOptionSyntax = 5016, - ExternalResourceNotFound = 5017, - ExternalResourceNameInvalid = 5018, - InvalidVersionFormat = 5019, - InvalidFileAlignment = 5020, - ErrorWritingFile = 5021, - UnrecognizedOption = 5022, - NoOutputFileSpecified = 5023, - SharedClassLoaderCannotBeUsedOnModuleTarget = 5024, - RuntimeNotFound = 5025, - MainClassRequiresExe = 5026, - ExeRequiresMainClass = 5027, - PropertiesRequireExe = 5028, - ModuleCannotHaveClassLoader = 5029, - ErrorParsingMapFile = 5030, - BootstrapClassesMissing = 5031, - StrongNameRequiresStrongNamedRefs = 5032, - MainClassNotFound = 5033, - MainMethodNotFound = 5034, - UnsupportedMainMethod = 5035, - ExternalMainNotAccessible = 5036, - ClassLoaderNotFound = 5037, - ClassLoaderNotAccessible = 5038, - ClassLoaderIsAbstract = 5039, - ClassLoaderNotClassLoader = 5040, - ClassLoaderConstructorMissing = 5041, - MapFileTypeNotFound = 5042, - MapFileClassNotFound = 5043, - MaximumErrorCountReached = 5044, - LinkageError = 5045, - RuntimeMismatch = 5046, - RuntimeMismatchStrongName = 5047, - CoreClassesMissing = 5048, - CriticalClassNotFound = 5049, - AssemblyContainsDuplicateClassNames = 5050, - CallerIDRequiresHasCallerIDAnnotation = 5051, - UnableToResolveInterface = 5052, - MissingBaseType = 5053, - MissingBaseTypeReference = 5054, - FileNotFound = 5055, - RuntimeMethodMissing = 5056, - MapFileFieldNotFound = 5057, - GhostInterfaceMethodMissing = 5058, - - // ModuleInitializer attribute placed on inappropriate method - ModuleInitializerMethodRequirements = 5059, - - } - -} diff --git a/src/IKVM.Tools.Importer/Proxy.cs b/src/IKVM.Tools.Importer/Proxy.cs index 47824dfdb2..69e0fa567e 100644 --- a/src/IKVM.Tools.Importer/Proxy.cs +++ b/src/IKVM.Tools.Importer/Proxy.cs @@ -25,6 +25,7 @@ Jeroen Frijters using System.Collections.Generic; using IKVM.Attributes; +using IKVM.CoreLib.Diagnostics; using IKVM.Reflection; using IKVM.Reflection.Emit; using IKVM.Runtime; @@ -104,7 +105,7 @@ internal void Create(CompilerClassLoader loader, string proxy) if (wrappers[i] == null) { - loader.Context.StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, "unable to load interface " + interfaces[i]); + loader.Diagnostics.UnableToCreateProxy(proxy, "unable to load interface " + interfaces[i]); return; } } @@ -121,12 +122,12 @@ private void Create(CompilerClassLoader loader, string proxy, RuntimeJavaType[] } catch (RetargetableJavaException x) { - loader.Context.StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, x.Message); + loader.Diagnostics.UnableToCreateProxy(proxy, x.Message); return; } catch (ProxyException x) { - loader.Context.StaticCompiler.IssueMessage(Message.UnableToCreateProxy, proxy, x.Message); + loader.Diagnostics.UnableToCreateProxy(proxy, x.Message); return; } diff --git a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs index db78dd01d2..b70b876571 100644 --- a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs +++ b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs @@ -26,6 +26,7 @@ Jeroen Frijters using System.Collections.Generic; using IKVM.Attributes; +using IKVM.CoreLib.Diagnostics; using IKVM.Reflection; using IKVM.Reflection.Emit; using IKVM.Runtime; @@ -270,8 +271,8 @@ private void PublishProperties(TypeBuilder typeBuilder, Class clazz) { foreach (var prop in clazz.Properties) { - var typeWrapper = GetClassLoader().RetTypeWrapperFromSig(prop.Sig, LoadMode.Link); - var propargs = GetClassLoader().ArgJavaTypeListFromSig(prop.Sig, LoadMode.Link); + var typeWrapper = ClassLoader.RetTypeWrapperFromSig(prop.Sig, LoadMode.Link); + var propargs = ClassLoader.ArgJavaTypeListFromSig(prop.Sig, LoadMode.Link); Type[] indexer = new Type[propargs.Length]; for (int i = 0; i < propargs.Length; i++) { @@ -448,8 +449,8 @@ private static void MapModifiers(MapModifiers mapmods, bool isConstructor, out b private void MapSignature(string sig, out Type returnType, out Type[] parameterTypes) { - returnType = GetClassLoader().RetTypeWrapperFromSig(sig, LoadMode.Link).TypeAsSignatureType; - var parameterTypeWrappers = GetClassLoader().ArgJavaTypeListFromSig(sig, LoadMode.Link); + returnType = ClassLoader.RetTypeWrapperFromSig(sig, LoadMode.Link).TypeAsSignatureType; + var parameterTypeWrappers = ClassLoader.ArgJavaTypeListFromSig(sig, LoadMode.Link); parameterTypes = new Type[parameterTypeWrappers.Length]; for (int i = 0; i < parameterTypeWrappers.Length; i++) { @@ -562,7 +563,7 @@ protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile cl if (method.Override != null) { - var mw = GetClassLoader().LoadClassByName(method.Override.Class).GetMethodWrapper(method.Override.Name, method.Sig, true); + var mw = ClassLoader.LoadClassByName(method.Override.Class).GetMethodWrapper(method.Override.Name, method.Sig, true); mw.Link(); typeBuilder.DefineMethodOverride(mb, (MethodInfo)mw.GetMethod()); } @@ -606,7 +607,7 @@ protected override void EmitMapXmlMetadata(TypeBuilder typeBuilder, ClassFile cl { foreach (Implements iface in clazz.Interfaces) { - var tw = GetClassLoader().LoadClassByName(iface.Class); + var tw = ClassLoader.LoadClassByName(iface.Class); // NOTE since this interface won't be part of the list in the ImplementAttribute, // it won't be visible from Java that the type implements this interface. typeBuilder.AddInterfaceImplementation(tw.TypeAsBaseType); @@ -689,7 +690,7 @@ protected override void FinishGhost(TypeBuilder typeBuilder, RuntimeJavaMethod[] if (methods[i].IsAbstract) { // This should only happen for remapped types (defined in map.xml), because normally you'd get a miranda method. - throw new FatalCompilerErrorException(Message.GhostInterfaceMethodMissing, implementers[j].Name, Name, methods[i].Name, methods[i].Signature); + throw new FatalCompilerErrorException(Diagnostic.GhostInterfaceMethodMissing.Event([implementers[j].Name, Name, methods[i].Name, methods[i].Signature])); } // We're inheriting a default method ilgen.Emit(OpCodes.Pop); @@ -1059,7 +1060,7 @@ protected override void DoLinkMethod() private void DoEmit(CodeEmitter ilgen) { - var context = new IKVM.Tools.Importer.MapXml.CodeGenContext(this.DeclaringType.GetClassLoader()); + var context = new IKVM.Tools.Importer.MapXml.CodeGenContext(DeclaringType.ClassLoader); // we don't want the line numbers from map.xml, so we have our own emit loop for (int i = 0; i < code.Instructions.Length; i++) code.Instructions[i].Generate(context, ilgen); @@ -1084,7 +1085,7 @@ internal override void EmitNewobj(CodeEmitter ilgen) internal override RuntimeJavaMethod[] GetReplacedMethodsFor(RuntimeJavaMethod mw) { - var replacedMethods = ((CompilerClassLoader)GetClassLoader()).GetReplacedMethodsFor(mw); + var replacedMethods = ((CompilerClassLoader)ClassLoader).GetReplacedMethodsFor(mw); var baseReplacedMethodWrappers = base.GetReplacedMethodsFor(mw); if (replacedMethods != null || baseReplacedMethodWrappers != null || this.replacedMethods != null) { @@ -1092,7 +1093,7 @@ internal override RuntimeJavaMethod[] GetReplacedMethodsFor(RuntimeJavaMethod mw if (replacedMethods != null) for (int i = 0; i < replacedMethods.Length; i++) - list.Add(new ReplacedMethodWrapper(GetClassLoader().LoadClassByName(replacedMethods[i].Class), replacedMethods[i].Name, replacedMethods[i].Sig, replacedMethods[i].Code)); + list.Add(new ReplacedMethodWrapper(ClassLoader.LoadClassByName(replacedMethods[i].Class), replacedMethods[i].Name, replacedMethods[i].Sig, replacedMethods[i].Code)); if (baseReplacedMethodWrappers != null) list.AddRange(baseReplacedMethodWrappers); diff --git a/src/IKVM.Tools.Importer/StaticCompiler.cs b/src/IKVM.Tools.Importer/StaticCompiler.cs index bfc78180af..215cfafeb1 100644 --- a/src/IKVM.Tools.Importer/StaticCompiler.cs +++ b/src/IKVM.Tools.Importer/StaticCompiler.cs @@ -29,6 +29,7 @@ Jeroen Frijters using System.Reflection.Metadata; using System.Reflection.PortableExecutable; +using IKVM.CoreLib.Diagnostics; using IKVM.Reflection; using IKVM.Reflection.Diagnostics; using IKVM.Runtime; @@ -43,6 +44,7 @@ class StaticCompiler readonly ConcurrentDictionary runtimeTypeCache = new(); + readonly IDiagnosticHandler diagnostics; internal Universe universe; internal Assembly runtimeAssembly; internal Assembly baseAssembly; @@ -51,6 +53,15 @@ class StaticCompiler internal Universe Universe => universe; + /// + /// Initializes a new instance. + /// + /// + public StaticCompiler(IDiagnosticHandler diagnostics) + { + this.diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); + } + /// /// Initializes the universe. /// @@ -142,7 +153,7 @@ void ResolvedMissingMember(Module requestingModule, MemberInfo member) { if (requestingModule != null && member is Type) { - IssueMessage(Message.UnableToResolveType, requestingModule.Name, ((Type)member).FullName, member.Module.FullyQualifiedName); + diagnostics.UnableToResolveType(requestingModule.Name, ((Type)member).FullName, member.Module.FullyQualifiedName); } } @@ -167,19 +178,19 @@ internal Type GetRuntimeType(string name) internal Type GetTypeForMapXml(RuntimeClassLoader loader, string name) { - return GetType(loader, name) ?? throw new FatalCompilerErrorException(Message.MapFileTypeNotFound, name); + return GetType(loader, name) ?? throw new FatalCompilerErrorException(Diagnostic.MapFileTypeNotFound.Event([name])); } internal RuntimeJavaType GetClassForMapXml(RuntimeClassLoader loader, string name) { - return loader.TryLoadClassByName(name) ?? throw new FatalCompilerErrorException(Message.MapFileClassNotFound, name); + return loader.TryLoadClassByName(name) ?? throw new FatalCompilerErrorException(Diagnostic.MapFileClassNotFound.Event([name])); } internal RuntimeJavaField GetFieldForMapXml(RuntimeClassLoader loader, string clazz, string name, string sig) { var fw = GetClassForMapXml(loader, clazz).GetFieldWrapper(name, sig); if (fw == null) - throw new FatalCompilerErrorException(Message.MapFileFieldNotFound, name, clazz); + throw new FatalCompilerErrorException(Diagnostic.MapFileFieldNotFound.Event([name, clazz])); fw.Link(); return fw; @@ -203,287 +214,35 @@ internal static void LinkageError(string msg, RuntimeJavaType actualType, Runtim str += string.Format("\n\t(Please add a reference to {0})", expectedType.TypeAsBaseType.Assembly.Location); } - throw new FatalCompilerErrorException(Message.LinkageError, str); + throw new FatalCompilerErrorException(Diagnostic.LinkageError.Event([str])); } - static string AssemblyQualifiedName(RuntimeJavaType tw) + static string AssemblyQualifiedName(RuntimeJavaType javaType) { - RuntimeClassLoader loader = tw.GetClassLoader(); - RuntimeAssemblyClassLoader acl = loader as RuntimeAssemblyClassLoader; + var loader = javaType.ClassLoader; + var acl = loader as RuntimeAssemblyClassLoader; if (acl != null) - { - return tw.Name + ", " + acl.GetAssembly(tw).FullName; - } - CompilerClassLoader ccl = loader as CompilerClassLoader; + return javaType.Name + ", " + acl.GetAssembly(javaType).FullName; + + var ccl = loader as CompilerClassLoader; if (ccl != null) - { - return tw.Name + ", " + ccl.GetTypeWrapperFactory().ModuleBuilder.Assembly.FullName; - } - return tw.Name + " (unknown assembly)"; + return javaType.Name + ", " + ccl.GetTypeWrapperFactory().ModuleBuilder.Assembly.FullName; + + return javaType.Name + " (unknown assembly)"; } internal void IssueMissingTypeMessage(Type type) { type = ReflectUtil.GetMissingType(type); - IssueMessage(type.Assembly.__IsMissing ? Message.MissingReference : Message.MissingType, type.FullName, type.Assembly.FullName); - } - - internal void SuppressWarning(CompilerOptions options, Message message, string name) - { - options.suppressWarnings[(int)message + ":" + name] = null; - } - - internal void IssueMessage(Message msgId, params string[] values) - { - IssueMessage(rootTarget, msgId, values); + if (type.Assembly.__IsMissing) + diagnostics.MissingReference(type.FullName, type.Assembly.FullName); + else + diagnostics.MissingType(type.FullName, type.Assembly.FullName); } - internal void IssueMessage(CompilerOptions options, Message msgId, params string[] values) + internal void SuppressWarning(CompilerOptions options, Diagnostic diagnostic, string name) { - if (errorCount != 0 && msgId < Message.StartErrors && !options.warnaserror) - { - // don't display any warnings after we've emitted an error message - return; - } - - string key = ((int)msgId).ToString(); - for (int i = 0; ; i++) - { - if (options.suppressWarnings.ContainsKey(key)) - { - return; - } - if (i == values.Length) - { - break; - } - key += ":" + values[i]; - } - options.suppressWarnings.Add(key, key); - if (options.writeSuppressWarningsFile != null) - { - File.AppendAllText(options.writeSuppressWarningsFile.FullName, "-nowarn:" + key + Environment.NewLine); - } - string msg; - switch (msgId) - { - case Message.MainMethodFound: - msg = "Found main method in class \"{0}\""; - break; - case Message.OutputFileIs: - msg = "Output file is \"{0}\""; - break; - case Message.AutoAddRef: - msg = "Automatically adding reference to \"{0}\""; - break; - case Message.MainMethodFromManifest: - msg = "Using main class \"{0}\" based on jar manifest"; - break; - case Message.ClassNotFound: - msg = "Class \"{0}\" not found"; - break; - case Message.ClassFormatError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (class format error \"{1}\")"; - break; - case Message.DuplicateClassName: - msg = "Duplicate class name: \"{0}\""; - break; - case Message.IllegalAccessError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (illegal access error \"{1}\")"; - break; - case Message.VerificationError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (verification error \"{1}\")"; - break; - case Message.NoClassDefFoundError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (missing class \"{1}\")"; - break; - case Message.GenericUnableToCompileError: - msg = "Unable to compile class \"{0}\"" + Environment.NewLine + - " (\"{1}\": \"{2}\")"; - break; - case Message.DuplicateResourceName: - msg = "Skipping resource (name clash): \"{0}\""; - break; - case Message.SkippingReferencedClass: - msg = "Skipping class: \"{0}\"" + Environment.NewLine + - " (class is already available in referenced assembly \"{1}\")"; - break; - case Message.NoJniRuntime: - msg = "Unable to load runtime JNI assembly"; - break; - case Message.EmittedNoClassDefFoundError: - msg = "Emitted java.lang.NoClassDefFoundError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedIllegalAccessError: - msg = "Emitted java.lang.IllegalAccessError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedInstantiationError: - msg = "Emitted java.lang.InstantiationError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedIncompatibleClassChangeError: - msg = "Emitted java.lang.IncompatibleClassChangeError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedNoSuchFieldError: - msg = "Emitted java.lang.NoSuchFieldError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedAbstractMethodError: - msg = "Emitted java.lang.AbstractMethodError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedNoSuchMethodError: - msg = "Emitted java.lang.NoSuchMethodError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedLinkageError: - msg = "Emitted java.lang.LinkageError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedVerificationError: - msg = "Emitted java.lang.VerificationError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.EmittedClassFormatError: - msg = "Emitted java.lang.ClassFormatError in \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.InvalidCustomAttribute: - msg = "Error emitting \"{0}\" custom attribute" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.IgnoredCustomAttribute: - msg = "Custom attribute \"{0}\" was ignored" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.AssumeAssemblyVersionMatch: - msg = "Assuming assembly reference \"{0}\" matches \"{1}\", you may need to supply runtime policy"; - break; - case Message.InvalidDirectoryInLibOptionPath: - msg = "Directory \"{0}\" specified in -lib option is not valid"; - break; - case Message.InvalidDirectoryInLibEnvironmentPath: - msg = "Directory \"{0}\" specified in LIB environment is not valid"; - break; - case Message.LegacySearchRule: - msg = "Found assembly \"{0}\" using legacy search rule, please append '.dll' to the reference"; - break; - case Message.AssemblyLocationIgnored: - msg = "Assembly \"{0}\" is ignored as previously loaded assembly \"{1}\" has the same identity \"{2}\""; - break; - case Message.InterfaceMethodCantBeInternal: - msg = "Ignoring @ikvm.lang.Internal annotation on interface method" + Environment.NewLine + - " (\"{0}.{1}{2}\")"; - break; - case Message.NonPrimaryAssemblyReference: - msg = "Referenced assembly \"{0}\" is not the primary assembly of a shared class loader group, please reference primary assembly \"{1}\" instead"; - break; - case Message.MissingType: - msg = "Reference to type \"{0}\" claims it is defined in \"{1}\", but it could not be found"; - break; - case Message.MissingReference: - msg = "The type '{0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{1}'"; - break; - case Message.DuplicateAssemblyReference: - msg = "Duplicate assembly reference \"{0}\""; - break; - case Message.UnableToResolveType: - msg = "Reference in \"{0}\" to type \"{1}\" claims it is defined in \"{2}\", but it could not be found"; - break; - case Message.StubsAreDeprecated: - msg = "Compiling stubs is deprecated. Please add a reference to assembly \"{0}\" instead."; - break; - case Message.WrongClassName: - msg = "Unable to compile \"{0}\" (wrong name: \"{1}\")"; - break; - case Message.ReflectionCallerClassRequiresCallerID: - msg = "Reflection.getCallerClass() called from non-CallerID method" + Environment.NewLine + - " (\"{0}.{1}{2}\")"; - break; - case Message.LegacyAssemblyAttributesFound: - msg = "Legacy assembly attributes container found. Please use the -assemblyattributes: option."; - break; - case Message.UnableToCreateLambdaFactory: - msg = "Unable to create static lambda factory."; - break; - case Message.UnableToCreateProxy: - msg = "Unable to create proxy \"{0}\"" + Environment.NewLine + - " (\"{1}\")"; - break; - case Message.DuplicateProxy: - msg = "Duplicate proxy \"{0}\""; - break; - case Message.MapXmlUnableToResolveOpCode: - msg = "Unable to resolve opcode in remap file: {0}"; - break; - case Message.MapXmlError: - msg = "Error in remap file: {0}"; - break; - case Message.InputFileNotFound: - msg = "Source file '{0}' not found"; - break; - case Message.UnknownFileType: - msg = "Unknown file type: {0}"; - break; - case Message.UnknownElementInMapFile: - msg = "Unknown element {0} in remap file, line {1}, column {2}"; - break; - case Message.UnknownAttributeInMapFile: - msg = "Unknown attribute {0} in remap file, line {1}, column {2}"; - break; - case Message.InvalidMemberNameInMapFile: - msg = "Invalid {0} name '{1}' in remap file in class {2}"; - break; - case Message.InvalidMemberSignatureInMapFile: - msg = "Invalid {0} signature '{3}' in remap file for {0} {1}.{2}"; - break; - case Message.InvalidPropertyNameInMapFile: - msg = "Invalid property {0} name '{3}' in remap file for property {1}.{2}"; - break; - case Message.InvalidPropertySignatureInMapFile: - msg = "Invalid property {0} signature '{3}' in remap file for property {1}.{2}"; - break; - case Message.UnknownWarning: - msg = "{0}"; - break; - case Message.CallerSensitiveOnUnsupportedMethod: - msg = "CallerSensitive annotation on unsupported method" + Environment.NewLine + - " (\"{0}.{1}{2}\")"; - break; - case Message.RemappedTypeMissingDefaultInterfaceMethod: - msg = "{0} does not implement default interface method {1}"; - break; - default: - throw new InvalidProgramException(); - } - bool error = msgId >= Message.StartErrors - || (options.warnaserror && msgId >= Message.StartWarnings) - || options.errorWarnings.ContainsKey(key) - || options.errorWarnings.ContainsKey(((int)msgId).ToString()); - Console.Error.Write("{0} IKVMC{1:D4}: ", error ? "error" : msgId < Message.StartWarnings ? "note" : "warning", (int)msgId); - if (error && Message.StartWarnings <= msgId && msgId < Message.StartErrors) - { - Console.Error.Write("Warning as Error: "); - } - Console.Error.WriteLine(msg, values); - if (options != this.rootTarget && options.path != null) - { - Console.Error.WriteLine(" (in {0})", options.path); - } - if (error) - { - if (++errorCount == 100) - { - throw new FatalCompilerErrorException(Message.MaximumErrorCountReached); - } - } + options.suppressWarnings[diagnostic.Id + ":" + name] = null; } }