Commit: 874cf38
Parent: 447dbae

Include properties

Mårten Åsberg committed on 2026-03-10 at 22:30
Core/CompilationExtensions.cs +1 -1
diff --git a/Core/CompilationExtensions.cs b/Core/CompilationExtensions.cs
index f2018af..7341af9 100644
@@ -5,7 +5,7 @@ namespace Reacher;
internal static class CompilationExtensions
{
public static IEnumerable<IMethodSymbol> GetPublicMembers(this Compilation compilation)
public static IEnumerable<ISymbol> GetPublicMembers(this Compilation compilation)
{
var collector = new PublicMembersCollector();
compilation.Assembly.Accept(collector);
Core/DocumentationCommentIdMemberCollector.cs +8 -7
diff --git a/Core/DocumentationCommentIdMemberCollector.cs b/Core/DocumentationCommentIdMemberCollector.cs
index 68b4ebf..abcbce9 100644
@@ -5,10 +5,7 @@ namespace Reacher;
internal class DocumentationCommentIdMemberCollector(HashSet<string> documentationIds) : SymbolVisitor
{
public static IEnumerable<IMethodSymbol> CollectMembers(
IEnumerable<string> documentationIds,
Compilation[] compilations
)
public static IEnumerable<ISymbol> CollectMembers(IEnumerable<string> documentationIds, Compilation[] compilations)
{
var collector = new DocumentationCommentIdMemberCollector([.. documentationIds]);
foreach (var compilation in compilations)
@@ -18,8 +15,8 @@ internal class DocumentationCommentIdMemberCollector(HashSet<string> documentati
return collector.Members;
}
public IEnumerable<IMethodSymbol> Members => members;
private readonly HashSet<IMethodSymbol> members = [];
public IEnumerable<ISymbol> Members => members;
private readonly HashSet<ISymbol> members = [];
public override void VisitAssembly(IAssemblySymbol symbol)
{
@@ -47,7 +44,11 @@ internal class DocumentationCommentIdMemberCollector(HashSet<string> documentati
}
}
public override void VisitMethod(IMethodSymbol member)
public override void VisitMethod(IMethodSymbol method) => VisitMember(method);
public override void VisitProperty(IPropertySymbol property) => VisitMember(property);
private void VisitMember(ISymbol member)
{
if (
member.GetDocumentationCommentId() is not string documentationId
Core/ExcludingMembersCollector.cs +8 -4
diff --git a/Core/ExcludingMembersCollector.cs b/Core/ExcludingMembersCollector.cs
index 33cd9fa..92961fc 100644
@@ -3,10 +3,10 @@ using Microsoft.CodeAnalysis;
namespace Reacher;
internal class ExcludingMembersCollector(IReadOnlySet<IMethodSymbol> excludedMembers) : SymbolVisitor
internal class ExcludingMembersCollector(IReadOnlySet<ISymbol> excludedMembers) : SymbolVisitor
{
public IReadOnlySet<IMethodSymbol> Members => members;
private readonly HashSet<IMethodSymbol> members = [];
public IReadOnlySet<ISymbol> Members => members;
private readonly HashSet<ISymbol> members = [];
public override void VisitAssembly(IAssemblySymbol symbol)
{
@@ -34,7 +34,11 @@ internal class ExcludingMembersCollector(IReadOnlySet<IMethodSymbol> excludedMem
}
}
public override void VisitMethod(IMethodSymbol member)
public override void VisitMethod(IMethodSymbol method) => VisitMember(method);
public override void VisitProperty(IPropertySymbol property) => VisitMember(property);
private void VisitMember(ISymbol member)
{
if (excludedMembers.Contains(member))
{
Core/PublicMembersCollector.cs +7 -3
diff --git a/Core/PublicMembersCollector.cs b/Core/PublicMembersCollector.cs
index 981033d..a39010c 100644
@@ -5,9 +5,9 @@ namespace Reacher;
internal class PublicMembersCollector : SymbolVisitor
{
private readonly HashSet<IMethodSymbol> publicMembers = [];
private readonly HashSet<ISymbol> publicMembers = [];
public IEnumerable<IMethodSymbol> PublicMembers => publicMembers;
public IEnumerable<ISymbol> PublicMembers => publicMembers;
public override void VisitAssembly(IAssemblySymbol symbol)
{
@@ -40,7 +40,11 @@ internal class PublicMembersCollector : SymbolVisitor
}
}
public override void VisitMethod(IMethodSymbol member)
public override void VisitMethod(IMethodSymbol method) => VisitMember(method);
public override void VisitProperty(IPropertySymbol property) => VisitMember(property);
private void VisitMember(ISymbol member)
{
if (member.DeclaredAccessibility is not Accessibility.Public)
{
Core/ReachabilityAnalysis.cs +2 -2
diff --git a/Core/ReachabilityAnalysis.cs b/Core/ReachabilityAnalysis.cs
index c32feaf..d6fb220 100644
@@ -11,6 +11,6 @@ namespace Reacher;
/// The members the analysis deemed unreachable from the original starting members.
/// </param>
public sealed record ReachabilityAnalysis(
IReadOnlySet<IMethodSymbol> ReachableMembers,
IReadOnlySet<IMethodSymbol> UnreachableMembers
IReadOnlySet<ISymbol> ReachableMembers,
IReadOnlySet<ISymbol> UnreachableMembers
);
Core/ReachabilityAnalyzer.cs +9 -6
diff --git a/Core/ReachabilityAnalyzer.cs b/Core/ReachabilityAnalyzer.cs
index 1af4ff6..be627a7 100644
@@ -11,9 +11,9 @@ namespace Reacher;
internal sealed class ReachabilityAnalyzer(IReadOnlyCollection<Compilation> compilations)
{
private readonly HashSet<IMethodSymbol> reachableMembers = [];
private readonly HashSet<ISymbol> reachableMembers = [];
public void Analyze(IMethodSymbol member, CancellationToken cancellationToken)
public void Analyze(ISymbol member, CancellationToken cancellationToken)
{
if (!TryGetAssociatedCompilation(member, out var compilation) || !reachableMembers.Add(member))
{
@@ -26,10 +26,10 @@ internal sealed class ReachabilityAnalyzer(IReadOnlyCollection<Compilation> comp
}
}
private bool TryGetAssociatedCompilation(IMethodSymbol member, [NotNullWhen(true)] out Compilation? compilation)
private bool TryGetAssociatedCompilation(ISymbol member, [NotNullWhen(true)] out Compilation? compilation)
{
compilation = compilations.FirstOrDefault(c =>
member.DeclaringSyntaxReferences.Any(d => c.ContainsSyntaxTree(d.SyntaxTree))
member.DeclaringSyntaxReferences.Any(d => !d.Span.IsEmpty && c.ContainsSyntaxTree(d.SyntaxTree))
);
return compilation is not null;
}
@@ -51,7 +51,10 @@ internal sealed class ReachabilityAnalyzer(IReadOnlyCollection<Compilation> comp
{
continue;
}
if (semanticModel.GetSymbolInfo(identifier, cancellationToken) is not { Symbol: IMethodSymbol member })
if (
semanticModel.GetSymbolInfo(identifier, cancellationToken) is not { Symbol: ISymbol member }
|| member is not (IMethodSymbol or IPropertySymbol)
)
{
continue;
}
@@ -70,7 +73,7 @@ internal sealed class ReachabilityAnalyzer(IReadOnlyCollection<Compilation> comp
public ReachabilityAnalysis GetAnalysis() => new(reachableMembers, GetUnreachableMembers());
private IReadOnlySet<IMethodSymbol> GetUnreachableMembers()
private IReadOnlySet<ISymbol> GetUnreachableMembers()
{
var collector = new ExcludingMembersCollector(reachableMembers);
Core/SolutionExtensions.cs +2 -2
diff --git a/Core/SolutionExtensions.cs b/Core/SolutionExtensions.cs
index 9ea9d23..acfd44a 100644
@@ -20,7 +20,7 @@ public static class SolutionExtensions
var compilations = await solution.GetCompilations(cancellationToken);
return AnalyzeReachability(
compilations,
[.. compilations.Select(c => c.GetEntryPoint(cancellationToken)).OfType<IMethodSymbol>()],
[.. compilations.Select(c => c.GetEntryPoint(cancellationToken)).OfType<ISymbol>()],
cancellationToken
);
}
@@ -67,7 +67,7 @@ public static class SolutionExtensions
private static ReachabilityAnalysis AnalyzeReachability(
IReadOnlyCollection<Compilation> compilations,
IEnumerable<IMethodSymbol> entryPoints,
IEnumerable<ISymbol> entryPoints,
CancellationToken cancellationToken
)
{