obfuz/Plugins/dnlib/DotNet/ILogger.cs

436 lines
17 KiB
C#

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