Skip to content

Commit 9ebf24c

Browse files
authored
Gallery (#2)
Added Gallery - Refactored context menu handling - Refactored undo stack
1 parent a4a1c6d commit 9ebf24c

39 files changed

+1370
-823
lines changed

CSharpCodeAnalyst/App.xaml.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ protected override void OnStartup(StartupEventArgs e)
3939

4040
mainWindow.SetViewer(explorationGraphViewer);
4141
var viewModel = new MainViewModel(messaging, settings);
42-
var graphViewModel = new GraphViewModel(explorationGraphViewer, explorer, settings);
42+
var graphViewModel = new GraphViewModel(explorationGraphViewer, explorer, messaging, settings);
4343
var treeViewModel = new TreeViewModel(messaging);
4444
var cycleViewModel = new CycleSummaryViewModel();
4545
viewModel.GraphViewModel = graphViewModel;
@@ -64,8 +64,6 @@ protected override void OnStartup(StartupEventArgs e)
6464

6565
messaging.Subscribe<CycleCalculationComplete>(cycleViewModel.HandleCycleCalculationComplete);
6666

67-
messaging.Subscribe<AddMissingDependenciesRequest>(graphViewModel.HandleAddMissingDependenciesRequest);
68-
6967
messaging.Subscribe<DeleteFromModelRequest>(viewModel.HandleDeleteFromModel);
7068

7169
mainWindow.DataContext = viewModel;

CSharpCodeAnalyst/Exploration/CodeGraphExplorer.cs

Lines changed: 144 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,89 @@ namespace CSharpCodeAnalyst.Exploration;
44

55
public class CodeGraphExplorer : ICodeGraphExplorer
66
{
7-
public Invocation FindIncomingCalls(CodeGraph codeGraph, CodeElement method)
7+
private CodeGraph? _codeGraph;
8+
9+
public void LoadCodeGraph(CodeGraph graph)
10+
{
11+
_codeGraph = graph;
12+
}
13+
14+
public List<CodeElement> GetElements(List<string> ids)
815
{
9-
ArgumentNullException.ThrowIfNull(codeGraph);
10-
ArgumentNullException.ThrowIfNull(method);
16+
ArgumentNullException.ThrowIfNull(ids);
1117

12-
var callDependencies = GetCallDependencies(codeGraph);
18+
if (_codeGraph is null)
19+
{
20+
return [];
21+
}
22+
23+
List<CodeElement> elements = new();
24+
foreach (var id in ids)
25+
{
26+
if (_codeGraph.Nodes.TryGetValue(id, out var element))
27+
{
28+
// The element is cloned internally and the dependencies discarded.
29+
elements.Add(element);
30+
}
31+
}
32+
33+
return elements;
34+
}
35+
36+
/// <summary>
37+
/// Returns all dependencies that link the given nodes (ids).
38+
/// </summary>
39+
public IEnumerable<Dependency> FindAllDependencies(HashSet<string> ids)
40+
{
41+
if (_codeGraph is null)
42+
{
43+
return [];
44+
}
45+
46+
var dependencies = _codeGraph.Nodes.Values
47+
.SelectMany(n => n.Dependencies)
48+
.Where(d => ids.Contains(d.SourceId) && ids.Contains(d.TargetId))
49+
.ToList();
50+
51+
return dependencies;
52+
}
53+
54+
public Invocation FindIncomingCalls(string id)
55+
{
56+
ArgumentNullException.ThrowIfNull(id);
57+
58+
if (_codeGraph is null)
59+
{
60+
return new Invocation([], []);
61+
}
62+
63+
var method = _codeGraph.Nodes[id];
64+
65+
var callDependencies = GetCallDependencies();
1366
var calls = callDependencies.Where(call => call.TargetId == method.Id).ToArray();
14-
var methods = calls.Select(d => codeGraph.Nodes[d.SourceId]);
67+
var methods = calls.Select(d => _codeGraph.Nodes[d.SourceId]);
1568

1669
return new Invocation(methods, calls);
1770
}
1871

19-
public Invocation FindIncomingCallsRecursive(CodeGraph codeGraph, CodeElement method)
72+
public Invocation FindIncomingCallsRecursive(string id)
2073
{
21-
ArgumentNullException.ThrowIfNull(codeGraph);
22-
ArgumentNullException.ThrowIfNull(method);
74+
ArgumentNullException.ThrowIfNull(id);
75+
76+
if (_codeGraph is null)
77+
{
78+
return new Invocation([], []);
79+
}
80+
81+
var method = _codeGraph.Nodes[id];
2382

2483
var processingQueue = new Queue<CodeElement>();
2584
processingQueue.Enqueue(method);
2685

2786
var allCalls = new HashSet<Dependency>();
2887
var allMethods = new HashSet<CodeElement>();
2988

30-
var callDependencies = GetCallDependencies(codeGraph);
89+
var callDependencies = GetCallDependencies();
3190

3291
var processed = new HashSet<string>();
3392
while (processingQueue.Any())
@@ -41,12 +100,12 @@ public Invocation FindIncomingCallsRecursive(CodeGraph codeGraph, CodeElement me
41100
var calls = callDependencies.Where(call => call.TargetId == element.Id).ToArray();
42101
allCalls.UnionWith(calls);
43102

44-
var methods = calls.Select(d => codeGraph.Nodes[d.SourceId]).ToArray();
103+
var methods = calls.Select(d => _codeGraph.Nodes[d.SourceId]).ToArray();
45104
allMethods.UnionWith(methods);
46105

47106
foreach (var methodToExplore in methods)
48107
{
49-
processingQueue.Enqueue(codeGraph.Nodes[methodToExplore.Id]);
108+
processingQueue.Enqueue(_codeGraph.Nodes[methodToExplore.Id]);
50109
}
51110
}
52111

@@ -56,18 +115,24 @@ public Invocation FindIncomingCallsRecursive(CodeGraph codeGraph, CodeElement me
56115
/// <summary>
57116
/// subclass -- inherits--> baseclass
58117
/// </summary>
59-
public SearchResult FindFullInheritanceTree(CodeGraph codeGraph, CodeElement type)
118+
public SearchResult FindFullInheritanceTree(string id)
60119
{
61-
ArgumentNullException.ThrowIfNull(codeGraph);
62-
ArgumentNullException.ThrowIfNull(type);
120+
ArgumentNullException.ThrowIfNull(id);
121+
122+
if (_codeGraph is null)
123+
{
124+
return new SearchResult([], []);
125+
}
126+
127+
var type = _codeGraph.Nodes[id];
63128

64129
var types = new HashSet<CodeElement>();
65130
var relationships = new HashSet<Dependency>();
66131
var processingQueue = new Queue<CodeElement>();
67132
processingQueue.Enqueue(type);
68133
var processed = new HashSet<string>();
69134

70-
var inheritsAndImplements = FindInheritsAndImplementsRelationships(codeGraph);
135+
var inheritsAndImplements = FindInheritsAndImplementsRelationships();
71136
while (processingQueue.Any())
72137
{
73138
var typeToAnalyze = processingQueue.Dequeue();
@@ -82,7 +147,7 @@ public SearchResult FindFullInheritanceTree(CodeGraph codeGraph, CodeElement typ
82147
typeToAnalyze.Dependencies.Where(d => d.Type is DependencyType.Implements or DependencyType.Inherits);
83148
foreach (var abstraction in abstractionsOfAnalyzedType)
84149
{
85-
var baseType = codeGraph.Nodes[abstraction.TargetId];
150+
var baseType = _codeGraph.Nodes[abstraction.TargetId];
86151
types.Add(baseType);
87152
relationships.Add(abstraction);
88153
processingQueue.Enqueue(baseType);
@@ -93,7 +158,7 @@ var specializationsOfAnalyzedType
93158
= inheritsAndImplements.Where(d => typeToAnalyze.Id == d.TargetId);
94159
foreach (var specialization in specializationsOfAnalyzedType)
95160
{
96-
var specializedType = codeGraph.Nodes[specialization.SourceId];
161+
var specializedType = _codeGraph.Nodes[specialization.SourceId];
97162

98163
types.Add(specializedType);
99164
relationships.Add(specialization);
@@ -105,104 +170,123 @@ var specializationsOfAnalyzedType
105170
}
106171

107172
/// <summary>
108-
/// Returns all dependencies that link the given nodes (ids).
173+
/// x (source) -- derives from/overrides/implements --> y (target, search input)
109174
/// </summary>
110-
public IEnumerable<Dependency> FindAllDependencies(HashSet<string> ids, CodeGraph? graph)
175+
public SearchResult FindSpecializations(string id)
111176
{
112-
if (graph is null)
177+
ArgumentNullException.ThrowIfNull(id);
178+
179+
if (_codeGraph is null)
113180
{
114-
return [];
181+
return new SearchResult([], []);
115182
}
116183

117-
var dependencies = graph.Nodes.Values
118-
.SelectMany(n => n.Dependencies)
119-
.Where(d => ids.Contains(d.SourceId) && ids.Contains(d.TargetId))
120-
.ToList();
121-
122-
return dependencies;
123-
}
124-
125-
/// <summary>
126-
/// x (source) -- derives from/overrides/implements --> y (target, search input)
127-
/// </summary>
128-
public SearchResult FindSpecializations(CodeGraph codeGraph, CodeElement element)
129-
{
130-
ArgumentNullException.ThrowIfNull(codeGraph);
131-
ArgumentNullException.ThrowIfNull(element);
184+
var element = _codeGraph.Nodes[id];
132185

133-
var dependencies = codeGraph.GetAllDependencies()
186+
var dependencies = _codeGraph.GetAllDependencies()
134187
.Where(d => (d.Type == DependencyType.Overrides ||
135188
d.Type == DependencyType.Implements) &&
136189
d.TargetId == element.Id).ToList();
137-
var methods = dependencies.Select(m => codeGraph.Nodes[m.SourceId]).ToList();
190+
var methods = dependencies.Select(m => _codeGraph.Nodes[m.SourceId]).ToList();
138191
return new SearchResult(methods, dependencies);
139192
}
140193

141194
/// <summary>
142195
/// x (source, search input) -- derives from/overrides/implements --> y (target)
143196
/// </summary>
144-
public SearchResult FindAbstractions(CodeGraph codeGraph, CodeElement element)
197+
public SearchResult FindAbstractions(string id)
145198
{
146-
ArgumentNullException.ThrowIfNull(codeGraph);
147-
ArgumentNullException.ThrowIfNull(element);
199+
ArgumentNullException.ThrowIfNull(id);
200+
201+
if (_codeGraph is null)
202+
{
203+
return new SearchResult([], []);
204+
}
205+
206+
var element = _codeGraph.Nodes[id];
148207

149208
var dependencies = element.Dependencies
150209
.Where(d => (d.Type == DependencyType.Overrides ||
151210
d.Type == DependencyType.Implements) &&
152211
d.SourceId == element.Id).ToList();
153-
var methods = dependencies.Select(m => codeGraph.Nodes[m.TargetId]).ToList();
212+
var methods = dependencies.Select(m => _codeGraph.Nodes[m.TargetId]).ToList();
154213
return new SearchResult(methods, dependencies);
155214
}
156215

157216

158-
public Invocation FindOutgoingCalls(CodeGraph codeGraph, CodeElement method)
217+
public Invocation FindOutgoingCalls(string id)
159218
{
160-
ArgumentNullException.ThrowIfNull(codeGraph);
161-
ArgumentNullException.ThrowIfNull(method);
219+
ArgumentNullException.ThrowIfNull(id);
220+
221+
if (_codeGraph is null)
222+
{
223+
return new Invocation([], []);
224+
}
225+
226+
var method = _codeGraph.Nodes[id];
162227

163228
var calls = method.Dependencies
164229
.Where(d => d.Type == DependencyType.Calls).ToList();
165-
var methods = calls.Select(m => codeGraph.Nodes[m.TargetId]).ToList();
230+
var methods = calls.Select(m => _codeGraph.Nodes[m.TargetId]).ToList();
166231
return new Invocation(methods, calls);
167232
}
168233

169-
public SearchResult FindOutgoingDependencies(CodeGraph codeGraph, CodeElement element)
234+
public SearchResult FindOutgoingDependencies(string id)
170235
{
171-
ArgumentNullException.ThrowIfNull(codeGraph);
172-
ArgumentNullException.ThrowIfNull(element);
236+
ArgumentNullException.ThrowIfNull(id);
173237

238+
if (_codeGraph is null)
239+
{
240+
return new SearchResult([], []);
241+
}
242+
243+
var element = _codeGraph.Nodes[id];
174244
var dependencies = element.Dependencies;
175-
var targets = dependencies.Select(m => codeGraph.Nodes[m.TargetId]).ToList();
245+
var targets = dependencies.Select(m => _codeGraph.Nodes[m.TargetId]).ToList();
176246
return new SearchResult(targets, dependencies);
177247
}
178248

179-
public SearchResult FindIncomingDependencies(CodeGraph codeGraph, CodeElement element)
249+
public SearchResult FindIncomingDependencies(string id)
180250
{
181-
ArgumentNullException.ThrowIfNull(codeGraph);
182-
ArgumentNullException.ThrowIfNull(element);
251+
ArgumentNullException.ThrowIfNull(id);
252+
if (_codeGraph is null)
253+
{
254+
return new SearchResult([], []);
255+
}
183256

184-
var dependencies = codeGraph.Nodes.Values
257+
var element = _codeGraph.Nodes[id];
258+
var dependencies = _codeGraph.Nodes.Values
185259
.SelectMany(node => node.Dependencies)
186260
.Where(d => d.TargetId == element.Id).ToList();
187261

188-
var elements = dependencies.Select(d => codeGraph.Nodes[d.SourceId]);
262+
var elements = dependencies.Select(d => _codeGraph.Nodes[d.SourceId]);
189263

190264
return new SearchResult(elements, dependencies);
191265
}
192266

193-
private static List<Dependency> GetCallDependencies(CodeGraph codeGraph)
267+
private List<Dependency> GetCallDependencies()
194268
{
195-
var callDependencies = codeGraph.Nodes.Values
269+
if (_codeGraph is null)
270+
{
271+
return [];
272+
}
273+
274+
var callDependencies = _codeGraph.Nodes.Values
196275
.SelectMany(node => node.Dependencies)
197276
.Where(d => d.Type == DependencyType.Calls)
198277
.ToList();
199278
return callDependencies;
200279
}
201280

202-
private static HashSet<Dependency> FindInheritsAndImplementsRelationships(CodeGraph codeGraph)
281+
private HashSet<Dependency> FindInheritsAndImplementsRelationships()
203282
{
283+
if (_codeGraph is null)
284+
{
285+
return [];
286+
}
287+
204288
var inheritsAndImplements = new HashSet<Dependency>();
205-
codeGraph.DfsHierarchy(Collect);
289+
_codeGraph.DfsHierarchy(Collect);
206290
return inheritsAndImplements;
207291

208292
void Collect(CodeElement c)
@@ -225,6 +309,4 @@ void Collect(CodeElement c)
225309

226310
public record struct SearchResult(IEnumerable<CodeElement> Elements, IEnumerable<Dependency> Dependencies);
227311

228-
public record struct Invocation(IEnumerable<CodeElement> Methods, IEnumerable<Dependency> Calls);
229-
230-
public record struct Relationship(IEnumerable<CodeElement> Types, IEnumerable<Dependency> Relationships);
312+
public record struct Invocation(IEnumerable<CodeElement> Methods, IEnumerable<Dependency> Calls);

CSharpCodeAnalyst/Exploration/ICodeGraphExplorer.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,28 @@ namespace CSharpCodeAnalyst.Exploration;
44

55
public interface ICodeGraphExplorer
66
{
7-
Invocation FindIncomingCalls(CodeGraph codeGraph, CodeElement method);
8-
Invocation FindOutgoingCalls(CodeGraph codeGraph, CodeElement method);
9-
Invocation FindIncomingCallsRecursive(CodeGraph codeGraph, CodeElement method);
10-
SearchResult FindFullInheritanceTree(CodeGraph codeGraph, CodeElement type);
7+
Invocation FindIncomingCalls(string id);
8+
Invocation FindOutgoingCalls(string id);
9+
Invocation FindIncomingCallsRecursive(string id);
10+
SearchResult FindFullInheritanceTree(string id);
1111

1212
/// <summary>
1313
/// Finds all dependencies connect the given nodes.
1414
/// </summary>
15-
IEnumerable<Dependency> FindAllDependencies(HashSet<string> ids, CodeGraph? graph);
15+
IEnumerable<Dependency> FindAllDependencies(HashSet<string> ids);
1616

1717
/// <summary>
1818
/// Methods that implement or overload the given method
1919
/// </summary>
20-
SearchResult FindSpecializations(CodeGraph codeGraph, CodeElement method);
20+
SearchResult FindSpecializations(string id);
2121

2222
/// <summary>
2323
/// Methods that are implemented or overloaded by the given method
2424
/// </summary>
25-
SearchResult FindAbstractions(CodeGraph codeGraph, CodeElement method);
25+
SearchResult FindAbstractions(string id);
2626

27-
SearchResult FindOutgoingDependencies(CodeGraph codeGraph, CodeElement codeElement);
28-
SearchResult FindIncomingDependencies(CodeGraph codeGraph, CodeElement codeElement);
27+
SearchResult FindOutgoingDependencies(string id);
28+
SearchResult FindIncomingDependencies(string id);
29+
void LoadCodeGraph(CodeGraph graph);
30+
List<CodeElement> GetElements(List<string> ids);
2931
}

0 commit comments

Comments
 (0)