Skip to content

Commit a50f0ce

Browse files
committed
Added context
1 parent 5ed682a commit a50f0ce

File tree

1 file changed

+34
-33
lines changed

1 file changed

+34
-33
lines changed

CSharpCodeAnalyst/Exploration/CodeGraphExplorer.cs

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44

55
namespace CSharpCodeAnalyst.Exploration;
66

7+
internal class Context
8+
{
9+
public HashSet<string> Remember { get; } = [];
10+
11+
public HashSet<string> BlockedAbstraction { get; } = [];
12+
13+
public Context Clone()
14+
{
15+
var clone = new Context();
16+
return clone;
17+
}
18+
}
19+
720
public class CodeGraphExplorer : ICodeGraphExplorer
821
{
922
private List<Relationship> _allRelationships = [];
@@ -194,9 +207,8 @@ public SearchResult FollowIncomingCallsHeuristically(string id)
194207

195208
var method = _codeGraph.Nodes[id];
196209

197-
var restriction = new FollowIncomingCallsRestriction();
198-
var processingQueue = new PriorityQueue<CodeElement, int>();
199-
processingQueue.Enqueue(method, 0); // Start with the initial method, priority 0
210+
var processingQueue = new PriorityQueue<(CodeElement, Context), int>();
211+
processingQueue.Enqueue((method, new Context()), 0); // Start with the initial method, priority 0
200212

201213
var foundRelationships = new HashSet<Relationship>();
202214
var foundElements = new HashSet<CodeElement>();
@@ -210,12 +222,13 @@ public SearchResult FollowIncomingCallsHeuristically(string id)
210222
{
211223
// 0 = highest priority
212224

213-
var element = processingQueue.Dequeue();
225+
var (element, context) = processingQueue.Dequeue();
214226
if (!processed.Add(element.Id))
215227
{
216228
continue;
217229
}
218230

231+
var currentContext = context.Clone();
219232

220233
if (element.ElementType == CodeElementType.Event)
221234
{
@@ -224,14 +237,14 @@ public SearchResult FollowIncomingCallsHeuristically(string id)
224237
foundRelationships.UnionWith(specializations);
225238
var specializedSources = specializations.Select(d => _codeGraph.Nodes[d.SourceId]).ToHashSet();
226239
foundElements.UnionWith(specializedSources);
227-
AddToProcessingQueue(specializedSources, 0);
240+
AddToProcessingQueue(specializedSources, currentContext, 0);
228241

229242
// Add all methods that invoke the event
230243
var invokes = allInvokes.Where(call => call.TargetId == element.Id).ToArray();
231244
foundRelationships.UnionWith(invokes);
232245
var invokeSources = invokes.Select(d => _codeGraph.Nodes[d.SourceId]).ToHashSet();
233246
foundElements.UnionWith(invokeSources);
234-
AddToProcessingQueue(invokeSources, 2);
247+
AddToProcessingQueue(invokeSources, currentContext, 2);
235248
}
236249

237250
if (element.ElementType == CodeElementType.Method)
@@ -243,53 +256,43 @@ public SearchResult FollowIncomingCallsHeuristically(string id)
243256
foundRelationships.UnionWith(abstractions);
244257
var abstractionTargets = abstractions.Select(d => _codeGraph.Nodes[d.TargetId]).ToHashSet();
245258
foundElements.UnionWith(abstractionTargets);
246-
restriction.BlockeBaseCalls.UnionWith(abstractionTargets.Select(t => t.Id));
247-
AddToProcessingQueue(abstractionTargets, 0);
259+
AddToProcessingQueue(abstractionTargets, currentContext, 0);
248260

249261

250262
// Add Events that are handled by this method (priority 1).
251263
var handles = allHandles.Where(h => h.SourceId == element.Id).ToArray();
252264
foundRelationships.UnionWith(handles);
253265
var events = handles.Select(h => _codeGraph.Nodes[h.TargetId]).ToHashSet();
254266
foundElements.UnionWith(events);
255-
AddToProcessingQueue(events, 1);
256-
267+
AddToProcessingQueue(events, currentContext, 1);
268+
257269

258270
// 3. Calls (priority 2)
259-
var calls = allCalls.Where(call => call.TargetId == element.Id && IsAllowedCall(call)).ToArray();
271+
var calls = allCalls.Where(call => call.TargetId == element.Id && IsAllowedCall(call, currentContext)).ToArray();
260272
foundRelationships.UnionWith(calls);
261273
var callSources = calls
262274
.Select(d => _codeGraph.Nodes[d.SourceId])
263275
.ToHashSet();
264276
foundElements.UnionWith(callSources);
265-
AddToProcessingQueue(callSources, 2);
277+
AddToProcessingQueue(callSources, currentContext, 2);
266278
}
267279
}
268280

269281
return new SearchResult(foundElements, foundRelationships);
270282

271-
void AddToProcessingQueue(IEnumerable<CodeElement> elementsToExplore, int priority)
283+
void AddToProcessingQueue(IEnumerable<CodeElement> elementsToExplore, Context context, int priority)
272284
{
273285
foreach (var elementToExplore in elementsToExplore)
274286
{
275-
processingQueue.Enqueue(_codeGraph.Nodes[elementToExplore.Id], priority);
287+
processingQueue.Enqueue((_codeGraph.Nodes[elementToExplore.Id], context), priority);
276288
}
277289
}
278-
279-
bool IsAllowedCall(Relationship call)
280-
{
281-
if (restriction.BlockeBaseCalls.Contains(call.TargetId))
282-
{
283-
var allow = !IsCallToOwnBase(call);
284-
if (!allow)
285-
{
286-
var sourceName = _codeGraph.Nodes[call.SourceId].FullName;
287-
var targetName = _codeGraph.Nodes[call.TargetId].FullName;
288-
Trace.WriteLine($"Removed: {sourceName} -> {targetName}");
289-
}
290290

291-
return allow;
292-
}
291+
bool IsAllowedCall(Relationship call, Context context)
292+
{
293+
var sourceName = _codeGraph.Nodes[call.SourceId].FullName;
294+
var targetName = _codeGraph.Nodes[call.TargetId].FullName;
295+
Trace.WriteLine($"Removed: {sourceName} -> {targetName}");
293296

294297
return true;
295298
}
@@ -341,7 +344,7 @@ public SearchResult FindFullInheritanceTree(string id)
341344
}
342345
}
343346

344-
// Find sub-classes recursive
347+
// Find subclasses recursively
345348
processingQueue.Enqueue(type);
346349
processed.Clear();
347350
while (processingQueue.Any())
@@ -532,13 +535,12 @@ private class FollowIncomingCallsRestriction
532535
/// This is because the method may be indirectly called by the interface.
533536
/// If we proceed we may also find calls the base. But this is the wrong direction for the path we follow.
534537
/// So if we followed an abstraction we block the base call to this abstraction
535-
///
536538
/// <code>
537539
/// class Base
538540
/// {
539541
/// protected virtual void Foo() {}
540542
/// }
541-
///
543+
///
542544
/// class Derived : Base
543545
/// {
544546
/// // We start following here!
@@ -548,11 +550,10 @@ private class FollowIncomingCallsRestriction
548550
/// }
549551
/// }
550552
/// </code>
551-
///
552553
/// Hashset of target ids of base methods.
553554
/// </summary>
554555
public HashSet<string> BlockeBaseCalls { get; } = [];
555-
556+
556557
public HashSet<string> BlockedAbstraction { get; } = [];
557558
}
558559
}

0 commit comments

Comments
 (0)