diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs index 69f87fdcd48f6c..eebab2be296144 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs @@ -138,14 +138,14 @@ private void GenStruct(LoggerMethod lm, string nestedIndentation) {nestedIndentation}/// {s_generatedTypeSummary} {nestedIndentation}[{s_generatedCodeAttribute}] {nestedIndentation}[{s_editorBrowsableAttribute}] - {nestedIndentation}private readonly struct __{lm.Name}Struct : global::System.Collections.Generic.IReadOnlyList> + {nestedIndentation}private readonly struct __{lm.UniqueName}Struct : global::System.Collections.Generic.IReadOnlyList> {nestedIndentation}{{"); GenFields(lm, nestedIndentation); if (lm.TemplateParameters.Count > 0) { _builder.Append($@" - {nestedIndentation}public __{lm.Name}Struct("); + {nestedIndentation}public __{lm.UniqueName}Struct("); GenArguments(lm); _builder.Append($@") {nestedIndentation}{{"); @@ -166,7 +166,7 @@ private void GenStruct(LoggerMethod lm, string nestedIndentation) {nestedIndentation}}} "); _builder.Append($@" - {nestedIndentation}public static readonly global::System.Func<__{lm.Name}Struct, global::System.Exception?, string> Format = (state, ex) => state.ToString(); + {nestedIndentation}public static readonly global::System.Func<__{lm.UniqueName}Struct, global::System.Exception?, string> Format = (state, ex) => state.ToString(); {nestedIndentation}public int Count => {lm.TemplateParameters.Count + 1}; @@ -343,7 +343,7 @@ private void GenArguments(LoggerMethod lm) private void GenHolder(LoggerMethod lm) { - string typeName = $"__{lm.Name}Struct"; + string typeName = $"__{lm.UniqueName}Struct"; _builder.Append($"new {typeName}("); foreach (LoggerParameter p in lm.TemplateParameters) @@ -375,7 +375,7 @@ private void GenLogMethod(LoggerMethod lm, string nestedIndentation) GenDefineTypes(lm, brackets: false); - _builder.Append($@"global::System.Exception?> __{lm.Name}Callback = + _builder.Append($@"global::System.Exception?> __{lm.UniqueName}Callback = {nestedIndentation}global::Microsoft.Extensions.Logging.LoggerMessage.Define"); GenDefineTypes(lm, brackets: true); @@ -404,7 +404,7 @@ private void GenLogMethod(LoggerMethod lm, string nestedIndentation) if (UseLoggerMessageDefine(lm)) { _builder.Append($@" - {nestedIndentation}{enabledCheckIndentation}__{lm.Name}Callback({logger}, "); + {nestedIndentation}{enabledCheckIndentation}__{lm.UniqueName}Callback({logger}, "); GenCallbackArguments(lm); @@ -420,7 +420,7 @@ private void GenLogMethod(LoggerMethod lm, string nestedIndentation) GenHolder(lm); _builder.Append($@", {nestedIndentation}{enabledCheckIndentation}{exceptionArg}, - {nestedIndentation}{enabledCheckIndentation}__{lm.Name}Struct.Format);"); + {nestedIndentation}{enabledCheckIndentation}__{lm.UniqueName}Struct.Format);"); } if (!lm.SkipEnabledCheck) diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs index ad8a524b0fc8cc..0f7aa5539a7d61 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs @@ -510,6 +510,23 @@ bool IsAllowedKind(SyntaxKind kind) => if (lc != null) { + //once we've collected all methods for the given class, check for overloads + //and provide unique names for logger methods + var methods = new Dictionary(lc.Methods.Count); + foreach (LoggerMethod lm in lc.Methods) + { + if (methods.ContainsKey(lm.Name)) + { + int currentCount = methods[lm.Name]; + lm.UniqueName = $"{lm.Name}{currentCount}"; + methods[lm.Name] = currentCount + 1; + } + else + { + lm.UniqueName = lm.Name; + methods[lm.Name] = 1; //start from 1 + } + } results.Add(lc); } } @@ -693,6 +710,7 @@ internal class LoggerMethod public readonly Dictionary TemplateMap = new(StringComparer.OrdinalIgnoreCase); public readonly List TemplateList = new(); public string Name = string.Empty; + public string UniqueName = string.Empty; public string Message = string.Empty; public int? Level; public int EventId; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs index d55bf4a8028d52..677dc148f60d25 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs @@ -498,6 +498,26 @@ public void TemplateTests() } + [Fact] + public void OverloadTests() + { + var logger = new MockLogger(); + + logger.Reset(); + OverloadTestExtensions.M0(logger, 1); + Assert.Null(logger.LastException); + Assert.Equal($"{nameof(OverloadTestExtensions.M0)}1", logger.LastFormattedString); + Assert.Equal(LogLevel.Trace, logger.LastLogLevel); + Assert.Equal("M0", logger.LastEventId.Name); + + logger.Reset(); + OverloadTestExtensions.M0(logger, "string"); + Assert.Null(logger.LastException); + Assert.Equal($"{nameof(OverloadTestExtensions.M0)}string", logger.LastFormattedString); + Assert.Equal(LogLevel.Trace, logger.LastLogLevel); + Assert.Equal("M0", logger.LastEventId.Name); + } + private static void AssertLastState(MockLogger logger, params KeyValuePair[] expected) { var rol = (IReadOnlyList>)logger.LastState!; diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/OverloadTestExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/OverloadTestExtensions.cs new file mode 100644 index 00000000000000..e0c84fcebedd02 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/OverloadTestExtensions.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses +{ + internal static partial class OverloadTestExtensions + { + [LoggerMessage(EventId = 0, Level = LogLevel.Trace, Message = "M0{p0}")] + public static partial void M0(ILogger logger, int p0); + + [LoggerMessage(EventId = 1, Level = LogLevel.Trace, Message = "M0{p0}")] + public static partial void M0(ILogger logger, string p0); + } +}