Skip to content

Commit

Permalink
Merge pull request #159 from ponder-lab/work
Browse files Browse the repository at this point in the history
Work on several issues but mainly #155.
  • Loading branch information
khatchad authored Jan 16, 2018
2 parents 4ecfd96 + d14631e commit 3faedb8
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 16 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Explicit entry points may be marked using the appropriate annotation found in th

There are currently some limitations with embedded streams (i.e., streams declared as part of lambda expressions sent as arguments to intermediate stream operations). This is due to model differences between the Eclipse JDT and WALA. See [#155](https://github.com/ponder-lab/Java-8-Stream-Refactoring/issues/155) for details.

In general, there are some issues with the mapping between the Eclipse DOM and WALA DOM, particuarly when using Anonymous Inner Classes (AICs). We are currently working with the WALA developers to solve [this issue](https://github.com/ponder-lab/Java-8-Stream-Refactoring/issues/155).

## Contributing

Please see [the wiki](http://github.com/ponder-lab/Java-8-Stream-Refactoring/wiki) for more information regarding development.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,10 +329,14 @@ public MethodDeclaration getEnclosingMethodDeclaration() {
}

private IR getEnclosingMethodIR(EclipseProjectAnalysisEngine<InstanceKey> engine)
throws IOException, CoreException {
throws IOException, CoreException, UnhandledCaseException {
if (enclosingMethodDeclarationIR == null) {
// get the IR for the enclosing method.
com.ibm.wala.classLoader.IMethod resolvedMethod = getEnclosingWalaMethod(engine);

if (resolvedMethod == null)
throw new UnhandledCaseException("Couldn't retrieve enclosing WALA method. Most likely an AIC #155.");

enclosingMethodDeclarationIR = engine.getCache().getIR(resolvedMethod);

if (enclosingMethodDeclarationIR == null)
Expand Down Expand Up @@ -361,12 +365,13 @@ protected CGNode getEnclosingMethodNode(EclipseProjectAnalysisEngine<InstanceKey
}

MethodReference getEnclosingMethodReference() {
JDTIdentityMapper mapper = getJDTIdentifyMapper(getEnclosingMethodDeclaration());
MethodReference methodRef = mapper.getMethodRef(getEnclosingMethodDeclaration().resolveBinding());
MethodDeclaration enclosingMethodDeclaration = getEnclosingMethodDeclaration();
JDTIdentityMapper mapper = getJDTIdentifyMapper(enclosingMethodDeclaration);
MethodReference methodRef = mapper.getMethodRef(enclosingMethodDeclaration.resolveBinding());

if (methodRef == null)
throw new IllegalStateException(
"Could not get method reference for: " + getEnclosingMethodDeclaration().getName());
"Could not get method reference for: " + enclosingMethodDeclaration.getName());
return methodRef;
}

Expand Down Expand Up @@ -405,8 +410,8 @@ protected Ordering getInitialOrdering() {
}

public InstanceKey getInstanceKey(Collection<InstanceKey> trackedInstances,
EclipseProjectAnalysisEngine<InstanceKey> engine)
throws InvalidClassFileException, IOException, CoreException, InstanceKeyNotFoundException {
EclipseProjectAnalysisEngine<InstanceKey> engine) throws InvalidClassFileException, IOException,
CoreException, InstanceKeyNotFoundException, UnhandledCaseException {
if (instanceKey == null) {
instanceKey = this.getInstructionForCreation(engine)
.flatMap(instruction -> trackedInstances.stream()
Expand All @@ -420,13 +425,14 @@ public InstanceKey getInstanceKey(Collection<InstanceKey> trackedInstances,
}

Optional<SSAInvokeInstruction> getInstructionForCreation(EclipseProjectAnalysisEngine<InstanceKey> engine)
throws InvalidClassFileException, IOException, CoreException {
throws InvalidClassFileException, IOException, CoreException, UnhandledCaseException {
if (this.instructionForCreation == null) {
IBytecodeMethod method = (IBytecodeMethod) this.getEnclosingMethodIR(engine).getMethod();
IR enclosingMethodIR = this.getEnclosingMethodIR(engine);

IBytecodeMethod method = (IBytecodeMethod) enclosingMethodIR.getMethod();
SimpleName methodName = this.getCreation().getName();

for (Iterator<SSAInstruction> it = this.getEnclosingMethodIR(engine).iterateNormalInstructions(); it
.hasNext();) {
for (Iterator<SSAInstruction> it = enclosingMethodIR.iterateNormalInstructions(); it.hasNext();) {
SSAInstruction instruction = it.next();

int lineNumberFromIR = getLineNumberFromIR(method, instruction);
Expand Down Expand Up @@ -515,7 +521,7 @@ public TypeReference getTypeReference() {
}

private int getUseValueNumberForCreation(EclipseProjectAnalysisEngine<InstanceKey> engine)
throws InvalidClassFileException, IOException, CoreException {
throws InvalidClassFileException, IOException, CoreException, UnhandledCaseException {
return getInstructionForCreation(engine).map(i -> i.getUse(0)).orElse(-1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,12 @@ private void fillInstanceToStreamMap(Set<Stream> streamSet, EclipseProjectAnalys
}
++skippedStreams;
continue; // next stream.
} catch (UnhandledCaseException e) {
String msg = "Encountered possible unhandled case (AIC #155) while processing: " + stream.getCreation();
LOGGER.log(Level.WARNING, msg, e);
stream.addStatusEntry(PreconditionFailure.CURRENTLY_NOT_HANDLED, msg);
++skippedStreams;
continue; // next stream.
}
instanceToStreamMap.put(instanceKey, stream);
} // end each stream.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package p;

import java.util.ArrayList;

import edu.cuny.hunter.streamrefactoring.annotations.EntryPoint;

class A {
@EntryPoint
void m() {
new A() {
@Override
void m() {
new ArrayList().stream().count();
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
class A {
@EntryPoint
void m() {
Arrays.asList().stream();
Arrays.asList().stream().count();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,10 @@ protected void tearDown() throws Exception {
* Test #34.
*/
public void testArraysAsList() throws Exception {
helper(new StreamAnalysisExpectedResult("Arrays.asList().stream()",
Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false,
false, null, null, null, RefactoringStatus.ERROR,
Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS)));
helper(new StreamAnalysisExpectedResult("Arrays.asList().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL),
EnumSet.of(Ordering.ORDERED), false, false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL),
PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK,
Collections.emptySet()));
}

/**
Expand All @@ -371,6 +371,24 @@ public void testConstructor() throws Exception {
Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet()));
}

/**
* There is a problem between mapping methods declared within AICs from the
* Eclipse DOM to the WALA DOM #155.
*/
public void testAnonymousInnerClass() throws Exception {
boolean passed = false;
try {
helper(new StreamAnalysisExpectedResult("new ArrayList().stream()",
Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, false, false,
EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2,
Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet()));
} catch (NullPointerException e) {
LOGGER.throwing(this.getClass().getName(), "testArraysAsList", e);
passed = true;
}
assertTrue("Should throw exception per AIC issue.", passed);
}

public void testBitSet() throws Exception {
helper(new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL),
Collections.singleton(Ordering.ORDERED), false, false, false,
Expand Down

0 comments on commit 3faedb8

Please sign in to comment.