// dnlib: See LICENSE.txt for more info
using System;
using System.Reflection;
using dnlib.DotNet.Writer;
namespace dnlib.DotNet {
///
/// events
///
public enum LoggerEvent {
///
/// An error was detected. An exception should normally be thrown but the error
/// can be ignored.
///
Error,
///
/// Just a warning and can be ignored.
///
Warning,
///
/// A normal message
///
Info,
///
/// A verbose message
///
Verbose,
///
/// A very verbose message
///
VeryVerbose,
}
///
/// Simple logger
///
public interface ILogger {
///
/// Log something
///
/// Caller or null
/// Logger event
/// Format
/// Arguments
void Log(object sender, LoggerEvent loggerEvent, string format, params object[] args);
///
/// true if this event is ignored. If the event is ignored, the caller can
/// choose not to call . This is useful if it can take time to
/// prepare the message.
///
/// The logger event
bool IgnoresEvent(LoggerEvent loggerEvent);
}
public static partial class Extensions {
///
/// Log an error message
///
/// this
/// Sender or null
/// Message
public static void Error(this ILogger logger, object sender, string message) =>
logger.Log(sender, LoggerEvent.Error, "{0}", message);
///
/// Log an error message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
public static void Error(this ILogger logger, object sender, string message, object arg1) =>
logger.Log(sender, LoggerEvent.Error, message, arg1);
///
/// Log an error message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2) =>
logger.Log(sender, LoggerEvent.Error, message, arg1, arg2);
///
/// Log an error message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) =>
logger.Log(sender, LoggerEvent.Error, message, arg1, arg2, arg3);
///
/// Log an error message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
/// Message arg #4
public static void Error(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) =>
logger.Log(sender, LoggerEvent.Error, message, arg1, arg2, arg3, arg4);
///
/// Log an error message
///
/// this
/// Sender or null
/// Message
/// Message arguments
public static void Error(this ILogger logger, object sender, string message, params object[] args) =>
logger.Log(sender, LoggerEvent.Error, message, args);
///
/// Log a warning message
///
/// this
/// Sender or null
/// Message
public static void Warning(this ILogger logger, object sender, string message) =>
logger.Log(sender, LoggerEvent.Warning, "{0}", message);
///
/// Log a warning message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
public static void Warning(this ILogger logger, object sender, string message, object arg1) =>
logger.Log(sender, LoggerEvent.Warning, message, arg1);
///
/// Log a warning message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2) =>
logger.Log(sender, LoggerEvent.Warning, message, arg1, arg2);
///
/// Log a warning message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) => logger.Log(sender, LoggerEvent.Warning, message, arg1, arg2, arg3);
///
/// Log a warning message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
/// Message arg #4
public static void Warning(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) =>
logger.Log(sender, LoggerEvent.Warning, message, arg1, arg2, arg3, arg4);
///
/// Log a warning message
///
/// this
/// Sender or null
/// Message
/// Message arguments
public static void Warning(this ILogger logger, object sender, string message, params object[] args) =>
logger.Log(sender, LoggerEvent.Warning, message, args);
///
/// Log an info message
///
/// this
/// Sender or null
/// Message
public static void Info(this ILogger logger, object sender, string message) =>
logger.Log(sender, LoggerEvent.Info, "{0}", message);
///
/// Log an info message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
public static void Info(this ILogger logger, object sender, string message, object arg1) =>
logger.Log(sender, LoggerEvent.Info, message, arg1);
///
/// Log an info message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2) =>
logger.Log(sender, LoggerEvent.Info, message, arg1, arg2);
///
/// Log an info message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) =>
logger.Log(sender, LoggerEvent.Info, message, arg1, arg2, arg3);
///
/// Log an info message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
/// Message arg #4
public static void Info(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) =>
logger.Log(sender, LoggerEvent.Info, message, arg1, arg2, arg3, arg4);
///
/// Log an info message
///
/// this
/// Sender or null
/// Message
/// Message arguments
public static void Info(this ILogger logger, object sender, string message, params object[] args) =>
logger.Log(sender, LoggerEvent.Info, message, args);
///
/// Log a verbose message
///
/// this
/// Sender or null
/// Message
public static void Verbose(this ILogger logger, object sender, string message) =>
logger.Log(sender, LoggerEvent.Verbose, "{0}", message);
///
/// Log a verbose message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
public static void Verbose(this ILogger logger, object sender, string message, object arg1) =>
logger.Log(sender, LoggerEvent.Verbose, message, arg1);
///
/// Log a verbose message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2) =>
logger.Log(sender, LoggerEvent.Verbose, message, arg1, arg2);
///
/// Log a verbose message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) =>
logger.Log(sender, LoggerEvent.Verbose, message, arg1, arg2, arg3);
///
/// Log a verbose message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
/// Message arg #4
public static void Verbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) =>
logger.Log(sender, LoggerEvent.Verbose, message, arg1, arg2, arg3, arg4);
///
/// Log a verbose message
///
/// this
/// Sender or null
/// Message
/// Message arguments
public static void Verbose(this ILogger logger, object sender, string message, params object[] args) =>
logger.Log(sender, LoggerEvent.Verbose, message, args);
///
/// Log a very verbose message
///
/// this
/// Sender or null
/// Message
public static void VeryVerbose(this ILogger logger, object sender, string message) =>
logger.Log(sender, LoggerEvent.VeryVerbose, "{0}", message);
///
/// Log a very verbose message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1) =>
logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1);
///
/// Log a very verbose message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2) =>
logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1, arg2);
///
/// Log a very verbose message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3) =>
logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1, arg2, arg3);
///
/// Log a very verbose message
///
/// this
/// Sender or null
/// Message
/// Message arg #1
/// Message arg #2
/// Message arg #3
/// Message arg #4
public static void VeryVerbose(this ILogger logger, object sender, string message, object arg1, object arg2, object arg3, object arg4) =>
logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1, arg2, arg3, arg4);
///
/// Log a very verbose message
///
/// this
/// Sender or null
/// Message
/// Message arguments
public static void VeryVerbose(this ILogger logger, object sender, string message, params object[] args) =>
logger.Log(sender, LoggerEvent.VeryVerbose, message, args);
}
///
/// Dummy logger which ignores all messages, but can optionally throw on errors.
///
public sealed class DummyLogger : ILogger {
ConstructorInfo ctor;
///
/// It ignores everything and doesn't throw anything.
///
public static readonly DummyLogger NoThrowInstance = new DummyLogger();
///
/// Throws a on errors, but ignores anything else.
///
public static readonly DummyLogger ThrowModuleWriterExceptionOnErrorInstance = new DummyLogger(typeof(ModuleWriterException));
DummyLogger() {
}
///
/// Constructor
///
/// If non-null, this exception type is thrown on
/// errors. It must have a public constructor that takes a as the only
/// argument.
public DummyLogger(Type exceptionToThrow) {
if (exceptionToThrow is not null) {
if (!exceptionToThrow.IsSubclassOf(typeof(Exception)))
throw new ArgumentException($"Not a System.Exception sub class: {exceptionToThrow.GetType()}");
ctor = exceptionToThrow.GetConstructor(new Type[] { typeof(string) });
if (ctor is null)
throw new ArgumentException($"Exception type {exceptionToThrow.GetType()} doesn't have a public constructor that takes a string as the only argument");
}
}
///
public void Log(object sender, LoggerEvent loggerEvent, string format, params object[] args) {
if (loggerEvent == LoggerEvent.Error && ctor is not null)
throw (Exception)ctor.Invoke(new object[] { string.Format(format, args) });
}
///
public bool IgnoresEvent(LoggerEvent loggerEvent) {
if (ctor is null)
return true;
return loggerEvent != LoggerEvent.Error;
}
}
}