Skip to content

Commit c7a9686

Browse files
committed
Initial commit for #178.
Make N flexible within the framework. Now, will need to modify the evaluator.
1 parent c94c3db commit c7a9686

File tree

8 files changed

+154
-11
lines changed

8 files changed

+154
-11
lines changed

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.Set;
1212
import java.util.logging.Level;
1313
import java.util.logging.Logger;
14+
import java.util.stream.BaseStream;
1415
import java.util.stream.Collectors;
1516

1617
import org.eclipse.core.runtime.CoreException;
@@ -42,6 +43,8 @@ public class StreamAnalyzer extends ASTVisitor {
4243

4344
private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME);
4445

46+
private static final int N_FOR_STREAMS_DEFAULT = 2;
47+
4548
private static void addImplicitEntryPoints(Collection<Entrypoint> target, Iterable<Entrypoint> source) {
4649
for (Entrypoint implicitEntryPoint : source)
4750
if (target.add(implicitEntryPoint))
@@ -63,6 +66,11 @@ private static void addImplicitEntryPoints(Collection<Entrypoint> target, Iterab
6366

6467
private Set<Stream> streamSet = new HashSet<>();
6568

69+
/**
70+
* The N to use for instances of {@link BaseStream} in the nCFA.
71+
*/
72+
private int nForStreams = N_FOR_STREAMS_DEFAULT;
73+
6674
public StreamAnalyzer() {
6775
this(false);
6876
}
@@ -76,13 +84,24 @@ public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints) {
7684
this.findImplicitEntryPoints = findImplicitEntryPoints;
7785
}
7886

87+
public StreamAnalyzer(boolean visitDocTags, int nForStreams, boolean findImplicitEntryPoints) {
88+
this(visitDocTags, findImplicitEntryPoints);
89+
this.nForStreams = nForStreams;
90+
}
91+
7992
public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints, boolean findImplicitTestEntryPoints,
8093
boolean findImplicitBenchmarkEntryPoints) {
8194
this(visitDocTags, findImplicitEntryPoints);
8295
this.findImplicitTestEntryPoints = findImplicitTestEntryPoints;
8396
this.findImplicitBenchmarkEntryPoints = findImplicitBenchmarkEntryPoints;
8497
}
8598

99+
public StreamAnalyzer(boolean visitDocTags, int nForStreams, boolean findImplicitEntryPoints,
100+
boolean findImplicitTestEntryPoints, boolean findImplicitBenchmarkEntryPoints) {
101+
this(visitDocTags, findImplicitEntryPoints, findImplicitTestEntryPoints, findImplicitBenchmarkEntryPoints);
102+
this.nForStreams = nForStreams;
103+
}
104+
86105
/**
87106
* Analyzes this {@link StreamAnalyzer}'s streams.
88107
*
@@ -100,7 +119,7 @@ public Map<IJavaProject, Collection<Entrypoint>> analyze() throws CoreException
100119
// create the analysis engine for the project.
101120
EclipseProjectAnalysisEngine<InstanceKey> engine = null;
102121
try {
103-
engine = new EclipseProjectAnalysisEngine<>(project);
122+
engine = new EclipseProjectAnalysisEngine<>(project, getNForStreams());
104123
engine.buildAnalysisScope();
105124
} catch (IOException e) {
106125
LOGGER.log(Level.SEVERE, "Could not create analysis engine for: " + project.getElementName(), e);
@@ -290,4 +309,12 @@ public boolean visit(MethodInvocation node) {
290309

291310
return super.visit(node);
292311
}
312+
313+
public int getNForStreams() {
314+
return nForStreams;
315+
}
316+
317+
protected void setNForStreams(int nForStreams) {
318+
this.nForStreams = nForStreams;
319+
}
293320
}

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/refactorings/ConvertToParallelStreamRefactoringProcessor.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public class ConvertToParallelStreamRefactoringProcessor extends RefactoringProc
7878
*/
7979
private static int loggingLevel = IStatus.WARNING;
8080

