Skip to content

Commit 22b6f28

Browse files
authored
Skipped log calls with generic arguments due to LoggerMessage constraint (#18)
1 parent 9ac2582 commit 22b6f28

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ Take a look at [benchmark](https://github.com/stbychkov/AutoLoggerMessage/wiki/B
4848
so if you pass more than that, the default `Logger.Log(*, params object[] args)` will be executed.
4949
* As this solution is based on interceptors, only .NET 8+ is supported
5050
* Hash-based interceptors are incompatible with .NET SDK versions earlier than 8.0.8, most likely due to differences in the compiler version. To resolve this issue, please update your SDK to version [8.0.8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) or later.
51+
* Generic arguments are https://github.com/dotnet/extensions/blob/ca2fe808b3d6c55817467f46ca58657456b4a928/docs/list-of-diagnostics.md?plain=1#L66C4-L66C13. If you pass a generic argument to the log function, the default `Logger.Log(*, params object[] args)` will be executed.
5152

5253
## Is something wrong?
5354

src/AutoLoggerMessageGenerator.UnitTests/Extractors/LogCallParametersExtractorTests.cs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,11 @@ private static void Log<T1, T2>(
2424
""";
2525

2626
var (compilation, syntaxTree) = await CompileSourceCode($"Log({parameters});", extensionDeclaration);
27-
var invocationExpression = syntaxTree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().First();
28-
29-
var semanticModel = compilation.GetSemanticModel(syntaxTree);
30-
var methodSymbol = (IMethodSymbol)semanticModel.GetSymbolInfo(invocationExpression).Symbol!;
27+
var (_, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
3128

3229
var sut = new LogCallParametersExtractor();
3330

34-
var result = sut.Extract(message, methodSymbol);
31+
var result = sut.Extract(message, methodSymbol!);
3532

3633
await Assert.That(result).IsEquivalentTo(new LogCallParameter[]
3734
{
@@ -144,4 +141,29 @@ await Assert.That(result).IsEquivalentTo(new LogCallParameter[]
144141
new("global::System.Int32", "@time", LogCallParameterType.Others),
145142
});
146143
}
144+
145+
[Test]
146+
[Arguments("T")]
147+
[Arguments("List<T>")]
148+
public async Task Extract_WithGenericParameters_ShouldSkipExtractingParameters(string genericType)
149+
{
150+
var message = "{GenericParameter}";
151+
var (compilation, syntaxTree) = await CompileSourceCode(string.Empty,
152+
$$"""
153+
private static void Log<T>(string {{MessageParameterName}}, T {{ParameterName}}) {}
154+
155+
public void Foo<T>({{genericType}} arg)
156+
{
157+
Log<{{genericType}}>("{{message}}", arg);
158+
}
159+
""");
160+
var (_, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
161+
162+
var sut = new LogCallParametersExtractor();
163+
164+
var result = sut.Extract(message, methodSymbol!);
165+
166+
await Assert.That(result).IsNull();
167+
}
147168
}
169+

src/AutoLoggerMessageGenerator/Extractors/LogCallParametersExtractor.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ internal class LogCallParametersExtractor(LogPropertiesCheck? logPropertiesCheck
2727
if (templateParametersNames.Length < methodParameters.Length)
2828
return null;
2929

30+
// https://github.com/dotnet/extensions/blob/ca2fe808b3d6c55817467f46ca58657456b4a928/docs/list-of-diagnostics.md?plain=1#L66C4-L66C13
31+
if (methodParameters.Any(IsGenericParameter))
32+
return null;
33+
3034
var uniqueNameSuffix = ReservedParameterNameResolver.GenerateUniqueIdentifierSuffix(templateParametersNames);
3135

3236
var utilityParameters = methodSymbol.Parameters
@@ -70,4 +74,7 @@ private static LogCallParameter CreateLogCallParameter(ITypeSymbol @nativeType,
7074

7175
private static string TransformParameterName(string parameterName) =>
7276
parameterName.StartsWith("@") ? parameterName : '@' + parameterName;
77+
78+
private static bool IsGenericParameter(IParameterSymbol parameterSymbol) =>
79+
parameterSymbol.Type is INamedTypeSymbol { IsGenericType: true } or ITypeParameterSymbol;
7380
}

0 commit comments

Comments
 (0)