@@ -33,8 +33,7 @@ public class CallTreeCypher {
33
33
34
34
private static final AtomicInteger virtualNodeId = new AtomicInteger (-1 );
35
35
public static final Pattern DISPLAY_PATTERN = Pattern .compile (
36
- "\\ b[a-zA-Z]|[A-Z]|\\ ."
37
- );
36
+ "\\ b[a-zA-Z]|[A-Z]|\\ ." );
38
37
39
38
public static void print (BigBang bigbang , String path , String reportName ) {
40
39
// Re-initialize method ids back to 0 to better diagnose disparities
@@ -66,31 +65,32 @@ private static void printAll(Map<AnalysisMethod, MethodNode> methodToNode, Strin
66
65
}
67
66
68
67
final String vmFileName = ReportUtils .report ("call tree for vm entry point" , path + File .separatorChar + "reports" , "csv_call_tree_vm_" + reportName , "csv" ,
69
- CallTreeCypher ::printVMEntryPoint );
68
+ CallTreeCypher ::printVMEntryPoint );
70
69
71
70
final String methodsFileName = ReportUtils .report ("call tree for methods" , path + File .separatorChar + "reports" , "csv_call_tree_methods_" + reportName , "csv" ,
72
- writer -> printMethodNodes (methodToNode .values (), writer ));
71
+ writer -> printMethodNodes (methodToNode .values (), writer ));
73
72
74
73
final String virtualMethodsFileName = ReportUtils .report ("call tree for virtual methods" , path + File .separatorChar + "reports" , "csv_call_tree_virtual_methods_" + reportName , "csv" ,
75
- writer -> printVirtualNodes (virtualNodes , writer ));
74
+ writer -> printVirtualNodes (virtualNodes , writer ));
76
75
77
76
final String entryPointsFileName = ReportUtils .report ("call tree for entry points" , path + File .separatorChar + "reports" , "csv_call_tree_entry_points_" + reportName , "csv" ,
78
- writer -> printEntryPointIds (entryPointIds , writer ));
77
+ writer -> printEntryPointIds (entryPointIds , writer ));
79
78
80
79
final String directEdgesFileName = ReportUtils .report ("call tree for direct edges" , path + File .separatorChar + "reports" , "csv_call_tree_direct_edges_" + reportName , "csv" ,
81
- writer -> printBciEdges (directEdges , writer ));
80
+ writer -> printBciEdges (directEdges , writer ));
82
81
83
82
final String overridenByEdgesFileName = ReportUtils .report ("call tree for overriden by edges" , path + File .separatorChar + "reports" , "csv_call_tree_override_by_edges_" + reportName , "csv" ,
84
- writer -> printNonBciEdges (overridenByEdges , writer ));
83
+ writer -> printNonBciEdges (overridenByEdges , writer ));
85
84
86
85
final String virtualEdgesFileName = ReportUtils .report ("call tree for virtual edges" , path + File .separatorChar + "reports" , "csv_call_tree_virtual_edges_" + reportName , "csv" ,
87
- writer -> printBciEdges (virtualEdges , writer ));
86
+ writer -> printBciEdges (virtualEdges , writer ));
88
87
89
88
ReportUtils .report ("call tree cypher" , path + File .separatorChar + "reports" , "cypher_call_tree_" + reportName , "cypher" ,
90
- writer -> printCypher (vmFileName , methodsFileName , virtualMethodsFileName , entryPointsFileName , directEdgesFileName , overridenByEdgesFileName , virtualEdgesFileName , writer ));
89
+ writer -> printCypher (vmFileName , methodsFileName , virtualMethodsFileName , entryPointsFileName , directEdgesFileName , overridenByEdgesFileName , virtualEdgesFileName , writer ));
91
90
}
92
91
93
- private static void printCypher (String vmFileName , String methodsFileName , String virtualMethodsFileName , String entryPointsFileName , String directEdgesFileName , String overridenByEdgesFileName , String virtualEdgesFileName , PrintWriter writer ) {
92
+ private static void printCypher (String vmFileName , String methodsFileName , String virtualMethodsFileName , String entryPointsFileName , String directEdgesFileName , String overridenByEdgesFileName ,
93
+ String virtualEdgesFileName , PrintWriter writer ) {
94
94
writer .println ("CREATE CONSTRAINT unique_vm_id ON (v:VM) ASSERT v.vmId IS UNIQUE;" );
95
95
writer .println ("CREATE CONSTRAINT unique_method_id ON (m:Method) ASSERT m.methodId IS UNIQUE;" );
96
96
writer .println ("" );
@@ -136,7 +136,8 @@ private static void printVMEntryPoint(PrintWriter writer) {
136
136
writer .println (convertToCSV ("0" , "VM" ));
137
137
}
138
138
139
- private static void walkNodes (MethodNode methodNode , Map <Integer , Set <BciEndEdge >> directEdges , Map <Integer , Set <BciEndEdge >> virtualEdges , Map <Integer , Set <Integer >> overridenByEdges , Map <List <String >, Integer > virtualNodes , Set <MethodNode > nonVirtualNodes ) {
139
+ private static void walkNodes (MethodNode methodNode , Map <Integer , Set <BciEndEdge >> directEdges , Map <Integer , Set <BciEndEdge >> virtualEdges , Map <Integer , Set <Integer >> overridenByEdges ,
140
+ Map <List <String >, Integer > virtualNodes , Set <MethodNode > nonVirtualNodes ) {
140
141
for (InvokeNode invoke : methodNode .invokes ) {
141
142
if (invoke .isDirectInvoke ) {
142
143
if (invoke .callees .size () > 0 ) {
@@ -162,9 +163,9 @@ private static void walkNodes(MethodNode methodNode, Map<Integer, Set<BciEndEdge
162
163
private static void printMethodNodes (Collection <MethodNode > methods , PrintWriter writer ) {
163
164
writer .println (convertToCSV ("Id" , "Name" , "Type" , "Parameters" , "Return" , "Display" ));
164
165
methods .stream ()
165
- .map (CallTreeCypher ::methodNodeInfo )
166
- .map (CallTreeCypher ::convertToCSV )
167
- .forEach (writer ::println );
166
+ .map (CallTreeCypher ::methodNodeInfo )
167
+ .map (CallTreeCypher ::convertToCSV )
168
+ .forEach (writer ::println );
168
169
}
169
170
170
171
private static List <String > methodNodeInfo (MethodNode method ) {
@@ -184,24 +185,24 @@ private static void addVirtualMethodEdge(int startId, InvokeNode invoke, int end
184
185
private static void addDirectEdge (int nodeId , InvokeNode invoke , Node calleeNode , Map <Integer , Set <BciEndEdge >> edges , Set <MethodNode > nodes ) {
185
186
Set <BciEndEdge > nodeEdges = edges .computeIfAbsent (nodeId , k -> new HashSet <>());
186
187
MethodNode methodNode = calleeNode instanceof MethodNode
187
- ? (MethodNode ) calleeNode
188
- : ((MethodNodeReference ) calleeNode ).methodNode ;
188
+ ? (MethodNode ) calleeNode
189
+ : ((MethodNodeReference ) calleeNode ).methodNode ;
189
190
nodes .add (methodNode );
190
191
nodeEdges .add (new BciEndEdge (methodNode .id , bytecodeIndexes (invoke )));
191
192
}
192
193
193
194
private static List <Integer > bytecodeIndexes (InvokeNode node ) {
194
195
return Stream .of (node .sourceReferences )
195
- .map (source -> source .bci )
196
- .collect (Collectors .toList ());
196
+ .map (source -> source .bci )
197
+ .collect (Collectors .toList ());
197
198
}
198
199
199
200
private static void printVirtualNodes (Map <List <String >, Integer > virtualNodes , PrintWriter writer ) {
200
201
writer .println (convertToCSV ("Id" , "Name" , "Type" , "Parameters" , "Return" , "Display" ));
201
202
virtualNodes .entrySet ().stream ()
202
- .map (CallTreeCypher ::virtualMethodAndIdInfo )
203
- .map (CallTreeCypher ::convertToCSV )
204
- .forEach (writer ::println );
203
+ .map (CallTreeCypher ::virtualMethodAndIdInfo )
204
+ .map (CallTreeCypher ::convertToCSV )
205
+ .forEach (writer ::println );
205
206
}
206
207
207
208
private static List <String > virtualMethodAndIdInfo (Map .Entry <List <String >, Integer > entry ) {
@@ -222,61 +223,62 @@ private static void printEntryPointIds(Set<Integer> entryPoints, PrintWriter wri
222
223
private static void addOverridenByEdge (int nodeId , Node calleeNode , Map <Integer , Set <Integer >> edges , Set <MethodNode > nodes ) {
223
224
Set <Integer > nodeEdges = edges .computeIfAbsent (nodeId , k -> new HashSet <>());
224
225
MethodNode methodNode = calleeNode instanceof MethodNode
225
- ? (MethodNode ) calleeNode
226
- : ((MethodNodeReference ) calleeNode ).methodNode ;
226
+ ? (MethodNode ) calleeNode
227
+ : ((MethodNodeReference ) calleeNode ).methodNode ;
227
228
nodes .add (methodNode );
228
229
nodeEdges .add (methodNode .id );
229
230
}
230
231
231
232
private static void printBciEdges (Map <Integer , Set <BciEndEdge >> edges , PrintWriter writer ) {
232
233
final Set <BciEdge > idEdges = edges .entrySet ().stream ()
233
- .flatMap (entry -> entry .getValue ().stream ().map (endId -> new BciEdge (entry .getKey (), endId )))
234
- .collect (Collectors .toSet ());
234
+ .flatMap (entry -> entry .getValue ().stream ().map (endId -> new BciEdge (entry .getKey (), endId )))
235
+ .collect (Collectors .toSet ());
235
236
236
237
writer .println (convertToCSV ("StartId" , "EndId" , "BytecodeIndexes" ));
237
238
idEdges .stream ()
238
- .map (edge -> convertToCSV (String .valueOf (edge .startId ), String .valueOf (edge .endEdge .id ), showBytecodeIndexes (edge .endEdge .bytecodeIndexes )))
239
- .forEach (writer ::println );
239
+ .map (edge -> convertToCSV (String .valueOf (edge .startId ), String .valueOf (edge .endEdge .id ), showBytecodeIndexes (edge .endEdge .bytecodeIndexes )))
240
+ .forEach (writer ::println );
240
241
}
241
242
242
243
private static String showBytecodeIndexes (List <Integer > bytecodeIndexes ) {
243
244
return bytecodeIndexes .stream ()
244
- .map (String ::valueOf )
245
- .collect (Collectors .joining ("->" ));
245
+ .map (String ::valueOf )
246
+ .collect (Collectors .joining ("->" ));
246
247
}
247
248
248
249
private static void printNonBciEdges (Map <Integer , Set <Integer >> edges , PrintWriter writer ) {
249
250
final Set <NonBciEdge > idEdges = edges .entrySet ().stream ()
250
- .flatMap (entry -> entry .getValue ().stream ().map (endId -> new NonBciEdge (entry .getKey (), endId )))
251
- .collect (Collectors .toSet ());
251
+ .flatMap (entry -> entry .getValue ().stream ().map (endId -> new NonBciEdge (entry .getKey (), endId )))
252
+ .collect (Collectors .toSet ());
252
253
253
254
writer .println (convertToCSV ("StartId" , "EndId" ));
254
255
idEdges .stream ()
255
- .map (edge -> convertToCSV (String .valueOf (edge .startId ), String .valueOf (edge .endId )))
256
- .forEach (writer ::println );
256
+ .map (edge -> convertToCSV (String .valueOf (edge .startId ), String .valueOf (edge .endId )))
257
+ .forEach (writer ::println );
257
258
}
258
259
259
260
private static List <String > virtualMethodInfo (AnalysisMethod method ) {
260
261
return resolvedJavaMethodInfo (null , method );
261
262
}
262
263
263
264
private static List <String > resolvedJavaMethodInfo (Integer id , ResolvedJavaMethod method ) {
264
- // TODO method parameter types are opaque, but could in the future be split out and link together
265
- // e.g. each method could BELONG to a type, and a method could have PARAMETER relationships with N types
266
- // see https://neo4j.com/developer/guide-import-csv/#_converting_data_values_with_load_csv for examples
267
- final String parameters =
268
- method .getSignature ().getParameterCount (false ) > 0
265
+ // TODO method parameter types are opaque, but could in the future be split out and link
266
+ // together
267
+ // e.g. each method could BELONG to a type, and a method could have PARAMETER relationships
268
+ // with N types
269
+ // see https://neo4j.com/developer/guide-import-csv/#_converting_data_values_with_load_csv
270
+ // for examples
271
+ final String parameters = method .getSignature ().getParameterCount (false ) > 0
269
272
? method .format ("%P" ).replace ("," , "" )
270
273
: "empty" ;
271
274
272
275
return Arrays .asList (
273
- id == null ? null : Integer .toString (id ),
274
- method .getName (),
275
- method .getDeclaringClass ().toJavaName (true ),
276
- parameters ,
277
- method .getSignature ().getReturnType (null ).toJavaName (true ),
278
- display (method )
279
- );
276
+ id == null ? null : Integer .toString (id ),
277
+ method .getName (),
278
+ method .getDeclaringClass ().toJavaName (true ),
279
+ parameters ,
280
+ method .getSignature ().getReturnType (null ).toJavaName (true ),
281
+ display (method ));
280
282
}
281
283
282
284
private static String display (ResolvedJavaMethod method ) {
@@ -335,11 +337,13 @@ private BciEndEdge(int id, List<Integer> bytecodeIndexes) {
335
337
336
338
@ Override
337
339
public boolean equals (Object o ) {
338
- if (this == o ) return true ;
339
- if (o == null || getClass () != o .getClass ()) return false ;
340
+ if (this == o )
341
+ return true ;
342
+ if (o == null || getClass () != o .getClass ())
343
+ return false ;
340
344
BciEndEdge endEdge = (BciEndEdge ) o ;
341
345
return id == endEdge .id &&
342
- bytecodeIndexes .equals (endEdge .bytecodeIndexes );
346
+ bytecodeIndexes .equals (endEdge .bytecodeIndexes );
343
347
}
344
348
345
349
@ Override
0 commit comments