cli/src/ScanCommand.cs
+51
-2
diff --git a/cli/src/ScanCommand.cs b/cli/src/ScanCommand.cs
index 1723a14..a1c8312 100644
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.CommandLine;
using System.CommandLine.Invocation;
@@ -9,6 +10,7 @@ using System.Threading;
using System.Threading.Tasks;
using GlobExpressions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Spectre.Console;
namespace Cfa.Cli;
@@ -181,16 +183,63 @@ internal sealed class ScanCommand : Command
PrintCallGraph(
callGraphAnalysis.Origin,
callGraphAnalysis.CalledFrom,
TrimToEvents(callGraphAnalysis.Origin, callGraphAnalysis.CalledFrom),
callGraphAnalysis.Appearances,
reverse: true
);
PrintMember(callGraphAnalysis.Origin, callGraphAnalysis.Appearances[callGraphAnalysis.Origin]);
PrintCallGraph(callGraphAnalysis.Origin, callGraphAnalysis.CallsTo, callGraphAnalysis.Appearances);
PrintCallGraph(
callGraphAnalysis.Origin,
TrimToEvents(callGraphAnalysis.Origin, callGraphAnalysis.CallsTo),
callGraphAnalysis.Appearances
);
return 0;
}
private static IImmutableDictionary<ISymbol, IImmutableList<CallAnalysis>> TrimToEvents(
ISymbol origin,
IImmutableDictionary<ISymbol, IImmutableList<CallAnalysis>> links
)
{
Trim(origin);
return links;
bool Trim(ISymbol current)
{
if (!links.TryGetValue(current, out var direct))
{
return false;
}
var sawEvent = false;
foreach (var call in direct)
{
if (call.LinkKind is LinkKind.Event)
{
sawEvent |= true;
Trim(call.Target);
}
else if (Trim(call.Target))
{
sawEvent |= true;
}
else
{
direct = direct.Remove(call);
}
}
if (sawEvent)
{
links = links.SetItem(current, direct);
}
else
{
links = links.Remove(current);
}
return sawEvent;
}
}
private static void PrintCallGraph(
ISymbol origin,
IImmutableDictionary<ISymbol, IImmutableList<CallAnalysis>> links,