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
+
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;
}
}