diff --git a/README.md b/README.md
index 4e6d956..95ad5ec 100644
--- a/README.md
+++ b/README.md
@@ -28,13 +28,23 @@ Check [this](https://github.com/stbychkov/AutoLoggerMessage/wiki/Configuration)
## Benchmarks
-You can achieve performance boosts of up to 90% according to my benchmarks just by including this source generator in your project.
+You can achieve performance boosts of up to 90% just by including this source generator in your project.
-| Configuration | Mean | Ratio | Allocated |
-|------------------------|-----------|-------|-----------|
-| Default implementation | 38.149 ns | 1.00 | 216 B |
-| Default + AutoLogger | 3.734 ns | 0.10 | - |
-| AutoLoggerMessage | 3.747 ns | 0.10 | - |
+For `ILogger.Log*` methods:
+
+| Configuration | Mean | Ratio | Allocated |
+|-------------------------|-----------|-------|-----------|
+| Default implementation | 41.419 ns | 1.00 | 216 B |
+| Default + LoggerMessage | 4.004 ns | 0.10 | - |
+| AutoLoggerMessage | 4.577 ns | 0.11 | - |
+
+And for `ILogger.DefineScope`:
+
+| Configuration | Mean | Ratio | Allocated |
+|-------------------------|-----------|-------|-----------|
+| BeginScope | 39.566 ns | 1.00 | 216 B |
+| DefineScope | 5.197 ns | 0.13 | - |
+| AutoLoggerMessage | 5.296 ns | 0.13 | - |
Take a look at [benchmark](https://github.com/stbychkov/AutoLoggerMessage/wiki/Benchmarks) page for more details.
diff --git a/benchmarks/AutoLoggerMessageGenerator.Benchmarks.csproj b/benchmarks/AutoLoggerMessageGenerator.Benchmarks.csproj
index 893b51f..a8ffde0 100644
--- a/benchmarks/AutoLoggerMessageGenerator.Benchmarks.csproj
+++ b/benchmarks/AutoLoggerMessageGenerator.Benchmarks.csproj
@@ -21,6 +21,7 @@
+
diff --git a/benchmarks/BenchmarkFiles/ExecutionTimeBenchmark.cs b/benchmarks/BenchmarkFiles/LogCallBenchmark.cs
similarity index 92%
rename from benchmarks/BenchmarkFiles/ExecutionTimeBenchmark.cs
rename to benchmarks/BenchmarkFiles/LogCallBenchmark.cs
index 901df78..42a5f24 100644
--- a/benchmarks/BenchmarkFiles/ExecutionTimeBenchmark.cs
+++ b/benchmarks/BenchmarkFiles/LogCallBenchmark.cs
@@ -5,7 +5,7 @@
[RankColumn]
[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
-public partial class ExecutionTimeBenchmark
+public partial class LogCallBenchmark
{
private ILogger _logger = null!;
private ConfigurationExample _configuration = null!;
@@ -13,7 +13,7 @@ public partial class ExecutionTimeBenchmark
[GlobalSetup]
public void Setup()
{
- _logger = CustomNullLogger.Instance;
+ _logger = CustomNullLogger.Instance;
_configuration = new ConfigurationExample(
0, "Root", new ConfigurationExample(
1, "First Level", new ConfigurationExample(
@@ -29,6 +29,8 @@ public void LogInformationWithoutParameters()
_logger.LogInformation("Hello world!");
}
+#if DEFAULT && !TELEMETRY && !AUTO_LOGGER_MESSAGE
+
[Benchmark]
[BenchmarkCategory("Without parameters")]
public void LoggerMessageWithoutParameters()
@@ -39,6 +41,8 @@ public void LoggerMessageWithoutParameters()
[LoggerMessage(LogLevel.Information, Message = "Hello world!")]
partial void LoggerMessageWithoutParametersImpl();
+#endif
+
[Benchmark(Baseline = true)]
[BenchmarkCategory("With 6 Parameters")]
public void LogInformationWith6PrimitiveParameters()
@@ -46,6 +50,8 @@ public void LogInformationWith6PrimitiveParameters()
_logger.LogInformation("Hello world! {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}", 1, 2, 3, 4, 5, 6);
}
+#if DEFAULT && !TELEMETRY && !AUTO_LOGGER_MESSAGE
+
[Benchmark]
[BenchmarkCategory("With 6 Parameters")]
public void LoggerMessageWith6Parameters()
@@ -56,6 +62,8 @@ public void LoggerMessageWith6Parameters()
[LoggerMessage(LogLevel.Information, Message = "Hello world! {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}")]
partial void LoggerMessageWith6ParametersImpl(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);
+#endif
+
[Benchmark(Baseline = true)]
[BenchmarkCategory("With 7 Parameters")]
public void LogInformationWith7PrimitiveParameters()
@@ -63,6 +71,8 @@ public void LogInformationWith7PrimitiveParameters()
_logger.LogInformation("Hello world! {arg1} {arg2} {arg3} {arg4} {arg5} {arg6} {arg7}", 1, 2, 3, 4, 5, 6, 7);
}
+#if DEFAULT && !TELEMETRY && !AUTO_LOGGER_MESSAGE
+
[Benchmark]
[BenchmarkCategory("With 7 Parameters")]
public void LoggerMessageWith7Parameters()
@@ -74,6 +84,8 @@ public void LoggerMessageWith7Parameters()
partial void LoggerMessageWith7ParametersImpl(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6,
int arg7);
+#endif
+
[Benchmark(Baseline = true)]
[BenchmarkCategory("With Complex Types Parameters")]
public void LogInformationWithComplexParameters()
@@ -82,6 +94,7 @@ public void LogInformationWithComplexParameters()
_configuration, _configuration, _configuration, _configuration, _configuration, _configuration);
}
+#if DEFAULT && !TELEMETRY && !AUTO_LOGGER_MESSAGE
[Benchmark]
[BenchmarkCategory("With Complex Types Parameters")]
public void LoggerMessageWithComplexParameters()
@@ -102,6 +115,8 @@ partial void LoggerMessageWithComplexParametersImpl(
ConfigurationExample arg6
);
+#endif
+
#if TELEMETRY
[Benchmark]
diff --git a/benchmarks/BenchmarkFiles/LogScopeBenchmark.cs b/benchmarks/BenchmarkFiles/LogScopeBenchmark.cs
new file mode 100644
index 0000000..448c1da
--- /dev/null
+++ b/benchmarks/BenchmarkFiles/LogScopeBenchmark.cs
@@ -0,0 +1,109 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Configs;
+using Microsoft.Extensions.Logging;
+
+[RankColumn]
+[MemoryDiagnoser]
+[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
+public partial class LogScopeBenchmark
+{
+ private ILogger _logger = null!;
+ private ConfigurationExample _configuration = null!;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _logger = CustomNullLogger.Instance;
+ _configuration = new ConfigurationExample(
+ 0, "Root", new ConfigurationExample(
+ 1, "First Level", new ConfigurationExample(
+ 2, "Second level", null)
+ )
+ );
+ }
+
+#if !TELEMETRY
+
+ [Benchmark(Baseline = true)]
+ [BenchmarkCategory("Without parameters")]
+ public void BeginScopeWithoutParameters()
+ {
+ using var _ = _logger.BeginScope("Hello world!");
+ }
+
+#endif
+
+#if DEFAULT && !TELEMETRY && !AUTO_LOGGER_MESSAGE
+
+ [Benchmark]
+ [BenchmarkCategory("Without parameters")]
+ public void LoggerDefineScopeWithoutParameters()
+ {
+ using var _ = _loggerDefineScopeWithoutParameters(_logger);
+ }
+
+ private static readonly Func _loggerDefineScopeWithoutParameters =
+ LoggerMessage.DefineScope("Hello world!");
+
+#endif
+
+#if !TELEMETRY
+ [Benchmark(Baseline = true)]
+ [BenchmarkCategory("With 6 Parameters")]
+ public void BeginScopeWith6PrimitiveParameters()
+ {
+ using var _ = _logger.BeginScope("Hello world! {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}", 1, 2, 3, 4, 5, 6);
+ }
+#endif
+
+#if DEFAULT && !TELEMETRY && !AUTO_LOGGER_MESSAGE
+
+ [Benchmark]
+ [BenchmarkCategory("With 6 Parameters")]
+ public void LoggerDefineScopeWith6Parameters()
+ {
+ using var _ = _loggerDefineScopeWith6Parameters(_logger, 1, 2, 3, 4, 5, 6);
+ }
+
+ private static readonly Func _loggerDefineScopeWith6Parameters =
+ LoggerMessage.DefineScope("Hello world! {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}");
+
+#endif
+
+#if !TELEMETRY
+
+ [Benchmark(Baseline = true)]
+ [BenchmarkCategory("With Complex Types Parameters")]
+ public void BeginScopeWithComplexParameters()
+ {
+ using var _ = _logger.BeginScope("Hello world! {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}",
+ _configuration, _configuration, _configuration, _configuration, _configuration, _configuration);
+ }
+
+#endif
+
+#if DEFAULT && !TELEMETRY && !AUTO_LOGGER_MESSAGE
+
+ [Benchmark]
+ [BenchmarkCategory("With Complex Types Parameters")]
+ public void LoggerDefineScopeWithComplexParameters()
+ {
+ using var _ = _loggerDefineScopeWithComplexParameters(_logger,
+ _configuration, _configuration, _configuration,
+ _configuration, _configuration, _configuration
+ );
+ }
+
+ private static readonly Func _loggerDefineScopeWithComplexParameters =
+ LoggerMessage.DefineScope(
+ "Hello world! {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}"
+ );
+
+#endif
+
+ public record ConfigurationExample(int Id, string Name, ConfigurationExample? NestedConfiguration);
+}
diff --git a/benchmarks/PackagesProvider.cs b/benchmarks/PackagesProvider.cs
index c2a806a..ee2e996 100644
--- a/benchmarks/PackagesProvider.cs
+++ b/benchmarks/PackagesProvider.cs
@@ -5,5 +5,6 @@ internal static class PackagesProvider
public const string BenchmarkPackage = """""";
public const string MicrosoftExtensionsLoggingPackage = """""";
public const string MicrosoftExtensionsTelemetryPackage = """""";
- public const string AutoLoggerMessagePackage = """""";
+ public const string AutoLoggerMessageBuildOutput = """""";
+ public const string AutoLoggerMessagePackage = """""";
}
diff --git a/benchmarks/Program.cs b/benchmarks/Program.cs
index ffc621b..510f663 100644
--- a/benchmarks/Program.cs
+++ b/benchmarks/Program.cs
@@ -28,6 +28,7 @@
{
PackagesProvider.BenchmarkPackage,
PackagesProvider.MicrosoftExtensionsLoggingPackage,
+ PackagesProvider.AutoLoggerMessageBuildOutput,
PackagesProvider.AutoLoggerMessagePackage
}
},
@@ -38,6 +39,7 @@
{
PackagesProvider.BenchmarkPackage,
PackagesProvider.AutoLoggerMessagePackage,
+ PackagesProvider.AutoLoggerMessageBuildOutput,
PackagesProvider.MicrosoftExtensionsLoggingPackage,
PackagesProvider.MicrosoftExtensionsTelemetryPackage,
}
diff --git a/benchmarks/ProjectBuilder.cs b/benchmarks/ProjectBuilder.cs
index 1a3011a..edc051e 100644
--- a/benchmarks/ProjectBuilder.cs
+++ b/benchmarks/ProjectBuilder.cs
@@ -55,9 +55,7 @@ private static void CopyBenchmarkFiles(string workingDirectory)
private async Task<(string OutputFolder, string projFilePath)> GenerateProjectFile(string projectName, string workingDirectory)
{
- var telemetryConstant = projectConfiguration.References.Contains(PackagesProvider.MicrosoftExtensionsTelemetryPackage)
- ? "TELEMETRY"
- : string.Empty;
+ var configurations = string.Join(";", GetProjectConfigurations());
var targetFramework = TargetFrameworkMonikerDetector.Detect();
@@ -74,7 +72,7 @@ private static void CopyBenchmarkFiles(string workingDirectory)
false
{outputFolder}
{projectName}
- $(DefineConstants);{telemetryConstant}
+ $(DefineConstants);{configurations}
@@ -99,6 +97,18 @@ private static void CopyBenchmarkFiles(string workingDirectory)
return (outputFolder, projFilePath);
}
+ private IEnumerable GetProjectConfigurations()
+ {
+ if (projectConfiguration.References.Contains(PackagesProvider.MicrosoftExtensionsLoggingPackage))
+ yield return "DEFAULT";
+
+ if (projectConfiguration.References.Contains(PackagesProvider.MicrosoftExtensionsTelemetryPackage))
+ yield return "TELEMETRY";
+
+ if (projectConfiguration.References.Contains(PackagesProvider.AutoLoggerMessagePackage))
+ yield return "AUTO_LOGGER_MESSAGE";
+ }
+
internal class BuildResult
{
public required string ProjectDirectory { get; init; }
diff --git a/docs/ADR/ADR-07_Generation_of_BeginScope_methods.md b/docs/ADR/ADR-07_Generation_of_BeginScope_methods.md
new file mode 100644
index 0000000..34be801
--- /dev/null
+++ b/docs/ADR/ADR-07_Generation_of_BeginScope_methods.md
@@ -0,0 +1,46 @@
+### Title: ADR-07 Generation of `BeginScope` methods
+### Status: Accepted
+
+### Context:
+
+The existing `ILogger.BeginScope` method has the same problems as the `ILogger.Log*` methods:
+1. Lack of compile-time checks for mismatches between template parameters and the actual arguments, which can lead to runtime exceptions.
+2. Performance overhead due to the need to create a new scope object every time.
+3. Unnecessary allocations due to boxing of template parameters, even with identical arguments.
+
+`ILogger.BeginScope` is backed by `LoggerMessage.DefineScope`, which allows generation of strongly-typed, precompiled delegates with up to 6 parameters. This enables high-performance and allocation-free scope creation, similar to how `LoggerMessage.Define` is used for logging methods.
+
+The main difference is that `ILogger.BeginScope` **with only one parameter** is an instance method, not an extension method. This means we cannot intercept or replace calls that only use a single message argument (i.e., `BeginScope("Starting operation")`) because the instance method takes precedence over extension methods. Therefore, generation will be limited to `BeginScope` calls with one or more structured parameters (i.e., key-value pairs or anonymous objects), which typically benefit the most from strongly-typed scope generation.
+[Reference test](https://github.com/stbychkov/AutoLoggerMessage/blob/main/tests/AutoLoggerMessageGenerator.UnitTests/MethodSpecificityRules/InstanceCallVsExtensionCallTests.cs)
+
+### Decision:
+
+Extend the AutoLoggerMessage source generator to support generation of strongly-typed scope delegates using `LoggerMessage.DefineScope`.
+
+Specifically:
+- Identify all usages of `ILogger.BeginScope` in the codebase where the call includes **at least one structured argument** (excluding pure string messages).
+- For each identified scope usage:
+ - Generate a static readonly field that contains the compiled scope delegate using `LoggerMessage.DefineScope`.
+ - Generate an extension method (or internal interceptor method) that redirects the original `BeginScope` call to the generated delegate, preserving structure and performance.
+- Ensure that the generated methods follow the same naming, visibility, and partial class strategy as existing `Log*` method interceptors.
+
+### Consequences:
+
+* **Short-term**:
+ - Improves performance and reduces allocations for scoped logging with parameters.
+ - Introduces new source generation complexity; testing must be extended to validate generated scopes.
+
+* **Long-term**:
+ - Moves the library closer to complete compile-time safety for all common logging patterns (`Log*` and `BeginScope`).
+
+* **Risks**:
+ - May cause confusion if developers attempt to use `BeginScope(string message)` expecting interception (which is not supported).
+ - Reliance on exact call shapes (number and types of arguments) may introduce fragility unless thoroughly tested.
+
+* **Maintenance**:
+ - Must track and test against future changes in `LoggerMessage.DefineScope` API (currently supports up to 6 parameters).
+ - Increases the surface area of generated code, potentially impacting future refactors or compatibility with downstream tools.
+
+### Alternatives Considered
+
+* **Do nothing**: Keep relying on `ILogger.BeginScope` as is. This maintains simplicity but misses out on performance and compile-time safety.
diff --git a/src/AutoLoggerMessageGenerator.BuildOutput/GenericLoggerExtensions.g.cs b/src/AutoLoggerMessageGenerator.BuildOutput/GenericLoggerExtensions.g.cs
new file mode 100644
index 0000000..bdd555c
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator.BuildOutput/GenericLoggerExtensions.g.cs
@@ -0,0 +1,997 @@
+//
+#nullable enable
+
+using System;
+
+namespace Microsoft.Extensions.Logging
+{
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("AutoLoggerMessageGenerator", "1.0.10.0")]
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.DebuggerStepThrough]
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ public static class GenericLoggerExtensions
+ {
+ public static void LogTrace(this ILogger @logger, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @message);
+ }
+
+ public static void LogDebug(this ILogger @logger, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @message);
+ }
+
+ public static void LogInformation(this ILogger @logger, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @message);
+ }
+
+ public static void LogWarning(this ILogger @logger, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @message);
+ }
+
+ public static void LogError(this ILogger @logger, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @message);
+ }
+
+ public static void LogCritical(this ILogger @logger, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @message);
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @message);
+ }
+
+ public static void LogTrace(this ILogger @logger, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogDebug(this ILogger @logger, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogInformation(this ILogger @logger, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogWarning(this ILogger @logger, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogError(this ILogger @logger, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogCritical(this ILogger @logger, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @message, new object?[] { @arg0 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogTrace(this ILogger @logger, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogDebug(this ILogger @logger, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogInformation(this ILogger @logger, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogWarning(this ILogger @logger, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogError(this ILogger @logger, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogCritical(this ILogger @logger, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogTrace(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogDebug(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogInformation(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogWarning(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogError(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogCritical(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogTrace(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogDebug(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogInformation(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogWarning(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogError(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogCritical(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogTrace(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogDebug(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogInformation(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogWarning(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogError(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogCritical(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogTrace(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogDebug(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogInformation(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogWarning(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogError(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogCritical(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+
+ public static void LogTrace(this ILogger @logger, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @exception, @message);
+ }
+
+ public static void LogDebug(this ILogger @logger, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @exception, @message);
+ }
+
+ public static void LogInformation(this ILogger @logger, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @exception, @message);
+ }
+
+ public static void LogWarning(this ILogger @logger, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @exception, @message);
+ }
+
+ public static void LogError(this ILogger @logger, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @exception, @message);
+ }
+
+ public static void LogCritical(this ILogger @logger, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @exception, @message);
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @exception, @message);
+ }
+
+ public static void LogTrace(this ILogger @logger, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogDebug(this ILogger @logger, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogInformation(this ILogger @logger, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogWarning(this ILogger @logger, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogError(this ILogger @logger, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogCritical(this ILogger @logger, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogTrace(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogDebug(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogInformation(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogWarning(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogError(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogCritical(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogTrace(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogDebug(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogInformation(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogWarning(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogError(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogCritical(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogTrace(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogDebug(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogInformation(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogWarning(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogError(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogCritical(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogTrace(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogDebug(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogInformation(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogWarning(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogError(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogCritical(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogTrace(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogDebug(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogInformation(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogWarning(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogError(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogCritical(this ILogger @logger, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @message);
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @message);
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @message);
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @message);
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @message);
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @message);
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @message);
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @message, new object?[] { @arg0 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @exception, @message);
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @exception, @message);
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @exception, @message);
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @exception, @message);
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @exception, @message);
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @exception, @message);
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, Exception? @exception, string @message)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @exception, @message);
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, Exception? @exception, string @message, T0 @arg0)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @exception, @message, new object?[] { @arg0 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @exception, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static void LogTrace(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogTrace(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogDebug(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogDebug(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogInformation(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogWarning(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogWarning(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogError(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogError(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void LogCritical(this ILogger @logger, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.LogCritical(@logger, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ public static void Log(this ILogger @logger, Microsoft.Extensions.Logging.LogLevel @logLevel, EventId @eventId, Exception? @exception, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ Microsoft.Extensions.Logging.LoggerExtensions.Log(@logger, @logLevel, @eventId, @exception, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+ }
+}
diff --git a/src/AutoLoggerMessageGenerator.BuildOutput/GenericLoggerScopeExtensions.g.cs b/src/AutoLoggerMessageGenerator.BuildOutput/GenericLoggerScopeExtensions.g.cs
new file mode 100644
index 0000000..6010a02
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator.BuildOutput/GenericLoggerScopeExtensions.g.cs
@@ -0,0 +1,44 @@
+//
+#nullable enable
+
+using System;
+
+namespace Microsoft.Extensions.Logging
+{
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("AutoLoggerMessageGenerator", "1.0.10.0")]
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.DebuggerStepThrough]
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ public static class GenericLoggerScopeExtensions
+ {
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+ }
+}
diff --git a/src/AutoLoggerMessageGenerator.Sandbox/AutoLoggerMessageGenerator.Sandbox.csproj b/src/AutoLoggerMessageGenerator.Sandbox/AutoLoggerMessageGenerator.Sandbox.csproj
index 26e9c77..fecc1cc 100644
--- a/src/AutoLoggerMessageGenerator.Sandbox/AutoLoggerMessageGenerator.Sandbox.csproj
+++ b/src/AutoLoggerMessageGenerator.Sandbox/AutoLoggerMessageGenerator.Sandbox.csproj
@@ -9,6 +9,7 @@
+
- builder.AddSimpleConsole().SetMinimumLevel(LogLevel.Trace)
+ builder.AddSimpleConsole(options =>
+ {
+ options.IncludeScopes = true;
+ }).SetMinimumLevel(LogLevel.Trace)
);
var logger = loggerFactory.CreateLogger();
+using var parentScope = logger.BeginScope("Scope {Level}", 1);
+
logger.LogTrace("Log message without parameters");
logger.LogDebug("Log message with parameters: {Param1}, {Param2}", 42, "Hello, World!");
-logger.LogInformation("Log message with 6 parameters: {Arg1}, {Arg2}, {Arg3}, {Arg4}, {Arg5} {Arg6}", 1, 2, 3, 4, 5, 6);
-logger.LogWarning(new EventId(42, "Event1"), "Event1 happened");
+
+using (logger.BeginScope("Scope {Level}", 2))
+{
+ logger.LogInformation("Log message with 6 parameters: {Arg1}, {Arg2}, {Arg3}, {Arg4}, {Arg5} {Arg6}", 1, 2, 3, 4, 5, 6);
+ logger.LogWarning(new EventId(42, "Event1"), "Event1 happened");
+}
+
logger.LogError(new EventId(42, "Event1"), new Exception("Event1 error"), "Event1 happened");
logger.LogCritical(new EventId(42, "Event2"), new Exception("Event2 error"), "Event2 happened {Arg1}", new EventData(123, "Event details"));
diff --git a/src/AutoLoggerMessageGenerator/Analysers/InvalidTemplateParameterNameAnalyser.cs b/src/AutoLoggerMessageGenerator/Analysers/InvalidTemplateParameterNameAnalyser.cs
index 104c51b..305a252 100644
--- a/src/AutoLoggerMessageGenerator/Analysers/InvalidTemplateParameterNameAnalyser.cs
+++ b/src/AutoLoggerMessageGenerator/Analysers/InvalidTemplateParameterNameAnalyser.cs
@@ -31,33 +31,55 @@ public override void Initialize(AnalysisContext context)
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze |
GeneratedCodeAnalysisFlags.ReportDiagnostics);
- context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.InvocationExpression);
+ context.RegisterSyntaxNodeAction(AnalyzeLoggerMessageNode, SyntaxKind.InvocationExpression);
+ context.RegisterSyntaxNodeAction(AnalyzeLoggerScopeNode, SyntaxKind.InvocationExpression);
}
- private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
+ private static void AnalyzeLoggerMessageNode(SyntaxNodeAnalysisContext context)
{
var invocationExpression = (InvocationExpressionSyntax)context.Node;
- if (!LogCallFilter.IsLogCallInvocation(invocationExpression, context.CancellationToken))
+ if (!LogMessageCallFilter.IsLogCallInvocation(invocationExpression, context.CancellationToken))
return;
var semanticModel = context.SemanticModel;
var methodSymbol = semanticModel.GetSymbolInfo(invocationExpression).Symbol as IMethodSymbol;
- if (methodSymbol is null || !LogCallFilter.IsLoggerMethod(methodSymbol))
+ if (methodSymbol is null || !LogMessageCallFilter.IsLoggerMethod(methodSymbol))
return;
- var message = LogCallMessageExtractor.Extract(methodSymbol, invocationExpression, semanticModel);
+ AnalyzeNode(context, methodSymbol, invocationExpression, semanticModel);
+ }
+
+ private static void AnalyzeLoggerScopeNode(SyntaxNodeAnalysisContext context)
+ {
+ var invocationExpression = (InvocationExpressionSyntax)context.Node;
+
+ if (!LoggerScopeFilter.IsLoggerScopeInvocation(invocationExpression, context.CancellationToken))
+ return;
+
+ var semanticModel = context.SemanticModel;
+ var methodSymbol = semanticModel.GetSymbolInfo(invocationExpression).Symbol as IMethodSymbol;
+ if (methodSymbol is null || !LoggerScopeFilter.IsLoggerScopeMethod(methodSymbol))
+ return;
+
+ AnalyzeNode(context, methodSymbol, invocationExpression, semanticModel);
+ }
+
+ private static void AnalyzeNode(SyntaxNodeAnalysisContext context, IMethodSymbol methodSymbol,
+ InvocationExpressionSyntax invocationExpression, SemanticModel semanticModel)
+ {
+ var message = MessageParameterTextExtractor.Extract(methodSymbol, invocationExpression, semanticModel);
if (message is null)
return;
- var templateParameterNames = LogCallMessageParameterNamesExtractor.Extract(message)
+ var templateParameterNames = MessageParameterNamesExtractor.Extract(message)
.Where(parameterName => !IdentifierHelper.IsValidCSharpParameterName(parameterName))
.ToImmutableArray();
if (!templateParameterNames.Any())
return;
- var location = LogCallLocationMapper.Map(semanticModel, invocationExpression);
+ var location = CallLocationMapper.Map(semanticModel, invocationExpression);
if (location is null)
return;
diff --git a/src/AutoLoggerMessageGenerator/AutoLoggerMessageGenerator.Build.targets b/src/AutoLoggerMessageGenerator/AutoLoggerMessageGenerator.Build.targets
index 0ca7096..629fee6 100644
--- a/src/AutoLoggerMessageGenerator/AutoLoggerMessageGenerator.Build.targets
+++ b/src/AutoLoggerMessageGenerator/AutoLoggerMessageGenerator.Build.targets
@@ -54,6 +54,9 @@
<_Parameter1>$(AssemblyName).UnitTests.Roslyn4_11
+
+ <_Parameter1>$(AssemblyName).IntegrationTests
+
<_Parameter1>$(AssemblyName).Benchmarks
diff --git a/src/AutoLoggerMessageGenerator/AutoLoggerMessageGenerator.Roslyn4_11.csproj b/src/AutoLoggerMessageGenerator/AutoLoggerMessageGenerator.Roslyn4_11.csproj
index b92484b..c445972 100644
--- a/src/AutoLoggerMessageGenerator/AutoLoggerMessageGenerator.Roslyn4_11.csproj
+++ b/src/AutoLoggerMessageGenerator/AutoLoggerMessageGenerator.Roslyn4_11.csproj
@@ -7,5 +7,14 @@
false
+
+
+ AutoLoggerMessageGenerator.cs
+
+
+ AutoLoggerMessageGenerator.cs
+
+
+
diff --git a/src/AutoLoggerMessageGenerator/Caching/InputSourceComparer.cs b/src/AutoLoggerMessageGenerator/Caching/InputSourceComparer.cs
deleted file mode 100644
index 4bb42a4..0000000
--- a/src/AutoLoggerMessageGenerator/Caching/InputSourceComparer.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Collections.Immutable;
-using AutoLoggerMessageGenerator.Configuration;
-using AutoLoggerMessageGenerator.Models;
-using AutoLoggerMessageGenerator.ReferenceAnalyzer;
-using Microsoft.CodeAnalysis;
-
-namespace AutoLoggerMessageGenerator.Caching;
-
-internal class InputSourceComparer : IEqualityComparer<(Compilation Compilation, (SourceGeneratorConfiguration Configuration, (ImmutableArray References, ImmutableArray LogCalls) Others) Others)>
-{
- public bool Equals((Compilation Compilation, (SourceGeneratorConfiguration Configuration, (ImmutableArray References, ImmutableArray LogCalls) Others) Others) x, (Compilation Compilation, (SourceGeneratorConfiguration Configuration, (ImmutableArray References, ImmutableArray LogCalls) Others) Others) y) =>
- x.Others.Configuration == y.Others.Configuration &&
- x.Others.Others.References.SequenceEqual(y.Others.Others.References) &&
- x.Others.Others.LogCalls.SequenceEqual(y.Others.Others.LogCalls);
-
- public int GetHashCode((Compilation Compilation, (SourceGeneratorConfiguration Configuration, (ImmutableArray References, ImmutableArray LogCalls) Others) Others) obj) =>
- obj.Item2.GetHashCode();
-}
diff --git a/src/AutoLoggerMessageGenerator/Caching/LogCallInputSourceComparer.cs b/src/AutoLoggerMessageGenerator/Caching/LogCallInputSourceComparer.cs
new file mode 100644
index 0000000..a4a308f
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Caching/LogCallInputSourceComparer.cs
@@ -0,0 +1,23 @@
+using InputSource = (
+ Microsoft.CodeAnalysis.Compilation Compilation,
+ (
+ AutoLoggerMessageGenerator.Configuration.SourceGeneratorConfiguration Configuration,
+ (
+ System.Collections.Immutable.ImmutableArray References,
+ System.Collections.Immutable.ImmutableArray LogCalls
+ ) Others
+ ) Others
+);
+
+namespace AutoLoggerMessageGenerator.Caching;
+
+internal class LogCallInputSourceComparer : IEqualityComparer
+{
+ public bool Equals(InputSource x, InputSource y) =>
+ x.Others.Configuration == y.Others.Configuration &&
+ x.Others.Others.References.SequenceEqual(y.Others.Others.References) &&
+ x.Others.Others.LogCalls.SequenceEqual(y.Others.Others.LogCalls);
+
+ public int GetHashCode(InputSource obj) =>
+ obj.Item2.GetHashCode();
+}
diff --git a/src/AutoLoggerMessageGenerator/Caching/LogScopeDefinitionInputSourceComparer.cs b/src/AutoLoggerMessageGenerator/Caching/LogScopeDefinitionInputSourceComparer.cs
new file mode 100644
index 0000000..c2e1480
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Caching/LogScopeDefinitionInputSourceComparer.cs
@@ -0,0 +1,19 @@
+using InputSource = (
+ Microsoft.CodeAnalysis.Compilation Compilation,
+ (
+ AutoLoggerMessageGenerator.Configuration.SourceGeneratorConfiguration Configuration,
+ System.Collections.Immutable.ImmutableArray LoggerScopes
+ ) Others
+);
+
+namespace AutoLoggerMessageGenerator.Caching;
+
+internal class LogScopeDefinitionInputSourceComparer : IEqualityComparer
+{
+ public bool Equals(InputSource x, InputSource y) =>
+ x.Others.Configuration == y.Others.Configuration &&
+ x.Others.LoggerScopes.SequenceEqual(y.Others.LoggerScopes);
+
+ public int GetHashCode(InputSource obj) =>
+ obj.Item2.GetHashCode();
+}
diff --git a/src/AutoLoggerMessageGenerator/Configuration/GeneratorOptionsProvider.cs b/src/AutoLoggerMessageGenerator/Configuration/GeneratorOptionsProvider.cs
index b1549fa..d0b64e7 100644
--- a/src/AutoLoggerMessageGenerator/Configuration/GeneratorOptionsProvider.cs
+++ b/src/AutoLoggerMessageGenerator/Configuration/GeneratorOptionsProvider.cs
@@ -11,6 +11,7 @@ internal static class GeneratorOptionsProvider
private const string GenerateOmitReferenceNameKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.GenerateOmitReferenceName)}";
private const string GenerateSkipNullPropertiesKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.GenerateSkipNullProperties)}";
private const string GenerateTransitiveKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.GenerateTransitive)}";
+ private const string OverrideBeginScopeBehaviorKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.OverrideBeginScopeBehavior)}";
public static IncrementalValueProvider Provide(IncrementalGeneratorInitializationContext context) =>
context.AnalyzerConfigOptionsProvider.Select((options, _) => new SourceGeneratorConfiguration(
@@ -18,7 +19,8 @@ public static IncrementalValueProvider Provide(Inc
GenerateSkipEnabledCheck: GetValue(options.GlobalOptions, GenerateSkipEnabledCheckKey, true),
GenerateOmitReferenceName: GetValue(options.GlobalOptions, GenerateOmitReferenceNameKey, false),
GenerateSkipNullProperties: GetValue(options.GlobalOptions, GenerateSkipNullPropertiesKey, false),
- GenerateTransitive: GetValue(options.GlobalOptions, GenerateTransitiveKey, false)
+ GenerateTransitive: GetValue(options.GlobalOptions, GenerateTransitiveKey, false),
+ OverrideBeginScopeBehavior: GetValue(options.GlobalOptions, OverrideBeginScopeBehaviorKey, true)
));
private static bool GetValue(AnalyzerConfigOptions options, string key, bool defaultValue = true) =>
diff --git a/src/AutoLoggerMessageGenerator/Configuration/SourceGeneratorConfiguration.cs b/src/AutoLoggerMessageGenerator/Configuration/SourceGeneratorConfiguration.cs
index a843faf..af6424b 100644
--- a/src/AutoLoggerMessageGenerator/Configuration/SourceGeneratorConfiguration.cs
+++ b/src/AutoLoggerMessageGenerator/Configuration/SourceGeneratorConfiguration.cs
@@ -8,5 +8,6 @@ internal record struct SourceGeneratorConfiguration
bool GenerateSkipEnabledCheck,
bool GenerateOmitReferenceName,
bool GenerateSkipNullProperties,
- bool GenerateTransitive
+ bool GenerateTransitive,
+ bool OverrideBeginScopeBehavior
);
diff --git a/src/AutoLoggerMessageGenerator/Constants.cs b/src/AutoLoggerMessageGenerator/Constants.cs
index 794a047..d56ba8c 100644
--- a/src/AutoLoggerMessageGenerator/Constants.cs
+++ b/src/AutoLoggerMessageGenerator/Constants.cs
@@ -11,6 +11,7 @@ internal static class Constants
public const string InterceptorAttributeName = "InterceptsLocationAttribute";
public const string LogMethodPrefix = "Log_";
+ public const string LogScopeMethodPrefix = "LogScope_";
public const string LoggerClassName = "AutoLoggerMessage";
public const string ParameterName = "@arg";
@@ -20,6 +21,9 @@ internal static class Constants
public const string ExceptionParameterName = "@exception";
public const string MessageParameterName = "@message";
+ public const string LoggerMessageGeneratorName = "LoggerMessage";
+ public const string LoggerScopesGeneratorName = "LoggerScopes";
+
public static readonly HashSet ReservedParameterNames =
[
LoggerParameterName, LogLevelParameterName,
@@ -28,8 +32,8 @@ internal static class Constants
];
// List of parameters that will be moved to LoggerMessage attribute arguments
- public static readonly HashSet LoggerMessageAttributeParameterTypes =
- [LogCallParameterType.LogLevel, LogCallParameterType.Message];
+ public static readonly HashSet LoggerMessageAttributeParameterTypes =
+ [CallParameterType.LogLevel, CallParameterType.Message];
///
/// Support for an arbitrary number of logging parameters. LoggerMessage.Define supports a maximum of six.
diff --git a/src/AutoLoggerMessageGenerator/Diagnostics/DiagnosticReporter.cs b/src/AutoLoggerMessageGenerator/Diagnostics/LogMessageDiagnosticReporter.cs
similarity index 76%
rename from src/AutoLoggerMessageGenerator/Diagnostics/DiagnosticReporter.cs
rename to src/AutoLoggerMessageGenerator/Diagnostics/LogMessageDiagnosticReporter.cs
index a57af95..bac9e0f 100644
--- a/src/AutoLoggerMessageGenerator/Diagnostics/DiagnosticReporter.cs
+++ b/src/AutoLoggerMessageGenerator/Diagnostics/LogMessageDiagnosticReporter.cs
@@ -5,12 +5,12 @@
namespace AutoLoggerMessageGenerator.Diagnostics;
-internal class DiagnosticReporter
+internal class LogMessageDiagnosticReporter
{
private readonly SourceProductionContext _context;
- private readonly Dictionary _logCallsIndex;
+ private readonly Dictionary _logCallsIndex;
- public DiagnosticReporter(SourceProductionContext context, IEnumerable logCalls)
+ public LogMessageDiagnosticReporter(SourceProductionContext context, IEnumerable logCalls)
{
_context = context;
_logCallsIndex = logCalls.ToDictionary(c => c.Id);
@@ -24,7 +24,7 @@ public void Report(Diagnostic diagnostic)
var sourceText = diagnostic.Location.SourceTree?.GetText(_context.CancellationToken);
var location = sourceText is not null &&
- LogCallLocationMap.TryMapBack(sourceText, diagnostic.Location, out var logCallId) &&
+ LogMessageCallLocationMap.TryMapBack(sourceText, diagnostic.Location, out var logCallId) &&
_logCallsIndex.TryGetValue(logCallId, out var logCall)
? logCall.Location.Context
: Location.None;
diff --git a/src/AutoLoggerMessageGenerator/Emitters/LoggerExtensionMethodsEmitter.cs b/src/AutoLoggerMessageGenerator/Emitters/GenericLoggerExtensionsEmitter.cs
similarity index 99%
rename from src/AutoLoggerMessageGenerator/Emitters/LoggerExtensionMethodsEmitter.cs
rename to src/AutoLoggerMessageGenerator/Emitters/GenericLoggerExtensionsEmitter.cs
index ffdaabe..ea5f29a 100644
--- a/src/AutoLoggerMessageGenerator/Emitters/LoggerExtensionMethodsEmitter.cs
+++ b/src/AutoLoggerMessageGenerator/Emitters/GenericLoggerExtensionsEmitter.cs
@@ -9,7 +9,7 @@ namespace AutoLoggerMessageGenerator.Emitters;
/// The class is pre-generated and saved in the solution
/// to prevent excessive code duplication when multiple projects use the same library
/// To run this emitter you need to run LoggerExtensionEmitterTests and take it from the snapshot/>
-internal static class LoggerExtensionsEmitter
+internal static class GenericLoggerExtensionsEmitter
{
public const string ClassName = "GenericLoggerExtensions";
diff --git a/src/AutoLoggerMessageGenerator/Emitters/GenericLoggerScopeExtensionsEmitter.cs b/src/AutoLoggerMessageGenerator/Emitters/GenericLoggerScopeExtensionsEmitter.cs
new file mode 100644
index 0000000..554fa60
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Emitters/GenericLoggerScopeExtensionsEmitter.cs
@@ -0,0 +1,74 @@
+using System.CodeDom.Compiler;
+using Microsoft.Extensions.Logging;
+using static AutoLoggerMessageGenerator.Constants;
+
+namespace AutoLoggerMessageGenerator.Emitters;
+
+/// Generates the class.
+/// Provides type-specific logging method overrides to avoid boxing.
+/// The class is pre-generated and saved in the solution
+/// to prevent excessive code duplication when multiple projects use the same library
+/// To run this emitter you need to run LoggerScopeExtensionEmitterTests and take it from the snapshot
+internal static class GenericLoggerScopeExtensionsEmitter
+{
+ public const string ClassName = "GenericLoggerScopeExtensions";
+
+ public static string Emit()
+ {
+ using var sb = new IndentedTextWriter(new StringWriter());
+
+ sb.WriteLine(GeneratedFileHeader);
+
+ sb.WriteLine($"namespace {DefaultLoggingNamespace}");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ sb.WriteLine(Constants.GeneratedCodeAttribute);
+ sb.WriteLine(EditorNotBrowsableAttribute);
+ sb.WriteLine(DebuggerStepThroughAttribute);
+ sb.WriteLine(ExcludeFromCoverageAttribute);
+ sb.WriteLine($"public static class {ClassName}");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ for (int i = 1; i <= MaxLogParameters; i++)
+ {
+ var parameters = Enumerable.Range(0, i).ToArray();
+
+ var genericTypesDefinition = string.Join(", ", parameters.Select(ix => $"T{ix}"));
+ genericTypesDefinition = string.IsNullOrEmpty(genericTypesDefinition)
+ ? string.Empty
+ : $"<{genericTypesDefinition}>";
+
+ var genericParametersDefinition =
+ string.Join(", ", parameters.Select(ix => $"T{ix} {ParameterName}{ix}"));
+ genericParametersDefinition = string.IsNullOrEmpty(genericParametersDefinition)
+ ? string.Empty
+ : $", {genericParametersDefinition}";
+
+ var objectParameters = string.Join(", ", parameters.Select(ix => $"{ParameterName}{ix}"));
+ objectParameters = string.IsNullOrEmpty(objectParameters)
+ ? string.Empty
+ : $", new object?[] {{ {objectParameters} }}";
+
+ sb.WriteLine($"public static IDisposable? BeginScope{genericTypesDefinition}(this ILogger {LoggerParameterName}, string {MessageParameterName}{genericParametersDefinition})");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ sb.WriteLine($"return {DefaultLoggingNamespace}.{nameof(LoggerExtensions)}.{nameof(LoggerExtensions.BeginScope)}({LoggerParameterName}, {MessageParameterName}{objectParameters});");
+
+ sb.Indent--;
+ sb.WriteLine('}');
+
+ sb.WriteLine();
+ }
+
+ sb.Indent--;
+ sb.WriteLine('}');
+
+ sb.Indent--;
+ sb.WriteLine('}');
+
+ return sb.InnerWriter.ToString()!;
+ }
+}
diff --git a/src/AutoLoggerMessageGenerator/Emitters/LoggerInterceptorsEmitter.cs b/src/AutoLoggerMessageGenerator/Emitters/LoggerInterceptorsEmitter.cs
index b1414d2..fe25f55 100644
--- a/src/AutoLoggerMessageGenerator/Emitters/LoggerInterceptorsEmitter.cs
+++ b/src/AutoLoggerMessageGenerator/Emitters/LoggerInterceptorsEmitter.cs
@@ -1,12 +1,11 @@
using System.CodeDom.Compiler;
using AutoLoggerMessageGenerator.Models;
-using AutoLoggerMessageGenerator.Utilities;
namespace AutoLoggerMessageGenerator.Emitters;
internal static class LoggerInterceptorsEmitter
{
- public static string Emit(IEnumerable logCalls)
+ public static string Emit(IEnumerable logCalls)
{
using var sb = new IndentedTextWriter(new StringWriter());
@@ -26,7 +25,6 @@ public static string Emit(IEnumerable logCalls)
foreach (var logCall in logCalls)
{
- sb.WriteLine(Constants.EditorNotBrowsableAttribute);
sb.WriteLine(logCall.Location.InterceptableLocationSyntax);
var parameters = string.Join(", ", logCall.Parameters.Select((c, i) => $"{c.NativeType} {c.Name}"));
@@ -37,15 +35,11 @@ public static string Emit(IEnumerable logCalls)
.Select((c, i) => c.Name));
parameterValues = string.IsNullOrEmpty(parameterValues) ? string.Empty : $", {parameterValues}";
- var methodName = IdentifierHelper.ToValidCSharpMethodName(
- $"{Constants.LogMethodPrefix}{logCall.Namespace}{logCall.ClassName}_{logCall.Location.Line}_{logCall.Location.Character}"
- );
-
- sb.WriteLine($"public static void {methodName}(this ILogger {Constants.LoggerParameterName}{parameters})");
+ sb.WriteLine($"public static void {logCall.GeneratedMethodName}(this ILogger {Constants.LoggerParameterName}{parameters})");
sb.WriteLine('{');
sb.Indent++;
- sb.WriteLine($"{Constants.GeneratorNamespace}.{Constants.LoggerClassName}.{methodName}({Constants.LoggerParameterName}{parameterValues});");
+ sb.WriteLine($"{Constants.GeneratorNamespace}.{Constants.LoggerClassName}.{logCall.GeneratedMethodName}({Constants.LoggerParameterName}{parameterValues});");
sb.Indent--;
sb.WriteLine('}');
diff --git a/src/AutoLoggerMessageGenerator/Emitters/LoggerScopeInterceptorsEmitter.cs b/src/AutoLoggerMessageGenerator/Emitters/LoggerScopeInterceptorsEmitter.cs
new file mode 100644
index 0000000..6ec7361
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Emitters/LoggerScopeInterceptorsEmitter.cs
@@ -0,0 +1,57 @@
+using System.CodeDom.Compiler;
+using AutoLoggerMessageGenerator.Models;
+
+namespace AutoLoggerMessageGenerator.Emitters;
+
+internal static class LoggerScopeInterceptorsEmitter
+{
+ public static string Emit(IEnumerable loggerScopes)
+ {
+ using var sb = new IndentedTextWriter(new StringWriter());
+
+ sb.WriteLine(Constants.GeneratedFileHeader);
+
+ sb.WriteLine($"namespace {Constants.GeneratorNamespace}");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ sb.WriteLine(Constants.GeneratedCodeAttribute);
+ sb.WriteLine(Constants.EditorNotBrowsableAttribute);
+ sb.WriteLine(Constants.ExcludeFromCoverageAttribute);
+ sb.WriteLine(Constants.DebuggerStepThroughAttribute);
+ sb.WriteLine("internal static class LoggerScopeInterceptors");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ foreach (var loggerScope in loggerScopes)
+ {
+ sb.WriteLine(loggerScope.Location.InterceptableLocationSyntax);
+
+ var parameters = string.Join(", ", loggerScope.Parameters.Select((c, i) => $"{c.NativeType} {c.Name}"));
+ parameters = string.IsNullOrEmpty(parameters) ? string.Empty : $", {parameters}";
+
+ var parameterValues = string.Join(", ", loggerScope.Parameters
+ .Where(c => c.Name != Constants.MessageParameterName)
+ .Select((c, i) => c.Name));
+ parameterValues = string.IsNullOrEmpty(parameterValues) ? string.Empty : $", {parameterValues}";
+
+ sb.WriteLine($"public static IDisposable? {loggerScope.GeneratedMethodName}(this ILogger {Constants.LoggerParameterName}{parameters})");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ sb.WriteLine($"return {Constants.GeneratorNamespace}.{Constants.LoggerScopesGeneratorName}.{loggerScope.GeneratedMethodName}({Constants.LoggerParameterName}{parameterValues});");
+
+ sb.Indent--;
+ sb.WriteLine('}');
+ sb.WriteLine();
+ }
+
+ sb.Indent--;
+ sb.WriteLine('}');
+
+ sb.Indent--;
+ sb.WriteLine('}');
+
+ return sb.InnerWriter.ToString()!;
+ }
+}
diff --git a/src/AutoLoggerMessageGenerator/Emitters/LoggerScopesEmitter.cs b/src/AutoLoggerMessageGenerator/Emitters/LoggerScopesEmitter.cs
new file mode 100644
index 0000000..6bd9780
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Emitters/LoggerScopesEmitter.cs
@@ -0,0 +1,63 @@
+using System.CodeDom.Compiler;
+using System.Collections.Immutable;
+using AutoLoggerMessageGenerator.Models;
+using static AutoLoggerMessageGenerator.Constants;
+
+namespace AutoLoggerMessageGenerator.Emitters;
+
+internal static class LoggerScopesEmitter
+{
+ public static string Emit(ImmutableArray loggerScopes)
+ {
+ using var sb = new IndentedTextWriter(new StringWriter());
+
+ sb.WriteLine(GeneratedFileHeader);
+
+ sb.WriteLine($"namespace {GeneratorNamespace}");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ sb.WriteLine(Constants.GeneratedCodeAttribute);
+ sb.WriteLine(EditorNotBrowsableAttribute);
+ sb.WriteLine($"public static class {LoggerScopesGeneratorName}");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ foreach (var loggerScope in loggerScopes)
+ {
+ var parameters = loggerScope.Parameters.Where(c => c.Name != MessageParameterName).ToArray();
+
+ var genericTypes = string.Join(", ", parameters.Select(c => c.NativeType));
+ var defineScopeGenericTypes = genericTypes == string.Empty ? string.Empty : $"<{genericTypes}>";
+ genericTypes = string.IsNullOrEmpty(genericTypes) ? string.Empty : $", {genericTypes}";
+
+ var parameterList = string.Join(", ", parameters.Select(c => $"{c.NativeType} {c.Name}"));
+ parameterList = string.IsNullOrEmpty(parameterList) ? string.Empty : $", {parameterList}";
+
+ var parameterValues = string.Join(", ", parameters.Where(c => c.Name != MessageParameterName).Select(c => c.Name));
+ parameterValues = string.IsNullOrEmpty(parameterValues) ? string.Empty : $", {parameterValues}";
+
+ var loggerDefineFunctorName = $"_{loggerScope.GeneratedMethodName}";
+ sb.WriteLine($"private static readonly Func {loggerDefineFunctorName} = LoggerMessage.DefineScope{defineScopeGenericTypes}(\"{loggerScope.Message}\");");
+
+ sb.WriteLine($"public static IDisposable? {loggerScope.GeneratedMethodName}(ILogger @logger{parameterList})");
+ sb.WriteLine('{');
+ sb.Indent++;
+
+ sb.WriteLine($"return {loggerDefineFunctorName}(@logger{parameterValues});");
+
+ sb.Indent--;
+ sb.WriteLine('}');
+
+ sb.WriteLine();
+ }
+
+ sb.Indent--;
+ sb.WriteLine('}');
+
+ sb.Indent--;
+ sb.WriteLine('}');
+
+ return sb.InnerWriter.ToString()!;
+ }
+}
diff --git a/src/AutoLoggerMessageGenerator/Extractors/LogCallParametersExtractor.cs b/src/AutoLoggerMessageGenerator/Extractors/CallParametersExtractor.cs
similarity index 75%
rename from src/AutoLoggerMessageGenerator/Extractors/LogCallParametersExtractor.cs
rename to src/AutoLoggerMessageGenerator/Extractors/CallParametersExtractor.cs
index 6144d1c..388ca00 100644
--- a/src/AutoLoggerMessageGenerator/Extractors/LogCallParametersExtractor.cs
+++ b/src/AutoLoggerMessageGenerator/Extractors/CallParametersExtractor.cs
@@ -8,11 +8,11 @@
namespace AutoLoggerMessageGenerator.Extractors;
-internal class LogCallParametersExtractor(LogPropertiesCheck? logPropertiesCheck = null)
+internal class CallParametersExtractor(LogPropertiesCheck? logPropertiesCheck = null)
{
- public ImmutableArray? Extract(string message, IMethodSymbol methodSymbol)
+ public ImmutableArray? Extract(string message, IMethodSymbol methodSymbol)
{
- var templateParametersNames = LogCallMessageParameterNamesExtractor.Extract(message)
+ var templateParametersNames = MessageParameterNamesExtractor.Extract(message)
.Select(IdentifierHelper.AddAtPrefixIfNotExists)
.ToArray();
@@ -40,12 +40,12 @@ internal class LogCallParametersExtractor(LogPropertiesCheck? logPropertiesCheck
var parameterName = TransformParameterName(parameter.Name);
var type = parameterName switch
{
- LoggerParameterName => LogCallParameterType.Logger,
- LogLevelParameterName => LogCallParameterType.LogLevel,
- ExceptionParameterName => LogCallParameterType.Exception,
- EventIdParameterName => LogCallParameterType.EventId,
- MessageParameterName => LogCallParameterType.Message,
- _ => LogCallParameterType.None
+ LoggerParameterName => CallParameterType.Logger,
+ LogLevelParameterName => CallParameterType.LogLevel,
+ ExceptionParameterName => CallParameterType.Exception,
+ EventIdParameterName => CallParameterType.EventId,
+ MessageParameterName => CallParameterType.Message,
+ _ => CallParameterType.None
};
return CreateLogCallParameter(parameter.Type, $"{parameterName}{uniqueNameSuffix}", type, false);
});
@@ -54,7 +54,7 @@ internal class LogCallParametersExtractor(LogPropertiesCheck? logPropertiesCheck
.Select((parameter, ix) => CreateLogCallParameter(
nativeType: parameter.Type,
name: templateParametersNames[ix],
- type: LogCallParameterType.Others,
+ type: CallParameterType.Others,
hasPropertiesToLog: logPropertiesCheck?.IsApplicable(parameter.Type) ?? false
)
);
@@ -62,8 +62,7 @@ internal class LogCallParametersExtractor(LogPropertiesCheck? logPropertiesCheck
return utilityParameters.Concat(messageParameters).ToImmutableArray();
}
- private static LogCallParameter CreateLogCallParameter(ITypeSymbol @nativeType, string name,
- LogCallParameterType type, bool hasPropertiesToLog) =>
+ private static CallParameter CreateLogCallParameter(ITypeSymbol @nativeType, string name, CallParameterType type, bool hasPropertiesToLog) =>
new(
NativeType: nativeType.ToDisplayString(
SymbolDisplayFormat.FullyQualifiedFormat.WithMiscellaneousOptions(SymbolDisplayMiscellaneousOptions
diff --git a/src/AutoLoggerMessageGenerator/Extractors/LogCallCallerExtractor.cs b/src/AutoLoggerMessageGenerator/Extractors/EnclosingClassExtractor.cs
similarity index 92%
rename from src/AutoLoggerMessageGenerator/Extractors/LogCallCallerExtractor.cs
rename to src/AutoLoggerMessageGenerator/Extractors/EnclosingClassExtractor.cs
index b0e4bc8..1f2ca2f 100644
--- a/src/AutoLoggerMessageGenerator/Extractors/LogCallCallerExtractor.cs
+++ b/src/AutoLoggerMessageGenerator/Extractors/EnclosingClassExtractor.cs
@@ -3,21 +3,21 @@
namespace AutoLoggerMessageGenerator.Extractors;
-internal static class LogCallCallerExtractor
+internal static class EnclosingClassExtractor
{
public static (string Namespace, string ClassName) Extract(InvocationExpressionSyntax invocationExpression)
{
string className = string.Empty, ns = string.Empty;
-
+
SyntaxNode syntaxNode = invocationExpression;
while (syntaxNode.Parent is not null)
{
if (syntaxNode is ClassDeclarationSyntax classDeclarationSyntax)
className = classDeclarationSyntax.Identifier.Text;
-
+
if (syntaxNode is NamespaceDeclarationSyntax namespaceDeclarationSyntax)
ns = namespaceDeclarationSyntax.Name.ToString();
-
+
if (syntaxNode is FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax)
ns = fileScopedNamespaceDeclarationSyntax.Name.ToString();
diff --git a/src/AutoLoggerMessageGenerator/Extractors/LogCallExtractor.cs b/src/AutoLoggerMessageGenerator/Extractors/LogCallExtractor.cs
index 3cbc39b..dcc631a 100644
--- a/src/AutoLoggerMessageGenerator/Extractors/LogCallExtractor.cs
+++ b/src/AutoLoggerMessageGenerator/Extractors/LogCallExtractor.cs
@@ -8,13 +8,13 @@ namespace AutoLoggerMessageGenerator.Extractors;
internal static class LogCallExtractor
{
- public static LogCall? Extract(IMethodSymbol methodSymbol,
+ public static LogMessageCall? Extract(IMethodSymbol methodSymbol,
InvocationExpressionSyntax invocationExpression,
SemanticModel semanticModel)
{
- var (ns, className) = LogCallCallerExtractor.Extract(invocationExpression);
+ var (ns, className) = EnclosingClassExtractor.Extract(invocationExpression);
- var location = LogCallLocationMapper.Map(semanticModel, invocationExpression);
+ var location = CallLocationMapper.Map(semanticModel, invocationExpression);
if (location is null)
return default;
@@ -22,17 +22,17 @@ internal static class LogCallExtractor
if (logLevel is null)
return default;
- var message = LogCallMessageExtractor.Extract(methodSymbol, invocationExpression, semanticModel);
+ var message = MessageParameterTextExtractor.Extract(methodSymbol, invocationExpression, semanticModel);
if (message is null)
return default;
var logPropertiesCheck = new LogPropertiesCheck(semanticModel.Compilation);
- var parameters = new LogCallParametersExtractor(logPropertiesCheck)
+ var parameters = new CallParametersExtractor(logPropertiesCheck)
.Extract(message, methodSymbol);
if (parameters is null)
return default;
- return new LogCall(Guid.NewGuid(), location.Value, ns, className, methodSymbol.Name, logLevel, message, parameters.Value);
+ return new LogMessageCall(Guid.NewGuid(), location.Value, ns, className, methodSymbol.Name, logLevel, message, parameters.Value);
}
}
diff --git a/src/AutoLoggerMessageGenerator/Extractors/LoggerScopeCallExtractor.cs b/src/AutoLoggerMessageGenerator/Extractors/LoggerScopeCallExtractor.cs
new file mode 100644
index 0000000..2ebcba4
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Extractors/LoggerScopeCallExtractor.cs
@@ -0,0 +1,34 @@
+using AutoLoggerMessageGenerator.Import.Microsoft.Extensions.Telemetry.LoggerMessage;
+using AutoLoggerMessageGenerator.Mappers;
+using AutoLoggerMessageGenerator.Models;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace AutoLoggerMessageGenerator.Extractors;
+
+internal static class LoggerScopeCallExtractor
+{
+ public static LoggerScopeCall? Extract(IMethodSymbol methodSymbol,
+ InvocationExpressionSyntax invocationExpression,
+ SemanticModel semanticModel)
+ {
+ var (ns, className) = EnclosingClassExtractor.Extract(invocationExpression);
+
+ var location = CallLocationMapper.Map(semanticModel, invocationExpression);
+ if (location is null)
+ return default;
+
+ var message = MessageParameterTextExtractor.Extract(methodSymbol, invocationExpression, semanticModel);
+ if (message is null)
+ return default;
+
+ var logPropertiesCheck = new LogPropertiesCheck(semanticModel.Compilation);
+ var parameters = new CallParametersExtractor(logPropertiesCheck)
+ .Extract(message, methodSymbol);
+
+ if (parameters is null)
+ return default;
+
+ return new LoggerScopeCall(location.Value, ns, className, methodSymbol.Name, message, parameters.Value);
+ }
+}
diff --git a/src/AutoLoggerMessageGenerator/Extractors/LogCallMessageParameterNamesExtractor.cs b/src/AutoLoggerMessageGenerator/Extractors/MessageParameterNamesExtractor.cs
similarity index 88%
rename from src/AutoLoggerMessageGenerator/Extractors/LogCallMessageParameterNamesExtractor.cs
rename to src/AutoLoggerMessageGenerator/Extractors/MessageParameterNamesExtractor.cs
index 5ede393..7a51c9b 100644
--- a/src/AutoLoggerMessageGenerator/Extractors/LogCallMessageParameterNamesExtractor.cs
+++ b/src/AutoLoggerMessageGenerator/Extractors/MessageParameterNamesExtractor.cs
@@ -3,7 +3,7 @@
namespace AutoLoggerMessageGenerator.Extractors;
-internal static class LogCallMessageParameterNamesExtractor
+internal static class MessageParameterNamesExtractor
{
public static ImmutableArray Extract(string? message) =>
MessageArgumentRegex.Matches(message ?? string.Empty)
diff --git a/src/AutoLoggerMessageGenerator/Extractors/LogCallMessageExtractor.cs b/src/AutoLoggerMessageGenerator/Extractors/MessageParameterTextExtractor.cs
similarity index 89%
rename from src/AutoLoggerMessageGenerator/Extractors/LogCallMessageExtractor.cs
rename to src/AutoLoggerMessageGenerator/Extractors/MessageParameterTextExtractor.cs
index 28e30e6..6d5187e 100644
--- a/src/AutoLoggerMessageGenerator/Extractors/LogCallMessageExtractor.cs
+++ b/src/AutoLoggerMessageGenerator/Extractors/MessageParameterTextExtractor.cs
@@ -4,12 +4,15 @@
namespace AutoLoggerMessageGenerator.Extractors;
-internal static class LogCallMessageExtractor
+internal static class MessageParameterTextExtractor
{
public static string? Extract(IMethodSymbol methodSymbol, InvocationExpressionSyntax invocationExpressionSyntax,
SemanticModel semanticModel)
{
- var messageParameter = methodSymbol.Parameters.Single(c => c.Name == Constants.MessageParameterName.TrimStart('@'));
+ var messageParameter = methodSymbol.Parameters.FirstOrDefault(c => c.Name == Constants.MessageParameterName.TrimStart('@'));
+ if (messageParameter is null)
+ return null;
+
var messageParameterIx = methodSymbol.Parameters.IndexOf(messageParameter);
var valueExpression = invocationExpressionSyntax.ArgumentList.Arguments[messageParameterIx].Expression;
diff --git a/src/AutoLoggerMessageGenerator/Filters/LogCallFilter.cs b/src/AutoLoggerMessageGenerator/Filters/LogMessageCallFilter.cs
similarity index 75%
rename from src/AutoLoggerMessageGenerator/Filters/LogCallFilter.cs
rename to src/AutoLoggerMessageGenerator/Filters/LogMessageCallFilter.cs
index 7a34ffc..5927313 100644
--- a/src/AutoLoggerMessageGenerator/Filters/LogCallFilter.cs
+++ b/src/AutoLoggerMessageGenerator/Filters/LogMessageCallFilter.cs
@@ -1,11 +1,12 @@
+using AutoLoggerMessageGenerator.Utilities;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Extensions.Logging;
-using static AutoLoggerMessageGenerator.Emitters.LoggerExtensionsEmitter;
+using static AutoLoggerMessageGenerator.Emitters.GenericLoggerExtensionsEmitter;
namespace AutoLoggerMessageGenerator.Filters;
-internal static class LogCallFilter
+internal static class LogMessageCallFilter
{
private static readonly HashSet LogMethodNames =
[
@@ -24,7 +25,7 @@ public static bool IsLoggerMethod(IMethodSymbol methodSymbol) =>
methodSymbol.IsExtensionMethod &&
methodSymbol.Parameters.All(c =>
c.Type.IsAnonymousType is not true && c.Type.TypeKind is not TypeKind.TypeParameter &&
- RecursivelyCheckTypeAccessibility(c.Type)
+ TypeAccessibilityChecker.IsAccessible(c.Type)
);
public static bool IsLogCallInvocation(SyntaxNode node, CancellationToken cts) =>
@@ -33,8 +34,4 @@ public static bool IsLogCallInvocation(SyntaxNode node, CancellationToken cts) =
!cts.IsCancellationRequested &&
invocationExpression.Expression.DescendantNodes()
.Any(c => c is IdentifierNameSyntax identifierNameSyntax && LogMethodNames.Contains(identifierNameSyntax.Identifier.Text));
-
- private static bool RecursivelyCheckTypeAccessibility(ITypeSymbol typeSymbol) =>
- typeSymbol.DeclaredAccessibility is Accessibility.Friend or Accessibility.Public or Accessibility.Internal &&
- (typeSymbol.ContainingType is null || RecursivelyCheckTypeAccessibility(typeSymbol.ContainingType));
}
diff --git a/src/AutoLoggerMessageGenerator/Filters/LoggerScopeFilter.cs b/src/AutoLoggerMessageGenerator/Filters/LoggerScopeFilter.cs
new file mode 100644
index 0000000..bcc8299
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Filters/LoggerScopeFilter.cs
@@ -0,0 +1,25 @@
+using AutoLoggerMessageGenerator.Utilities;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using static AutoLoggerMessageGenerator.Emitters.GenericLoggerScopeExtensionsEmitter;
+
+namespace AutoLoggerMessageGenerator.Filters;
+
+internal static class LoggerScopeFilter
+{
+ public static bool IsLoggerScopeMethod(IMethodSymbol methodSymbol) =>
+ methodSymbol is { ContainingType: not null, ReceiverType.Name: "ILogger", ReturnsVoid: false, ReturnType.Name: "IDisposable" } &&
+ methodSymbol.ContainingType.ToDisplayString() is $"{Constants.DefaultLoggingNamespace}.{ClassName}" &&
+ methodSymbol.IsExtensionMethod &&
+ methodSymbol.Parameters.All(c =>
+ c.Type.IsAnonymousType is not true && c.Type.TypeKind is not TypeKind.TypeParameter &&
+ TypeAccessibilityChecker.IsAccessible(c.Type)
+ );
+
+ public static bool IsLoggerScopeInvocation(SyntaxNode node, CancellationToken cts) =>
+ !node.SyntaxTree.FilePath.EndsWith(".g.cs") &&
+ node is InvocationExpressionSyntax { ArgumentList.Arguments.Count: > 1 } invocationExpression &&
+ !cts.IsCancellationRequested &&
+ invocationExpression.Expression.DescendantNodes()
+ .Any(c => c is IdentifierNameSyntax { Identifier.Text: "BeginScope" });
+}
diff --git a/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerMessage.cs b/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerMessage.cs
new file mode 100644
index 0000000..6d8b9eb
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerMessage.cs
@@ -0,0 +1,118 @@
+using System.Collections.Immutable;
+using System.Text;
+using AutoLoggerMessageGenerator.Caching;
+using AutoLoggerMessageGenerator.Configuration;
+using AutoLoggerMessageGenerator.Diagnostics;
+using AutoLoggerMessageGenerator.Emitters;
+using AutoLoggerMessageGenerator.Extractors;
+using AutoLoggerMessageGenerator.Filters;
+using AutoLoggerMessageGenerator.Models;
+using AutoLoggerMessageGenerator.PostProcessing;
+using AutoLoggerMessageGenerator.ReferenceAnalyzer;
+using AutoLoggerMessageGenerator.VirtualLoggerMessage;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+using Microsoft.Extensions.Logging.Generators;
+using Microsoft.Gen.Logging.Parsing;
+
+namespace AutoLoggerMessageGenerator.Generators;
+
+public partial class AutoLoggerMessageGenerator
+{
+ private static void GenerateLoggerMessages(IncrementalGeneratorInitializationContext context,
+ IncrementalValueProvider configuration, IncrementalValueProvider> modulesProvider)
+ {
+ var logCallsProvider = context.SyntaxProvider.CreateSyntaxProvider(
+ LogMessageCallFilter.IsLogCallInvocation,
+ static (ctx, cts) => ParseLogCall(ctx, cts)
+ )
+ .Where(static t => t.HasValue)
+ .Select(static (t, _) => t!.Value)
+ .Collect()
+ .WithTrackingName("Searching for log calls");
+
+ var inputSource = context.CompilationProvider.Combine(configuration.Combine(modulesProvider.Combine(logCallsProvider)))
+ .WithComparer(new LogCallInputSourceComparer());
+
+ context.RegisterImplementationSourceOutput(inputSource,
+ static (ctx, t) => GenerateCode(ctx, t.Item1, t.Item2.Item1, t.Item2.Item2.Item1, t.Item2.Item2.Item2));
+ }
+
+ private static LogMessageCall? ParseLogCall(GeneratorSyntaxContext context, CancellationToken cts)
+ {
+ var semanticModel = context.SemanticModel;
+ var invocationExpression = (InvocationExpressionSyntax)context.Node;
+ var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression);
+
+ if (symbolInfo.Symbol is not IMethodSymbol methodSymbol ||
+ !LogMessageCallFilter.IsLoggerMethod(methodSymbol) ||
+ cts.IsCancellationRequested)
+ return default;
+
+ return LogCallExtractor.Extract(methodSymbol, invocationExpression, semanticModel);
+ }
+
+ private static void GenerateCode(SourceProductionContext context, Compilation compilation,
+ SourceGeneratorConfiguration configuration, ImmutableArray modules,
+ ImmutableArray logCalls)
+ {
+ if (logCalls.IsDefaultOrEmpty || context.CancellationToken.IsCancellationRequested) return;
+
+ var telemetryAbstractions = "Microsoft.Extensions.Telemetry.Abstractions.dll";
+ var useTelemetryExtensions = modules.Any(c => c.Name == telemetryAbstractions);
+
+ // We need to keep the current LoggerMessage source generator as it makes future updates easier.
+ // All [LoggerMessage] attributes are generated to match the current implementation.
+ // These attributes are only used to trigger the source generator, so we can create them virtually and add them to the compilation unit.
+ var virtualClassDeclaration = new VirtualLoggerMessageClassBuilder(configuration, useTelemetryExtensions)
+ .Build(logCalls);
+ compilation = VirtualMembersInjector.InjectMembers(compilation, virtualClassDeclaration);
+
+ var classDeclarations = compilation.SyntaxTrees.Last()
+ .GetRoot()
+ .DescendantNodes()
+ .OfType()
+ .ToImmutableHashSet();
+
+ var diagnosticReporter = new LogMessageDiagnosticReporter(context, logCalls);
+
+ var loggerMessageCode = useTelemetryExtensions
+ ? GenerateNewLoggerMessage(diagnosticReporter, compilation, classDeclarations, context.CancellationToken)
+ : GenerateOldLoggerMessage(diagnosticReporter, compilation, classDeclarations, context.CancellationToken);
+
+ if (context.CancellationToken.IsCancellationRequested) return;
+
+ loggerMessageCode = LoggerMessageResultAdjuster.Adjust(loggerMessageCode);
+ if (!string.IsNullOrEmpty(loggerMessageCode))
+ context.AddSource($"{Constants.LoggerMessageGeneratorName}.g.cs", SourceText.From(loggerMessageCode!, Encoding.UTF8));
+
+ context.AddSource("LogCallInterceptors.g.cs", SourceText.From(LoggerInterceptorsEmitter.Emit(logCalls), Encoding.UTF8));
+ }
+
+ private static string? GenerateNewLoggerMessage(
+ LogMessageDiagnosticReporter diagnosticReporter, Compilation compilation,
+ ImmutableHashSet classDeclarationSyntaxes, CancellationToken cts)
+ {
+ var p = new Parser(compilation, diagnosticReporter.Report, cts);
+ var logTypes = p.GetLogTypes(classDeclarationSyntaxes);
+
+ if (logTypes.Count <= 0) return null;
+
+ var e = new Microsoft.Gen.Logging.Emission.Emitter();
+ return e.Emit(logTypes, cts);
+ }
+
+ private static string? GenerateOldLoggerMessage(
+ LogMessageDiagnosticReporter diagnosticReporter, Compilation compilation,
+ ImmutableHashSet classDeclarationSyntaxes, CancellationToken cts)
+ {
+ var loggerMessageParser = new LoggerMessageGenerator.Parser(compilation, diagnosticReporter.Report, cts);
+ var logClasses = loggerMessageParser.GetLogClasses(classDeclarationSyntaxes);
+
+ if (logClasses.Count <= 0) return null;
+
+ var loggerMessageEmitter = new LoggerMessageGenerator.Emitter();
+ return loggerMessageEmitter.Emit(logClasses, cts);
+ }
+}
diff --git a/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerScopes.cs b/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerScopes.cs
new file mode 100644
index 0000000..f1af1aa
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerScopes.cs
@@ -0,0 +1,64 @@
+using System.Collections.Immutable;
+using System.Text;
+using AutoLoggerMessageGenerator.Caching;
+using AutoLoggerMessageGenerator.Configuration;
+using AutoLoggerMessageGenerator.Emitters;
+using AutoLoggerMessageGenerator.Extractors;
+using AutoLoggerMessageGenerator.Filters;
+using AutoLoggerMessageGenerator.Models;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+
+namespace AutoLoggerMessageGenerator.Generators;
+
+public partial class AutoLoggerMessageGenerator
+{
+ private static void GenerateLoggerScopes(IncrementalGeneratorInitializationContext context, IncrementalValueProvider configuration)
+ {
+ var loggerScopeProvider = context.SyntaxProvider.CreateSyntaxProvider(
+ LoggerScopeFilter.IsLoggerScopeInvocation,
+ static (ctx, cts) => ParseLoggerScope(ctx, cts)
+ )
+ .Where(static t => t.HasValue)
+ .Select(static (t, _) => t!.Value)
+ .Collect()
+ .WithTrackingName("Searching for log scope definitions");
+
+ var inputSource = context.CompilationProvider.Combine(configuration.Combine(loggerScopeProvider))
+ .WithComparer(new LogScopeDefinitionInputSourceComparer());
+
+ context.RegisterImplementationSourceOutput(inputSource, static (ctx, t) =>
+ GenerateCode(ctx, t.Item2.Item1, t.Item2.Item2));
+ }
+
+ private static LoggerScopeCall? ParseLoggerScope(GeneratorSyntaxContext context, CancellationToken cts)
+ {
+ var semanticModel = context.SemanticModel;
+ var invocationExpression = (InvocationExpressionSyntax)context.Node;
+ var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression);
+
+ if (symbolInfo.Symbol is not IMethodSymbol methodSymbol ||
+ !LoggerScopeFilter.IsLoggerScopeMethod(methodSymbol) ||
+ cts.IsCancellationRequested)
+ return default;
+
+ return LoggerScopeCallExtractor.Extract(methodSymbol, invocationExpression, semanticModel);
+ }
+
+ private static void GenerateCode(SourceProductionContext context,
+ SourceGeneratorConfiguration configuration, ImmutableArray loggerScopes)
+ {
+ if (context.CancellationToken.IsCancellationRequested ||
+ loggerScopes.IsDefaultOrEmpty ||
+ !configuration.OverrideBeginScopeBehavior)
+ return;
+
+ var generatedLoggerScopes = LoggerScopesEmitter.Emit(loggerScopes);
+
+ if (!string.IsNullOrEmpty(generatedLoggerScopes))
+ context.AddSource($"{Constants.LoggerScopesGeneratorName}.g.cs", SourceText.From(generatedLoggerScopes, Encoding.UTF8));
+
+ context.AddSource("LoggerScopeInterceptors.g.cs", SourceText.From(LoggerScopeInterceptorsEmitter.Emit(loggerScopes), Encoding.UTF8));
+ }
+}
diff --git a/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.cs b/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.cs
index 17a7330..3feb67f 100644
--- a/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.cs
+++ b/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.cs
@@ -1,25 +1,14 @@
-using System.Collections.Immutable;
using System.Text;
-using AutoLoggerMessageGenerator.Caching;
using AutoLoggerMessageGenerator.Configuration;
-using AutoLoggerMessageGenerator.Diagnostics;
using AutoLoggerMessageGenerator.Emitters;
-using AutoLoggerMessageGenerator.Extractors;
-using AutoLoggerMessageGenerator.Filters;
-using AutoLoggerMessageGenerator.Models;
-using AutoLoggerMessageGenerator.PostProcessing;
using AutoLoggerMessageGenerator.ReferenceAnalyzer;
-using AutoLoggerMessageGenerator.VirtualLoggerMessage;
using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
-using Microsoft.Extensions.Logging.Generators;
-using Microsoft.Gen.Logging.Parsing;
namespace AutoLoggerMessageGenerator.Generators;
[Generator]
-public class AutoLoggerMessageGenerator : IIncrementalGenerator
+public partial class AutoLoggerMessageGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
@@ -30,102 +19,18 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
.Collect()
.WithTrackingName("Scanning project references");
- var logCallsProvider = context.SyntaxProvider.CreateSyntaxProvider(
- LogCallFilter.IsLogCallInvocation,
- static (ctx, cts) => GetLogCalls(ctx, cts)
- )
- .Where(static t => t.HasValue)
- .Select(static (t, _) => t!.Value)
- .Collect()
- .WithTrackingName("Searching for log calls");
-
- var inputSource = context.CompilationProvider.Combine(configuration.Combine(modulesProvider.Combine(logCallsProvider)))
- .WithComparer(new InputSourceComparer());
-
- context.RegisterImplementationSourceOutput(inputSource,
- static (ctx, t) => GenerateCode(ctx, t.Item1, t.Item2.Item1, t.Item2.Item2.Item1, t.Item2.Item2.Item2));
+ GenerateLoggerMessages(context, configuration, modulesProvider);
+ GenerateLoggerScopes(context, configuration);
+ GenerateInterceptorAttribute(context, configuration);
+ }
+ private static void GenerateInterceptorAttribute(IncrementalGeneratorInitializationContext context,
+ IncrementalValueProvider configuration)
+ {
context.RegisterImplementationSourceOutput(configuration, static (ctx, configuration) =>
{
if (configuration.GenerateInterceptorAttribute)
ctx.AddSource("InterceptorAttribute.g.cs", SourceText.From(InterceptorAttributeEmitter.Emit(), Encoding.UTF8));
});
}
-
- private static LogCall? GetLogCalls(GeneratorSyntaxContext context, CancellationToken cts)
- {
- var semanticModel = context.SemanticModel;
- var invocationExpression = (InvocationExpressionSyntax)context.Node;
- var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression);
-
- if (symbolInfo.Symbol is not IMethodSymbol methodSymbol ||
- !LogCallFilter.IsLoggerMethod(methodSymbol) ||
- cts.IsCancellationRequested)
- return default;
-
- return LogCallExtractor.Extract(methodSymbol, invocationExpression, semanticModel);
- }
-
- private static void GenerateCode(SourceProductionContext context, Compilation compilation,
- SourceGeneratorConfiguration configuration, ImmutableArray modules,
- ImmutableArray logCalls)
- {
- if (logCalls.IsDefaultOrEmpty || context.CancellationToken.IsCancellationRequested) return;
-
- var telemetryAbstractions = "Microsoft.Extensions.Telemetry.Abstractions.dll";
- var useTelemetryExtensions = modules.Any(c => c.Name == telemetryAbstractions);
-
- // We need to keep the current LoggerMessage source generator as it makes future updates easier.
- // All [LoggerMessage] attributes are generated to match the current implementation.
- // These attributes are only used to trigger the source generator, so we can create them virtually and add them to the compilation unit.
- var virtualClassDeclaration = new VirtualLoggerMessageClassBuilder(configuration, useTelemetryExtensions)
- .Build(logCalls);
- compilation = VirtualMembersInjector.InjectMembers(compilation, virtualClassDeclaration);
-
- var classDeclarations = compilation.SyntaxTrees.Last()
- .GetRoot()
- .DescendantNodes()
- .OfType()
- .ToImmutableHashSet();
-
- var diagnosticReporter = new DiagnosticReporter(context, logCalls);
-
- var loggerMessageCode = useTelemetryExtensions
- ? GenerateNewLoggerMessage(diagnosticReporter, compilation, classDeclarations, context.CancellationToken)
- : GenerateOldLoggerMessage(diagnosticReporter, compilation, classDeclarations, context.CancellationToken);
-
- if (context.CancellationToken.IsCancellationRequested) return;
-
- loggerMessageCode = LoggerMessageResultAdjuster.Adjust(loggerMessageCode);
- if (!string.IsNullOrEmpty(loggerMessageCode))
- context.AddSource("LoggerMessage.g.cs", SourceText.From(loggerMessageCode!, Encoding.UTF8));
-
- context.AddSource("Interceptors.g.cs", SourceText.From(LoggerInterceptorsEmitter.Emit(logCalls), Encoding.UTF8));
- }
-
- private static string? GenerateNewLoggerMessage(
- DiagnosticReporter diagnosticReporter, Compilation compilation,
- ImmutableHashSet classDeclarationSyntaxes, CancellationToken cts)
- {
- var p = new Parser(compilation, diagnosticReporter.Report, cts);
- var logTypes = p.GetLogTypes(classDeclarationSyntaxes);
-
- if (logTypes.Count <= 0) return null;
-
- var e = new Microsoft.Gen.Logging.Emission.Emitter();
- return e.Emit(logTypes, cts);
- }
-
- private static string? GenerateOldLoggerMessage(
- DiagnosticReporter diagnosticReporter, Compilation compilation,
- ImmutableHashSet classDeclarationSyntaxes, CancellationToken cts)
- {
- var loggerMessageParser = new LoggerMessageGenerator.Parser(compilation, diagnosticReporter.Report, cts);
- var logClasses = loggerMessageParser.GetLogClasses(classDeclarationSyntaxes);
-
- if (logClasses.Count <= 0) return null;
-
- var loggerMessageEmitter = new LoggerMessageGenerator.Emitter();
- return loggerMessageEmitter.Emit(logClasses, cts);
- }
}
diff --git a/src/AutoLoggerMessageGenerator/Mappers/LogCallLocationMapper.cs b/src/AutoLoggerMessageGenerator/Mappers/CallLocationMapper.cs
similarity index 85%
rename from src/AutoLoggerMessageGenerator/Mappers/LogCallLocationMapper.cs
rename to src/AutoLoggerMessageGenerator/Mappers/CallLocationMapper.cs
index e6354dd..a15dd14 100644
--- a/src/AutoLoggerMessageGenerator/Mappers/LogCallLocationMapper.cs
+++ b/src/AutoLoggerMessageGenerator/Mappers/CallLocationMapper.cs
@@ -1,5 +1,3 @@
-using System.Diagnostics;
-using System.Text;
using AutoLoggerMessageGenerator.Models;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@@ -7,9 +5,9 @@
namespace AutoLoggerMessageGenerator.Mappers;
-internal static class LogCallLocationMapper
+internal static class CallLocationMapper
{
- public static LogCallLocation? Map(SemanticModel semanticModel, InvocationExpressionSyntax invocationExpression)
+ public static CallLocation? Map(SemanticModel semanticModel, InvocationExpressionSyntax invocationExpression)
{
var memberAccessExpression = invocationExpression.Expression as MemberAccessExpressionSyntax;
if (memberAccessExpression?.Expression is not IdentifierNameSyntax identifierName)
@@ -36,7 +34,7 @@ internal static class LogCallLocationMapper
if (interceptableLocation is null)
return null;
- return new LogCallLocation(filePath, line, character, interceptableLocation, location);
+ return new CallLocation(filePath, line, character, interceptableLocation, location);
}
#if PATH_BASED_INTERCEPTORS
diff --git a/src/AutoLoggerMessageGenerator/Models/LogCallLocation.cs b/src/AutoLoggerMessageGenerator/Models/CallLocation.cs
similarity index 87%
rename from src/AutoLoggerMessageGenerator/Models/LogCallLocation.cs
rename to src/AutoLoggerMessageGenerator/Models/CallLocation.cs
index 44ac9b5..38fcacd 100644
--- a/src/AutoLoggerMessageGenerator/Models/LogCallLocation.cs
+++ b/src/AutoLoggerMessageGenerator/Models/CallLocation.cs
@@ -2,7 +2,7 @@
namespace AutoLoggerMessageGenerator.Models;
-internal readonly record struct LogCallLocation(
+internal readonly record struct CallLocation(
string FilePath,
int Line,
int Character,
@@ -10,7 +10,7 @@ internal readonly record struct LogCallLocation(
Location Context
)
{
- public readonly bool Equals(LogCallLocation other) =>
+ public bool Equals(CallLocation other) =>
FilePath == other.FilePath &&
Line == other.Line &&
Character == other.Character &&
diff --git a/src/AutoLoggerMessageGenerator/Models/LogCallParameter.cs b/src/AutoLoggerMessageGenerator/Models/CallParameter.cs
similarity index 64%
rename from src/AutoLoggerMessageGenerator/Models/LogCallParameter.cs
rename to src/AutoLoggerMessageGenerator/Models/CallParameter.cs
index adb23d5..db710ed 100644
--- a/src/AutoLoggerMessageGenerator/Models/LogCallParameter.cs
+++ b/src/AutoLoggerMessageGenerator/Models/CallParameter.cs
@@ -1,9 +1,9 @@
namespace AutoLoggerMessageGenerator.Models;
-internal record struct LogCallParameter
+internal record struct CallParameter
(
string NativeType,
string Name,
- LogCallParameterType Type,
+ CallParameterType Type,
bool HasPropertiesToLog = false
);
diff --git a/src/AutoLoggerMessageGenerator/Models/LogCallParameterType.cs b/src/AutoLoggerMessageGenerator/Models/CallParameterType.cs
similarity index 79%
rename from src/AutoLoggerMessageGenerator/Models/LogCallParameterType.cs
rename to src/AutoLoggerMessageGenerator/Models/CallParameterType.cs
index 9fa8cec..8d33634 100644
--- a/src/AutoLoggerMessageGenerator/Models/LogCallParameterType.cs
+++ b/src/AutoLoggerMessageGenerator/Models/CallParameterType.cs
@@ -1,6 +1,6 @@
namespace AutoLoggerMessageGenerator.Models;
-internal enum LogCallParameterType
+internal enum CallParameterType
{
None,
Logger,
diff --git a/src/AutoLoggerMessageGenerator/Models/LogCall.cs b/src/AutoLoggerMessageGenerator/Models/LogCall.cs
deleted file mode 100644
index 5144773..0000000
--- a/src/AutoLoggerMessageGenerator/Models/LogCall.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System.Collections.Immutable;
-
-namespace AutoLoggerMessageGenerator.Models;
-
-internal readonly record struct LogCall(
- // Need this property for backtracking diagnostic reports
- Guid Id,
- LogCallLocation Location,
- string Namespace,
- string ClassName,
- string Name,
- string LogLevel,
- string Message,
- ImmutableArray Parameters
-)
-{
- public bool Equals(LogCall other) =>
- Location.Equals(other.Location) &&
- Namespace == other.Namespace &&
- ClassName == other.ClassName &&
- Name == other.Name &&
- LogLevel == other.LogLevel &&
- Message == other.Message &&
- Parameters.SequenceEqual(other.Parameters);
-
- public override int GetHashCode()
- {
- unchecked
- {
- var hashCode = Location.GetHashCode();
- hashCode = (hashCode * 397) ^ Namespace.GetHashCode();
- hashCode = (hashCode * 397) ^ ClassName.GetHashCode();
- hashCode = (hashCode * 397) ^ Name.GetHashCode();
- hashCode = (hashCode * 397) ^ LogLevel.GetHashCode();
- hashCode = (hashCode * 397) ^ Message.GetHashCode();
- hashCode = (hashCode * 397) ^ Parameters.GetHashCode();
- return hashCode;
- }
- }
-};
-
diff --git a/src/AutoLoggerMessageGenerator/Models/LogMessageCall.cs b/src/AutoLoggerMessageGenerator/Models/LogMessageCall.cs
new file mode 100644
index 0000000..3f9e065
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Models/LogMessageCall.cs
@@ -0,0 +1,35 @@
+using System.Collections.Immutable;
+using AutoLoggerMessageGenerator.Utilities;
+
+namespace AutoLoggerMessageGenerator.Models;
+
+internal readonly record struct LogMessageCall(
+ // Need this property for backtracking diagnostic reports
+ Guid Id,
+ CallLocation Location,
+ string Namespace,
+ string ClassName,
+ string MethodName,
+ string LogLevel,
+ string Message,
+ ImmutableArray Parameters
+)
+{
+ public string GeneratedMethodName =>
+ IdentifierHelper.ToValidCSharpMethodName(
+ $"{Constants.LogMethodPrefix}{Namespace}{ClassName}_{Location.Line}_{Location.Character}"
+ );
+
+ public bool Equals(LogMessageCall other) =>
+ Location.Equals(other.Location) &&
+ Namespace == other.Namespace &&
+ ClassName == other.ClassName &&
+ MethodName == other.MethodName &&
+ LogLevel == other.LogLevel &&
+ Message == other.Message &&
+ Parameters.SequenceEqual(other.Parameters);
+
+ public override int GetHashCode() =>
+ (Location, Namespace, ClassName, MethodName, LogLevel, Message, Parameters).GetHashCode();
+};
+
diff --git a/src/AutoLoggerMessageGenerator/Models/LoggerScopeCall.cs b/src/AutoLoggerMessageGenerator/Models/LoggerScopeCall.cs
new file mode 100644
index 0000000..135a12c
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Models/LoggerScopeCall.cs
@@ -0,0 +1,30 @@
+using System.Collections.Immutable;
+using AutoLoggerMessageGenerator.Utilities;
+
+namespace AutoLoggerMessageGenerator.Models;
+
+internal readonly record struct LoggerScopeCall(
+ CallLocation Location,
+ string Namespace,
+ string ClassName,
+ string MethodName,
+ string Message,
+ ImmutableArray Parameters
+)
+{
+ public string GeneratedMethodName =>
+ IdentifierHelper.ToValidCSharpMethodName(
+ $"{Constants.LogScopeMethodPrefix}{Namespace}{ClassName}_{Location.Line}_{Location.Character}"
+ );
+
+ public bool Equals(LoggerScopeCall other) =>
+ Location.Equals(other.Location) &&
+ Namespace == other.Namespace &&
+ ClassName == other.ClassName &&
+ MethodName == other.MethodName &&
+ Message == other.Message &&
+ Parameters.SequenceEqual(other.Parameters);
+
+ public override int GetHashCode() => (Location, Namespace, ClassName, MethodName, Message, Parameters).GetHashCode();
+};
+
diff --git a/src/AutoLoggerMessageGenerator/Utilities/TypeAccessibilityChecker.cs b/src/AutoLoggerMessageGenerator/Utilities/TypeAccessibilityChecker.cs
new file mode 100644
index 0000000..8471c8b
--- /dev/null
+++ b/src/AutoLoggerMessageGenerator/Utilities/TypeAccessibilityChecker.cs
@@ -0,0 +1,10 @@
+using Microsoft.CodeAnalysis;
+
+namespace AutoLoggerMessageGenerator.Utilities;
+
+internal static class TypeAccessibilityChecker
+{
+ public static bool IsAccessible(ITypeSymbol typeSymbol) =>
+ typeSymbol.DeclaredAccessibility is Accessibility.Public or Accessibility.Internal &&
+ (typeSymbol.ContainingType is null || IsAccessible(typeSymbol.ContainingType));
+}
diff --git a/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/LogCallLocationMap.cs b/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/LogMessageCallLocationMap.cs
similarity index 56%
rename from src/AutoLoggerMessageGenerator/VirtualLoggerMessage/LogCallLocationMap.cs
rename to src/AutoLoggerMessageGenerator/VirtualLoggerMessage/LogMessageCallLocationMap.cs
index 75dd885..0bb4c25 100644
--- a/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/LogCallLocationMap.cs
+++ b/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/LogMessageCallLocationMap.cs
@@ -4,12 +4,12 @@
namespace AutoLoggerMessageGenerator.VirtualLoggerMessage;
-internal static class LogCallLocationMap
+internal static class LogMessageCallLocationMap
{
- private const string LogCallMappingLocationFlag = "// : ";
+ private const string LogMessageCallMappingLocationFlag = "// : ";
- public static string CreateMapping(LogCall logCall) =>
- $"{LogCallMappingLocationFlag}{logCall.Id}";
+ public static string CreateMapping(LogMessageCall logMessageCall) =>
+ $"{LogMessageCallMappingLocationFlag}{logMessageCall.Id}";
public static bool TryMapBack(SourceText syntaxTree, Location currentLocation, out Guid logCallId)
{
@@ -20,9 +20,9 @@ public static bool TryMapBack(SourceText syntaxTree, Location currentLocation, o
for (var lineIndex = subText.Lines.Count - 1; lineIndex >= 0; lineIndex--)
{
var line = subText.Lines[lineIndex].ToString().TrimStart();
- if (!line.StartsWith(LogCallMappingLocationFlag)) continue;
+ if (!line.StartsWith(LogMessageCallMappingLocationFlag)) continue;
- return Guid.TryParse(line.Substring(LogCallMappingLocationFlag.Length), out logCallId);
+ return Guid.TryParse(line.Substring(LogMessageCallMappingLocationFlag.Length), out logCallId);
}
return false;
diff --git a/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/VirtualLoggerMessageClassBuilder.cs b/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/VirtualLoggerMessageClassBuilder.cs
index 3453e01..a7daf71 100644
--- a/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/VirtualLoggerMessageClassBuilder.cs
+++ b/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/VirtualLoggerMessageClassBuilder.cs
@@ -1,7 +1,6 @@
using System.Collections.Immutable;
using AutoLoggerMessageGenerator.Configuration;
using AutoLoggerMessageGenerator.Models;
-using AutoLoggerMessageGenerator.Utilities;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -17,7 +16,7 @@ internal class VirtualLoggerMessageClassBuilder(
private const string LoggerMessageAttributeName = LoggerMessageGenerator.Parser.LoggerMessageAttribute;
private const string LogPropertiesAttribute = "Microsoft.Extensions.Logging.LogPropertiesAttribute";
- public MemberDeclarationSyntax Build(ImmutableArray logCalls)
+ public MemberDeclarationSyntax Build(ImmutableArray logCalls)
{
var methods = logCalls.Select(GenerateMethod).OfType().ToArray();
@@ -31,14 +30,14 @@ public MemberDeclarationSyntax Build(ImmutableArray logCalls)
return namespaceDeclaration;
}
- private MethodDeclarationSyntax GenerateMethod(LogCall logCall)
+ private MethodDeclarationSyntax GenerateMethod(LogMessageCall logMessageCall)
{
- var attributeList = GenerateLoggerMessageAttribute(logCall);
+ var attributeList = GenerateLoggerMessageAttribute(logMessageCall);
var loggerParameter = Parameter(Identifier("Logger"))
.WithType(IdentifierName($"{Constants.DefaultLoggingNamespace}.ILogger"));
- var parameters = logCall.Parameters
+ var parameters = logMessageCall.Parameters
.Where(c => !Constants.LoggerMessageAttributeParameterTypes.Contains(c.Type))
.Select(c =>
{
@@ -50,11 +49,8 @@ private MethodDeclarationSyntax GenerateMethod(LogCall logCall)
return parameter;
}).ToArray();
- var methodName = IdentifierHelper.ToValidCSharpMethodName(
- $"{Constants.LogMethodPrefix}{logCall.Namespace}{logCall.ClassName}_{logCall.Location.Line}_{logCall.Location.Character}");
-
- var logCallMappingLocation = ParseLeadingTrivia(LogCallLocationMap.CreateMapping(logCall));
- var methodDeclaration = MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), methodName)
+ var logCallMappingLocation = ParseLeadingTrivia(LogMessageCallLocationMap.CreateMapping(logMessageCall));
+ var methodDeclaration = MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), logMessageCall.GeneratedMethodName)
.AddModifiers(
Token(SyntaxKind.InternalKeyword),
Token(SyntaxKind.StaticKeyword),
@@ -69,7 +65,7 @@ private MethodDeclarationSyntax GenerateMethod(LogCall logCall)
return methodDeclaration;
}
- private AttributeListSyntax GenerateLoggerMessageAttribute(LogCall logCall)
+ private AttributeListSyntax GenerateLoggerMessageAttribute(LogMessageCall logMessageCall)
{
var attribute = Attribute(ParseName(LoggerMessageAttributeName))
.WithArgumentList(
@@ -78,11 +74,11 @@ private AttributeListSyntax GenerateLoggerMessageAttribute(LogCall logCall)
{
AttributeArgument(
ParseExpression(
- $"Level = {Constants.DefaultLoggingNamespace}.LogLevel.{logCall.LogLevel}")),
+ $"Level = {Constants.DefaultLoggingNamespace}.LogLevel.{logMessageCall.LogLevel}")),
AttributeArgument(
AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
IdentifierName("Message"),
- LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(logCall.Message)))),
+ LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(logMessageCall.Message)))),
AttributeArgument(
ParseExpression(
$"SkipEnabledCheck = {configuration.GenerateSkipEnabledCheck.ToLowerBooleanString()}"))
diff --git a/tests/AutoLoggerMessageGenerator.IntegrationTests/AutoLoggerMessageGenerator.IntegrationTests.csproj b/tests/AutoLoggerMessageGenerator.IntegrationTests/AutoLoggerMessageGenerator.IntegrationTests.csproj
index 930b801..302de68 100644
--- a/tests/AutoLoggerMessageGenerator.IntegrationTests/AutoLoggerMessageGenerator.IntegrationTests.csproj
+++ b/tests/AutoLoggerMessageGenerator.IntegrationTests/AutoLoggerMessageGenerator.IntegrationTests.csproj
@@ -28,7 +28,7 @@
-
-
+
+
diff --git a/tests/AutoLoggerMessageGenerator.IntegrationTests/BeginScopeWithAllParameterRangeTests.cs b/tests/AutoLoggerMessageGenerator.IntegrationTests/BeginScopeWithAllParameterRangeTests.cs
new file mode 100644
index 0000000..1cc4c57
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.IntegrationTests/BeginScopeWithAllParameterRangeTests.cs
@@ -0,0 +1,78 @@
+
+using Microsoft.Extensions.Logging;
+
+namespace AutoLoggerMessageGenerator.IntegrationTests;
+
+internal class BeginScopeWithAllParameterRangeTests
+{
+ [Test]
+ [MethodDataSource(nameof(BeginScopeMethodsWithDifferentParameters))]
+ public async Task WithAllLogMethods_RequestShouldBeForwardedToLoggerMessageSourceGenerator(Func beginScopeCall)
+ {
+ ILogger logger = LoggerFactory.Create(c =>
+ c.AddSimpleConsole(options =>
+ {
+ options.IncludeScopes = true;
+ })
+ ).CreateLogger();
+
+ var proxy = DispatchProxyExecutionVerificationDecorator.Decorate(logger,
+ Constants.LoggerScopesGeneratorName, methodName => methodName == "BeginScope");
+
+ using var _ = beginScopeCall((ILogger) proxy);
+ logger.LogInformation("Hello world");
+
+ await Assert.That(proxy.ExecutionsWithoutGenerator).IsEmpty();
+ await Assert.That(proxy.ExecutionsFromGenerator.Count).IsEqualTo(1);
+ }
+
+ [Test]
+ [MethodDataSource(nameof(BeginScopeMethodsWithUnsupportedParametersCount))]
+ public async Task WithUnsupportedParametersCount_RequestShouldBeForwardedToOriginalImplementation(Func beginScopeCall)
+ {
+ ILogger logger = LoggerFactory.Create(c =>
+ c.AddSimpleConsole().SetMinimumLevel(LogLevel.Trace)
+ ).CreateLogger();
+
+ var proxy = DispatchProxyExecutionVerificationDecorator.Decorate(logger,
+ Constants.LoggerScopesGeneratorName, methodName => methodName == "BeginScope");
+
+ using var _ = beginScopeCall((ILogger) proxy);
+ logger.LogInformation("Hello world");
+
+ await Assert.That(proxy.ExecutionsFromGenerator).IsEmpty();
+ await Assert.That(proxy.ExecutionsWithoutGenerator.Count).IsEqualTo(1);
+ }
+
+ public static IEnumerable>> BeginScopeMethodsWithDifferentParameters()
+ {
+ const string messageWith1Parameters = "Message Scope: {arg1}";
+ const string messageWith2Parameters = "Message Scope: {arg1} {arg2}";
+ const string messageWith3Parameters = "Message Scope: {arg1} {arg2} {arg3}";
+ const string messageWith4Parameters = "Message Scope: {arg1} {arg2} {arg3} {arg4}";
+ const string messageWith5Parameters = "Message Scope: {arg1} {arg2} {arg3} {arg4} {arg5}";
+ const string messageWith6Parameters = "Message Scope: {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}";
+
+ return
+ [
+ () => l => l.BeginScope(messageWith1Parameters, 1),
+ () => l => l.BeginScope(messageWith2Parameters, 1, 2),
+ () => l => l.BeginScope(messageWith3Parameters, 1, 2, 3),
+ () => l => l.BeginScope(messageWith4Parameters, 1, 2, 3, 4),
+ () => l => l.BeginScope(messageWith5Parameters, 1, 2, 3, 4, 5),
+ () => l => l.BeginScope(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
+ ];
+ }
+
+ public static IEnumerable>> BeginScopeMethodsWithUnsupportedParametersCount()
+ {
+ const string messageWithoutParameters = "Message Scope";
+ const string messageWith7Parameters = "Message Scope: {arg1} {arg2} {arg3} {arg4} {arg5} {arg6} {arg7}";
+
+ return
+ [
+ () => l => l.BeginScope(messageWithoutParameters),
+ () => l => l.BeginScope(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
+ ];
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.IntegrationTests/DispatchProxyExecutionVerificationDecorator.cs b/tests/AutoLoggerMessageGenerator.IntegrationTests/DispatchProxyExecutionVerificationDecorator.cs
index de5d351..2db5db4 100644
--- a/tests/AutoLoggerMessageGenerator.IntegrationTests/DispatchProxyExecutionVerificationDecorator.cs
+++ b/tests/AutoLoggerMessageGenerator.IntegrationTests/DispatchProxyExecutionVerificationDecorator.cs
@@ -5,7 +5,7 @@ namespace AutoLoggerMessageGenerator.IntegrationTests;
public class DispatchProxyExecutionVerificationDecorator : DispatchProxy
{
private T? Target { get; set; }
-
+ private string? GeneratorName { get; set; }
private Func? MethodFilter { get; set; }
private readonly List _executionsFromGenerator = [];
@@ -14,13 +14,15 @@ public class DispatchProxyExecutionVerificationDecorator : DispatchProxy
public IReadOnlyList ExecutionsFromGenerator => _executionsFromGenerator.AsReadOnly();
public IReadOnlyList ExecutionsWithoutGenerator => _executionsWithoutGenerator.AsReadOnly();
- public static DispatchProxyExecutionVerificationDecorator Decorate(T target, Func? methodFilter = default)
+ public static DispatchProxyExecutionVerificationDecorator Decorate(T target, string generatorName, Func? methodFilter = default)
{
if (Create>() is not DispatchProxyExecutionVerificationDecorator proxy)
throw new InvalidOperationException($"Unable to create DispatchProxyExecutionVerificationDecorator for {typeof(T).FullName}");
proxy.Target = target;
+ proxy.GeneratorName = generatorName;
proxy.MethodFilter = methodFilter;
+
return proxy;
}
@@ -35,7 +37,7 @@ public static DispatchProxyExecutionVerificationDecorator Decorate(T target,
private void CaptureExecutionCall()
{
var stackTrace = Environment.StackTrace;
- var callFromGenerator = stackTrace.Contains("LoggerMessage.g.cs");
+ var callFromGenerator = stackTrace.Contains($"{GeneratorName}.g.cs");
var executionList = callFromGenerator ? _executionsFromGenerator : _executionsWithoutGenerator;
executionList.Add(stackTrace);
diff --git a/tests/AutoLoggerMessageGenerator.IntegrationTests/ExecutionSourceTests.cs b/tests/AutoLoggerMessageGenerator.IntegrationTests/ExecutionSourceTests.cs
deleted file mode 100644
index 2da8129..0000000
--- a/tests/AutoLoggerMessageGenerator.IntegrationTests/ExecutionSourceTests.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-using Microsoft.Extensions.Logging;
-
-namespace AutoLoggerMessageGenerator.IntegrationTests;
-
-internal class ExecutionSourceTests
-{
- [Test]
- [MethodDataSource(nameof(LogMethodsWithDifferentParameters))]
- public async Task WithAllLogMethods_RequestShouldBeForwardedToLoggerMessageSourceGenerator(Action[] logCalls)
- {
- ILogger logger = LoggerFactory.Create(c =>
- c.AddSimpleConsole().SetMinimumLevel(LogLevel.Trace)
- ).CreateLogger();
-
- var proxy = DispatchProxyExecutionVerificationDecorator.Decorate(logger, methodName => methodName == "Log");
-
- foreach (var logCall in logCalls)
- logCall((ILogger) proxy);
-
- await Assert.That(proxy.ExecutionsWithoutGenerator).IsEmpty();
- await Assert.That(proxy.ExecutionsFromGenerator.Count).IsEqualTo(logCalls.Length);
- }
-
- [Test]
- public async Task WithMoreThan6Parameters_RequestShouldBeForwardedToOriginalImplementation()
- {
- ILogger logger = LoggerFactory.Create(c =>
- c.AddSimpleConsole().SetMinimumLevel(LogLevel.Trace)
- ).CreateLogger();
-
- var proxy = DispatchProxyExecutionVerificationDecorator.Decorate(logger, methodName => methodName == "Log");
-
- const string messageWith7Parameters = "Event received: {arg1} {arg2} {arg3} {arg4} {arg5} {arg6} {arg7}";
- var logCalls = new Action[]
- {
- l => l.LogTrace(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
- l => l.LogDebug(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
- l => l.LogInformation(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
- l => l.LogWarning(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
- l => l.LogError(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
- l => l.LogCritical(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
- l => l.Log(LogLevel.Information, messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7)
- };
-
- foreach (var logCall in logCalls)
- logCall((ILogger) proxy);
-
- await Assert.That(proxy.ExecutionsFromGenerator).IsEmpty();
- await Assert.That(proxy.ExecutionsWithoutGenerator.Count).IsEqualTo(logCalls.Length);
- await Assert.That(proxy.ExecutionsWithoutGenerator.Where(c => !c.Contains("LoggerExtensions.Log"))).IsEmpty();
- }
-
- public static IEnumerable[]>> LogMethodsWithDifferentParameters()
- {
- const string messageWithoutParameters = "Event received";
- const string messageWith1Parameters = "Event received: {arg1}";
- const string messageWith2Parameters = "Event received: {arg1} {arg2}";
- const string messageWith3Parameters = "Event received: {arg1} {arg2} {arg3}";
- const string messageWith4Parameters = "Event received: {arg1} {arg2} {arg3} {arg4}";
- const string messageWith5Parameters = "Event received: {arg1} {arg2} {arg3} {arg4} {arg5}";
- const string messageWith6Parameters = "Event received: {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}";
-
- return
- [
- () =>
- [
- logger => logger.LogTrace(messageWithoutParameters),
- logger => logger.LogDebug(messageWithoutParameters),
- logger => logger.LogInformation(messageWithoutParameters),
- logger => logger.LogWarning(messageWithoutParameters),
- logger => logger.LogError(messageWithoutParameters),
- logger => logger.LogCritical(messageWithoutParameters),
- logger => logger.Log(LogLevel.Information, messageWithoutParameters)
- ],
- () =>
- [
- logger => logger.LogTrace(messageWith1Parameters, 1),
- logger => logger.LogDebug(messageWith1Parameters, 1),
- logger => logger.LogInformation(messageWith1Parameters, 1),
- logger => logger.LogWarning(messageWith1Parameters, 1),
- logger => logger.LogError(messageWith1Parameters, 1),
- logger => logger.LogCritical(messageWith1Parameters, 1),
- logger => logger.Log(LogLevel.Information, messageWith1Parameters, 1)
- ],
- () =>
- [
- logger => logger.LogTrace(messageWith2Parameters, 1, 2),
- logger => logger.LogDebug(messageWith2Parameters, 1, 2),
- logger => logger.LogInformation(messageWith2Parameters, 1, 2),
- logger => logger.LogWarning(messageWith2Parameters, 1, 2),
- logger => logger.LogError(messageWith2Parameters, 1, 2),
- logger => logger.LogCritical(messageWith2Parameters, 1, 2),
- logger => logger.Log(LogLevel.Information, messageWith2Parameters, 1, 2)
- ],
- () =>
- [
- logger => logger.LogTrace(messageWith3Parameters, 1, 2, 3),
- logger => logger.LogDebug(messageWith3Parameters, 1, 2, 3),
- logger => logger.LogInformation(messageWith3Parameters, 1, 2, 3),
- logger => logger.LogWarning(messageWith3Parameters, 1, 2, 3),
- logger => logger.LogError(messageWith3Parameters, 1, 2, 3),
- logger => logger.LogCritical(messageWith3Parameters, 1, 2, 3),
- logger => logger.Log(LogLevel.Information, messageWith3Parameters, 1, 2, 3)
- ],
- () =>
- [
- logger => logger.LogTrace(messageWith4Parameters, 1, 2, 3, 4),
- logger => logger.LogDebug(messageWith4Parameters, 1, 2, 3, 4),
- logger => logger.LogInformation(messageWith4Parameters, 1, 2, 3, 4),
- logger => logger.LogWarning(messageWith4Parameters, 1, 2, 3, 4),
- logger => logger.LogError(messageWith4Parameters, 1, 2, 3, 4),
- logger => logger.LogCritical(messageWith4Parameters, 1, 2, 3, 4),
- logger => logger.Log(LogLevel.Information, messageWith4Parameters, 1, 2, 3, 4)
- ],
- () =>
- [
- logger => logger.LogTrace(messageWith5Parameters, 1, 2, 3, 4, 5),
- logger => logger.LogDebug(messageWith5Parameters, 1, 2, 3, 4, 5),
- logger => logger.LogInformation(messageWith5Parameters, 1, 2, 3, 4, 5),
- logger => logger.LogWarning(messageWith5Parameters, 1, 2, 3, 4, 5),
- logger => logger.LogError(messageWith5Parameters, 1, 2, 3, 4, 5),
- logger => logger.LogCritical(messageWith5Parameters, 1, 2, 3, 4, 5),
- logger => logger.Log(LogLevel.Information, messageWith5Parameters, 1, 2, 3, 4, 5)
- ],
- () =>
- [
- logger => logger.LogTrace(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
- logger => logger.LogDebug(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
- logger => logger.LogInformation(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
- logger => logger.LogWarning(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
- logger => logger.LogError(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
- logger => logger.LogCritical(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
- logger => logger.Log(LogLevel.Information, messageWith6Parameters, 1, 2, 3, 4, 5, 6)
- ]
- ];
- }
-}
diff --git a/tests/AutoLoggerMessageGenerator.IntegrationTests/LogPropertiesAttributeTests.cs b/tests/AutoLoggerMessageGenerator.IntegrationTests/LogPropertiesAttributeTests.cs
index d6c3ad6..17b15ed 100644
--- a/tests/AutoLoggerMessageGenerator.IntegrationTests/LogPropertiesAttributeTests.cs
+++ b/tests/AutoLoggerMessageGenerator.IntegrationTests/LogPropertiesAttributeTests.cs
@@ -13,7 +13,9 @@ internal class LogPropertiesAttributeTests
public async Task AllLogPropertiesHaveToBeLogged()
{
IEvent generatorCallCapturedEvent = new GeneratorCallCapturedEvent { Id = Guid.NewGuid() };
- var proxy = DispatchProxyExecutionVerificationDecorator.Decorate(generatorCallCapturedEvent);
+ var proxy = DispatchProxyExecutionVerificationDecorator.Decorate(
+ generatorCallCapturedEvent, Constants.LoggerMessageGeneratorName
+ );
generatorCallCapturedEvent = (IEvent) proxy;
var propertiesCount = typeof(GeneratorCallCapturedEvent)
diff --git a/tests/AutoLoggerMessageGenerator.IntegrationTests/LogWithAllParameterRangeTests.cs b/tests/AutoLoggerMessageGenerator.IntegrationTests/LogWithAllParameterRangeTests.cs
new file mode 100644
index 0000000..7eb659a
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.IntegrationTests/LogWithAllParameterRangeTests.cs
@@ -0,0 +1,127 @@
+using Microsoft.Extensions.Logging;
+
+namespace AutoLoggerMessageGenerator.IntegrationTests;
+
+internal class LogWithAllParameterRangeTests
+{
+ [Test]
+ [MethodDataSource(nameof(LogMethodsWithDifferentParameters))]
+ public async Task WithAllLogMethods_RequestShouldBeForwardedToLoggerMessageSourceGenerator(
+ Action logCall)
+ {
+ ILogger logger = LoggerFactory.Create(c =>
+ c.AddSimpleConsole().SetMinimumLevel(LogLevel.Trace)
+ ).CreateLogger();
+
+ var proxy = DispatchProxyExecutionVerificationDecorator.Decorate(logger,
+ Constants.LoggerMessageGeneratorName, methodName => methodName == "Log");
+
+ logCall((ILogger) proxy);
+
+ await Assert.That(proxy.ExecutionsWithoutGenerator).IsEmpty();
+ await Assert.That(proxy.ExecutionsFromGenerator.Count).IsEqualTo(1);
+ }
+
+ [Test]
+ [MethodDataSource(nameof(LogMethodsWithUnsupportedParametersCount))]
+ public async Task WithUnsupportedParametersCount_RequestShouldBeForwardedToOriginalImplementation(Action logCall)
+ {
+ ILogger logger = LoggerFactory.Create(c =>
+ c.AddSimpleConsole().SetMinimumLevel(LogLevel.Trace)
+ ).CreateLogger();
+
+ var proxy = DispatchProxyExecutionVerificationDecorator.Decorate(logger,
+ Constants.LoggerMessageGeneratorName, methodName => methodName == "Log");
+
+ logCall((ILogger) proxy);
+
+ await Assert.That(proxy.ExecutionsFromGenerator).IsEmpty();
+ await Assert.That(proxy.ExecutionsWithoutGenerator.Count).IsEqualTo(1);
+ await Assert.That(proxy.ExecutionsWithoutGenerator.Where(c => !c.Contains("LoggerExtensions.Log"))).IsEmpty();
+ }
+
+ public static IEnumerable>> LogMethodsWithDifferentParameters()
+ {
+ const string messageWithoutParameters = "Event received";
+ const string messageWith1Parameters = "Event received: {arg1}";
+ const string messageWith2Parameters = "Event received: {arg1} {arg2}";
+ const string messageWith3Parameters = "Event received: {arg1} {arg2} {arg3}";
+ const string messageWith4Parameters = "Event received: {arg1} {arg2} {arg3} {arg4}";
+ const string messageWith5Parameters = "Event received: {arg1} {arg2} {arg3} {arg4} {arg5}";
+ const string messageWith6Parameters = "Event received: {arg1} {arg2} {arg3} {arg4} {arg5} {arg6}";
+
+ return
+ [
+ () => l => l.LogTrace(messageWithoutParameters),
+ () => l => l.LogDebug(messageWithoutParameters),
+ () => l => l.LogInformation(messageWithoutParameters),
+ () => l => l.LogWarning(messageWithoutParameters),
+ () => l => l.LogError(messageWithoutParameters),
+ () => l => l.LogCritical(messageWithoutParameters),
+ () => l => l.Log(LogLevel.Information, messageWithoutParameters),
+
+ () => l => l.LogTrace(messageWith1Parameters, 1),
+ () => l => l.LogDebug(messageWith1Parameters, 1),
+ () => l => l.LogInformation(messageWith1Parameters, 1),
+ () => l => l.LogWarning(messageWith1Parameters, 1),
+ () => l => l.LogError(messageWith1Parameters, 1),
+ () => l => l.LogCritical(messageWith1Parameters, 1),
+ () => l => l.Log(LogLevel.Information, messageWith1Parameters, 1),
+
+ () => l => l.LogTrace(messageWith2Parameters, 1, 2),
+ () => l => l.LogDebug(messageWith2Parameters, 1, 2),
+ () => l => l.LogInformation(messageWith2Parameters, 1, 2),
+ () => l => l.LogWarning(messageWith2Parameters, 1, 2),
+ () => l => l.LogError(messageWith2Parameters, 1, 2),
+ () => l => l.LogCritical(messageWith2Parameters, 1, 2),
+ () => l => l.Log(LogLevel.Information, messageWith2Parameters, 1, 2),
+
+ () => l => l.LogTrace(messageWith3Parameters, 1, 2, 3),
+ () => l => l.LogDebug(messageWith3Parameters, 1, 2, 3),
+ () => l => l.LogInformation(messageWith3Parameters, 1, 2, 3),
+ () => l => l.LogWarning(messageWith3Parameters, 1, 2, 3),
+ () => l => l.LogError(messageWith3Parameters, 1, 2, 3),
+ () => l => l.LogCritical(messageWith3Parameters, 1, 2, 3),
+ () => l => l.Log(LogLevel.Information, messageWith3Parameters, 1, 2, 3),
+
+ () => l => l.LogTrace(messageWith4Parameters, 1, 2, 3, 4),
+ () => l => l.LogDebug(messageWith4Parameters, 1, 2, 3, 4),
+ () => l => l.LogInformation(messageWith4Parameters, 1, 2, 3, 4),
+ () => l => l.LogWarning(messageWith4Parameters, 1, 2, 3, 4),
+ () => l => l.LogError(messageWith4Parameters, 1, 2, 3, 4),
+ () => l => l.LogCritical(messageWith4Parameters, 1, 2, 3, 4),
+ () => l => l.Log(LogLevel.Information, messageWith4Parameters, 1, 2, 3, 4),
+
+ () => l => l.LogTrace(messageWith5Parameters, 1, 2, 3, 4, 5),
+ () => l => l.LogDebug(messageWith5Parameters, 1, 2, 3, 4, 5),
+ () => l => l.LogInformation(messageWith5Parameters, 1, 2, 3, 4, 5),
+ () => l => l.LogWarning(messageWith5Parameters, 1, 2, 3, 4, 5),
+ () => l => l.LogError(messageWith5Parameters, 1, 2, 3, 4, 5),
+ () => l => l.LogCritical(messageWith5Parameters, 1, 2, 3, 4, 5),
+ () => l => l.Log(LogLevel.Information, messageWith5Parameters, 1, 2, 3, 4, 5),
+
+ () => l => l.LogTrace(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
+ () => l => l.LogDebug(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
+ () => l => l.LogInformation(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
+ () => l => l.LogWarning(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
+ () => l => l.LogError(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
+ () => l => l.LogCritical(messageWith6Parameters, 1, 2, 3, 4, 5, 6),
+ () => l => l.Log(LogLevel.Information, messageWith6Parameters, 1, 2, 3, 4, 5, 6)
+ ];
+ }
+
+ public static IEnumerable>> LogMethodsWithUnsupportedParametersCount()
+ {
+ const string messageWith7Parameters = "Event received: {arg1} {arg2} {arg3} {arg4} {arg5} {arg6} {arg7}";
+ return
+ [
+ () => l => l.LogTrace(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
+ () => l => l.LogDebug(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
+ () => l => l.LogInformation(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
+ () => l => l.LogWarning(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
+ () => l => l.LogError(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
+ () => l => l.LogCritical(messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7),
+ () => l => l.Log(LogLevel.Information, messageWith7Parameters, 1, 2, 3, 4, 5, 6, 7)
+ ];
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/AutoLoggerMessageGenerator.UnitTests.Build.targets b/tests/AutoLoggerMessageGenerator.UnitTests/AutoLoggerMessageGenerator.UnitTests.Build.targets
index 1a85b03..8d9e28b 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/AutoLoggerMessageGenerator.UnitTests.Build.targets
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/AutoLoggerMessageGenerator.UnitTests.Build.targets
@@ -7,9 +7,9 @@
-
-
-
+
+
+
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/BaseSourceGeneratorTest.cs b/tests/AutoLoggerMessageGenerator.UnitTests/BaseSourceGeneratorTest.cs
index 5be1f64..d285b32 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/BaseSourceGeneratorTest.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/BaseSourceGeneratorTest.cs
@@ -66,7 +66,7 @@ public void Main()
return (compilation, syntaxTree);
}
- protected static (InvocationExpressionSyntax, IMethodSymbol?, SemanticModel?) FindLoggerMethodInvocation(
+ protected static (InvocationExpressionSyntax, IMethodSymbol?, SemanticModel?) FindMethodInvocation(
Compilation? compilation, SyntaxTree syntaxTree)
{
var invocationExpression = syntaxTree.GetRoot().DescendantNodes().OfType().First();
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Caching/InputSourceComparerTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Caching/LogCallInputSourceComparerTests.cs
similarity index 75%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Caching/InputSourceComparerTests.cs
rename to tests/AutoLoggerMessageGenerator.UnitTests/Caching/LogCallInputSourceComparerTests.cs
index 41325bd..07aa24a 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Caching/InputSourceComparerTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Caching/LogCallInputSourceComparerTests.cs
@@ -8,9 +8,18 @@
namespace AutoLoggerMessageGenerator.UnitTests.Caching;
-using InputSource = (Compilation Compilation, (SourceGeneratorConfiguration Configuration, (ImmutableArray References, ImmutableArray LogCalls) Others) Others);
-
-internal class InputSourceComparerTests
+using InputSource = (
+ Compilation Compilation,
+ (
+ SourceGeneratorConfiguration Configuration,
+ (
+ ImmutableArray References,
+ ImmutableArray LogCalls
+ ) Others
+ ) Others
+);
+
+internal class LogCallInputSourceComparerTests
{
[Test]
public async Task Equals_WithDifferentCompilation_ShouldReturnTrue()
@@ -21,7 +30,7 @@ public async Task Equals_WithDifferentCompilation_ShouldReturnTrue()
var inputSource1 = CreateInputSource(compilation: compilation1);
var inputSource2 = CreateInputSource(compilation: compilation2);
- var sut = new InputSourceComparer();
+ var sut = new LogCallInputSourceComparer();
var result = sut.Equals(inputSource1, inputSource2);
await Assert.That(result).IsTrue();
@@ -30,13 +39,13 @@ public async Task Equals_WithDifferentCompilation_ShouldReturnTrue()
[Test]
public async Task Equals_WithDifferentConfiguration_ShouldReturnFalse()
{
- var configuration1 = new SourceGeneratorConfiguration(true, true, true, true, true);
- var configuration2 = new SourceGeneratorConfiguration(false, false, false, false, false);
+ var configuration1 = new SourceGeneratorConfiguration(true, true, true, true, true, true);
+ var configuration2 = new SourceGeneratorConfiguration(false, false, false, false, false, false);
var inputSource1 = CreateInputSource(configuration: configuration1);
var inputSource2 = CreateInputSource(configuration: configuration2);
- var sut = new InputSourceComparer();
+ var sut = new LogCallInputSourceComparer();
var result = sut.Equals(inputSource1, inputSource2);
await Assert.That(result).IsFalse();
@@ -55,7 +64,7 @@ public async Task Equals_WithDifferentReferences_ShouldReturnFalse(
var inputSource1 = CreateInputSource(references: references1);
var inputSource2 = CreateInputSource(references: references2);
- var sut = new InputSourceComparer();
+ var sut = new LogCallInputSourceComparer();
var result = sut.Equals(inputSource1, inputSource2);
await Assert.That(result).IsFalse();
@@ -64,13 +73,13 @@ public async Task Equals_WithDifferentReferences_ShouldReturnFalse(
[Test]
public async Task Equals_WithDifferentLogCalls_ShouldReturnFalse()
{
- ImmutableArray logCalls = [new LogCall { Message = "message1"}];
- ImmutableArray logCalls2 = [new LogCall { Message = "message2"}];
+ ImmutableArray logCalls = [new LogMessageCall { Message = "message1"}];
+ ImmutableArray logCalls2 = [new LogMessageCall { Message = "message2"}];
var inputSource1 = CreateInputSource(logCalls: logCalls);
var inputSource2 = CreateInputSource(logCalls: logCalls2);
- var sut = new InputSourceComparer();
+ var sut = new LogCallInputSourceComparer();
var result = sut.Equals(inputSource1, inputSource2);
await Assert.That(result).IsFalse();
@@ -79,14 +88,14 @@ public async Task Equals_WithDifferentLogCalls_ShouldReturnFalse()
private static InputSource CreateInputSource(Compilation? compilation = default,
SourceGeneratorConfiguration? configuration = default,
ImmutableArray? references = default,
- ImmutableArray? logCalls = default)
+ ImmutableArray? logCalls = default)
{
compilation ??= CSharpCompilation.Create(default);
- configuration ??= new SourceGeneratorConfiguration(true, true, true, true, true);
+ configuration ??= new SourceGeneratorConfiguration(true, true, true, true, true, true);
references ??= [new Reference("some lib", new Version("1.2.3"))];
logCalls ??=
[
- new LogCall(Guid.NewGuid(), MockLogCallLocationBuilder.Build("some file", 1, 2), "namespace", "class", "name",
+ new LogMessageCall(Guid.NewGuid(), MockLogCallLocationBuilder.Build("some file", 1, 2), "namespace", "class", "name",
"information", "message", [])
];
diff --git a/src/AutoLoggerMessageGenerator.BuildOutput/LoggerExtensions.g.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/GenericLoggerExtensionsEmitterTests.Emit_ShouldGenerateValidLoggingExtensionsOverrides.verified.txt
similarity index 99%
rename from src/AutoLoggerMessageGenerator.BuildOutput/LoggerExtensions.g.cs
rename to tests/AutoLoggerMessageGenerator.UnitTests/Emitters/GenericLoggerExtensionsEmitterTests.Emit_ShouldGenerateValidLoggingExtensionsOverrides.verified.txt
index 0b3edad..da059ef 100644
--- a/src/AutoLoggerMessageGenerator.BuildOutput/LoggerExtensions.g.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/GenericLoggerExtensionsEmitterTests.Emit_ShouldGenerateValidLoggingExtensionsOverrides.verified.txt
@@ -1,11 +1,11 @@
-//
+//
#nullable enable
using System;
namespace Microsoft.Extensions.Logging
{
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("AutoLoggerMessageGenerator", "1.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("AutoLoggerMessageGenerator", "1.2.3.4")]
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[System.Diagnostics.DebuggerStepThrough]
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/GenericLoggerScopeExtensionsEmitterTests.Emit_ShouldGenerateValidLoggingScopeExtensionsOverrides.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/GenericLoggerScopeExtensionsEmitterTests.Emit_ShouldGenerateValidLoggingScopeExtensionsOverrides.verified.txt
new file mode 100644
index 0000000..7a7c2e8
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/GenericLoggerScopeExtensionsEmitterTests.Emit_ShouldGenerateValidLoggingScopeExtensionsOverrides.verified.txt
@@ -0,0 +1,45 @@
+//
+#nullable enable
+
+using System;
+
+namespace Microsoft.Extensions.Logging
+{
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("AutoLoggerMessageGenerator", "1.2.3.4")]
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.DebuggerStepThrough]
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ public static class GenericLoggerScopeExtensions
+ {
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1, @arg2 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4 });
+ }
+
+ public static IDisposable? BeginScope(this ILogger @logger, string @message, T0 @arg0, T1 @arg1, T2 @arg2, T3 @arg3, T4 @arg4, T5 @arg5)
+ {
+ return Microsoft.Extensions.Logging.LoggerExtensions.BeginScope(@logger, @message, new object?[] { @arg0, @arg1, @arg2, @arg3, @arg4, @arg5 });
+ }
+
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerExtensionsEmitterTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerExtensionsEmitterTests.cs
index 22b6f0f..5a585af 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerExtensionsEmitterTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerExtensionsEmitterTests.cs
@@ -3,12 +3,12 @@
namespace AutoLoggerMessageGenerator.UnitTests.Emitters;
-internal class LoggerExtensionsEmitterTests
+internal class GenericLoggerExtensionsEmitterTests
{
[Test]
- public async Task Emit_ShouldGenerateValidLoggingExtensionsAttribute()
+ public async Task Emit_ShouldGenerateValidLoggingExtensionsOverrides()
{
- var sourceCode = LoggerExtensionsEmitter.Emit();
+ var sourceCode = GenericLoggerExtensionsEmitter.Emit();
await Verify(sourceCode).AddCodeGeneratedAttributeScrubber();
}
}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerInterceptorsEmitterTests.Emit_ShouldGenerateValidLoggingExtensionsAttribute.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerInterceptorsEmitterTests.Emit_ShouldGenerateValidLoggingExtensionsAttribute.verified.txt
index 451234b..f0f3065 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerInterceptorsEmitterTests.Emit_ShouldGenerateValidLoggingExtensionsAttribute.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerInterceptorsEmitterTests.Emit_ShouldGenerateValidLoggingExtensionsAttribute.verified.txt
@@ -11,21 +11,18 @@ namespace Microsoft.Extensions.Logging.AutoLoggerMessage
[System.Diagnostics.DebuggerStepThrough]
internal static class LoggerInterceptors
{
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[FakeInterceptableLocation(-1, "ZmlsZSgxLDExKQ==")]
public static void Log_namespace1class1_1_11(this ILogger @logger, string @message)
{
Microsoft.Extensions.Logging.AutoLoggerMessage.AutoLoggerMessage.Log_namespace1class1_1_11(@logger);
}
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[FakeInterceptableLocation(-1, "ZmlsZTIoMiwyMik=")]
public static void Log_namespace2class2_2_22(this ILogger @logger, string @message, int @intParam)
{
Microsoft.Extensions.Logging.AutoLoggerMessage.AutoLoggerMessage.Log_namespace2class2_2_22(@logger, @intParam);
}
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
[FakeInterceptableLocation(-1, "ZmlsZTMoMywzMyk=")]
public static void Log_namespace3class3_3_33(this ILogger @logger, string @message, int @intParam, bool @boolParam, SomeClass @objectParam)
{
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerInterceptorsEmitterTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerInterceptorsEmitterTests.cs
index 99c8b39..c0aee98 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerInterceptorsEmitterTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerInterceptorsEmitterTests.cs
@@ -11,44 +11,44 @@ internal class LoggerInterceptorsEmitterTests
[Test]
public async Task Emit_ShouldGenerateValidLoggingExtensionsAttribute()
{
- ImmutableArray logCalls =
+ ImmutableArray logCalls =
[
- new LogCall(
+ new LogMessageCall(
Id: Guid.NewGuid(),
Location: MockLogCallLocationBuilder.Build("file", 1, 11),
Namespace: "namespace1",
ClassName: "class1",
- Name: "name1",
+ MethodName: "name1",
LogLevel: "Information",
Message: "Message1",
- Parameters: [new LogCallParameter("string", MessageParameterName, LogCallParameterType.Message)]
+ Parameters: [new CallParameter("string", MessageParameterName, CallParameterType.Message)]
),
- new LogCall(
+ new LogMessageCall(
Id: Guid.NewGuid(),
Location: MockLogCallLocationBuilder.Build("file2", 2, 22),
Namespace: "namespace2",
ClassName: "class2",
- Name: "name2",
+ MethodName: "name2",
LogLevel: "Warning",
Message: "Message2",
Parameters: [
- new LogCallParameter("string", MessageParameterName, LogCallParameterType.Message),
- new LogCallParameter("int", "@intParam", LogCallParameterType.Others)
+ new CallParameter("string", MessageParameterName, CallParameterType.Message),
+ new CallParameter("int", "@intParam", CallParameterType.Others)
]
),
- new LogCall(
+ new LogMessageCall(
Id: Guid.NewGuid(),
Location: MockLogCallLocationBuilder.Build("file3", 3, 33),
Namespace: "namespace3",
ClassName: "class3",
- Name: "name3",
+ MethodName: "name3",
LogLevel: "Error",
Message: "Message3",
Parameters: [
- new LogCallParameter("string", MessageParameterName, LogCallParameterType.Message),
- new LogCallParameter("int", "@intParam", LogCallParameterType.Others),
- new LogCallParameter("bool", "@boolParam", LogCallParameterType.Others),
- new LogCallParameter("SomeClass", "@objectParam", LogCallParameterType.Others, true)
+ new CallParameter("string", MessageParameterName, CallParameterType.Message),
+ new CallParameter("int", "@intParam", CallParameterType.Others),
+ new CallParameter("bool", "@boolParam", CallParameterType.Others),
+ new CallParameter("SomeClass", "@objectParam", CallParameterType.Others, true)
]
),
];
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeExtensionsEmitterTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeExtensionsEmitterTests.cs
new file mode 100644
index 0000000..b6459b8
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeExtensionsEmitterTests.cs
@@ -0,0 +1,14 @@
+using AutoLoggerMessageGenerator.Emitters;
+using AutoLoggerMessageGenerator.UnitTests.Scrubbers;
+
+namespace AutoLoggerMessageGenerator.UnitTests.Emitters;
+
+internal class GenericLoggerScopeExtensionsEmitterTests
+{
+ [Test]
+ public async Task Emit_ShouldGenerateValidLoggingScopeExtensionsOverrides()
+ {
+ var sourceCode = GenericLoggerScopeExtensionsEmitter.Emit();
+ await Verify(sourceCode).AddCodeGeneratedAttributeScrubber();
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeInterceptorsEmitterTests.Emit_WithGivenConfiguration_ShouldGenerateValidLoggerScopeInterceptors.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeInterceptorsEmitterTests.Emit_WithGivenConfiguration_ShouldGenerateValidLoggerScopeInterceptors.verified.txt
new file mode 100644
index 0000000..405a2af
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeInterceptorsEmitterTests.Emit_WithGivenConfiguration_ShouldGenerateValidLoggerScopeInterceptors.verified.txt
@@ -0,0 +1,33 @@
+//
+#nullable enable
+
+using System;
+
+namespace Microsoft.Extensions.Logging.AutoLoggerMessage
+{
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("AutoLoggerMessageGenerator", "1.2.3.4")]
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [System.Diagnostics.DebuggerStepThrough]
+ internal static class LoggerScopeInterceptors
+ {
+ [FakeInterceptableLocation(-1, "ZmlsZSgxLDExKQ==")]
+ public static IDisposable? LogScope_namespace1class1_1_11(this ILogger @logger, string @message)
+ {
+ return Microsoft.Extensions.Logging.AutoLoggerMessage.LoggerScopes.LogScope_namespace1class1_1_11(@logger);
+ }
+
+ [FakeInterceptableLocation(-1, "ZmlsZTIoMiwyMik=")]
+ public static IDisposable? LogScope_namespace2class2_2_22(this ILogger @logger, string @message, int @intParam)
+ {
+ return Microsoft.Extensions.Logging.AutoLoggerMessage.LoggerScopes.LogScope_namespace2class2_2_22(@logger, @intParam);
+ }
+
+ [FakeInterceptableLocation(-1, "ZmlsZTMoMywzMyk=")]
+ public static IDisposable? LogScope_namespace3class3_3_33(this ILogger @logger, string @message, int @intParam, bool @boolParam, SomeClass @objectParam)
+ {
+ return Microsoft.Extensions.Logging.AutoLoggerMessage.LoggerScopes.LogScope_namespace3class3_3_33(@logger, @intParam, @boolParam, @objectParam);
+ }
+
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeInterceptorsEmitterTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeInterceptorsEmitterTests.cs
new file mode 100644
index 0000000..3c7ed98
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopeInterceptorsEmitterTests.cs
@@ -0,0 +1,53 @@
+using System.Collections.Immutable;
+using AutoLoggerMessageGenerator.Emitters;
+using AutoLoggerMessageGenerator.Models;
+using AutoLoggerMessageGenerator.UnitTests.Scrubbers;
+using static AutoLoggerMessageGenerator.Constants;
+
+namespace AutoLoggerMessageGenerator.UnitTests.Emitters;
+
+internal class LoggerScopeInterceptorsEmitterTests
+{
+ [Test]
+ public async Task Emit_WithGivenConfiguration_ShouldGenerateValidLoggerScopeInterceptors()
+ {
+ ImmutableArray loggerScopes =
+ [
+ new(
+ Location: MockLogCallLocationBuilder.Build("file", 1, 11),
+ Namespace: "namespace1",
+ ClassName: "class1",
+ MethodName: "name1",
+ Message: "Message1",
+ Parameters: [new CallParameter("string", MessageParameterName, CallParameterType.Message)]
+ ),
+ new(
+ Location: MockLogCallLocationBuilder.Build("file2", 2, 22),
+ Namespace: "namespace2",
+ ClassName: "class2",
+ MethodName: "name2",
+ Message: "Message2",
+ Parameters: [
+ new CallParameter("string", MessageParameterName, CallParameterType.Message),
+ new CallParameter("int", "@intParam", CallParameterType.Others)
+ ]
+ ),
+ new(
+ Location: MockLogCallLocationBuilder.Build("file3", 3, 33),
+ Namespace: "namespace3",
+ ClassName: "class3",
+ MethodName: "name3",
+ Message: "Message3",
+ Parameters: [
+ new CallParameter("string", MessageParameterName, CallParameterType.Message),
+ new CallParameter("int", "@intParam", CallParameterType.Others),
+ new CallParameter("bool", "@boolParam", CallParameterType.Others),
+ new CallParameter("SomeClass", "@objectParam", CallParameterType.Others, true)
+ ]
+ ),
+ ];
+
+ var sourceCode = LoggerScopeInterceptorsEmitter.Emit(loggerScopes);
+ await Verify(sourceCode).AddCodeGeneratedAttributeScrubber();
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopesEmitterTests.Emit_WithGivenConfiguration_ShouldGenerateValidLoggerDefineScopedFunctors.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopesEmitterTests.Emit_WithGivenConfiguration_ShouldGenerateValidLoggerDefineScopedFunctors.verified.txt
new file mode 100644
index 0000000..6da4792
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopesEmitterTests.Emit_WithGivenConfiguration_ShouldGenerateValidLoggerDefineScopedFunctors.verified.txt
@@ -0,0 +1,31 @@
+//
+#nullable enable
+
+using System;
+
+namespace Microsoft.Extensions.Logging.AutoLoggerMessage
+{
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("AutoLoggerMessageGenerator", "1.2.3.4")]
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
+ public static class LoggerScopes
+ {
+ private static readonly Func _LogScope_namespace1class1_1_11 = LoggerMessage.DefineScope("Message1");
+ public static IDisposable? LogScope_namespace1class1_1_11(ILogger @logger)
+ {
+ return _LogScope_namespace1class1_1_11(@logger);
+ }
+
+ private static readonly Func _LogScope_namespace2class2_2_22 = LoggerMessage.DefineScope("Message2");
+ public static IDisposable? LogScope_namespace2class2_2_22(ILogger @logger, int @intParam)
+ {
+ return _LogScope_namespace2class2_2_22(@logger, @intParam);
+ }
+
+ private static readonly Func _LogScope_namespace3class3_3_33 = LoggerMessage.DefineScope("Message3");
+ public static IDisposable? LogScope_namespace3class3_3_33(ILogger @logger, int @intParam, bool @boolParam, SomeClass @objectParam)
+ {
+ return _LogScope_namespace3class3_3_33(@logger, @intParam, @boolParam, @objectParam);
+ }
+
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopesEmitterTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopesEmitterTests.cs
new file mode 100644
index 0000000..1680793
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Emitters/LoggerScopesEmitterTests.cs
@@ -0,0 +1,53 @@
+using System.Collections.Immutable;
+using AutoLoggerMessageGenerator.Emitters;
+using AutoLoggerMessageGenerator.Models;
+using AutoLoggerMessageGenerator.UnitTests.Scrubbers;
+using static AutoLoggerMessageGenerator.Constants;
+
+namespace AutoLoggerMessageGenerator.UnitTests.Emitters;
+
+internal class LoggerScopesEmitterTests
+{
+ [Test]
+ public async Task Emit_WithGivenConfiguration_ShouldGenerateValidLoggerDefineScopedFunctors()
+ {
+ ImmutableArray loggerScopes =
+ [
+ new(
+ Location: MockLogCallLocationBuilder.Build("file", 1, 11),
+ Namespace: "namespace1",
+ ClassName: "class1",
+ MethodName: "name1",
+ Message: "Message1",
+ Parameters: [new CallParameter("string", MessageParameterName, CallParameterType.Message)]
+ ),
+ new(
+ Location: MockLogCallLocationBuilder.Build("file2", 2, 22),
+ Namespace: "namespace2",
+ ClassName: "class2",
+ MethodName: "name2",
+ Message: "Message2",
+ Parameters: [
+ new CallParameter("string", MessageParameterName, CallParameterType.Message),
+ new CallParameter("int", "@intParam", CallParameterType.Others)
+ ]
+ ),
+ new(
+ Location: MockLogCallLocationBuilder.Build("file3", 3, 33),
+ Namespace: "namespace3",
+ ClassName: "class3",
+ MethodName: "name3",
+ Message: "Message3",
+ Parameters: [
+ new CallParameter("string", MessageParameterName, CallParameterType.Message),
+ new CallParameter("int", "@intParam", CallParameterType.Others),
+ new CallParameter("bool", "@boolParam", CallParameterType.Others),
+ new CallParameter("SomeClass", "@objectParam", CallParameterType.Others, true)
+ ]
+ ),
+ ];
+
+ var sourceCode = LoggerScopesEmitter.Emit(loggerScopes);
+ await Verify(sourceCode).AddCodeGeneratedAttributeScrubber();
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallParametersExtractorTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/CallParametersExtractorTests.cs
similarity index 76%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallParametersExtractorTests.cs
rename to tests/AutoLoggerMessageGenerator.UnitTests/Extractors/CallParametersExtractorTests.cs
index 7f796a5..9c64de1 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallParametersExtractorTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/CallParametersExtractorTests.cs
@@ -6,7 +6,7 @@
namespace AutoLoggerMessageGenerator.UnitTests.Extractors;
-internal class LogCallParametersExtractorTests : BaseSourceGeneratorTest
+internal class CallParametersExtractorTests : BaseSourceGeneratorTest
{
[Test]
public async Task Extract_WithGivenMessageAndParameters_ShouldReturnMessageAndParsedParameters()
@@ -24,17 +24,17 @@ private static void Log(
""";
var (compilation, syntaxTree) = await CompileSourceCode($"Log({parameters});", extensionDeclaration);
- var (_, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (_, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
- var sut = new LogCallParametersExtractor();
+ var sut = new CallParametersExtractor();
var result = sut.Extract(message, methodSymbol!);
- await Assert.That(result).IsEquivalentTo(new LogCallParameter[]
+ await Assert.That(result).IsEquivalentTo(new CallParameter[]
{
- new("global::System.String", MessageParameterName, LogCallParameterType.Message),
- new("global::System.String", "@EventName", LogCallParameterType.Others),
- new("global::System.Int32", "@Time", LogCallParameterType.Others),
+ new("global::System.String", MessageParameterName, CallParameterType.Message),
+ new("global::System.String", "@EventName", CallParameterType.Others),
+ new("global::System.Int32", "@Time", CallParameterType.Others),
});
}
@@ -46,19 +46,19 @@ public async Task Extract_WithGivenMessageAndNoParameters_ShouldReturnOnlyMessag
string extensionDeclaration = $"private static void Log(string {MessageParameterName}) {{}}";
var (compilation, syntaxTree) = await CompileSourceCode($"""Log("{message}");""", extensionDeclaration);
- var (_, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (_, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
- var sut = new LogCallParametersExtractor();
+ var sut = new CallParametersExtractor();
var result = sut.Extract(message, methodSymbol!);
await Assert.That(result.HasValue).IsTrue();
await Assert.That(result!.Value.Length).IsEqualTo(1);
await Assert.That(result.Value[0]).IsEquivalentTo(
- new LogCallParameter(
+ new CallParameter(
"global::System.String",
MessageParameterName,
- LogCallParameterType.Message
+ CallParameterType.Message
)
);
}
@@ -88,20 +88,20 @@ private static void Log(
40
);
""", extensionDeclaration);
- var (_, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (_, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
- var sut = new LogCallParametersExtractor();
+ var sut = new CallParametersExtractor();
var result = sut.Extract(message, methodSymbol!);
- await Assert.That(result).IsEquivalentTo(new LogCallParameter[]
+ await Assert.That(result).IsEquivalentTo(new CallParameter[]
{
- new("global::Microsoft.Extensions.Logging.LogLevel", LogLevelParameterName, LogCallParameterType.LogLevel),
- new("global::Microsoft.Extensions.Logging.EventId", EventIdParameterName, LogCallParameterType.EventId),
- new("global::System.Exception", ExceptionParameterName, LogCallParameterType.Exception),
- new("global::System.String", MessageParameterName, LogCallParameterType.Message),
- new("global::System.String", "@EventName", LogCallParameterType.Others),
- new("global::System.Int32", "@Time", LogCallParameterType.Others),
+ new("global::Microsoft.Extensions.Logging.LogLevel", LogLevelParameterName, CallParameterType.LogLevel),
+ new("global::Microsoft.Extensions.Logging.EventId", EventIdParameterName, CallParameterType.EventId),
+ new("global::System.Exception", ExceptionParameterName, CallParameterType.Exception),
+ new("global::System.String", MessageParameterName, CallParameterType.Message),
+ new("global::System.String", "@EventName", CallParameterType.Others),
+ new("global::System.Int32", "@Time", CallParameterType.Others),
});
}
@@ -128,17 +128,17 @@ private static void Log(
var semanticModel = compilation.GetSemanticModel(syntaxTree);
var methodSymbol = (IMethodSymbol)semanticModel.GetSymbolInfo(invocationExpression).Symbol!;
- var sut = new LogCallParametersExtractor();
+ var sut = new CallParametersExtractor();
var result = sut.Extract(message, methodSymbol);
- await Assert.That(result).IsEquivalentTo(new LogCallParameter[]
+ await Assert.That(result).IsEquivalentTo(new CallParameter[]
{
- new("global::Microsoft.Extensions.Logging.EventId", "@eventId__", LogCallParameterType.EventId),
- new("global::System.String", "@message__", LogCallParameterType.Message),
- new("global::System.Int32", "@eventId_", LogCallParameterType.Others),
- new("global::System.String", "@message", LogCallParameterType.Others),
- new("global::System.Int32", "@time", LogCallParameterType.Others),
+ new("global::Microsoft.Extensions.Logging.EventId", "@eventId__", CallParameterType.EventId),
+ new("global::System.String", "@message__", CallParameterType.Message),
+ new("global::System.Int32", "@eventId_", CallParameterType.Others),
+ new("global::System.String", "@message", CallParameterType.Others),
+ new("global::System.Int32", "@time", CallParameterType.Others),
});
}
@@ -157,9 +157,9 @@ public void Foo({{genericType}} arg)
Log<{{genericType}}>("{{message}}", arg);
}
""");
- var (_, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (_, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
- var sut = new LogCallParametersExtractor();
+ var sut = new CallParametersExtractor();
var result = sut.Extract(message, methodSymbol!);
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallCallerExtractorTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/EnclosingClassExtractorTests.cs
similarity index 79%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallCallerExtractorTests.cs
rename to tests/AutoLoggerMessageGenerator.UnitTests/Extractors/EnclosingClassExtractorTests.cs
index 6bc7459..946e4a5 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallCallerExtractorTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/EnclosingClassExtractorTests.cs
@@ -2,7 +2,7 @@
namespace AutoLoggerMessageGenerator.UnitTests.Extractors;
-internal class LogCallCallerExtractorTests : BaseSourceGeneratorTest
+internal class EnclosingClassExtractorTests : BaseSourceGeneratorTest
{
[Test]
[Arguments(false, Namespace, ClassName)]
@@ -12,9 +12,9 @@ public async Task Extract_WithLogCallAndGivenNamespace_ShouldReturnExpectedNames
{
var message = $$"""{{LoggerName}}.LogInformation("Hello world");""";
var (_, syntaxTree) = await CompileSourceCode(message, useGlobalNamespace: useGlobalNamespace);
- var (invocationExpression, _, _) = FindLoggerMethodInvocation(null, syntaxTree);
+ var (invocationExpression, _, _) = FindMethodInvocation(null, syntaxTree);
- var (ns, className) = LogCallCallerExtractor.Extract(invocationExpression);
+ var (ns, className) = EnclosingClassExtractor.Extract(invocationExpression);
await Assert.That(ns).IsEqualTo(expectedNamespace);
await Assert.That(className).IsEqualTo(expectedClassName);
@@ -34,9 +34,9 @@ class Inner
}
""";
var (_, syntaxTree) = await CompileSourceCode(string.Empty, additionalDeclaration);
- var (invocationExpression, _, _) = FindLoggerMethodInvocation(null, syntaxTree);
+ var (invocationExpression, _, _) = FindMethodInvocation(null, syntaxTree);
- var (ns, className) = LogCallCallerExtractor.Extract(invocationExpression);
+ var (ns, className) = EnclosingClassExtractor.Extract(invocationExpression);
await Assert.That(ns).IsEqualTo(Namespace);
await Assert.That(className).IsEqualTo(ClassName);
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_HashBasedInterceptor.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=with parameters_sourceCode=HashBasedInterceptor.verified.txt
similarity index 93%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_HashBasedInterceptor.verified.txt
rename to tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=with parameters_sourceCode=HashBasedInterceptor.verified.txt
index 49200cc..84308d4 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_HashBasedInterceptor.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=with parameters_sourceCode=HashBasedInterceptor.verified.txt
@@ -1,4 +1,4 @@
-{
+{
Id: Guid_1,
Location: {
FilePath: path/testFile.cs,
@@ -28,7 +28,7 @@
},
Namespace: Foo,
ClassName: Test,
- Name: LogInformation,
+ MethodName: LogInformation,
LogLevel: Information,
Message: Hello world {arg1} {arg2},
Parameters: [
@@ -50,5 +50,6 @@
Type: Others,
HasPropertiesToLog: false
}
- ]
-}
+ ],
+ GeneratedMethodName: Log_FooTest_12_16
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_PathBasedInterceptor.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=with parameters_sourceCode=PathBasedInterceptor.verified.txt
similarity index 93%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_PathBasedInterceptor.verified.txt
rename to tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=with parameters_sourceCode=PathBasedInterceptor.verified.txt
index 8314179..29c586b 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_PathBasedInterceptor.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=with parameters_sourceCode=PathBasedInterceptor.verified.txt
@@ -1,4 +1,4 @@
-{
+{
Id: Guid_1,
Location: {
FilePath: path/testFile.cs,
@@ -28,7 +28,7 @@
},
Namespace: Foo,
ClassName: Test,
- Name: LogInformation,
+ MethodName: LogInformation,
LogLevel: Information,
Message: Hello world {arg1} {arg2},
Parameters: [
@@ -50,5 +50,6 @@
Type: Others,
HasPropertiesToLog: false
}
- ]
-}
+ ],
+ GeneratedMethodName: Log_FooTest_12_16
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=without parameters_sourceCode=HashBasedInterceptor.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=without parameters_sourceCode=HashBasedInterceptor.verified.txt
new file mode 100644
index 0000000..2b6a799
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=without parameters_sourceCode=HashBasedInterceptor.verified.txt
@@ -0,0 +1,43 @@
+{
+ Id: Guid_1,
+ Location: {
+ FilePath: path/testFile.cs,
+ Line: 12,
+ Character: 16,
+ InterceptableLocationSyntax: [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "VSNN9b1ciRV2FhFsas3dUJkAAAB0ZXN0RmlsZS5jcw==")],
+ Context: {
+ Kind: SourceFile,
+ SourceSpan: {
+ Start: 146,
+ Length: 36
+ },
+ SourceTree: {
+ FilePath: path/testFile.cs,
+ Length: 191,
+ HasCompilationUnitRoot: true,
+ Options: {
+ LanguageVersion: CSharp12,
+ Language: C#,
+ DocumentationMode: Parse,
+ Errors: null
+ }
+ },
+ IsInSource: true,
+ IsInMetadata: false
+ }
+ },
+ Namespace: Foo,
+ ClassName: Test,
+ MethodName: LogInformation,
+ LogLevel: Information,
+ Message: Hello world,
+ Parameters: [
+ {
+ NativeType: global::System.String,
+ Name: @message,
+ Type: Message,
+ HasPropertiesToLog: false
+ }
+ ],
+ GeneratedMethodName: Log_FooTest_12_16
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=without parameters_sourceCode=PathBasedInterceptor.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=without parameters_sourceCode=PathBasedInterceptor.verified.txt
new file mode 100644
index 0000000..3ff25d2
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_description=without parameters_sourceCode=PathBasedInterceptor.verified.txt
@@ -0,0 +1,43 @@
+{
+ Id: Guid_1,
+ Location: {
+ FilePath: path/testFile.cs,
+ Line: 12,
+ Character: 16,
+ InterceptableLocationSyntax: [System.Runtime.CompilerServices.InterceptsLocationAttribute(filePath: @"path/testFile.cs", line: 12, character: 16)],
+ Context: {
+ Kind: SourceFile,
+ SourceSpan: {
+ Start: 146,
+ Length: 36
+ },
+ SourceTree: {
+ FilePath: path/testFile.cs,
+ Length: 191,
+ HasCompilationUnitRoot: true,
+ Options: {
+ LanguageVersion: CSharp12,
+ Language: C#,
+ DocumentationMode: Parse,
+ Errors: null
+ }
+ },
+ IsInSource: true,
+ IsInMetadata: false
+ }
+ },
+ Namespace: Foo,
+ ClassName: Test,
+ MethodName: LogInformation,
+ LogLevel: Information,
+ Message: Hello world,
+ Parameters: [
+ {
+ NativeType: global::System.String,
+ Name: @message,
+ Type: Message,
+ HasPropertiesToLog: false
+ }
+ ],
+ GeneratedMethodName: Log_FooTest_12_16
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.cs
index 10eb483..010fedb 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.cs
@@ -6,20 +6,21 @@ namespace AutoLoggerMessageGenerator.UnitTests.Extractors;
internal class LogCallExtractorTests : BaseSourceGeneratorTest
{
[Test]
- [Arguments($$"""{{LoggerName}}.LogInformation("Hello world {arg1} {arg2}", 1, true);""", true)]
- [Arguments($$"""{{LoggerName}}.LogInformation(null);""", false)]
- [Arguments($$"""{{LoggerName}}.LogInformation("Hello world {arg1}", 1, true);""", false)]
- public async Task Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject(string sourceCode, bool isValidCall)
+ [Arguments("without parameters", $$"""{{LoggerName}}.LogInformation("Hello world");""", true)]
+ [Arguments("with parameters", $$"""{{LoggerName}}.LogInformation("Hello world {arg1} {arg2}", 1, true);""", true)]
+ [Arguments("with only null passed", $$"""{{LoggerName}}.LogInformation(null);""", false)]
+ [Arguments("with parameter count mismatch", $$"""{{LoggerName}}.LogInformation("Hello world {arg1}", 1, true);""", false)]
+ public async Task Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject(string description, string sourceCode, bool isValidCall)
{
var (compilation, syntaxTree) = await CompileSourceCode(sourceCode);
- var (invocationExpression, methodSymbol, semanticModel) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, semanticModel) = FindMethodInvocation(compilation, syntaxTree);
var logCall = LogCallExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
if (isValidCall)
{
var configuration = InterceptorConfigurationUtilities.GetInterceptorConfiguration();
- await Verify(logCall).UseTextForParameters(configuration);
+ await Verify(logCall).UseParameters(description, configuration);
}
else
{
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogLevelExtractorTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogLevelExtractorTests.cs
index 3286126..ea5c657 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogLevelExtractorTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogLevelExtractorTests.cs
@@ -24,7 +24,7 @@ internal class LogLevelExtractorTests : BaseSourceGeneratorTest
public async Task Extract_WithGivenMethodCall_ShouldReturnExpectedLogLevel(string methodCall, string? expectedLogLevel)
{
var (compilation, syntaxTree) = await CompileSourceCode($"{LoggerName}.{methodCall};");
- var (invocationExpression, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
var result = LogLevelExtractor.Extract(methodSymbol!, invocationExpression);
@@ -39,7 +39,7 @@ public async Task Extract_WithNotConstantLogLevel_ShouldReturnNull()
Log(logLevel, default);
""";
var (compilation, syntaxTree) = await CompileSourceCode(sourceCode);
- var (invocationExpression, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
var result = LogLevelExtractor.Extract(methodSymbol!, invocationExpression);
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_sourceCode=logger.LogInformation(-Hello world {arg1} {arg2}-, 1, true);_isValidCall=True.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.Extract_WithGivenLoggerScope_ShouldTransformIntoLoggerScopeCallObject_description=with parameters_sourceCode=HashBasedInterceptor.verified.txt
similarity index 77%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_sourceCode=logger.LogInformation(-Hello world {arg1} {arg2}-, 1, true);_isValidCall=True.verified.txt
rename to tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.Extract_WithGivenLoggerScope_ShouldTransformIntoLoggerScopeCallObject_description=with parameters_sourceCode=HashBasedInterceptor.verified.txt
index 6d2de15..21a4e8a 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallExtractorTests.Extract_WithLogMethodInvocationCode_ShouldTransformThemIntoLogCallObject_sourceCode=logger.LogInformation(-Hello world {arg1} {arg2}-, 1, true);_isValidCall=True.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.Extract_WithGivenLoggerScope_ShouldTransformIntoLoggerScopeCallObject_description=with parameters_sourceCode=HashBasedInterceptor.verified.txt
@@ -1,19 +1,18 @@
{
- Id: Guid_1,
Location: {
- FilePath: ,
+ FilePath: path/testFile.cs,
Line: 12,
Character: 16,
- InterceptableLocationSyntax: [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "bg8SAsBDKqh7V1TqOZu8tZkAAAA=")],
+ InterceptableLocationSyntax: [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "nedh6WI/ifg2J0oGdnNJkZkAAAB0ZXN0RmlsZS5jcw==")],
Context: {
Kind: SourceFile,
SourceSpan: {
Start: 146,
- Length: 59
+ Length: 55
},
SourceTree: {
- FilePath: ,
- Length: 214,
+ FilePath: path/testFile.cs,
+ Length: 210,
HasCompilationUnitRoot: true,
Options: {
LanguageVersion: CSharp12,
@@ -28,8 +27,7 @@
},
Namespace: Foo,
ClassName: Test,
- Name: LogInformation,
- LogLevel: Information,
+ MethodName: BeginScope,
Message: Hello world {arg1} {arg2},
Parameters: [
{
@@ -50,5 +48,6 @@
Type: Others,
HasPropertiesToLog: false
}
- ]
+ ],
+ GeneratedMethodName: LogScope_FooTest_12_16
}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.Extract_WithGivenLoggerScope_ShouldTransformIntoLoggerScopeCallObject_description=with parameters_sourceCode=PathBasedInterceptor.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.Extract_WithGivenLoggerScope_ShouldTransformIntoLoggerScopeCallObject_description=with parameters_sourceCode=PathBasedInterceptor.verified.txt
new file mode 100644
index 0000000..90b47fa
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.Extract_WithGivenLoggerScope_ShouldTransformIntoLoggerScopeCallObject_description=with parameters_sourceCode=PathBasedInterceptor.verified.txt
@@ -0,0 +1,53 @@
+{
+ Location: {
+ FilePath: path/testFile.cs,
+ Line: 12,
+ Character: 16,
+ InterceptableLocationSyntax: [System.Runtime.CompilerServices.InterceptsLocationAttribute(filePath: @"path/testFile.cs", line: 12, character: 16)],
+ Context: {
+ Kind: SourceFile,
+ SourceSpan: {
+ Start: 146,
+ Length: 55
+ },
+ SourceTree: {
+ FilePath: path/testFile.cs,
+ Length: 210,
+ HasCompilationUnitRoot: true,
+ Options: {
+ LanguageVersion: CSharp12,
+ Language: C#,
+ DocumentationMode: Parse,
+ Errors: null
+ }
+ },
+ IsInSource: true,
+ IsInMetadata: false
+ }
+ },
+ Namespace: Foo,
+ ClassName: Test,
+ MethodName: BeginScope,
+ Message: Hello world {arg1} {arg2},
+ Parameters: [
+ {
+ NativeType: global::System.String,
+ Name: @message,
+ Type: Message,
+ HasPropertiesToLog: false
+ },
+ {
+ NativeType: global::System.Int32,
+ Name: @arg1,
+ Type: Others,
+ HasPropertiesToLog: false
+ },
+ {
+ NativeType: global::System.Boolean,
+ Name: @arg2,
+ Type: Others,
+ HasPropertiesToLog: false
+ }
+ ],
+ GeneratedMethodName: LogScope_FooTest_12_16
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.cs
new file mode 100644
index 0000000..3e5d25a
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LoggerScopeCallExtractorTests.cs
@@ -0,0 +1,29 @@
+using AutoLoggerMessageGenerator.Extractors;
+using AutoLoggerMessageGenerator.UnitTests.Utilities;
+
+namespace AutoLoggerMessageGenerator.UnitTests.Extractors;
+
+internal class LoggerScopeCallExtractorTests : BaseSourceGeneratorTest
+{
+ [Test]
+ [Arguments("with parameters", $$"""{{LoggerName}}.BeginScope("Hello world {arg1} {arg2}", 1, true);""", true)]
+ [Arguments("with null passed", $"""{LoggerName}.BeginScope(null);""", false)]
+ [Arguments("with parameter mismatch", $$"""{{LoggerName}}.BeginScope("Hello world {arg1}", 1, true);""", false)]
+ public async Task Extract_WithGivenLoggerScope_ShouldTransformIntoLoggerScopeCallObject(string description, string sourceCode, bool isValidCall)
+ {
+ var (compilation, syntaxTree) = await CompileSourceCode(sourceCode);
+ var (invocationExpression, methodSymbol, semanticModel) = FindMethodInvocation(compilation, syntaxTree);
+
+ var loggerScope = LoggerScopeCallExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
+
+ if (isValidCall)
+ {
+ var configuration = InterceptorConfigurationUtilities.GetInterceptorConfiguration();
+ await Verify(loggerScope).UseParameters(description, configuration);
+ }
+ else
+ {
+ await Assert.That(loggerScope.HasValue).IsFalse();
+ }
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallMessageParameterNamesExtractorTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/MessageParameterNamesExtractorTests.cs
similarity index 88%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallMessageParameterNamesExtractorTests.cs
rename to tests/AutoLoggerMessageGenerator.UnitTests/Extractors/MessageParameterNamesExtractorTests.cs
index 4adbdd6..208af50 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallMessageParameterNamesExtractorTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/MessageParameterNamesExtractorTests.cs
@@ -2,7 +2,7 @@
namespace AutoLoggerMessageGenerator.UnitTests.Extractors;
-internal class LogCallMessageParameterNamesExtractorTests
+internal class MessageParameterNamesExtractorTests
{
[Test]
[Arguments("Hello world {1}, {2}!", new[] { "1", "2" })]
@@ -18,7 +18,7 @@ internal class LogCallMessageParameterNamesExtractorTests
[Arguments(null, new string[0])]
public async Task Extract_WithGivenMessage_ShouldReturnGivenMessageParameterNames(string? message, params string[] expectedMessageParameters)
{
- var result = LogCallMessageParameterNamesExtractor.Extract(message);
+ var result = MessageParameterNamesExtractor.Extract(message);
await Assert.That(result).IsEquivalentTo(expectedMessageParameters);
}
}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallMessageExtractorTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/MessageParameterTextExtractorTests.cs
similarity index 75%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallMessageExtractorTests.cs
rename to tests/AutoLoggerMessageGenerator.UnitTests/Extractors/MessageParameterTextExtractorTests.cs
index d70c093..977db2d 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallMessageExtractorTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Extractors/MessageParameterTextExtractorTests.cs
@@ -2,7 +2,7 @@
namespace AutoLoggerMessageGenerator.UnitTests.Extractors;
-internal class LogCallMessageExtractorTests : BaseSourceGeneratorTest
+internal class MessageParameterTextExtractorTests : BaseSourceGeneratorTest
{
[Test]
[Arguments("Hello world {1}, {2}!")]
@@ -10,9 +10,9 @@ internal class LogCallMessageExtractorTests : BaseSourceGeneratorTest
public async Task Extract_WithPassingLiteralValues_ShouldReturnExpectedMessage(string expectedMessage)
{
var (compilation, syntaxTree) = await CompileSourceCode($"""{LoggerName}.LogInformation("{expectedMessage}");""");
- var (invocationExpression, methodSymbol, semanticModel) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, semanticModel) = FindMethodInvocation(compilation, syntaxTree);
- var result = LogCallMessageExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
+ var result = MessageParameterTextExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
await Assert.That(result).IsEqualTo(expectedMessage);
}
@@ -25,9 +25,9 @@ public async Task Extract_WithPassingConstClassMembers_ShouldReturnExpectedMessa
$"{LoggerName}.LogInformation(Message);",
$"""private const string Message = "{expectedMessage}";"""
);
- var (invocationExpression, methodSymbol, semanticModel) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, semanticModel) = FindMethodInvocation(compilation, syntaxTree);
- var result = LogCallMessageExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
+ var result = MessageParameterTextExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
await Assert.That(result).IsEqualTo(expectedMessage);
}
@@ -41,9 +41,9 @@ public async Task Extract_WithPassingLocalConstVariable_ShouldReturnExpectedMess
{LoggerName}.LogInformation(message);
"""
);
- var (invocationExpression, methodSymbol, semanticModel) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, semanticModel) = FindMethodInvocation(compilation, syntaxTree);
- var result = LogCallMessageExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
+ var result = MessageParameterTextExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
await Assert.That(result).IsEqualTo(expectedMessage);
}
@@ -52,9 +52,9 @@ public async Task Extract_WithPassingLocalConstVariable_ShouldReturnExpectedMess
public async Task Extract_WithPassingNullValues_ShouldReturnNull()
{
var (compilation, syntaxTree) = await CompileSourceCode($"{LoggerName}.LogInformation(null);");
- var (invocationExpression, methodSymbol, semanticModel) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, semanticModel) = FindMethodInvocation(compilation, syntaxTree);
- var result = LogCallMessageExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
+ var result = MessageParameterTextExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
await Assert.That(result).IsNull();
}
@@ -71,9 +71,9 @@ public async Task Extract_WithBinaryExpressions_ShouldReturnConcatenatedString()
""";
var (compilation, syntaxTree) = await CompileSourceCode(sourceCode);
- var (invocationExpression, methodSymbol, semanticModel) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, semanticModel) = FindMethodInvocation(compilation, syntaxTree);
- var result = LogCallMessageExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
+ var result = MessageParameterTextExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
await Assert.That(result).IsEqualTo("Hello world! 42");
}
@@ -90,9 +90,9 @@ public async Task Extract_WithBinaryNonConstantExpressions_ShouldReturnNull()
""";
var (compilation, syntaxTree) = await CompileSourceCode(sourceCode);
- var (invocationExpression, methodSymbol, semanticModel) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpression, methodSymbol, semanticModel) = FindMethodInvocation(compilation, syntaxTree);
- var result = LogCallMessageExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
+ var result = MessageParameterTextExtractor.Extract(methodSymbol!, invocationExpression, semanticModel!);
await Assert.That(result).IsNull();
}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Filters/LogCallFilterTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Filters/LogMessageCallFilterTests.cs
similarity index 88%
rename from tests/AutoLoggerMessageGenerator.UnitTests/Filters/LogCallFilterTests.cs
rename to tests/AutoLoggerMessageGenerator.UnitTests/Filters/LogMessageCallFilterTests.cs
index a790ccc..a1b5bec 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Filters/LogCallFilterTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Filters/LogMessageCallFilterTests.cs
@@ -5,7 +5,7 @@
namespace AutoLoggerMessageGenerator.UnitTests.Filters;
-internal class LogCallFilterTests : BaseSourceGeneratorTest
+internal class LogMessageCallFilterTests : BaseSourceGeneratorTest
{
[Test]
public async Task Filter_WithDifferentMethodInvocations_ShouldFilterOnlyLogMethodsFromLoggerInstance()
@@ -38,14 +38,14 @@ public void AnotherMethod(string message, DateTime arg1) {}
var invocationExpressions = syntaxTree.GetRoot()
.DescendantNodes()
- .Where(c => LogCallFilter.IsLogCallInvocation(c, CancellationToken.None))
+ .Where(c => LogMessageCallFilter.IsLogCallInvocation(c, CancellationToken.None))
.ToArray();
var semanticModel = compilation.GetSemanticModel(syntaxTree);
var filteredInvocationExpressions = invocationExpressions.OfType().Where(c =>
{
var methodSymbol = (IMethodSymbol) semanticModel.GetSymbolInfo(c).Symbol!;
- return LogCallFilter.IsLoggerMethod(methodSymbol);
+ return LogMessageCallFilter.IsLoggerMethod(methodSymbol);
}).ToArray();
await Assert.That(invocationExpressions.Length).IsEqualTo(2);
@@ -74,10 +74,10 @@ public class D {}
{{LoggerName}}.LogInformation("B class is private, so {this} argument is inaccessible as well", parameter);
""";
var (compilation, syntaxTree) = await CompileSourceCode(sourceCode, additionalDeclarations);
- var (invocationExpressionSyntax, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
+ var (invocationExpressionSyntax, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
- var isLogCallInvocation = LogCallFilter.IsLogCallInvocation(invocationExpressionSyntax, CancellationToken.None);
- var isLogCallMethod = LogCallFilter.IsLoggerMethod(methodSymbol!);
+ var isLogCallInvocation = LogMessageCallFilter.IsLogCallInvocation(invocationExpressionSyntax, CancellationToken.None);
+ var isLogCallMethod = LogMessageCallFilter.IsLoggerMethod(methodSymbol!);
await Assert.That(isLogCallInvocation).IsTrue();
await Assert.That(isLogCallMethod).IsFalse();
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Filters/LoggerScopeFilterTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Filters/LoggerScopeFilterTests.cs
new file mode 100644
index 0000000..00b14fa
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Filters/LoggerScopeFilterTests.cs
@@ -0,0 +1,94 @@
+using AutoLoggerMessageGenerator.Filters;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace AutoLoggerMessageGenerator.UnitTests.Filters;
+
+internal class LoggerScopeFilterTests : BaseSourceGeneratorTest
+{
+ [Test]
+ public async Task Filter_WithDifferentMethodInvocations_ShouldFilterOnlyBeginScopeCallsFromLoggerInstance()
+ {
+ var additionalDeclarations = """
+ public class AnotherObject
+ {
+ public IDisposable? BeginScope(string message, Guid arg1) {}
+ public IDisposable? BeginScope2(string message, Guid arg1) {}
+ }
+
+ public IDisposable? BeginScope(string message, Guid arg1) {}
+ """;
+ var sourceCode = $$"""
+ const string message = "CorrelationId: {CorrelationId}";
+ var correlationId = Guid.NewGuid();
+
+ {{LoggerName}}.BeginScope(message, correlationId);
+
+ AnotherMethod(message, correlationId);
+ BeginScope(message, correlationId);
+ new AnotherObject().BeginScope(message, correlationId);
+ new AnotherObject().BeginScope2(message, correlationId);
+ """;
+ var (compilation, syntaxTree) = await CompileSourceCode(sourceCode, additionalDeclarations);
+
+ var invocationExpressions = syntaxTree.GetRoot()
+ .DescendantNodes()
+ .Where(c => LoggerScopeFilter.IsLoggerScopeInvocation(c, CancellationToken.None))
+ .ToArray();
+
+ var semanticModel = compilation.GetSemanticModel(syntaxTree);
+ var filteredInvocationExpressions = invocationExpressions.OfType().Where(c =>
+ {
+ var methodSymbol = (IMethodSymbol) semanticModel.GetSymbolInfo(c).Symbol!;
+ return LoggerScopeFilter.IsLoggerScopeMethod(methodSymbol);
+ }).ToArray();
+
+ await Assert.That(invocationExpressions.Length).IsEqualTo(2);
+ await Assert.That(filteredInvocationExpressions.Length).IsEqualTo(1);
+ }
+
+ [Test]
+ public async Task Filter_WithInaccessibleClassAsParameter_ShouldExcludeBeginScopeCall()
+ {
+ const string additionalDeclarations = """
+ public class A
+ {
+ private class B
+ {
+ public class C
+ {
+ public class D {}
+ }
+ }
+ }
+ """;
+
+ const string sourceCode = $$"""
+ var parameter = new A.B.C.D();
+ {{LoggerName}}.BeginScope("B class is private, so {this} argument is inaccessible as well", parameter);
+ """;
+ var (compilation, syntaxTree) = await CompileSourceCode(sourceCode, additionalDeclarations);
+ var (invocationExpressionSyntax, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
+
+ var isLoggerScopeInvocation = LoggerScopeFilter.IsLoggerScopeInvocation(invocationExpressionSyntax, CancellationToken.None);
+ var isLoggerScopeCall = LoggerScopeFilter.IsLoggerScopeMethod(methodSymbol!);
+
+ await Assert.That(isLoggerScopeInvocation).IsTrue();
+ await Assert.That(isLoggerScopeCall).IsFalse();
+ }
+
+ [Test]
+ public async Task Filter_WithOnlyMessageParameterProvided_ShouldExcludeBeginScopeCall()
+ {
+ const string sourceCode = $"{LoggerName}.BeginScope(\"Some message\");";
+ var (compilation, syntaxTree) = await CompileSourceCode(sourceCode);
+ var (invocationExpressionSyntax, methodSymbol, _) = FindMethodInvocation(compilation, syntaxTree);
+
+ var isLoggerScopeInvocation = LoggerScopeFilter.IsLoggerScopeInvocation(invocationExpressionSyntax, CancellationToken.None);
+ var isLoggerScopeCall = LoggerScopeFilter.IsLoggerScopeMethod(methodSymbol!);
+
+ await Assert.That(isLoggerScopeInvocation).IsFalse();
+ await Assert.That(isLoggerScopeCall).IsFalse();
+ }
+}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/MethodSpecificityRules/InstanceCallVsExtensionCallTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/MethodSpecificityRules/InstanceCallVsExtensionCallTests.cs
new file mode 100644
index 0000000..cd87c8c
--- /dev/null
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/MethodSpecificityRules/InstanceCallVsExtensionCallTests.cs
@@ -0,0 +1,29 @@
+namespace AutoLoggerMessageGenerator.UnitTests;
+
+internal class InstanceCallVsExtensionCallTests
+{
+ [Test]
+ public async Task BeginScope_WithOnlyMessageParameter_InstanceCallShouldBePrioritized()
+ {
+ ILogger logger = new Logger();
+ var result = logger.BeginScope("Some scope");
+
+ await Assert.That(result).IsEqualTo(CallSource.Instance);
+ }
+}
+
+interface ILogger
+{
+ CallSource BeginScope(T _);
+}
+class Logger : ILogger
+{
+ public CallSource BeginScope(T _) => CallSource.Instance;
+}
+
+static class LoggerExtensions
+{
+ public static CallSource BeginScope(this ILogger _, string __) => CallSource.Extension;
+}
+
+enum CallSource { Instance, Extension }
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/Utilities/IdentifierHelperTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Utilities/IdentifierHelperTests.cs
index 8e8b20f..19bcc2a 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/Utilities/IdentifierHelperTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Utilities/IdentifierHelperTests.cs
@@ -1,4 +1,5 @@
using AutoLoggerMessageGenerator.Utilities;
+using TUnit.Assertions.AssertConditions.Throws;
namespace AutoLoggerMessageGenerator.UnitTests.Utilities;
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/MockLogCallLocationBuilder.cs b/tests/AutoLoggerMessageGenerator.UnitTests/Utilities/MockLogCallLocationBuilder.cs
similarity index 73%
rename from tests/AutoLoggerMessageGenerator.UnitTests/MockLogCallLocationBuilder.cs
rename to tests/AutoLoggerMessageGenerator.UnitTests/Utilities/MockLogCallLocationBuilder.cs
index e678029..44ffc9a 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/MockLogCallLocationBuilder.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/Utilities/MockLogCallLocationBuilder.cs
@@ -6,7 +6,7 @@ namespace AutoLoggerMessageGenerator.UnitTests;
internal static class MockLogCallLocationBuilder
{
- internal static LogCallLocation Build(string filePath, int line, int character)
+ internal static CallLocation Build(string filePath, int line, int character)
{
ArgumentException.ThrowIfNullOrEmpty(filePath);
@@ -15,6 +15,6 @@ internal static LogCallLocation Build(string filePath, int line, int character)
var data = Convert.ToBase64String(Encoding.UTF8.GetBytes(location));
var interceptableLocationSyntax = $"""[FakeInterceptableLocation({version}, "{data}")]""";
- return new LogCallLocation(filePath, line, character, interceptableLocationSyntax, Location.None);
+ return new CallLocation(filePath, line, character, interceptableLocationSyntax, Location.None);
}
}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/LogCallExtractorTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/LogCallExtractorTests.cs
index c94978b..ecfcb1f 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/LogCallExtractorTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/LogCallExtractorTests.cs
@@ -4,25 +4,25 @@
namespace AutoLoggerMessageGenerator.UnitTests.VirtualLoggerMessage;
-internal class LogCallLocationMapTests : BaseSourceGeneratorTest
+internal class LogMessageCallLocationMapTests : BaseSourceGeneratorTest
{
[Test]
public async Task MapBack_GivenMethodName_ShouldReturnLastLocationBeforeTheCurrentNode()
{
- var logCall1 = new LogCall { Id = Guid.NewGuid() };
- var logCall2 = new LogCall { Id = Guid.NewGuid() };
- var logCall3 = new LogCall { Id = Guid.NewGuid() };
+ var logCall1 = new LogMessageCall { Id = Guid.NewGuid() };
+ var logCall2 = new LogMessageCall { Id = Guid.NewGuid() };
+ var logCall3 = new LogMessageCall { Id = Guid.NewGuid() };
var additionalDeclarations = $$"""
public void Method0(){}
- {{LogCallLocationMap.CreateMapping(logCall1)}}
+ {{LogMessageCallLocationMap.CreateMapping(logCall1)}}
public void Method1(){}
- {{LogCallLocationMap.CreateMapping(logCall2)}}
+ {{LogMessageCallLocationMap.CreateMapping(logCall2)}}
public void Method2(){}
- {{LogCallLocationMap.CreateMapping(logCall3)}}
+ {{LogMessageCallLocationMap.CreateMapping(logCall3)}}
public void Method3(){}
""";
var (_, syntaxTree) = await CompileSourceCode(string.Empty, additionalDeclarations);
@@ -36,18 +36,18 @@ public void Method3(){}
var method2Declaration = methodDeclarations.Single(m => m.Identifier.Text == "Method2");
var method3Declaration = methodDeclarations.Single(m => m.Identifier.Text == "Method3");
- await Assert.That(LogCallLocationMap.TryMapBack(syntaxTree.GetText(), method0Declaration.GetLocation(), out var logCallId0))
+ await Assert.That(LogMessageCallLocationMap.TryMapBack(syntaxTree.GetText(), method0Declaration.GetLocation(), out var logCallId0))
.IsFalse();
- await Assert.That(LogCallLocationMap.TryMapBack(syntaxTree.GetText(), method1Declaration.GetLocation(), out var logCallId1))
+ await Assert.That(LogMessageCallLocationMap.TryMapBack(syntaxTree.GetText(), method1Declaration.GetLocation(), out var logCallId1))
.IsTrue();
await Assert.That(logCallId1).IsEqualTo(logCall1.Id);
- await Assert.That(LogCallLocationMap.TryMapBack(syntaxTree.GetText(), method2Declaration.GetLocation(), out var logCallId2))
+ await Assert.That(LogMessageCallLocationMap.TryMapBack(syntaxTree.GetText(), method2Declaration.GetLocation(), out var logCallId2))
.IsTrue();
await Assert.That(logCallId2).IsEqualTo(logCall2.Id);
- await Assert.That(LogCallLocationMap.TryMapBack(syntaxTree.GetText(), method3Declaration.GetLocation(), out var logCallId3))
+ await Assert.That(LogMessageCallLocationMap.TryMapBack(syntaxTree.GetText(), method3Declaration.GetLocation(), out var logCallId3))
.IsTrue();
await Assert.That(logCallId3).IsEqualTo(logCall3.Id);
}
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_72a4a8950e4d9a2c.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_all_disabled.verified.txt
similarity index 83%
rename from tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_72a4a8950e4d9a2c.verified.txt
rename to tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_all_disabled.verified.txt
index fc4fa50..99df045 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_72a4a8950e4d9a2c.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_all_disabled.verified.txt
@@ -1,12 +1,12 @@
-namespace Microsoft.Extensions.Logging.AutoLoggerMessage
+namespace Microsoft.Extensions.Logging.AutoLoggerMessage
{
static partial class AutoLoggerMessage
{
- // : Guid_1
+ // : Guid_1
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Critical, Message = "Hello, World!", SkipEnabledCheck = false)]
internal static partial void Log_SomeNamespaceSomeClass_2_22(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, SomeClass @classParam, SomeStruct @structParam);
- // : Guid_2
+ // : Guid_2
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Trace, Message = "Goodbye, World!", SkipEnabledCheck = false)]
internal static partial void Log_SomeNamespaceSomeClass_3_33(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, SomeClass @classParam, SomeStruct @structParam);
}
-}
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_90f6f16c422d1dd6.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_all_enabled.verified.txt
similarity index 89%
rename from tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_90f6f16c422d1dd6.verified.txt
rename to tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_all_enabled.verified.txt
index 47d8f99..6ebd768 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_90f6f16c422d1dd6.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_all_enabled.verified.txt
@@ -1,12 +1,12 @@
-namespace Microsoft.Extensions.Logging.AutoLoggerMessage
+namespace Microsoft.Extensions.Logging.AutoLoggerMessage
{
static partial class AutoLoggerMessage
{
- // : Guid_1
+ // : Guid_1
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Critical, Message = "Hello, World!", SkipEnabledCheck = true)]
internal static partial void Log_SomeNamespaceSomeClass_2_22(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, [Microsoft.Extensions.Logging.LogPropertiesAttribute(OmitReferenceName = true, SkipNullProperties = true, Transitive = true)] SomeClass @classParam, [Microsoft.Extensions.Logging.LogPropertiesAttribute(OmitReferenceName = true, SkipNullProperties = true, Transitive = true)] SomeStruct @structParam);
- // : Guid_2
+ // : Guid_2
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Trace, Message = "Goodbye, World!", SkipEnabledCheck = true)]
internal static partial void Log_SomeNamespaceSomeClass_3_33(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, [Microsoft.Extensions.Logging.LogPropertiesAttribute(OmitReferenceName = true, SkipNullProperties = true, Transitive = true)] SomeClass @classParam, [Microsoft.Extensions.Logging.LogPropertiesAttribute(OmitReferenceName = true, SkipNullProperties = true, Transitive = true)] SomeStruct @structParam);
}
-}
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_8aa982b1f9f3bd17.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_only_telemetry_enabled.verified.txt
similarity index 88%
rename from tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_8aa982b1f9f3bd17.verified.txt
rename to tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_only_telemetry_enabled.verified.txt
index 2a2657c..782cfdd 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_8aa982b1f9f3bd17.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_only_telemetry_enabled.verified.txt
@@ -1,12 +1,12 @@
-namespace Microsoft.Extensions.Logging.AutoLoggerMessage
+namespace Microsoft.Extensions.Logging.AutoLoggerMessage
{
static partial class AutoLoggerMessage
{
- // : Guid_1
+ // : Guid_1
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Critical, Message = "Hello, World!", SkipEnabledCheck = false)]
internal static partial void Log_SomeNamespaceSomeClass_2_22(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, [Microsoft.Extensions.Logging.LogPropertiesAttribute(OmitReferenceName = false, SkipNullProperties = false)] SomeClass @classParam, [Microsoft.Extensions.Logging.LogPropertiesAttribute(OmitReferenceName = false, SkipNullProperties = false)] SomeStruct @structParam);
- // : Guid_2
+ // : Guid_2
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Trace, Message = "Goodbye, World!", SkipEnabledCheck = false)]
internal static partial void Log_SomeNamespaceSomeClass_3_33(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, [Microsoft.Extensions.Logging.LogPropertiesAttribute(OmitReferenceName = false, SkipNullProperties = false)] SomeClass @classParam, [Microsoft.Extensions.Logging.LogPropertiesAttribute(OmitReferenceName = false, SkipNullProperties = false)] SomeStruct @structParam);
}
-}
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_7dc9492fbd4b4118.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_telemetry_disabled.verified.txt
similarity index 83%
rename from tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_7dc9492fbd4b4118.verified.txt
rename to tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_telemetry_disabled.verified.txt
index dfa01ac..9d3f72e 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_7dc9492fbd4b4118.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_telemetry_disabled.verified.txt
@@ -1,12 +1,12 @@
-namespace Microsoft.Extensions.Logging.AutoLoggerMessage
+namespace Microsoft.Extensions.Logging.AutoLoggerMessage
{
static partial class AutoLoggerMessage
{
- // : Guid_1
+ // : Guid_1
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Critical, Message = "Hello, World!", SkipEnabledCheck = true)]
internal static partial void Log_SomeNamespaceSomeClass_2_22(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, SomeClass @classParam, SomeStruct @structParam);
- // : Guid_2
+ // : Guid_2
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Trace, Message = "Goodbye, World!", SkipEnabledCheck = true)]
internal static partial void Log_SomeNamespaceSomeClass_3_33(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, SomeClass @classParam, SomeStruct @structParam);
}
-}
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithEscapeSequences_ShouldBuildAsItIs.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithEscapeSequences_ShouldBuildAsItIs.verified.txt
index 28c25bb..8a13548 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithEscapeSequences_ShouldBuildAsItIs.verified.txt
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithEscapeSequences_ShouldBuildAsItIs.verified.txt
@@ -2,8 +2,8 @@
{
static partial class AutoLoggerMessage
{
- // : Guid_1
+ // : Guid_1
[Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Trace, Message = "All characters should be passed as a string literal expression: \n\r\t", SkipEnabledCheck = false)]
internal static partial void Log_SomeNamespaceSomeClass_3_33(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, SomeClass @classParam, SomeStruct @structParam);
}
-}
+}
\ No newline at end of file
diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.cs b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.cs
index aef3c4c..f8f16c3 100644
--- a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.cs
+++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.cs
@@ -7,39 +7,40 @@ namespace AutoLoggerMessageGenerator.UnitTests.VirtualLoggerMessage;
internal class VirtualLoggerMessageClassBuilderTests
{
- private readonly LogCall _logCall = new()
+ private readonly LogMessageCall _logMessageCall = new()
{
Id = Guid.NewGuid(),
- Location = new LogCallLocation
+ Location = new CallLocation
{
FilePath = "./some/path/to/file.cs",
Line = 2,
Character = 22
},
Message = "Hello, World!",
- Name = "LogCall",
+ MethodName = "LogCall",
Namespace = "SomeNamespace",
ClassName = "SomeClass",
LogLevel = "Critical",
- Parameters = [
- new LogCallParameter("int", "@intParam", LogCallParameterType.Others),
- new LogCallParameter("string", "@stringParam", LogCallParameterType.Others),
- new LogCallParameter("bool", "@boolParam", LogCallParameterType.Others),
- new LogCallParameter("SomeClass", "@classParam", LogCallParameterType.Others, true),
- new LogCallParameter("SomeStruct", "@structParam", LogCallParameterType.Others, true)
+ Parameters =
+ [
+ new CallParameter("int", "@intParam", CallParameterType.Others),
+ new CallParameter("string", "@stringParam", CallParameterType.Others),
+ new CallParameter("bool", "@boolParam", CallParameterType.Others),
+ new CallParameter("SomeClass", "@classParam", CallParameterType.Others, true),
+ new CallParameter("SomeStruct", "@structParam", CallParameterType.Others, true)
]
};
[Test]
[MethodDataSource(nameof(TestConfigurations))]
public async Task Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration(
- SourceGeneratorConfiguration configuration, bool useTelemetryExtensions)
+ string description, SourceGeneratorConfiguration configuration, bool useTelemetryExtensions)
{
var sut = new VirtualLoggerMessageClassBuilder(configuration, useTelemetryExtensions);
var result = sut.Build([
- _logCall,
- _logCall with
+ _logMessageCall,
+ _logMessageCall with
{
Id = Guid.NewGuid(),
Location = MockLogCallLocationBuilder.Build("path/to/another/file.cs", 3, 33),
@@ -51,8 +52,7 @@ _logCall with
var syntaxTree = (await result.SyntaxTree.GetRootAsync()).NormalizeWhitespace().ToFullString();
await Verify(syntaxTree)
- .UseParameters(configuration, useTelemetryExtensions)
- .HashParameters()
+ .UseTextForParameters(description)
.ScrubInlineGuids();
}
@@ -62,7 +62,7 @@ public async Task Build_WithEscapeSequences_ShouldBuildAsItIs()
var sut = new VirtualLoggerMessageClassBuilder(default);
var result = sut.Build([
- _logCall with
+ _logMessageCall with
{
Id = Guid.NewGuid(),
Location = MockLogCallLocationBuilder.Build("path/to/another/file.cs", 3, 33),
@@ -76,11 +76,47 @@ _logCall with
await Verify(syntaxTree).ScrubInlineGuids();
}
- public static IEnumerable> TestConfigurations() =>
+ public static IEnumerable> TestConfigurations() =>
[
- () => (new SourceGeneratorConfiguration(default, true, true, true, true), true),
- () => (new SourceGeneratorConfiguration(default, true, true, true, true), false),
- () => (new SourceGeneratorConfiguration(default, false, false, false, false), true),
- () => (new SourceGeneratorConfiguration(default, false, false, false, false), false),
+ () => (
+ "all_enabled",
+ new SourceGeneratorConfiguration(
+ GenerateInterceptorAttribute: false,
+ GenerateSkipEnabledCheck: true,
+ GenerateOmitReferenceName: true,
+ GenerateSkipNullProperties: true,
+ GenerateTransitive: true,
+ OverrideBeginScopeBehavior: false
+ ), true),
+ () => (
+ "telemetry_disabled",
+ new SourceGeneratorConfiguration(
+ GenerateInterceptorAttribute: false,
+ GenerateSkipEnabledCheck: true,
+ GenerateOmitReferenceName: true,
+ GenerateSkipNullProperties: true,
+ GenerateTransitive: true,
+ OverrideBeginScopeBehavior: false),
+ false),
+ () => (
+ "only_telemetry_enabled",
+ new SourceGeneratorConfiguration(
+ GenerateInterceptorAttribute: false,
+ GenerateSkipEnabledCheck: false,
+ GenerateOmitReferenceName: false,
+ GenerateSkipNullProperties: false,
+ GenerateTransitive: false,
+ OverrideBeginScopeBehavior: false),
+ true),
+ () => (
+ "all_disabled",
+ new SourceGeneratorConfiguration(
+ GenerateInterceptorAttribute: false,
+ GenerateSkipEnabledCheck: false,
+ GenerateOmitReferenceName: false,
+ GenerateSkipNullProperties: false,
+ GenerateTransitive: false,
+ OverrideBeginScopeBehavior: false),
+ false),
];
}