Skip to content

Commit 0b3f52c

Browse files
author
Sviatoslav Bychkov
committed
Filtered log calls with inaccessible parameters
1 parent c834422 commit 0b3f52c

File tree

2 files changed

+47
-13
lines changed

2 files changed

+47
-13
lines changed

src/AutoLoggerMessageGenerator.UnitTests/Filters/LogCallFilterTests.cs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ public class AnotherObject
1717
public void LogInformation(string message, DateTime arg1) {}
1818
public void LogInformation2(string message, DateTime arg1) {}
1919
}
20-
20+
2121
public void LogInformation(string message, DateTime arg1) {}
2222
public void LogSomething(string message, DateTime arg1) {}
2323
public void AnotherMethod(string message, DateTime arg1) {}
24-
24+
2525
""";
2626
var sourceCode = $$"""
2727
const string message = "Event received at: {EventTime}";
2828
var eventTime = DateTime.Now;
29-
29+
3030
{{LoggerName}}.LogInformation(message, eventTime);
3131
3232
AnotherMethod(message, eventTime);
@@ -48,8 +48,39 @@ public void AnotherMethod(string message, DateTime arg1) {}
4848
var methodSymbol = (IMethodSymbol) semanticModel.GetSymbolInfo(c).Symbol!;
4949
return LogCallFilter.IsLoggerMethod(methodSymbol);
5050
}).ToArray();
51-
51+
5252
invocationExpressions.Length.Should().Be(2);
5353
filteredInvocationExpressions.Length.Should().Be(1);
5454
}
55+
56+
57+
[Fact]
58+
public void Filter_WithInaccessibleClassAsParameter_ShouldExcludeLogCall()
59+
{
60+
const string additionalDeclarations = """
61+
public class A
62+
{
63+
private class B
64+
{
65+
public class C
66+
{
67+
public class D {}
68+
}
69+
}
70+
}
71+
""";
72+
73+
const string sourceCode = $$"""
74+
var parameter = new A.B.C.D();
75+
{{LoggerName}}.LogInformation("B class is private, so {this} argument is inaccessible as well", parameter);
76+
""";
77+
var (compilation, syntaxTree) = CompileSourceCode(sourceCode, additionalDeclarations);
78+
var (invocationExpressionSyntax, methodSymbol, _) = FindLoggerMethodInvocation(compilation, syntaxTree);
79+
80+
var isLogCallInvocation = LogCallFilter.IsLogCallInvocation(invocationExpressionSyntax, CancellationToken.None);
81+
var isLogCallMethod = LogCallFilter.IsLoggerMethod(methodSymbol);
82+
83+
isLogCallInvocation.Should().BeTrue();
84+
isLogCallMethod.Should().BeFalse();
85+
}
5586
}

src/AutoLoggerMessageGenerator/Filters/LogCallFilter.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,23 @@ internal static class LogCallFilter
2121
nameof(LoggerExtensions.LogCritical),
2222
];
2323

24-
public static bool IsLoggerMethod(IMethodSymbol methodSymbol)
25-
{
26-
var containingType = methodSymbol.ContainingType;
27-
return containingType != null &&
28-
methodSymbol.ReceiverType?.Name is "ILogger" &&
29-
methodSymbol.ReturnsVoid &&
30-
methodSymbol.ContainingType.ToDisplayString() is $"{Constants.DefaultLoggingNamespace}.{ClassName}" &&
31-
methodSymbol.IsExtensionMethod;
32-
}
24+
public static bool IsLoggerMethod(IMethodSymbol methodSymbol) =>
25+
methodSymbol is { ContainingType: not null, ReceiverType.Name: "ILogger", ReturnsVoid: true } &&
26+
methodSymbol.ContainingType.ToDisplayString() is $"{Constants.DefaultLoggingNamespace}.{ClassName}" &&
27+
methodSymbol.IsExtensionMethod &&
28+
methodSymbol.Parameters.All(c =>
29+
c.Type.IsAnonymousType is not true && c.Type.TypeKind is not TypeKind.TypeParameter &&
30+
RecursivelyCheckTypeAccessibility(c.Type)
31+
);
3332

3433
public static bool IsLogCallInvocation(SyntaxNode node, CancellationToken cts) =>
3534
!node.SyntaxTree.FilePath.EndsWith(".g.cs") &&
3635
node is InvocationExpressionSyntax { ArgumentList.Arguments.Count: > 0 } invocationExpression &&
3736
!cts.IsCancellationRequested &&
3837
invocationExpression.Expression.DescendantNodes()
3938
.Any(c => c is IdentifierNameSyntax identifierNameSyntax && LogMethodNames.Contains(identifierNameSyntax.Identifier.Text));
39+
40+
private static bool RecursivelyCheckTypeAccessibility(ITypeSymbol typeSymbol) =>
41+
typeSymbol.DeclaredAccessibility is Accessibility.Friend or Accessibility.Public or Accessibility.Internal &&
42+
(typeSymbol.ContainingType is null || RecursivelyCheckTypeAccessibility(typeSymbol.ContainingType));
4043
}

0 commit comments

Comments
 (0)