Skip to content

Commit 3cc5b1e

Browse files
authored
Merge pull request #179 from ponder-lab/issue_80
Some work on #80.
2 parents 7f9e14f + 7f8db2e commit 3cc5b1e

File tree

4 files changed

+105
-83
lines changed

4 files changed

+105
-83
lines changed

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,27 @@
1919

2020
public class Util {
2121

22-
private Util() {
23-
}
22+
/**
23+
* The {@link TypeName} of the type {@link java.util.Arrays}.
24+
*/
25+
private static final TypeName ARRAYS_TYPE_NAME = TypeName.string2TypeName("Ljava/util/Arrays");
26+
27+
/**
28+
* {@link Atom} corresponding the the stream() method.
29+
*/
30+
private static final Atom STREAM_METHOD_NAME_ATOM = Atom.findOrCreateAsciiAtom("stream");
31+
32+
/**
33+
* The {@link TypeName} for the type {@link java.util.stream.StreamSupport}.
34+
*/
35+
private static final TypeName STREAM_SUPPORT_TYPE_NAME = TypeName
36+
.string2TypeName("Ljava/util/stream/StreamSupport");
2437

2538
/**
2639
* True iff the given {@link InstanceKey} corresponds with the given
2740
* {@link SSAInvokeInstruction} in the given {@link CallGraph}. In other words,
2841
* the result is true iff the instruction is used to create the instance.
29-
*
42+
*
3043
* @param instanceKey
3144
* An instance in question.
3245
* @param instruction
@@ -75,19 +88,24 @@ public static boolean instanceKeyCorrespondsWithInstantiationInstruction(Instanc
7588
else if (callSiteReference.getProgramCounter() == instructionCallSite.getProgramCounter()) {
7689
// compare declared targets.
7790
MethodReference callSiteDeclaredTarget = callSiteReference.getDeclaredTarget();
91+
TypeName callSiteTargetDeclaringClassName = callSiteDeclaredTarget.getDeclaringClass().getName();
92+
7893
MethodReference instructionCallDeclaredTarget = instructionCallSite.getDeclaredTarget();
94+
TypeName instructionTargetDeclaringClassName = instructionCallDeclaredTarget.getDeclaringClass()
95+
.getName();
7996

80-
if (callSiteDeclaredTarget.getDeclaringClass().getName()
81-
.equals(instructionCallDeclaredTarget.getDeclaringClass().getName())
82-
&& callSiteDeclaredTarget.getDeclaringClass().getName()
83-
.equals(TypeName.string2TypeName("Ljava/util/Arrays"))
97+
if (callSiteTargetDeclaringClassName.equals(instructionTargetDeclaringClassName)
98+
&& (callSiteTargetDeclaringClassName.equals(ARRAYS_TYPE_NAME)
99+
|| callSiteTargetDeclaringClassName.equals(STREAM_SUPPORT_TYPE_NAME))
84100
&& callSiteDeclaredTarget.getName().equals(instructionCallDeclaredTarget.getName())
85-
&& callSiteDeclaredTarget.getName().equals(Atom.findOrCreateAsciiAtom("stream")))
101+
&& callSiteDeclaredTarget.getName().equals(STREAM_METHOD_NAME_ATOM))
86102
return true;
87103
}
88104
}
89105
}
90106
return false;
91107
}
92108

109+
private Util() {
110+
}
93111
}

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,13 @@
2323

2424
public final class Util {
2525

26-
private Util() {
27-
}
28-
29-
public static String getOSName() {
30-
return System.getProperty("os.name");
31-
}
32-
33-
public static boolean isWindows() {
34-
return getOSName().startsWith("Windows");
35-
}
26+
private static final String OS_NAME = "os.name";
27+
private static final String WINDOWS = "Windows";
3628

3729
/**
38-
* Enhance an {@link AnalysisScope} to include in a particular loader,
39-
* elements from a set of Eclipse projects
40-
*
30+
* Enhance an {@link AnalysisScope} to include in a particular loader, elements
31+
* from a set of Eclipse projects
32+
*
4133
* @param loader
4234
* the class loader in which new {@link Module}s will live
4335
* @param projectPaths
@@ -46,22 +38,52 @@ public static boolean isWindows() {
4638
* the {@link AnalysisScope} under construction. This will be
4739
* mutated.
4840
* @param seen
49-
* set of {@link Module}s which have already been seen, and
50-
* should not be added to the analysis scope
41+
* set of {@link Module}s which have already been seen, and should
42+
* not be added to the analysis scope
5143
*/
5244
private static void buildScope(ClassLoaderReference loader, Collection<EclipseProjectPath> projectPaths,
5345
AnalysisScope scope, Collection<Module> seen) throws IOException {
5446
for (EclipseProjectPath path : projectPaths) {
5547
AnalysisScope pScope = path.toAnalysisScope((File) null);
56-
for (Module m : pScope.getModules(loader)) {
48+
for (Module m : pScope.getModules(loader))
5749
if (!seen.contains(m)) {
5850
seen.add(m);
5951
scope.addToScope(loader, m);
6052
}
61-
}
6253
}
6354
}
6455

56+
public static String getOSName() {
57+
return System.getProperty(OS_NAME);
58+
}
59+
60+
public static boolean isWindows() {
61+
return getOSName().startsWith(WINDOWS);
62+
}
63+
64+
/**
65+
* make a {@link CallGraphBuilder} that uses call-string context sensitivity,
66+
* with call-string length limited to n, and a context-sensitive
67+
* allocation-site-based heap abstraction.
68+
*/
69+
public static SSAPropagationCallGraphBuilder makeNCFABuilder(int n, AnalysisOptions options, AnalysisCache cache,
70+
IClassHierarchy cha, AnalysisScope scope) {
71+
if (options == null)
72+
throw new IllegalArgumentException("options is null");
73+
addDefaultSelectors(options, cha);
74+
addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
75+
ContextSelector appSelector = null;
76+
SSAContextInterpreter appInterpreter = null;
77+
SSAPropagationCallGraphBuilder result = new nCFABuilderWithActualParametersInContext(n, cha, options, cache,
78+
appSelector, appInterpreter);
79+
// nCFABuilder uses type-based heap abstraction by default, but we want
80+
// allocation sites
81+
result.setInstanceKeys(new ZeroXInstanceKeys(options, cha, result.getContextInterpreter(),
82+
ZeroXInstanceKeys.ALLOCATIONS | ZeroXInstanceKeys.SMUSH_MANY | ZeroXInstanceKeys.SMUSH_PRIMITIVE_HOLDERS
83+
| ZeroXInstanceKeys.SMUSH_STRINGS | ZeroXInstanceKeys.SMUSH_THROWABLES));
84+
return result;
85+
}
86+
6587
/**
6688
* create an analysis scope as the union of a bunch of EclipseProjectPath
6789
*/
@@ -77,26 +99,7 @@ public static AnalysisScope mergeProjectPaths(Collection<EclipseProjectPath> pro
7799
buildScope(ClassLoaderReference.Primordial, projectPaths, scope, seen);
78100
return scope;
79101
}
80-
81-
/**
82-
* make a {@link CallGraphBuilder} that uses call-string context sensitivity,
83-
* with call-string length limited to n, and a context-sensitive
84-
* allocation-site-based heap abstraction.
85-
*/
86-
public static SSAPropagationCallGraphBuilder makeNCFABuilder(int n, AnalysisOptions options, AnalysisCache cache,
87-
IClassHierarchy cha, AnalysisScope scope) {
88-
if (options == null) {
89-
throw new IllegalArgumentException("options is null");
90-
}
91-
addDefaultSelectors(options, cha);
92-
addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
93-
ContextSelector appSelector = null;
94-
SSAContextInterpreter appInterpreter = null;
95-
SSAPropagationCallGraphBuilder result = new nCFABuilderWithActualParametersInContext(n, cha, options, cache, appSelector, appInterpreter);
96-
// nCFABuilder uses type-based heap abstraction by default, but we want allocation sites
97-
result.setInstanceKeys(new ZeroXInstanceKeys(options, cha, result.getContextInterpreter(), ZeroXInstanceKeys.ALLOCATIONS
98-
| ZeroXInstanceKeys.SMUSH_MANY | ZeroXInstanceKeys.SMUSH_PRIMITIVE_HOLDERS | ZeroXInstanceKeys.SMUSH_STRINGS
99-
| ZeroXInstanceKeys.SMUSH_THROWABLES));
100-
return result;
101-
}
102+
103+
private Util() {
104+
}
102105
}

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,23 @@ public class nCFABuilderWithActualParametersInContext extends SSAPropagationCall
1919
public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, AnalysisOptions options,
2020
AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter) {
2121
super(cha, options, cache, new DefaultPointerKeyFactory());
22-
if (options == null) {
22+
if (options == null)
2323
throw new IllegalArgumentException("options is null");
24-
}
2524

26-
setInstanceKeys(new ClassBasedInstanceKeys(options, cha));
25+
this.setInstanceKeys(new ClassBasedInstanceKeys(options, cha));
2726

2827
ContextSelector def = new DefaultContextSelector(options, cha);
2928
ContextSelector contextSelector = appContextSelector == null ? def
3029
: new DelegatingContextSelector(appContextSelector, def);
3130
contextSelector = new nCFAContextWithReceiversSelector(n, contextSelector);
32-
setContextSelector(contextSelector);
31+
this.setContextSelector(contextSelector);
3332

3433
SSAContextInterpreter defI = new DefaultSSAInterpreter(options, cache);
3534
defI = new DelegatingSSAContextInterpreter(
36-
ReflectionContextInterpreter.createReflectionContextInterpreter(cha, options, getAnalysisCache()),
35+
ReflectionContextInterpreter.createReflectionContextInterpreter(cha, options, this.getAnalysisCache()),
3736
defI);
3837
SSAContextInterpreter contextInterpreter = appContextInterpreter == null ? defI
3938
: new DelegatingSSAContextInterpreter(appContextInterpreter, defI);
40-
setContextInterpreter(contextInterpreter);
39+
this.setContextInterpreter(contextInterpreter);
4140
}
42-
4341
}

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,25 @@ public class nCFAContextWithReceiversSelector extends nCFAContextSelector {
2121

2222
protected class CallStringTriple {
2323

24+
CGNode node;
25+
26+
CallSiteReference site;
27+
IMethod target;
28+
2429
public CallStringTriple(CGNode node, CallSiteReference site, IMethod target) {
2530
this.node = node;
2631
this.site = site;
2732
this.target = target;
2833
}
2934

30-
CGNode node;
31-
CallSiteReference site;
32-
IMethod target;
35+
@Override
36+
public boolean equals(Object obj) {
37+
if (obj instanceof CallStringTriple) {
38+
CallStringTriple rhs = (CallStringTriple) obj;
39+
return this.node.equals(rhs.node) && this.site.equals(rhs.site) && this.target.equals(rhs.target);
40+
} else
41+
return false;
42+
}
3343

3444
@Override
3545
public int hashCode() {
@@ -41,17 +51,13 @@ public int hashCode() {
4151

4252
return builder.toString().hashCode();
4353
}
44-
45-
@Override
46-
public boolean equals(Object obj) {
47-
if (obj instanceof CallStringTriple) {
48-
CallStringTriple rhs = (CallStringTriple) obj;
49-
return this.node.equals(rhs.node) && this.site.equals(rhs.site) && this.target.equals(rhs.target);
50-
} else
51-
return false;
52-
}
5354
}
5455

56+
/**
57+
* The N to use if the instance implements BaseStream.
58+
*/
59+
public static final int CONTEXT_LENGTH_FOR_STREAMS = 2;
60+
5561
protected Map<CallStringTriple, CallStringWithReceivers> callStringWithReceiversMap = new HashMap<>();
5662

5763
public nCFAContextWithReceiversSelector(int n, ContextSelector base) {
@@ -61,15 +67,14 @@ public nCFAContextWithReceiversSelector(int n, ContextSelector base) {
6167
@Override
6268
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee,
6369
InstanceKey[] actualParameters) {
64-
Context baseContext = base.getCalleeTarget(caller, site, callee, actualParameters);
65-
CallStringWithReceivers cs = getCallString(caller, site, callee, actualParameters);
66-
if (cs == null) {
70+
Context baseContext = this.base.getCalleeTarget(caller, site, callee, actualParameters);
71+
CallStringWithReceivers cs = this.getCallString(caller, site, callee, actualParameters);
72+
if (cs == null)
6773
return baseContext;
68-
} else if (baseContext == Everywhere.EVERYWHERE) {
74+
else if (baseContext == Everywhere.EVERYWHERE)
6975
return new CallStringContext(cs);
70-
} else {
76+
else
7177
return new CallStringContextPair(cs, baseContext);
72-
}
7378
}
7479

7580
protected CallStringWithReceivers getCallString(CGNode caller, CallSiteReference site, IMethod target,
@@ -89,17 +94,15 @@ protected CallStringWithReceivers getCallString(CGNode caller, CallSiteReference
8994
// not found. Compute it.
9095
CallStringWithReceivers ret = null;
9196

92-
int length = getLength(caller, site, target);
97+
int length = this.getLength(caller, site, target);
9398
if (length > 0) {
94-
if (caller.getContext().get(CALL_STRING) != null) {
99+
if (caller.getContext().get(CALL_STRING) != null)
95100
ret = new CallStringWithReceivers(site, caller.getMethod(), length,
96101
(CallString) caller.getContext().get(CALL_STRING));
97-
} else {
102+
else
98103
ret = new CallStringWithReceivers(site, caller.getMethod());
99-
}
100-
} else {
104+
} else
101105
ret = null;
102-
}
103106

104107
// if we have a receiver.
105108
if (ret != null && actualParameters != null && actualParameters.length > 0)
@@ -112,21 +115,21 @@ protected CallStringWithReceivers getCallString(CGNode caller, CallSiteReference
112115
}
113116

114117
protected Map<CallStringTriple, CallStringWithReceivers> getCallStringWithReceiversMap() {
115-
return callStringWithReceiversMap;
118+
return this.callStringWithReceiversMap;
116119
}
117120

118121
/**
119122
* {@inheritDoc}
120-
*
121-
* @return 2 if the target's return type implements {@link BaseStream},
122-
* otherwise, return the original value.
123+
*
124+
* @return CONTEXT_LENGTH_FOR_STREAMS if the target's return type implements
125+
* {@link BaseStream}, otherwise, return the original value.
123126
*/
124127
@Override
125128
protected int getLength(CGNode caller, CallSiteReference site, IMethod target) {
126129
boolean implementsBaseStream = Util.implementsBaseStream(target.getReturnType(), target.getClassHierarchy());
127130

128131
if (implementsBaseStream)
129-
return 2;
132+
return CONTEXT_LENGTH_FOR_STREAMS;
130133
else
131134
return super.getLength(caller, site, target);
132135
}

0 commit comments

Comments
 (0)