@@ -4,30 +4,89 @@ namespace CSharpCodeAnalyst.Exploration;
4
4
5
5
public class CodeGraphExplorer : ICodeGraphExplorer
6
6
{
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 )
8
15
{
9
- ArgumentNullException . ThrowIfNull ( codeGraph ) ;
10
- ArgumentNullException . ThrowIfNull ( method ) ;
16
+ ArgumentNullException . ThrowIfNull ( ids ) ;
11
17
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 ( ) ;
13
66
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 ] ) ;
15
68
16
69
return new Invocation ( methods , calls ) ;
17
70
}
18
71
19
- public Invocation FindIncomingCallsRecursive ( CodeGraph codeGraph , CodeElement method )
72
+ public Invocation FindIncomingCallsRecursive ( string id )
20
73
{
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 ] ;
23
82
24
83
var processingQueue = new Queue < CodeElement > ( ) ;
25
84
processingQueue . Enqueue ( method ) ;
26
85
27
86
var allCalls = new HashSet < Dependency > ( ) ;
28
87
var allMethods = new HashSet < CodeElement > ( ) ;
29
88
30
- var callDependencies = GetCallDependencies ( codeGraph ) ;
89
+ var callDependencies = GetCallDependencies ( ) ;
31
90
32
91
var processed = new HashSet < string > ( ) ;
33
92
while ( processingQueue . Any ( ) )
@@ -41,12 +100,12 @@ public Invocation FindIncomingCallsRecursive(CodeGraph codeGraph, CodeElement me
41
100
var calls = callDependencies . Where ( call => call . TargetId == element . Id ) . ToArray ( ) ;
42
101
allCalls . UnionWith ( calls ) ;
43
102
44
- var methods = calls . Select ( d => codeGraph . Nodes [ d . SourceId ] ) . ToArray ( ) ;
103
+ var methods = calls . Select ( d => _codeGraph . Nodes [ d . SourceId ] ) . ToArray ( ) ;
45
104
allMethods . UnionWith ( methods ) ;
46
105
47
106
foreach ( var methodToExplore in methods )
48
107
{
49
- processingQueue . Enqueue ( codeGraph . Nodes [ methodToExplore . Id ] ) ;
108
+ processingQueue . Enqueue ( _codeGraph . Nodes [ methodToExplore . Id ] ) ;
50
109
}
51
110
}
52
111
@@ -56,18 +115,24 @@ public Invocation FindIncomingCallsRecursive(CodeGraph codeGraph, CodeElement me
56
115
/// <summary>
57
116
/// subclass -- inherits--> baseclass
58
117
/// </summary>
59
- public SearchResult FindFullInheritanceTree ( CodeGraph codeGraph , CodeElement type )
118
+ public SearchResult FindFullInheritanceTree ( string id )
60
119
{
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 ] ;
63
128
64
129
var types = new HashSet < CodeElement > ( ) ;
65
130
var relationships = new HashSet < Dependency > ( ) ;
66
131
var processingQueue = new Queue < CodeElement > ( ) ;
67
132
processingQueue . Enqueue ( type ) ;
68
133
var processed = new HashSet < string > ( ) ;
69
134
70
- var inheritsAndImplements = FindInheritsAndImplementsRelationships ( codeGraph ) ;
135
+ var inheritsAndImplements = FindInheritsAndImplementsRelationships ( ) ;
71
136
while ( processingQueue . Any ( ) )
72
137
{
73
138
var typeToAnalyze = processingQueue . Dequeue ( ) ;
@@ -82,7 +147,7 @@ public SearchResult FindFullInheritanceTree(CodeGraph codeGraph, CodeElement typ
82
147
typeToAnalyze . Dependencies . Where ( d => d . Type is DependencyType . Implements or DependencyType . Inherits ) ;
83
148
foreach ( var abstraction in abstractionsOfAnalyzedType )
84
149
{
85
- var baseType = codeGraph . Nodes [ abstraction . TargetId ] ;
150
+ var baseType = _codeGraph . Nodes [ abstraction . TargetId ] ;
86
151
types . Add ( baseType ) ;
87
152
relationships . Add ( abstraction ) ;
88
153
processingQueue . Enqueue ( baseType ) ;
@@ -93,7 +158,7 @@ var specializationsOfAnalyzedType
93
158
= inheritsAndImplements . Where ( d => typeToAnalyze . Id == d . TargetId ) ;
94
159
foreach ( var specialization in specializationsOfAnalyzedType )
95
160
{
96
- var specializedType = codeGraph . Nodes [ specialization . SourceId ] ;
161
+ var specializedType = _codeGraph . Nodes [ specialization . SourceId ] ;
97
162
98
163
types . Add ( specializedType ) ;
99
164
relationships . Add ( specialization ) ;
@@ -105,104 +170,123 @@ var specializationsOfAnalyzedType
105
170
}
106
171
107
172
/// <summary>
108
- /// Returns all dependencies that link the given nodes (ids).
173
+ /// x (source) -- derives from/overrides/implements --> y (target, search input)
109
174
/// </summary>
110
- public IEnumerable < Dependency > FindAllDependencies ( HashSet < string > ids , CodeGraph ? graph )
175
+ public SearchResult FindSpecializations ( string id )
111
176
{
112
- if ( graph is null )
177
+ ArgumentNullException . ThrowIfNull ( id ) ;
178
+
179
+ if ( _codeGraph is null )
113
180
{
114
- return [ ] ;
181
+ return new SearchResult ( [ ] , [ ] ) ;
115
182
}
116
183
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 ] ;
132
185
133
- var dependencies = codeGraph . GetAllDependencies ( )
186
+ var dependencies = _codeGraph . GetAllDependencies ( )
134
187
. Where ( d => ( d . Type == DependencyType . Overrides ||
135
188
d . Type == DependencyType . Implements ) &&
136
189
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 ( ) ;
138
191
return new SearchResult ( methods , dependencies ) ;
139
192
}
140
193
141
194
/// <summary>
142
195
/// x (source, search input) -- derives from/overrides/implements --> y (target)
143
196
/// </summary>
144
- public SearchResult FindAbstractions ( CodeGraph codeGraph , CodeElement element )
197
+ public SearchResult FindAbstractions ( string id )
145
198
{
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 ] ;
148
207
149
208
var dependencies = element . Dependencies
150
209
. Where ( d => ( d . Type == DependencyType . Overrides ||
151
210
d . Type == DependencyType . Implements ) &&
152
211
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 ( ) ;
154
213
return new SearchResult ( methods , dependencies ) ;
155
214
}
156
215
157
216
158
- public Invocation FindOutgoingCalls ( CodeGraph codeGraph , CodeElement method )
217
+ public Invocation FindOutgoingCalls ( string id )
159
218
{
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 ] ;
162
227
163
228
var calls = method . Dependencies
164
229
. 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 ( ) ;
166
231
return new Invocation ( methods , calls ) ;
167
232
}
168
233
169
- public SearchResult FindOutgoingDependencies ( CodeGraph codeGraph , CodeElement element )
234
+ public SearchResult FindOutgoingDependencies ( string id )
170
235
{
171
- ArgumentNullException . ThrowIfNull ( codeGraph ) ;
172
- ArgumentNullException . ThrowIfNull ( element ) ;
236
+ ArgumentNullException . ThrowIfNull ( id ) ;
173
237
238
+ if ( _codeGraph is null )
239
+ {
240
+ return new SearchResult ( [ ] , [ ] ) ;
241
+ }
242
+
243
+ var element = _codeGraph . Nodes [ id ] ;
174
244
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 ( ) ;
176
246
return new SearchResult ( targets , dependencies ) ;
177
247
}
178
248
179
- public SearchResult FindIncomingDependencies ( CodeGraph codeGraph , CodeElement element )
249
+ public SearchResult FindIncomingDependencies ( string id )
180
250
{
181
- ArgumentNullException . ThrowIfNull ( codeGraph ) ;
182
- ArgumentNullException . ThrowIfNull ( element ) ;
251
+ ArgumentNullException . ThrowIfNull ( id ) ;
252
+ if ( _codeGraph is null )
253
+ {
254
+ return new SearchResult ( [ ] , [ ] ) ;
255
+ }
183
256
184
- var dependencies = codeGraph . Nodes . Values
257
+ var element = _codeGraph . Nodes [ id ] ;
258
+ var dependencies = _codeGraph . Nodes . Values
185
259
. SelectMany ( node => node . Dependencies )
186
260
. Where ( d => d . TargetId == element . Id ) . ToList ( ) ;
187
261
188
- var elements = dependencies . Select ( d => codeGraph . Nodes [ d . SourceId ] ) ;
262
+ var elements = dependencies . Select ( d => _codeGraph . Nodes [ d . SourceId ] ) ;
189
263
190
264
return new SearchResult ( elements , dependencies ) ;
191
265
}
192
266
193
- private static List < Dependency > GetCallDependencies ( CodeGraph codeGraph )
267
+ private List < Dependency > GetCallDependencies ( )
194
268
{
195
- var callDependencies = codeGraph . Nodes . Values
269
+ if ( _codeGraph is null )
270
+ {
271
+ return [ ] ;
272
+ }
273
+
274
+ var callDependencies = _codeGraph . Nodes . Values
196
275
. SelectMany ( node => node . Dependencies )
197
276
. Where ( d => d . Type == DependencyType . Calls )
198
277
. ToList ( ) ;
199
278
return callDependencies ;
200
279
}
201
280
202
- private static HashSet < Dependency > FindInheritsAndImplementsRelationships ( CodeGraph codeGraph )
281
+ private HashSet < Dependency > FindInheritsAndImplementsRelationships ( )
203
282
{
283
+ if ( _codeGraph is null )
284
+ {
285
+ return [ ] ;
286
+ }
287
+
204
288
var inheritsAndImplements = new HashSet < Dependency > ( ) ;
205
- codeGraph . DfsHierarchy ( Collect ) ;
289
+ _codeGraph . DfsHierarchy ( Collect ) ;
206
290
return inheritsAndImplements ;
207
291
208
292
void Collect ( CodeElement c )
@@ -225,6 +309,4 @@ void Collect(CodeElement c)
225
309
226
310
public record struct SearchResult ( IEnumerable < CodeElement > Elements , IEnumerable < Dependency > Dependencies ) ;
227
311
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 ) ;
0 commit comments