4
4
import java .util .logging .Logger ;
5
5
6
6
import com .ibm .wala .classLoader .CallSiteReference ;
7
- import com .ibm .wala .classLoader .IClassLoader ;
8
7
import com .ibm .wala .classLoader .IMethod ;
9
8
import com .ibm .wala .classLoader .NewSiteReference ;
10
9
import com .ibm .wala .ipa .callgraph .CGNode ;
17
16
import com .ibm .wala .types .ClassLoaderReference ;
18
17
import com .ibm .wala .types .MethodReference ;
19
18
import com .ibm .wala .types .TypeName ;
19
+ import com .ibm .wala .types .TypeReference ;
20
20
import com .ibm .wala .util .collections .Pair ;
21
21
import com .ibm .wala .util .strings .Atom ;
22
22
23
23
import edu .cuny .hunter .streamrefactoring .core .utils .LoggerNames ;
24
+ import edu .cuny .hunter .streamrefactoring .core .wala .EclipseProjectAnalysisEngine ;
24
25
import edu .cuny .hunter .streamrefactoring .core .wala .nCFAContextWithReceiversSelector ;
25
26
26
27
public class Util {
@@ -64,11 +65,11 @@ public class Util {
64
65
* Iff application code was not found while processing call strings.
65
66
*/
66
67
public static boolean instanceKeyCorrespondsWithInstantiationInstruction (InstanceKey instanceKey ,
67
- SSAInvokeInstruction instruction , MethodReference instructionEnclosingMethod , CallGraph callGraph )
68
- throws NoApplicationCodeExistsInCallStringsException {
68
+ SSAInvokeInstruction instruction , MethodReference instructionEnclosingMethod ,
69
+ EclipseProjectAnalysisEngine < InstanceKey > engine ) throws NoApplicationCodeExistsInCallStringsException {
69
70
// Creation sites for the instance with the given key in the given call
70
71
// graph.
71
- Iterator <Pair <CGNode , NewSiteReference >> creationSites = instanceKey .getCreationSites (callGraph );
72
+ Iterator <Pair <CGNode , NewSiteReference >> creationSites = instanceKey .getCreationSites (engine . getCallGraph () );
72
73
73
74
CallSiteReference instructionCallSite = instruction .getCallSite ();
74
75
LOGGER .fine ("instruction call site is: " + instructionCallSite );
@@ -77,6 +78,9 @@ public static boolean instanceKeyCorrespondsWithInstantiationInstruction(Instanc
77
78
// indicate that N is too small.
78
79
boolean applicationCodeInCallString = false ;
79
80
81
+ // true iff all non-application code in the call strings return streams.
82
+ boolean allNonApplicationCodeReturnsStreams = true ;
83
+
80
84
// for each creation site.
81
85
while (creationSites .hasNext ()) {
82
86
Pair <CGNode , NewSiteReference > pair = creationSites .next ();
@@ -102,21 +106,40 @@ public static boolean instanceKeyCorrespondsWithInstantiationInstruction(Instanc
102
106
IMethod method = methods [i ];
103
107
LOGGER .fine ("Method at " + i + " is: " + method );
104
108
109
+ ClassLoaderReference callSiteReferenceClassLoaderReference = callSiteReference .getDeclaredTarget ()
110
+ .getDeclaringClass ().getClassLoader ();
111
+ ClassLoaderReference methodClassLoader = method .getReference ().getDeclaringClass ().getClassLoader ();
112
+
105
113
// if we haven't encountered application code in the call string yet.
106
114
if (!applicationCodeInCallString ) {
107
115
// get the class loaders.
108
- ClassLoaderReference callSiteReferenceClassLoader = callSiteReference .getDeclaredTarget ()
109
- .getDeclaringClass ().getClassLoader ();
110
- IClassLoader methodClassLoader = method .getDeclaringClass ().getClassLoader ();
111
116
112
117
// if either the call site reference class loader or the (enclosing) method
113
118
// class loader is of type Application.
114
- if (callSiteReferenceClassLoader .equals (ClassLoaderReference .Application )
119
+ if (callSiteReferenceClassLoaderReference .equals (ClassLoaderReference .Application )
115
120
|| methodClassLoader .equals (ClassLoaderReference .Application ))
116
121
// then, we've seen application code.
117
122
applicationCodeInCallString = true ;
118
123
}
119
124
125
+ // if all non-application code in the call strings return streams.
126
+ if (allNonApplicationCodeReturnsStreams ) {
127
+ // find out if this one does as well.
128
+ if (!callSiteReferenceClassLoaderReference .equals (ClassLoaderReference .Application )) {
129
+ IMethod target = engine .getClassHierarchy ()
130
+ .resolveMethod (callSiteReference .getDeclaredTarget ());
131
+ TypeReference type = edu .cuny .hunter .streamrefactoring .core .analysis .Util
132
+ .getEvaluationType (target );
133
+
134
+ boolean implementsBaseStream = edu .cuny .hunter .streamrefactoring .core .analysis .Util
135
+ .implementsBaseStream (type , engine .getClassHierarchy ());
136
+
137
+ if (!implementsBaseStream )
138
+ // we found one that doesn't.
139
+ allNonApplicationCodeReturnsStreams = false ;
140
+ }
141
+ }
142
+
120
143
// if the call site reference equals the call site corresponding
121
144
// to the creation instruction.
122
145
if (callSiteReference .equals (instructionCallSite )
@@ -130,8 +153,9 @@ public static boolean instanceKeyCorrespondsWithInstantiationInstruction(Instanc
130
153
LOGGER .fine ("No match found. Instance key: " + instanceKey + " does not correspond with instruction: "
131
154
+ instruction + "." );
132
155
133
- // if we did not encounter application code in the call strings.
134
- if (!applicationCodeInCallString )
156
+ // if we did not encounter application code in the call strings and if all
157
+ // of the non-application code all return streams.
158
+ if (!applicationCodeInCallString && allNonApplicationCodeReturnsStreams )
135
159
throw new NoApplicationCodeExistsInCallStringsException (
136
160
"Could not find application code in call string while processing instance key: " + instanceKey
137
161
+ " and instruction: " + instruction + ". This may indicate that the current value of N ("
0 commit comments