81+
private static final int N_FOR_STREAMS_DEFAULT = 2;
82+
8183
@SuppressWarnings("unused")
8284
private static final GroupCategorySet SET_CONVERT_STREAM_TO_PARALLEL = new GroupCategorySet(
8385
new GroupCategory("edu.cuny.hunter.streamrefactoring", //$NON-NLS-1$
@@ -142,6 +144,8 @@ public static void setLoggingLevel(int level) {
142144

143145
private boolean useImplicitTestEntrypoints = false;
144146

147+
private int nForStreams = N_FOR_STREAMS_DEFAULT;
148+
145149
public ConvertToParallelStreamRefactoringProcessor() throws JavaModelException {
146150
this(null, null, false, true, false, false, Optional.empty());
147151
}
@@ -167,12 +171,31 @@ public ConvertToParallelStreamRefactoringProcessor(IJavaProject[] javaProjects,
167171
}
168172
}
169173

174+
public ConvertToParallelStreamRefactoringProcessor(IJavaProject[] javaProjects,
175+
final CodeGenerationSettings settings, boolean layer, int nForStreams, boolean useImplicitEntrypoints,
176+
boolean useImplicitTestEntrypoints, boolean useImplicitBenchmarkEntrypoints,
177+
Optional<IProgressMonitor> monitor) throws JavaModelException {
178+
this(javaProjects, settings, layer, useImplicitEntrypoints, useImplicitTestEntrypoints,
179+
useImplicitBenchmarkEntrypoints, monitor);
180+
try {
181+
this.nForStreams = nForStreams;
182+
} finally {
183+
monitor.ifPresent(IProgressMonitor::done);
184+
}
185+
}
186+
170187
public ConvertToParallelStreamRefactoringProcessor(IJavaProject[] javaProjects,
171188
final CodeGenerationSettings settings, boolean useImplicitJoinpoints, Optional<IProgressMonitor> monitor)
172189
throws JavaModelException {
173190
this(javaProjects, settings, false, useImplicitJoinpoints, false, false, monitor);
174191
}
175192

193+
public ConvertToParallelStreamRefactoringProcessor(IJavaProject[] javaProjects,
194+
final CodeGenerationSettings settings, int nForStreams, boolean useImplicitJoinpoints,
195+
Optional<IProgressMonitor> monitor) throws JavaModelException {
196+
this(javaProjects, settings, false, nForStreams, useImplicitJoinpoints, false, false, monitor);
197+
}
198+
176199
public ConvertToParallelStreamRefactoringProcessor(IJavaProject[] javaProjects,
177200
final CodeGenerationSettings settings, Optional<IProgressMonitor> monitor) throws JavaModelException {
178201
this(javaProjects, settings, false, true, false, false, monitor);
@@ -196,7 +219,7 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi
196219
SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.CheckingPreconditions,
197220
this.getJavaProjects().length * 1000);
198221
final RefactoringStatus status = new RefactoringStatus();
199-
StreamAnalyzer analyzer = new StreamAnalyzer(false, this.getUseImplicitEntrypoints(),
222+
StreamAnalyzer analyzer = new StreamAnalyzer(false, this.getNForStreams(), this.getUseImplicitEntrypoints(),
200223
this.getUseImplicitTestEntrypoints(), this.getUseImplicitBenchmarkEntrypoints());
201224
this.setStreamSet(analyzer.getStreamSet());
202225

@@ -251,6 +274,14 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi
251274
}
252275
}
253276

277+
public int getNForStreams() {
278+
return this.nForStreams;
279+
}
280+
281+
public void setNForStreams(int nForStreams) {
282+
this.nForStreams = nForStreams;
283+
}
284+
254285
@Override
255286
public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
256287
throws CoreException, OperationCanceledException {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.ibm.wala.ipa.callgraph.CallGraph;
1111
import com.ibm.wala.ipa.callgraph.ContextItem;
1212
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
13+
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
1314
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallString;
1415
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallStringContextSelector;
1516
import com.ibm.wala.ssa.SSAInvokeInstruction;
@@ -159,7 +160,9 @@ public static boolean instanceKeyCorrespondsWithInstantiationInstruction(Instanc
159160
throw new NoApplicationCodeExistsInCallStringsException(
160161
"Could not find application code in call string while processing instance key: " + instanceKey
161162
+ " and instruction: " + instruction + ". This may indicate that the current value of N ("
162-
+ nCFAContextWithReceiversSelector.CONTEXT_LENGTH_FOR_STREAMS + ") is too small.");
163+
+ ((nCFAContextWithReceiversSelector) ((PropagationCallGraphBuilder) engine
164+
.getCallGraphBuilder()).getContextSelector()).getContextLengthForStreams()
165+
+ ") is too small.");
163166

164167
return false;
165168
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ public static ConvertToParallelStreamRefactoringProcessor createConvertToParalle
4343
return processor;
4444
}
4545

46+
public static ConvertToParallelStreamRefactoringProcessor createConvertToParallelStreamRefactoringProcessor(
47+
IJavaProject[] projects, int nForStreams, boolean useImplicitEntrypoints,
48+
boolean useImplicitTestEntrypoints, boolean useImplicitBenchmarkEntrypoints,
49+
Optional<IProgressMonitor> monitor) throws JavaModelException {
50+
ConvertToParallelStreamRefactoringProcessor processor = createConvertToParallelStreamRefactoringProcessor(
51+
projects, useImplicitEntrypoints, useImplicitTestEntrypoints, useImplicitBenchmarkEntrypoints, monitor);
52+
processor.setNForStreams(nForStreams);
53+
return processor;
54+
}
55+
4656
public static ConvertToParallelStreamRefactoringProcessor createConvertToParallelStreamRefactoringProcessor(
4757
IJavaProject[] projects, Optional<IProgressMonitor> monitor) throws JavaModelException {
4858
CodeGenerationSettings settings = JavaPreferencesSettings.getCodeGenerationSettings(projects[0]);

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,34 @@ public class EclipseProjectAnalysisEngine<I extends InstanceKey> extends JDTJava
4949
*/
5050
private static final int N = 1;
5151

52+
/**
53+
* The default N value used for instances of {@link BaseStream} to create the
54+
* {@link nCFABuilder}.
55+
*/
56+
private static final int N_FOR_STREAMS_DEFAULT = 2;
57+
5258
private CallGraphBuilder<?> callGraphBuilder;
5359

5460
/**
5561
* The project used to create this engine.
5662
*/
5763
private IJavaProject project;
5864

65+
/**
66+
* The N to use for instances of {@link BaseStream}.
67+
*/
68+
private int nToUseForStreams = N_FOR_STREAMS_DEFAULT;
69+
5970
public EclipseProjectAnalysisEngine(IJavaProject project) throws IOException, CoreException {
6071
super(project);
6172
this.project = project;
6273
}
6374

75+
public EclipseProjectAnalysisEngine(IJavaProject project, int nForStreams) throws IOException, CoreException {
76+
this(project);
77+
this.nToUseForStreams = nForStreams;
78+
}
79+
6480
@Override
6581
public void buildAnalysisScope() throws IOException {
6682
try {
@@ -157,7 +173,7 @@ public CallGraphBuilder<?> getCallGraphBuilder() {
157173
@Override
158174
protected CallGraphBuilder<?> getCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options,
159175
IAnalysisCacheView cache) {
160-
return Util.makeNCFABuilder(N, options, (AnalysisCache) cache, cha, scope);
176+
return Util.makeNCFABuilder(N, options, (AnalysisCache) cache, cha, scope, this.getNToUseForStreams());
161177
}
162178

163179
public void clearCallGraphBuilder() {
@@ -172,4 +188,12 @@ public void clearCallGraphBuilder() {
172188
public IJavaProject getProject() {
173189
return project;
174190
}
191+
192+
public int getNToUseForStreams() {
193+
return nToUseForStreams;
194+
}
195+
196+
protected void setNToUseForStreams(int nToUseForStreams) {
197+
this.nToUseForStreams = nToUseForStreams;
198+
}
175199
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.io.File;
77
import java.io.IOException;
88
import java.util.Collection;
9+
import java.util.stream.BaseStream;
910

1011
import com.ibm.wala.classLoader.Module;
1112
import com.ibm.wala.ide.util.EclipseProjectPath;
@@ -65,17 +66,20 @@ public static boolean isWindows() {
6566
* make a {@link CallGraphBuilder} that uses call-string context sensitivity,
6667
* with call-string length limited to n, and a context-sensitive
6768
* allocation-site-based heap abstraction.
69+
*
70+
* @param nToUseForStreams
71+
* The N to use specifically for instances of {@link BaseStream}.
6872
*/
6973
public static SSAPropagationCallGraphBuilder makeNCFABuilder(int n, AnalysisOptions options, AnalysisCache cache,
70-
IClassHierarchy cha, AnalysisScope scope) {
74+
IClassHierarchy cha, AnalysisScope scope, int nToUseForStreams) {
7175
if (options == null)
7276
throw new IllegalArgumentException("options is null");
7377
addDefaultSelectors(options, cha);
7478
addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
7579
ContextSelector appSelector = null;
7680
SSAContextInterpreter appInterpreter = null;
7781
SSAPropagationCallGraphBuilder result = new nCFABuilderWithActualParametersInContext(n, cha, options, cache,
78-
appSelector, appInterpreter);
82+
appSelector, appInterpreter, nToUseForStreams);
7983
// nCFABuilder uses type-based heap abstraction by default, but we want
8084
// allocation sites
8185
result.setInstanceKeys(new ZeroXInstanceKeys(options, cha, result.getContextInterpreter(),

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
public class nCFABuilderWithActualParametersInContext extends SSAPropagationCallGraphBuilder {
1818

19+
private static final int N_TO_USE_FOR_STREAMS_DEFAULT = 2;
20+
1921
public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, AnalysisOptions options,
20-
AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter) {
22+
AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter,
23+
int nToUseForStreams) {
2124
super(cha, options, cache, new DefaultPointerKeyFactory());
2225
if (options == null)
2326
throw new IllegalArgumentException("options is null");
@@ -27,7 +30,7 @@ public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, Anal
2730
ContextSelector def = new DefaultContextSelector(options, cha);
2831
ContextSelector contextSelector = appContextSelector == null ? def
2932
: new DelegatingContextSelector(appContextSelector, def);
30-
contextSelector = new nCFAContextWithReceiversSelector(n, contextSelector);
33+
contextSelector = new nCFAContextWithReceiversSelector(n, contextSelector, nToUseForStreams);
3134
this.setContextSelector(contextSelector);
3235

3336
SSAContextInterpreter defI = new DefaultSSAInterpreter(options, cache);
@@ -38,4 +41,9 @@ public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, Anal
3841
: new DelegatingSSAContextInterpreter(appContextInterpreter, defI);
3942
this.setContextInterpreter(contextInterpreter);
4043
}
44+
45+
public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, AnalysisOptions options,
46+
AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter) {
47+
this(n, cha, options, cache, appContextSelector, appContextInterpreter, N_TO_USE_FOR_STREAMS_DEFAULT);
48+
}
4149
}

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

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,44 @@ public int hashCode() {
5555
}
5656

5757
/**
58-
* The N to use if the instance implements BaseStream.
58+
* The default N to use if the instance implements BaseStream.
5959
*/
60-
public static final int CONTEXT_LENGTH_FOR_STREAMS = 2;
60+
protected static final int CONTEXT_LENGTH_FOR_STREAMS_DEFAULT = 2;
61+
62+
/**
63+
* The N to use if the instance implements {@link BaseStream}.
64+
*/
65+
private int contextLengthForStreams = CONTEXT_LENGTH_FOR_STREAMS_DEFAULT;
6166

6267
protected Map<CallStringTriple, CallStringWithReceivers> callStringWithReceiversMap = new HashMap<>();
6368

69+
/**
70+
* Create a new {@link nCFAContextWithReceiversSelector}.
71+
*
72+
* @param n
73+
* The N to use generally.
74+
* @param base
75+
* The base {@link ContextSelector}.
76+
*/
6477
public nCFAContextWithReceiversSelector(int n, ContextSelector base) {
6578
super(n, base);
6679
}
6780

81+
/**
82+
* Create a new {@link nCFAContextWithReceiversSelector}.
83+
*
84+
* @param n
85+
* The N to use generally.
86+
* @param base
87+
* The base {@link ContextSelector}.
88+
* @param nToUseForStreams
89+
* The particular N to use if the instance is ok {@link BaseStream}.
90+
*/
91+
public nCFAContextWithReceiversSelector(int n, ContextSelector base, int nToUseForStreams) {
92+
super(n, base);
93+
this.contextLengthForStreams = nToUseForStreams;
94+
}
95+
6896
@Override
6997
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee,
7098
InstanceKey[] actualParameters) {
@@ -132,8 +160,16 @@ protected int getLength(CGNode caller, CallSiteReference site, IMethod target) {
132160
boolean implementsBaseStream = Util.implementsBaseStream(typeToCheck, target.getClassHierarchy());
133161

134162
if (implementsBaseStream)
135-
return CONTEXT_LENGTH_FOR_STREAMS;
163+
return this.getContextLengthForStreams();
136164
else
137165
return super.getLength(caller, site, target);
138166
}
167+
168+
public int getContextLengthForStreams() {
169+
return contextLengthForStreams;
170+
}
171+
172+
protected void setContextLengthForStreams(int contextLengthForStreams) {
173+
this.contextLengthForStreams = contextLengthForStreams;
174+
}
139175
}

0 commit comments

Comments
 (0)