diff --git a/src/AutoLoggerMessageGenerator/Configuration/GeneratorOptionsProvider.cs b/src/AutoLoggerMessageGenerator/Configuration/GeneratorOptionsProvider.cs index d0b64e7..18edc3c 100644 --- a/src/AutoLoggerMessageGenerator/Configuration/GeneratorOptionsProvider.cs +++ b/src/AutoLoggerMessageGenerator/Configuration/GeneratorOptionsProvider.cs @@ -1,3 +1,4 @@ +using AutoLoggerMessageGenerator.Models; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; @@ -12,6 +13,8 @@ internal static class GeneratorOptionsProvider private const string GenerateSkipNullPropertiesKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.GenerateSkipNullProperties)}"; private const string GenerateTransitiveKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.GenerateTransitive)}"; private const string OverrideBeginScopeBehaviorKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.OverrideBeginScopeBehavior)}"; + private const string DefaultEventIdKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.DefaultEventId)}"; + private const string DefaultEventNameKey = $"{CommonPrefix}_{nameof(SourceGeneratorConfiguration.DefaultEventId)}_Name"; public static IncrementalValueProvider Provide(IncrementalGeneratorInitializationContext context) => context.AnalyzerConfigOptionsProvider.Select((options, _) => new SourceGeneratorConfiguration( @@ -20,7 +23,8 @@ public static IncrementalValueProvider Provide(Inc GenerateOmitReferenceName: GetValue(options.GlobalOptions, GenerateOmitReferenceNameKey, false), GenerateSkipNullProperties: GetValue(options.GlobalOptions, GenerateSkipNullPropertiesKey, false), GenerateTransitive: GetValue(options.GlobalOptions, GenerateTransitiveKey, false), - OverrideBeginScopeBehavior: GetValue(options.GlobalOptions, OverrideBeginScopeBehaviorKey, true) + OverrideBeginScopeBehavior: GetValue(options.GlobalOptions, OverrideBeginScopeBehaviorKey, true), + DefaultEventId: GetDefaultEventId(options.GlobalOptions) )); private static bool GetValue(AnalyzerConfigOptions options, string key, bool defaultValue = true) => @@ -31,4 +35,15 @@ private static bool IsFeatureEnabled(string value, bool defaultValue) => || StringComparer.OrdinalIgnoreCase.Equals("enabled", value) || StringComparer.OrdinalIgnoreCase.Equals("true", value) || (bool.TryParse(value, out var boolVal) ? boolVal : defaultValue); + + private static EventId? GetDefaultEventId(AnalyzerConfigOptions options) + { + if (options.TryGetValue(DefaultEventIdKey, out var defaultEventIdString) is false || + int.TryParse(defaultEventIdString, out var parsedDefaultEventId) is false) + return null; + + options.TryGetValue(DefaultEventNameKey, out var eventName); + + return new EventId(parsedDefaultEventId, eventName); + } } diff --git a/src/AutoLoggerMessageGenerator/Configuration/SourceGeneratorConfiguration.cs b/src/AutoLoggerMessageGenerator/Configuration/SourceGeneratorConfiguration.cs index af6424b..b45b65e 100644 --- a/src/AutoLoggerMessageGenerator/Configuration/SourceGeneratorConfiguration.cs +++ b/src/AutoLoggerMessageGenerator/Configuration/SourceGeneratorConfiguration.cs @@ -1,3 +1,5 @@ +using AutoLoggerMessageGenerator.Models; + namespace AutoLoggerMessageGenerator.Configuration; internal record struct SourceGeneratorConfiguration @@ -9,5 +11,6 @@ internal record struct SourceGeneratorConfiguration bool GenerateOmitReferenceName, bool GenerateSkipNullProperties, bool GenerateTransitive, - bool OverrideBeginScopeBehavior + bool OverrideBeginScopeBehavior, + EventId? DefaultEventId = null ); diff --git a/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerMessage.cs b/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerMessage.cs index 6d8b9eb..ddf4569 100644 --- a/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerMessage.cs +++ b/src/AutoLoggerMessageGenerator/Generators/AutoLoggerMessageGenerator.LoggerMessage.cs @@ -20,8 +20,10 @@ namespace AutoLoggerMessageGenerator.Generators; public partial class AutoLoggerMessageGenerator { - private static void GenerateLoggerMessages(IncrementalGeneratorInitializationContext context, - IncrementalValueProvider configuration, IncrementalValueProvider> modulesProvider) + private static void GenerateLoggerMessages( + IncrementalGeneratorInitializationContext context, + IncrementalValueProvider configuration, + IncrementalValueProvider> modulesProvider) { var logCallsProvider = context.SyntaxProvider.CreateSyntaxProvider( LogMessageCallFilter.IsLogCallInvocation, diff --git a/src/AutoLoggerMessageGenerator/Models/EventId.cs b/src/AutoLoggerMessageGenerator/Models/EventId.cs new file mode 100644 index 0000000..3241c6f --- /dev/null +++ b/src/AutoLoggerMessageGenerator/Models/EventId.cs @@ -0,0 +1,3 @@ +namespace AutoLoggerMessageGenerator.Models; + +internal record struct EventId(int Id, string? Name); diff --git a/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/VirtualLoggerMessageClassBuilder.cs b/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/VirtualLoggerMessageClassBuilder.cs index a7daf71..b88705d 100644 --- a/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/VirtualLoggerMessageClassBuilder.cs +++ b/src/AutoLoggerMessageGenerator/VirtualLoggerMessage/VirtualLoggerMessageClassBuilder.cs @@ -67,22 +67,38 @@ private MethodDeclarationSyntax GenerateMethod(LogMessageCall logMessageCall) private AttributeListSyntax GenerateLoggerMessageAttribute(LogMessageCall logMessageCall) { + var attributeArguments = SeparatedList(new[] + { + AttributeArgument( + ParseExpression( + $"Level = {Constants.DefaultLoggingNamespace}.LogLevel.{logMessageCall.LogLevel}")), + AttributeArgument( + AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, + IdentifierName("Message"), + LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(logMessageCall.Message)))), + AttributeArgument( + ParseExpression( + $"SkipEnabledCheck = {configuration.GenerateSkipEnabledCheck.ToLowerBooleanString()}")) + }); + + if (configuration.DefaultEventId is not null) + { + attributeArguments = attributeArguments.Add( + AttributeArgument( + ParseExpression($"EventId = {configuration.DefaultEventId.Value.Id}") + ) + ); + attributeArguments = attributeArguments.Add( + AttributeArgument( + ParseExpression($"EventName = \"{configuration.DefaultEventId.Value.Name}\"") + ) + ); + } + var attribute = Attribute(ParseName(LoggerMessageAttributeName)) .WithArgumentList( AttributeArgumentList( - SeparatedList(new[] - { - AttributeArgument( - ParseExpression( - $"Level = {Constants.DefaultLoggingNamespace}.LogLevel.{logMessageCall.LogLevel}")), - AttributeArgument( - AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, - IdentifierName("Message"), - LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(logMessageCall.Message)))), - AttributeArgument( - ParseExpression( - $"SkipEnabledCheck = {configuration.GenerateSkipEnabledCheck.ToLowerBooleanString()}")) - }) + SeparatedList(attributeArguments) ) ); diff --git a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_with_empty_event_id.verified.txt b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_with_empty_event_id.verified.txt new file mode 100644 index 0000000..55a9186 --- /dev/null +++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.Build_WithDifferentConfiguration_ShouldReturnLegitLoggerMessageDeclaration_with_empty_event_id.verified.txt @@ -0,0 +1,12 @@ +namespace Microsoft.Extensions.Logging.AutoLoggerMessage +{ + static partial class AutoLoggerMessage + { + // : Guid_1 + [Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Critical, Message = "Hello, World!", SkipEnabledCheck = false, EventId = 0, EventName = "")] + internal static partial void Log_SomeNamespace_SomeClass_Method_2_22(Microsoft.Extensions.Logging.ILogger Logger, int @intParam, string @stringParam, bool @boolParam, SomeClass @classParam, SomeStruct @structParam); + // : Guid_2 + [Microsoft.Extensions.Logging.LoggerMessageAttribute(Level = Microsoft.Extensions.Logging.LogLevel.Trace, Message = "Goodbye, World!", SkipEnabledCheck = false, EventId = 0, EventName = "")] + internal static partial void Log_SomeNamespace_SomeClass_Method_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 20dd4df..2124ff7 100644 --- a/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.cs +++ b/tests/AutoLoggerMessageGenerator.UnitTests/VirtualLoggerMessage/VirtualLoggerMessageClassBuilderTests.cs @@ -119,5 +119,16 @@ _logMessageCall with GenerateTransitive: false, OverrideBeginScopeBehavior: false), false), + () => ( + "with_empty_event_id", + new SourceGeneratorConfiguration( + GenerateInterceptorAttribute: false, + GenerateSkipEnabledCheck: false, + GenerateOmitReferenceName: false, + GenerateSkipNullProperties: false, + GenerateTransitive: false, + OverrideBeginScopeBehavior: false, + DefaultEventId: new EventId(0, null)), + false), ]; }