Skip to content

Commit 721fdf6

Browse files
authored
Fix handling of culture in logging generator for > 6 parameters (#117009)
* Fix handling of culture in logging generator for > 6 parameters * Address PR feedback
1 parent 384be54 commit 721fdf6

File tree

6 files changed

+47
-6
lines changed

6 files changed

+47
-6
lines changed

src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Emitter.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Linq;
67
using System.Text;
78
using System.Threading;
9+
using Microsoft.CodeAnalysis;
810

911
namespace Microsoft.Extensions.Logging.Generators
1012
{
1113
public partial class LoggerMessageGenerator
1214
{
13-
internal sealed class Emitter
15+
internal sealed class Emitter(Compilation compilation)
1416
{
1517
// The maximum arity of LoggerMessage.Define.
1618
private const int MaxLoggerMessageDefineArguments = 6;
@@ -28,6 +30,14 @@ internal sealed class Emitter
2830
private const string EditorBrowsableAttribute =
2931
"global::System.ComponentModel.EditorBrowsableAttribute(" +
3032
"global::System.ComponentModel.EditorBrowsableState.Never)";
33+
34+
private readonly bool _hasStringCreate =
35+
compilation.GetSpecialType(SpecialType.System_String).GetMembers("Create").OfType<IMethodSymbol>()
36+
.Any(m => m.IsStatic &&
37+
m.Parameters.Length == 2 &&
38+
m.Parameters[0].Type.Name == "IFormatProvider" &&
39+
m.Parameters[1].RefKind == RefKind.Ref);
40+
3141
private readonly StringBuilder _builder = new StringBuilder(DefaultStringBuilderCapacity);
3242
private bool _needEnumerationHelper;
3343

@@ -163,8 +173,15 @@ private void GenStruct(LoggerMethod lm, string nestedIndentation)
163173
{nestedIndentation}{{
164174
");
165175
GenVariableAssignments(lm, nestedIndentation);
176+
177+
string formatMethodBegin =
178+
!lm.Message.Contains('{') ? "" :
179+
_hasStringCreate ? "string.Create(global::System.Globalization.CultureInfo.InvariantCulture, " :
180+
"global::System.Diagnostics.CodeAnalysis.FormattableString.Invariant(";
181+
string formatMethodEnd = formatMethodBegin.Length > 0 ? ")" : "";
182+
166183
_builder.Append($@"
167-
{nestedIndentation}return $""{ConvertEndOfLineAndQuotationCharactersToEscapeForm(lm.Message)}"";
184+
{nestedIndentation}return {formatMethodBegin}$""{ConvertEndOfLineAndQuotationCharactersToEscapeForm(lm.Message)}""{formatMethodEnd};
168185
{nestedIndentation}}}
169186
");
170187
_builder.Append($@"

src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Roslyn3.11.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public void Execute(GeneratorExecutionContext context)
3333
IReadOnlyList<LoggerClass> logClasses = p.GetLogClasses(receiver.ClassDeclarations);
3434
if (logClasses.Count > 0)
3535
{
36-
var e = new Emitter();
36+
var e = new Emitter(context.Compilation);
3737
string result = e.Emit(logClasses, context.CancellationToken);
3838

3939
context.AddSource("LoggerMessage.g.cs", SourceText.From(result, Encoding.UTF8));

src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Roslyn4.0.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private static void Execute(Compilation compilation, ImmutableArray<ClassDeclara
5151
IReadOnlyList<LoggerClass> logClasses = p.GetLogClasses(distinctClasses);
5252
if (logClasses.Count > 0)
5353
{
54-
var e = new Emitter();
54+
var e = new Emitter(compilation);
5555
string result = e.Emit(logClasses, context.CancellationToken);
5656

5757
context.AddSource("LoggerMessage.g.cs", SourceText.From(result, Encoding.UTF8));

src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/Baselines/TestWithMoreThan6Params.generated.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
4040
var p6 = this._p6;
4141
var p7 = global::__LoggerMessageGenerator.Enumerate((global::System.Collections.IEnumerable ?)this._p7);
4242

43-
return $"M9 {p1} {p2} {p3} {p4} {p5} {p6} {p7}";
43+
return string.Create(global::System.Globalization.CultureInfo.InvariantCulture, $"M9 {p1} {p2} {p3} {p4} {p5} {p6} {p7}");
4444
}
4545

4646
public static readonly global::System.Func<__Method9Struct, global::System.Exception?, string> Format = (state, ex) => state.ToString();

src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratedCodeTests.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33

44
using System;
55
using System.Collections.Generic;
6-
using Microsoft.Extensions.Logging.Abstractions;
6+
using System.Globalization;
77
using Microsoft.Extensions.Logging.Generators.Tests.TestClasses;
88
using Microsoft.Extensions.Logging.Generators.Tests.TestClasses.UsesConstraintInAnotherNamespace;
99
using Xunit;
1010
using NamespaceForABC;
1111
using ConstraintInAnotherNamespace;
12+
using System.Tests;
1213

1314
namespace Microsoft.Extensions.Logging.Generators.Tests
1415
{
@@ -713,7 +714,24 @@ public void TemplateTests()
713714
new KeyValuePair<string, object?>("A1", 42),
714715
new KeyValuePair<string, object?>("a2", 43),
715716
new KeyValuePair<string, object?>("{OriginalFormat}", "M3 {a2} {A1}"));
717+
}
718+
719+
[Fact]
720+
public void TemplateTests_UsesInvariantCulture()
721+
{
722+
using ThreadCultureChange _ = new("fr-FR");
723+
724+
var logger = new MockLogger();
716725

726+
logger.Reset();
727+
TemplateTestExtensions.M4(logger, 1.23);
728+
Assert.Null(logger.LastException);
729+
Assert.Equal("M4 1.23", logger.LastFormattedString);
730+
731+
logger.Reset();
732+
TemplateTestExtensions.M5(logger, 1.23, 4.56, 7.89, 10.11, 12.13, 14.15, 16.17);
733+
Assert.Null(logger.LastException);
734+
Assert.Equal("M5 1.23 4.56 7.89 10.11 12.13 14.15 16.17", logger.LastFormattedString);
717735
}
718736

719737
[Fact]

src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/TestClasses/TemplateTestExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,11 @@ internal static partial class TemplateTestExtensions
1616

1717
[LoggerMessage(EventId = 3, Level = LogLevel.Error, Message = "M3 {a2} {A1}")]
1818
public static partial void M3(ILogger logger, int a1, int a2);
19+
20+
[LoggerMessage(EventId = 4, Level = LogLevel.Error, Message = "M4 {A1}")]
21+
public static partial void M4(ILogger logger, double a1);
22+
23+
[LoggerMessage(EventId = 5, Level = LogLevel.Error, Message = "M5 {A1} {a2} {A3} {a4} {A5} {a6} {A7}")]
24+
public static partial void M5(ILogger logger, double a1, double a2, double a3, double a4, double a5, double a6, double a7);
1925
}
2026
}

0 commit comments

Comments
 (0)