29
29
import pascal .taie .language .classes .JClass ;
30
30
import pascal .taie .language .classes .JMethod ;
31
31
import pascal .taie .language .classes .Subsignature ;
32
+ import polyglot .util .WorkList ;
32
33
34
+ import java .lang .invoke .CallSite ;
33
35
import java .util .ArrayDeque ;
36
+ import java .util .HashSet ;
34
37
import java .util .Queue ;
35
38
import java .util .Set ;
36
39
@@ -49,8 +52,24 @@ public CallGraph<Invoke, JMethod> build() {
49
52
50
53
private CallGraph <Invoke , JMethod > buildCallGraph (JMethod entry ) {
51
54
DefaultCallGraph callGraph = new DefaultCallGraph ();
52
- callGraph .addEntryMethod (entry );
55
+ // callGraph.addEntryMethod(entry);
53
56
// TODO - finish me
57
+ Queue <JMethod > worklist = new ArrayDeque <>();
58
+ worklist .add (entry );
59
+ while (!worklist .isEmpty ()) {
60
+ JMethod method = worklist .remove ();
61
+ if (!callGraph .contains (method )) {
62
+ callGraph .addReachableMethod (method );
63
+ callGraph .callSitesIn (method ).forEach (cs -> {
64
+ var methods = resolve (cs );
65
+ for (var m : methods ) {
66
+ var edge = new Edge <Invoke , JMethod >(CallGraphs .getCallKind (cs ), cs , m );
67
+ callGraph .addEdge (edge );
68
+ worklist .add (m );
69
+ }
70
+ });
71
+ }
72
+ }
54
73
return callGraph ;
55
74
}
56
75
@@ -59,7 +78,27 @@ private CallGraph<Invoke, JMethod> buildCallGraph(JMethod entry) {
59
78
*/
60
79
private Set <JMethod > resolve (Invoke callSite ) {
61
80
// TODO - finish me
62
- return null ;
81
+ Set <JMethod > candidates = new HashSet <>();
82
+ var kind = CallGraphs .getCallKind (callSite );
83
+ var methodRef = callSite .getMethodRef ();
84
+ var declareClass = methodRef .getDeclaringClass ();
85
+ var signature = methodRef .getSubsignature ();
86
+ if (kind == CallKind .STATIC ) {
87
+ var method = declareClass .getDeclaredMethod (signature );
88
+ candidates .add (method );
89
+ return candidates ;
90
+ }
91
+ if (kind == CallKind .SPECIAL ) {
92
+ candidates .add (dispatch (declareClass , signature ));
93
+ return candidates ;
94
+ }
95
+ if (kind == CallKind .VIRTUAL ) {
96
+ candidates .add (dispatch (declareClass , signature ));
97
+ hierarchy .getDirectSubclassesOf (declareClass ).forEach (jClass -> {
98
+ candidates .add (dispatch (jClass , methodRef .getSubsignature ()));
99
+ });
100
+ }
101
+ return candidates ;
63
102
}
64
103
65
104
/**
@@ -70,6 +109,9 @@ private Set<JMethod> resolve(Invoke callSite) {
70
109
*/
71
110
private JMethod dispatch (JClass jclass , Subsignature subsignature ) {
72
111
// TODO - finish me
73
- return null ;
112
+ var method = jclass .getDeclaredMethod (subsignature );
113
+ if (method != null ) return method ;
114
+ if (jclass .getSuperClass () == null ) return null ;
115
+ return dispatch (jclass .getSuperClass (), subsignature );
74
116
}
75
117
}
0 commit comments