Skip to content

Commit 4a05df4

Browse files
committed
opt: 优化占位符名称生成逻辑
1 parent 02eb8ca commit 4a05df4

File tree

4 files changed

+82
-70
lines changed

4 files changed

+82
-70
lines changed

src/Cuture.CodeAnalysis.LoggingCodeFixes/PlaceHolderNormalizer.cs

Lines changed: 51 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ public class PlaceHolderNormalizer
1010
{
1111
#region Private 字段
1212

13-
private static readonly Regex s_normalizeRegex = new("\\?|\\.|\\(.*?\\)|\\[.*?\\]|this\\.|This\\.|@", RegexOptions.Compiled);
14-
15-
private static readonly char[] s_shouldUpperFollowChars = ['.', '@'];
16-
17-
private static ReadOnlySpan<char> ShouldUpperFollowChars => s_shouldUpperFollowChars;
13+
private static readonly Regex s_normalizeRegex = new(@"\?|\.|\(.*?\)|\[.*?\]", RegexOptions.Compiled);
1814

1915
#endregion Private 字段
2016

@@ -25,14 +21,7 @@ public class PlaceHolderNormalizer
2521
/// </summary>
2622
/// <param name="input"></param>
2723
/// <returns></returns>
28-
public static string Normalize(string input) => Normalize(input.AsSpan());
29-
30-
/// <summary>
31-
/// 创建规范化的占位符
32-
/// </summary>
33-
/// <param name="input"></param>
34-
/// <returns></returns>
35-
public static string Normalize(ReadOnlySpan<char> input)
24+
public static string Normalize(string input)
3625
{
3726
input = input.Trim()
3827
.TrimStart('{')
@@ -41,37 +30,60 @@ public static string Normalize(ReadOnlySpan<char> input)
4130
.TrimEnd('}')
4231
.Trim();
4332

44-
var bufferLength = 0;
45-
var buffer = ArrayPool<char>.Shared.Rent(input.Length + 4);
46-
try
47-
{
48-
Span<char> newSpan = buffer;
49-
var firstChar = input[0];
50-
newSpan[bufferLength++] = char.ToUpper(firstChar);
51-
input.Slice(1).CopyTo(newSpan.Slice(bufferLength));
52-
bufferLength += input.Length - 1;
53-
54-
var index = 0;
55-
while (newSpan.Slice(index).IndexOfAny(ShouldUpperFollowChars) is { } nextIndex
56-
&& nextIndex >= 0)
57-
{
58-
nextIndex = nextIndex + index + 1;
59-
if (nextIndex >= newSpan.Length)
60-
{
61-
break;
62-
}
63-
64-
newSpan[nextIndex] = char.ToUpper(newSpan[nextIndex]);
65-
index = nextIndex;
66-
}
33+
var segments = s_normalizeRegex.Split(input)
34+
.Where(static m => !string.IsNullOrWhiteSpace(m) && !string.Equals("ToString", m, StringComparison.Ordinal))
35+
.ToList();
6736

68-
return s_normalizeRegex.Replace(newSpan.Slice(0, bufferLength).ToString(), "");
37+
if (segments.Count < 3) //两个或一个分段,只取最后的分段
38+
{
39+
return NormalizeSegment(segments[segments.Count - 1]);
6940
}
70-
finally
41+
42+
//超过三个分段只取最后两个
43+
segments.RemoveAll(static m => string.Equals("this", m, StringComparison.Ordinal) || string.Equals("This", m, StringComparison.Ordinal));
44+
45+
if (segments.Count > 1)
7146
{
72-
ArrayPool<char>.Shared.Return(buffer);
47+
return $"{NormalizeSegment(segments[segments.Count - 2])}{NormalizeSegment(segments[segments.Count - 1])}";
7348
}
49+
return NormalizeSegment(segments[segments.Count - 1]);
7450
}
7551

7652
#endregion Public 方法
53+
54+
#region Private 方法
55+
56+
private static string NormalizeSegment(string value)
57+
{
58+
var span = value.AsSpan().Trim('@');
59+
//以get开始,则去掉get
60+
if (span.StartsWith("Get", StringComparison.OrdinalIgnoreCase)
61+
&& span.Length > 3)
62+
{
63+
span = span.Slice(3);
64+
}
65+
return FirstCharToUpper(span);
66+
67+
static string FirstCharToUpper(ReadOnlySpan<char> input)
68+
{
69+
var bufferLength = 0;
70+
var buffer = ArrayPool<char>.Shared.Rent(input.Length + 4);
71+
try
72+
{
73+
Span<char> newSpan = buffer;
74+
var firstChar = input[0];
75+
newSpan[bufferLength++] = char.ToUpper(firstChar);
76+
input.Slice(1).CopyTo(newSpan.Slice(bufferLength));
77+
bufferLength += input.Length - 1;
78+
79+
return newSpan.Slice(0, bufferLength).ToString();
80+
}
81+
finally
82+
{
83+
ArrayPool<char>.Shared.Return(buffer);
84+
}
85+
}
86+
}
87+
88+
#endregion Private 方法
7789
}

test/Cuture.CodeAnalysis.LoggingCodeFixes.Test/NumericPlaceHolderFixTest.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public async Task Should_BeginLine_NewLine_Retain()
2222
LoggingCodeTemplate fixtest =
2323
@"
2424
var type = _logger.GetType();
25-
_logger.LogInformation(""\r\nValue: {TypeName}"", type?.Name);
25+
_logger.LogInformation(""\r\nValue: {Name}"", type?.Name);
2626
";
2727

2828
var expected = GetExpected();
@@ -41,7 +41,7 @@ public async Task Should_ConditionalAccess_Replace_With_Memeber_Name()
4141
LoggingCodeTemplate fixtest =
4242
"""
4343
var type = _logger.GetType();
44-
_logger.LogInformation("Value: {TypeName}", type?.Name);
44+
_logger.LogInformation("Value: {Name}", type?.Name);
4545
""";
4646

4747
var expected = GetExpected();
@@ -60,7 +60,7 @@ public async Task Should_ConditionalAccess_Replace_With_Memeber_Name_ML()
6060
LoggingCodeTemplate fixtest =
6161
"""
6262
var type = _logger.GetType();
63-
_logger.LogInformation("Value: {TypeAssemblyEntryPointName}", type?.Assembly?.EntryPoint?.Name);
63+
_logger.LogInformation("Value: {EntryPointName}", type?.Assembly?.EntryPoint?.Name);
6464
""";
6565

6666
var expected = GetExpected();
@@ -79,7 +79,7 @@ public async Task Should_ConditionalAccess_Replace_With_Method_Name()
7979
LoggingCodeTemplate fixtest =
8080
"""
8181
var ex = new Exception();
82-
_logger.LogInformation("Value: {ExGetType}", ex?.GetType());
82+
_logger.LogInformation("Value: {Type}", ex?.GetType());
8383
""";
8484

8585
var expected = GetExpected();
@@ -98,7 +98,7 @@ public async Task Should_ConditionalAccess_Replace_With_Method_Name_ML()
9898
LoggingCodeTemplate fixtest =
9999
"""
100100
var ex = new Exception();
101-
_logger.LogInformation("Value: {ExGetTypeGetPropertiesGetHashCode}", ex?.GetType()?.GetProperties()?.GetHashCode());
101+
_logger.LogInformation("Value: {PropertiesHashCode}", ex?.GetType()?.GetProperties()?.GetHashCode());
102102
""";
103103

104104
var expected = GetExpected();
@@ -117,7 +117,7 @@ public async Task Should_EndLine_NewLine_Retain()
117117
LoggingCodeTemplate fixtest =
118118
@"
119119
var type = _logger.GetType();
120-
_logger.LogInformation(""Value: {TypeName}\r\n"", type?.Name);
120+
_logger.LogInformation(""Value: {Name}\r\n"", type?.Name);
121121
";
122122

123123
var expected = GetExpected();
@@ -136,7 +136,7 @@ public async Task Should_MidLine_NewLine_Retain()
136136
LoggingCodeTemplate fixtest =
137137
@"
138138
var type = _logger.GetType();
139-
_logger.LogInformation(""Value: {TypeName}\r\n{Type}"", type?.Name, type);
139+
_logger.LogInformation(""Value: {Name}\r\n{Type}"", type?.Name, type);
140140
";
141141

142142
var expected = GetExpected();
@@ -155,7 +155,7 @@ public async Task Should_Multi_NewLine_Retain()
155155
LoggingCodeTemplate fixtest =
156156
@"
157157
var type = _logger.GetType();
158-
_logger.LogInformation(""Value\r\n: {TypeName}\r\n{Type}\r\n"", type?.Name, type);
158+
_logger.LogInformation(""Value\r\n: {Name}\r\n{Type}\r\n"", type?.Name, type);
159159
";
160160

161161
var expected = GetExpected();
@@ -174,7 +174,7 @@ public async Task Should_Replace_With_Memeber_Name()
174174
LoggingCodeTemplate fixtest =
175175
"""
176176
var type = _logger.GetType();
177-
_logger.LogInformation("Value: {TypeName}", type.Name);
177+
_logger.LogInformation("Value: {Name}", type.Name);
178178
""";
179179

180180
var expected = GetExpected();
@@ -193,7 +193,7 @@ public async Task Should_Replace_With_Memeber_Name_ML()
193193
LoggingCodeTemplate fixtest =
194194
"""
195195
var type = _logger.GetType();
196-
_logger.LogInformation("Value: {TypeAssemblyEntryPointName}", type.Assembly.EntryPoint.Name);
196+
_logger.LogInformation("Value: {EntryPointName}", type.Assembly.EntryPoint.Name);
197197
""";
198198

199199
var expected = GetExpected();
@@ -212,7 +212,7 @@ public async Task Should_Replace_With_Method_Name()
212212
LoggingCodeTemplate fixtest =
213213
"""
214214
var ex = new Exception();
215-
_logger.LogInformation("Value: {ExGetType}", ex.GetType());
215+
_logger.LogInformation("Value: {Type}", ex.GetType());
216216
""";
217217

218218
var expected = GetExpected();
@@ -231,7 +231,7 @@ public async Task Should_Replace_With_Method_Name_ML()
231231
LoggingCodeTemplate fixtest =
232232
"""
233233
var ex = new Exception();
234-
_logger.LogInformation("Value: {ExGetTypeGetPropertiesGetHashCode}", ex.GetType().GetProperties().GetHashCode());
234+
_logger.LogInformation("Value: {PropertiesHashCode}", ex.GetType().GetProperties().GetHashCode());
235235
""";
236236

237237
var expected = GetExpected();
@@ -290,7 +290,7 @@ public async Task Should_Success()
290290
"""
291291
var type = _logger.GetType();
292292
var ex = new Exception();
293-
_logger.LogInformation("Value: {Ex} {TypeAssemblyEntryPointName} {ExGetTypeGetPropertiesGetHashCode} {Type}", nameof(ex), type.Assembly?.EntryPoint.Name, ex.GetType().GetProperties()?.GetHashCode(), type);
293+
_logger.LogInformation("Value: {Ex} {EntryPointName} {PropertiesHashCode} {Type}", nameof(ex), type.Assembly?.EntryPoint.Name, ex.GetType().GetProperties()?.GetHashCode(), type);
294294
""";
295295

296296
var expected = GetExpected();

test/Cuture.CodeAnalysis.LoggingCodeFixes.Test/PlaceHolderNormalizerTest.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ public class PlaceHolderNormalizerTest
1010
[DataRow("Hello", "Hello")]
1111
[DataRow("hello", "Hello")]
1212
[DataRow("ex", "Ex")]
13-
[DataRow("ex.Message", "ExMessage")]
14-
[DataRow("ex.message.length.value", "ExMessageLengthValue")]
15-
[DataRow("ex.@Message", "ExMessage")]
16-
[DataRow("ex.@default", "ExDefault")]
17-
[DataRow("ex.@default.@int", "ExDefaultInt")]
18-
[DataRow("ex?.Message", "ExMessage")]
19-
[DataRow("ex?.Message?.Length", "ExMessageLength")]
20-
[DataRow("ex.GetType()", "ExGetType")]
21-
[DataRow("ex?.GetType()", "ExGetType")]
22-
[DataRow("ex.GetType().GetProperties()", "ExGetTypeGetProperties")]
23-
[DataRow("ex.GetType()?.GetProperties()", "ExGetTypeGetProperties")]
24-
[DataRow("ex.GetType().@default.Method()", "ExGetTypeDefaultMethod")]
25-
[DataRow("ex.GetType().@default.Property", "ExGetTypeDefaultProperty")]
13+
[DataRow("ex.Message", "Message")]
14+
[DataRow("ex.message.length.value", "LengthValue")]
15+
[DataRow("ex.@Message", "Message")]
16+
[DataRow("ex.@default", "Default")]
17+
[DataRow("ex.@default.@int", "DefaultInt")]
18+
[DataRow("ex?.Message", "Message")]
19+
[DataRow("ex?.Message?.Length", "MessageLength")]
20+
[DataRow("ex.GetType()", "Type")]
21+
[DataRow("ex?.GetType()", "Type")]
22+
[DataRow("ex.GetType().GetProperties()", "TypeProperties")]
23+
[DataRow("ex.GetType()?.GetProperties()", "TypeProperties")]
24+
[DataRow("ex.GetType().@default.Method()", "DefaultMethod")]
25+
[DataRow("ex.GetType().@default.Property", "DefaultProperty")]
2626
public void Should_Success(string source, string target)
2727
{
2828
var normalizeResult = PlaceHolderNormalizer.Normalize(source);

test/Cuture.CodeAnalysis.LoggingCodeFixes.Test/StructuredLoggingFixTest.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public async Task Should_Generate_Name_Success_For_MemberAccess()
2222
LoggingCodeTemplate fixtest =
2323
"""
2424
var type = _logger.GetType();
25-
_logger.LogInformation("Value: {TypeName}", type.Name);
25+
_logger.LogInformation("Value: {Name}", type.Name);
2626
""";
2727

2828
var expected = GetExpected();
@@ -41,7 +41,7 @@ public async Task Should_Generate_Name_Success_For_MemberAccess_ML()
4141
LoggingCodeTemplate fixtest =
4242
"""
4343
var type = _logger.GetType();
44-
_logger.LogInformation("Value: {TypeAssemblyEntryPointName}", type.Assembly.EntryPoint.Name);
44+
_logger.LogInformation("Value: {EntryPointName}", type.Assembly.EntryPoint.Name);
4545
""";
4646

4747
var expected = GetExpected();
@@ -58,7 +58,7 @@ public async Task Should_Generate_Name_Success_For_MethodAccess()
5858

5959
LoggingCodeTemplate fixtest =
6060
"""
61-
_logger.LogInformation("Value: {LoggerGetType}", _logger.GetType());
61+
_logger.LogInformation("Value: {Type}", _logger.GetType());
6262
""";
6363

6464
var expected = GetExpected();
@@ -75,7 +75,7 @@ public async Task Should_Generate_Name_Success_For_MethodAccess_ML()
7575

7676
LoggingCodeTemplate fixtest =
7777
"""
78-
_logger.LogInformation("Value: {LoggerGetTypeGetPropertiesGetHashCode}", _logger.GetType().GetProperties().GetHashCode());
78+
_logger.LogInformation("Value: {PropertiesHashCode}", _logger.GetType().GetProperties().GetHashCode());
7979
""";
8080

8181
var expected = GetExpected();
@@ -128,7 +128,7 @@ public async Task Should_Success()
128128
LoggingCodeTemplate fixtest =
129129
"""
130130
Exception ex = null;
131-
_logger.LogInformation(ex, $"Value: 1 - {nameof(TestClass)} - {{Logger}} - {{Ex}} - {{ExMessage}} - {{1f}} - {{GetTypeFullName}}", _logger, ex, ex.Message, 1f.ToString("D2"), this.GetType().FullName);
131+
_logger.LogInformation(ex, $"Value: 1 - {nameof(TestClass)} - {{Logger}} - {{Ex}} - {{Message}} - {{1f}} - {{TypeFullName}}", _logger, ex, ex.Message, 1f.ToString("D2"), this.GetType().FullName);
132132
""";
133133

134134
var expected = VerifyCS.Diagnostic("CA2254").WithLocation(0).WithArguments("LoggerExtensions.LogInformation(ILogger, string?, params object?[])");

0 commit comments

Comments
 (0)