From 2c307de69eea4eddffcf0be68426249abf44af18 Mon Sep 17 00:00:00 2001 From: Grace Tang Date: Fri, 5 Jan 2018 18:34:58 -0500 Subject: [PATCH 1/9] Add test cases for concurrent reductions (#150) * add test cases and fail the stream * calculate LOC * Revert "calculate LOC" This reverts commit 034b677e792a90d9d9fa1d1032245b2928dc000e. * revert changing functional code * change test cases * change test * change test cases * change refactoring * delete useless importation * Remove extra space. * change name and collections * Add collector kind * remove duplication * improve format * remove overloading helper * format * remove duplication * Remove whitespace addition. --- .../core/analysis/CollectorKind.java | 6 ++ .../core/analysis/PreconditionSuccess.java | 9 ++- .../core/analysis/Refactoring.java | 3 +- .../core/analysis/Stream.java | 10 +++ .../core/analysis/TransformationAction.java | 5 +- .../testConcurrentReduction/in/A.java | 33 ++++++++ .../testConcurrentReduction1/in/A.java | 33 ++++++++ .../testConcurrentReduction2/in/A.java | 33 ++++++++ .../testConcurrentReduction3/in/A.java | 34 +++++++++ .../testConcurrentReduction4/in/A.java | 35 +++++++++ .../testConcurrentReduction5/in/A.java | 34 +++++++++ ...onvertStreamToParallelRefactoringTest.java | 76 +++++++++++++++++++ .../tests/StreamAnalysisExpectedResult.java | 21 +++++ 13 files changed, 327 insertions(+), 5 deletions(-) create mode 100644 edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CollectorKind.java create mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction/in/A.java create mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction1/in/A.java create mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction2/in/A.java create mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction3/in/A.java create mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction4/in/A.java create mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction5/in/A.java diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CollectorKind.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CollectorKind.java new file mode 100644 index 00000000..5936bcc9 --- /dev/null +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CollectorKind.java @@ -0,0 +1,6 @@ +package edu.cuny.hunter.streamrefactoring.core.analysis; + +public enum CollectorKind { + CONCURRENT, + NONCONCURRENT +} \ No newline at end of file diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionSuccess.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionSuccess.java index 69ffa95f..9870eb51 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionSuccess.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionSuccess.java @@ -5,6 +5,11 @@ public enum PreconditionSuccess { P2, P3, P4, - P5 - + P5, + P6, + P7, + P8, + P9, + P10, + P11 } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Refactoring.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Refactoring.java index 3e230b36..ab96bf63 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Refactoring.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Refactoring.java @@ -7,5 +7,6 @@ */ public enum Refactoring { CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, - OPTIMIZE_PARALLEL_STREAM + OPTIMIZE_PARALLEL_STREAM, + OPTIMIZE_COMPLEX_MUTABLE_REDUCTION } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java index 91777a10..7b4d20d4 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java @@ -100,6 +100,8 @@ public class Stream { private IR enclosingMethodDeclarationIR; private final TypeDeclaration enclosingTypeDeclaration; + + private CollectorKind collectorKind; private boolean hasPossibleSideEffects; @@ -480,6 +482,10 @@ public Set getPossibleOrderings() { return possibleOrderings.stream().map(e -> e == null ? initialOrdering : e).collect(Collectors.toSet()); } + public CollectorKind getCollectorKind() { + return this.collectorKind; + } + public Refactoring getRefactoring() { return this.refactoring; } @@ -667,6 +673,10 @@ protected void setInitialOrdering(Ordering initialOrdering) { Objects.requireNonNull(initialOrdering); this.initialOrdering = initialOrdering; } + + protected void setCollectorKind(CollectorKind collectorKind) { + this.collectorKind = collectorKind; + } private void setPassingPrecondition(PreconditionSuccess succcess) { if (this.passingPrecondition == null) diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/TransformationAction.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/TransformationAction.java index b126de5d..03e9bfe5 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/TransformationAction.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/TransformationAction.java @@ -3,6 +3,7 @@ public enum TransformationAction { CONVERT_TO_PARALLEL, UNORDER, - CONVERT_TO_SEQUENTIAL - + CONVERT_TO_SEQUENTIAL, + CONVERT_COLLECTOR_TO_CONCURRENT, + CONVERT_COLLECTOR_TO_NON_CONCURRENT } diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction/in/A.java new file mode 100644 index 00000000..689a533b --- /dev/null +++ b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction/in/A.java @@ -0,0 +1,33 @@ +package p; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import edu.cuny.hunter.streamrefactoring.annotations.*; +import p.A.Widget.Color; + +public class A { + + static class Widget { + enum Color { + RED, BLUE, GREEN, PINK, ORANGE, YELLOW + }; + + public Color getColor() { + return this.getColor(); + } + } + + /** + * P6 in table 3 + */ + @EntryPoint + void m() { + Collection orderedWidgets = new ArrayList<>(); + Map> widgetsByColor = orderedWidgets.stream() + .collect(Collectors.groupingByConcurrent(Widget::getColor)); + } +} diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction1/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction1/in/A.java new file mode 100644 index 00000000..ccb9917a --- /dev/null +++ b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction1/in/A.java @@ -0,0 +1,33 @@ +package p; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import edu.cuny.hunter.streamrefactoring.annotations.*; +import p.A.Widget.Color; + +public class A { + + static class Widget { + enum Color { + RED, BLUE, GREEN, PINK, ORANGE, YELLOW + }; + + public Color getColor() { + return this.getColor(); + } + } + + /** + * P7 in table 3 + */ + @EntryPoint + void m() { + Collection orderedWidgets = new ArrayList<>(); + Map> widgetsByColor = orderedWidgets.parallelStream() + .collect(Collectors.groupingBy(Widget::getColor)); + } +} diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction2/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction2/in/A.java new file mode 100644 index 00000000..88f967f4 --- /dev/null +++ b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction2/in/A.java @@ -0,0 +1,33 @@ +package p; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import edu.cuny.hunter.streamrefactoring.annotations.*; +import p.A.Widget.Color; + +public class A { + + static class Widget { + enum Color { + RED, BLUE, GREEN, PINK, ORANGE, YELLOW + }; + + public Color getColor() { + return this.getColor(); + } + } + + /** + * P8 in table 3 + */ + @EntryPoint + void m() { + Collection orderedWidgets = new ArrayList<>(); + Map> widgetsByColor = orderedWidgets.parallelStream() + .collect(Collectors.groupingByConcurrent(Widget::getColor)); + } +} diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction3/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction3/in/A.java new file mode 100644 index 00000000..c4f4edcf --- /dev/null +++ b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction3/in/A.java @@ -0,0 +1,34 @@ +package p; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import edu.cuny.hunter.streamrefactoring.annotations.*; +import p.A.Widget.Color; + +public class A { + + static class Widget { + enum Color { + RED, BLUE, GREEN, PINK, ORANGE, YELLOW + }; + + public Color getColor() { + return this.getColor(); + } + } + + /** + * P9 in table 3 + */ + @EntryPoint + void m() { + Collection orderedWidgets = new ArrayList<>(); + Map> widgetsByColor = orderedWidgets.stream() + .collect(Collectors.groupingBy(Widget::getColor, HashMap::new, Collectors.toSet())); + } +} diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction4/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction4/in/A.java new file mode 100644 index 00000000..b9d47447 --- /dev/null +++ b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction4/in/A.java @@ -0,0 +1,35 @@ +package p; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import edu.cuny.hunter.streamrefactoring.annotations.*; +import p.A.Widget.Color; + +public class A { + + static class Widget { + enum Color { + RED, BLUE, GREEN, PINK, ORANGE, YELLOW + }; + + public Color getColor() { + return this.getColor(); + } + } + + /** + * P10 in table 3 + */ + @EntryPoint + void m() { + Collection orderedWidgets = new ArrayList<>(); + Map> widgetsByColor = orderedWidgets.stream().collect(Collectors.groupingByConcurrent( + Widget::getColor, ConcurrentHashMap::new, Collectors.toCollection(LinkedHashSet::new))); + } +} diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction5/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction5/in/A.java new file mode 100644 index 00000000..a9b8128b --- /dev/null +++ b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction5/in/A.java @@ -0,0 +1,34 @@ +package p; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import edu.cuny.hunter.streamrefactoring.annotations.*; +import p.A.Widget.Color; + +public class A { + + static class Widget { + enum Color { + RED, BLUE, GREEN, PINK, ORANGE, YELLOW + }; + + public Color getColor() { + return this.getColor(); + } + } + + /** + * P11 in table 3 + */ + @EntryPoint + void m() { + Collection orderedWidgets = new ArrayList<>(); + Map> widgetsByColor = orderedWidgets.parallelStream() + .collect(Collectors.groupingBy(Widget::getColor, HashMap::new, Collectors.toSet())); + } +} diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java index feba9d02..8b7cdaf8 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java @@ -39,6 +39,7 @@ import org.eclipse.jdt.ui.tests.refactoring.RefactoringTest; import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import edu.cuny.hunter.streamrefactoring.core.analysis.CollectorKind; import edu.cuny.hunter.streamrefactoring.core.analysis.ExecutionMode; import edu.cuny.hunter.streamrefactoring.core.analysis.Ordering; import edu.cuny.hunter.streamrefactoring.core.analysis.PreconditionFailure; @@ -288,6 +289,12 @@ private void helper(StreamAnalysisExpectedResult... expectedResults) throws Exce Set orderings = stream.getPossibleOrderings(); assertEquals(errorMessage("orderings", result), result.getExpectedOrderings(), orderings); + + // exceptedCollecterKind is initialized in the excepted result class + if (result.getExceptedCollectorKind() != null) { + CollectorKind collectorKind = stream.getCollectorKind(); + assertEquals(errorMessage("collector kind", result), result.getExceptedCollectorKind(), collectorKind); + } assertEquals(errorMessage("side effects", result), result.isExpectingSideEffects(), stream.hasPossibleSideEffects()); @@ -704,4 +711,73 @@ public void testField() throws Exception { false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } + + /** + * Test #64. Test P6 in table3. + */ + public void testConcurrentReduction() throws Exception { + helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, false, true, + EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT), PreconditionSuccess.P6, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P7 in table 3. + */ + public void testConcurrentReduction1() throws Exception { + helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.PARALLEL), + EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, false, true, + EnumSet.of(TransformationAction.CONVERT_TO_SEQUENTIAL), PreconditionSuccess.P7, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P8 in table 3. + */ + public void testConcurrentReduction2() throws Exception { + HashSet transformations = new HashSet<>(); + transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT); + transformations.add(TransformationAction.CONVERT_TO_SEQUENTIAL); + + helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.PARALLEL), + EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, false, true, transformations, + PreconditionSuccess.P8, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, + Collections.emptySet())); + } + + /** + * Test #64. Test P9 in table 3. + */ + public void testConcurrentReduction3() throws Exception { + HashSet transformations = new HashSet<>(); + transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT); + transformations.add(TransformationAction.CONVERT_TO_PARALLEL); + + helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, false, false, transformations, + PreconditionSuccess.P9, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, + Collections.emptySet())); + } + + /** + * Test #64. Test P10 in table 3. + */ + public void testConcurrentReduction4() throws Exception { + helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, false, false, + EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P10, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P11 in table 3. + */ + public void testConcurrentReduction5() throws Exception { + helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.PARALLEL), + EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, false, false, + EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT), PreconditionSuccess.P11, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + } + } diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java index 51edf6d9..8eecad0c 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java @@ -2,6 +2,7 @@ import java.util.Set; +import edu.cuny.hunter.streamrefactoring.core.analysis.CollectorKind; import edu.cuny.hunter.streamrefactoring.core.analysis.ExecutionMode; import edu.cuny.hunter.streamrefactoring.core.analysis.Ordering; import edu.cuny.hunter.streamrefactoring.core.analysis.PreconditionFailure; @@ -15,6 +16,8 @@ class StreamAnalysisExpectedResult { private Set expectedExecutionModes; private Set expectedOrderings; + + private CollectorKind expectedCollectorKind; private boolean expectingSideEffects; @@ -49,7 +52,25 @@ public StreamAnalysisExpectedResult(String expectedCreation, Set this.expectedStatusSeverity = expectedStatusSeverity; this.expectedFailures = expectedFailures; } + + /** + * Overloading constructor to test complex mutable reduction + */ + public StreamAnalysisExpectedResult(String expectedCreation, Set expectedExecutionModes, + Set expectedOrderings, CollectorKind expectedCollectorKind, boolean expectingSideEffects, + boolean expectingStatefulIntermediateOperation, boolean expectingThatReduceOrderingMatters, + Set expectedActions, PreconditionSuccess expectedPassingPrecondition, + Refactoring expectedRefactoring, int expectedStatusSeverity, Set expectedFailures) { + this(expectedCreation, expectedExecutionModes, expectedOrderings, expectingSideEffects, + expectingStatefulIntermediateOperation, expectingThatReduceOrderingMatters, expectedActions, + expectedPassingPrecondition, expectedRefactoring, expectedStatusSeverity, expectedFailures); + this.expectedCollectorKind = expectedCollectorKind; + } + public CollectorKind getExceptedCollectorKind() { + return expectedCollectorKind; + } + public String getExpectedCreation() { return expectedCreation; } From 1e8395b772a26c72319468d7cb8971b7e2d8b4ab Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Mon, 29 Jan 2018 16:17:29 -0500 Subject: [PATCH 2/9] Re-architect expected result class hierarchy for #64. Really, an excellent example of when to use OOP. --- ...onvertStreamToParallelRefactoringTest.java | 86 ++++++------------- .../tests/StreamAnalysisExpectedResult.java | 56 +++++++----- ...alysisExpectedResultWithCollectorKind.java | 43 ++++++++++ 3 files changed, 102 insertions(+), 83 deletions(-) create mode 100644 edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResultWithCollectorKind.java diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java index 8a63ef03..1e7dd24f 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java @@ -283,48 +283,10 @@ private void helper(StreamAnalysisExpectedResult... expectedResults) throws Exce expectingStreams.size()); Stream stream = expectingStreams.get(0); - - Set executionModes = stream.getPossibleExecutionModes(); - assertEquals(errorMessage("execution mode", result), result.getExpectedExecutionModes(), executionModes); - - Set orderings = stream.getPossibleOrderings(); - assertEquals(errorMessage("orderings", result), result.getExpectedOrderings(), orderings); - - // exceptedCollecterKind is initialized in the excepted result class - if (result.getExceptedCollectorKind() != null) { - CollectorKind collectorKind = stream.getCollectorKind(); - assertEquals(errorMessage("collector kind", result), result.getExceptedCollectorKind(), collectorKind); - } - - assertEquals(errorMessage("side effects", result), result.isExpectingSideEffects(), - stream.hasPossibleSideEffects()); - assertEquals(errorMessage("stateful intermediate operations", result), - result.isExpectingStatefulIntermediateOperation(), - stream.hasPossibleStatefulIntermediateOperations()); - assertEquals(errorMessage("ROM", result), result.isExpectingThatReduceOrderingMatters(), - stream.reduceOrderingPossiblyMatters()); - assertEquals(errorMessage("transformation actions", result), result.getExpectedActions(), - stream.getActions()); - assertEquals(errorMessage("passing precondition", result), result.getExpectedPassingPrecondition(), - stream.getPassingPrecondition()); - assertEquals(errorMessage("refactoring", result), result.getExpectedRefactoring(), stream.getRefactoring()); - assertEquals(errorMessage("status severity", result), result.getExpectedStatusSeverity(), - stream.getStatus().getSeverity()); - - Set actualCodes = Arrays.stream(stream.getStatus().getEntries()).map(e -> e.getCode()) - .collect(Collectors.toSet()); - - Set expectedCodes = result.getExpectedFailures().stream().map(e -> e.getCode()) - .collect(Collectors.toSet()); - - assertEquals(errorMessage("status codes", result), expectedCodes, actualCodes); + result.evaluate(stream); } } - private static String errorMessage(String attribute, StreamAnalysisExpectedResult result) { - return "Unexpected " + attribute + " for " + result.getExpectedCreation() + "."; - } - private void refreshFromLocal() throws CoreException { if (getRoot().exists()) getRoot().getResource().refreshLocal(IResource.DEPTH_INFINITE, null); @@ -759,24 +721,25 @@ public void testField() throws Exception { false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } - + /** * Test #64. Test P6 in table3. */ public void testConcurrentReduction() throws Exception { - helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), - EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, false, true, - EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT), PreconditionSuccess.P6, - Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + false, true, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT), + PreconditionSuccess.P6, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, + Collections.emptySet())); } /** * Test #64. Test P7 in table 3. */ public void testConcurrentReduction1() throws Exception { - helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.PARALLEL), - EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, false, true, - EnumSet.of(TransformationAction.CONVERT_TO_SEQUENTIAL), PreconditionSuccess.P7, + helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, true, EnumSet.of(TransformationAction.CONVERT_TO_SEQUENTIAL), PreconditionSuccess.P7, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); } @@ -788,10 +751,10 @@ public void testConcurrentReduction2() throws Exception { transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT); transformations.add(TransformationAction.CONVERT_TO_SEQUENTIAL); - helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.PARALLEL), - EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, false, true, transformations, - PreconditionSuccess.P8, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, - Collections.emptySet())); + helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + false, true, transformations, PreconditionSuccess.P8, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, + RefactoringStatus.OK, Collections.emptySet())); } /** @@ -802,19 +765,19 @@ public void testConcurrentReduction3() throws Exception { transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT); transformations.add(TransformationAction.CONVERT_TO_PARALLEL); - helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), - EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, false, false, transformations, - PreconditionSuccess.P9, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, - Collections.emptySet())); + helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, false, transformations, PreconditionSuccess.P9, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, + RefactoringStatus.OK, Collections.emptySet())); } /** * Test #64. Test P10 in table 3. */ public void testConcurrentReduction4() throws Exception { - helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), - EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P10, + helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P10, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); } @@ -822,13 +785,12 @@ public void testConcurrentReduction4() throws Exception { * Test #64. Test P11 in table 3. */ public void testConcurrentReduction5() throws Exception { - helper(new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.PARALLEL), - EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, false, false, - EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT), PreconditionSuccess.P11, + helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, false, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT), PreconditionSuccess.P11, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); } - public void testImplicitEntryPoint() throws Exception { helper(new StreamAnalysisExpectedResult("IntStream.of(1)", EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java index 8eecad0c..69b2a057 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java @@ -1,13 +1,17 @@ package edu.cuny.hunter.streamrefactoring.ui.tests; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; import java.util.Set; +import java.util.stream.Collectors; -import edu.cuny.hunter.streamrefactoring.core.analysis.CollectorKind; import edu.cuny.hunter.streamrefactoring.core.analysis.ExecutionMode; import edu.cuny.hunter.streamrefactoring.core.analysis.Ordering; import edu.cuny.hunter.streamrefactoring.core.analysis.PreconditionFailure; import edu.cuny.hunter.streamrefactoring.core.analysis.PreconditionSuccess; import edu.cuny.hunter.streamrefactoring.core.analysis.Refactoring; +import edu.cuny.hunter.streamrefactoring.core.analysis.Stream; import edu.cuny.hunter.streamrefactoring.core.analysis.TransformationAction; class StreamAnalysisExpectedResult { @@ -16,8 +20,6 @@ class StreamAnalysisExpectedResult { private Set expectedExecutionModes; private Set expectedOrderings; - - private CollectorKind expectedCollectorKind; private boolean expectingSideEffects; @@ -52,25 +54,7 @@ public StreamAnalysisExpectedResult(String expectedCreation, Set this.expectedStatusSeverity = expectedStatusSeverity; this.expectedFailures = expectedFailures; } - - /** - * Overloading constructor to test complex mutable reduction - */ - public StreamAnalysisExpectedResult(String expectedCreation, Set expectedExecutionModes, - Set expectedOrderings, CollectorKind expectedCollectorKind, boolean expectingSideEffects, - boolean expectingStatefulIntermediateOperation, boolean expectingThatReduceOrderingMatters, - Set expectedActions, PreconditionSuccess expectedPassingPrecondition, - Refactoring expectedRefactoring, int expectedStatusSeverity, Set expectedFailures) { - this(expectedCreation, expectedExecutionModes, expectedOrderings, expectingSideEffects, - expectingStatefulIntermediateOperation, expectingThatReduceOrderingMatters, expectedActions, - expectedPassingPrecondition, expectedRefactoring, expectedStatusSeverity, expectedFailures); - this.expectedCollectorKind = expectedCollectorKind; - } - public CollectorKind getExceptedCollectorKind() { - return expectedCollectorKind; - } - public String getExpectedCreation() { return expectedCreation; } @@ -114,4 +98,34 @@ public int getExpectedStatusSeverity() { public Set getExpectedFailures() { return expectedFailures; } + + public void evaluate(Stream stream) { + Set executionModes = stream.getPossibleExecutionModes(); + assertEquals(errorMessage("execution mode"), this.getExpectedExecutionModes(), executionModes); + + Set orderings = stream.getPossibleOrderings(); + assertEquals(errorMessage("orderings"), this.getExpectedOrderings(), orderings); + + assertEquals(errorMessage("side effects"), isExpectingSideEffects(), stream.hasPossibleSideEffects()); + assertEquals(errorMessage("stateful intermediate operations"), isExpectingStatefulIntermediateOperation(), + stream.hasPossibleStatefulIntermediateOperations()); + assertEquals(errorMessage("ROM"), isExpectingThatReduceOrderingMatters(), + stream.reduceOrderingPossiblyMatters()); + assertEquals(errorMessage("transformation actions"), getExpectedActions(), stream.getActions()); + assertEquals(errorMessage("passing precondition"), getExpectedPassingPrecondition(), + stream.getPassingPrecondition()); + assertEquals(errorMessage("refactoring"), getExpectedRefactoring(), stream.getRefactoring()); + assertEquals(errorMessage("status severity"), getExpectedStatusSeverity(), stream.getStatus().getSeverity()); + + Set actualCodes = Arrays.stream(stream.getStatus().getEntries()).map(e -> e.getCode()) + .collect(Collectors.toSet()); + + Set expectedCodes = getExpectedFailures().stream().map(e -> e.getCode()).collect(Collectors.toSet()); + + assertEquals(errorMessage("status codes"), expectedCodes, actualCodes); + } + + protected String errorMessage(String attribute) { + return "Unexpected " + attribute + " for " + this.getExpectedCreation() + "."; + } } diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResultWithCollectorKind.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResultWithCollectorKind.java new file mode 100644 index 00000000..3f712af0 --- /dev/null +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResultWithCollectorKind.java @@ -0,0 +1,43 @@ +package edu.cuny.hunter.streamrefactoring.ui.tests; + +import static org.junit.Assert.assertEquals; + +import java.util.Set; + +import edu.cuny.hunter.streamrefactoring.core.analysis.CollectorKind; +import edu.cuny.hunter.streamrefactoring.core.analysis.ExecutionMode; +import edu.cuny.hunter.streamrefactoring.core.analysis.Ordering; +import edu.cuny.hunter.streamrefactoring.core.analysis.PreconditionFailure; +import edu.cuny.hunter.streamrefactoring.core.analysis.PreconditionSuccess; +import edu.cuny.hunter.streamrefactoring.core.analysis.Refactoring; +import edu.cuny.hunter.streamrefactoring.core.analysis.Stream; +import edu.cuny.hunter.streamrefactoring.core.analysis.TransformationAction; + +public class StreamAnalysisExpectedResultWithCollectorKind extends StreamAnalysisExpectedResult { + + private CollectorKind expectedCollectorKind; + + public StreamAnalysisExpectedResultWithCollectorKind(String expectedCreation, + Set expectedExecutionModes, Set expectedOrderings, + CollectorKind expectedCollectorKind, boolean expectingSideEffects, + boolean expectingStatefulIntermediateOperation, boolean expectingThatReduceOrderingMatters, + Set expectedActions, PreconditionSuccess expectedPassingPrecondition, + Refactoring expectedRefactoring, int expectedStatusSeverity, Set expectedFailures) { + super(expectedCreation, expectedExecutionModes, expectedOrderings, expectingSideEffects, + expectingStatefulIntermediateOperation, expectingThatReduceOrderingMatters, expectedActions, + expectedPassingPrecondition, expectedRefactoring, expectedStatusSeverity, expectedFailures); + this.expectedCollectorKind = expectedCollectorKind; + } + + @Override + public void evaluate(Stream stream) { + super.evaluate(stream); + + CollectorKind collectorKind = stream.getCollectorKind(); + assertEquals(this.errorMessage("collector kind"), this.getExpectedCollectorKind(), collectorKind); + } + + public CollectorKind getExpectedCollectorKind() { + return this.expectedCollectorKind; + } +} From e0501c3388bd15194cae1817683d2171490d67f2 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Mon, 29 Jan 2018 16:20:38 -0500 Subject: [PATCH 3/9] Clean up. --- ...onvertStreamToParallelRefactoringTest.java | 606 +++++++++--------- .../tests/StreamAnalysisExpectedResult.java | 110 ++-- 2 files changed, 361 insertions(+), 355 deletions(-) diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java index 1e7dd24f..a205361d 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java @@ -9,7 +9,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; @@ -59,18 +58,18 @@ @SuppressWarnings("restriction") public class ConvertStreamToParallelRefactoringTest extends RefactoringTest { - /** - * The name of the directory containing resources under the project directory. - */ - private static final String RESOURCE_PATH = "resources"; - private static final Class CLAZZ = ConvertStreamToParallelRefactoringTest.class; private static final Logger LOGGER = Logger.getLogger(CLAZZ.getName()); + private static final int MAX_RETRY = 5; + private static final String REFACTORING_PATH = "ConvertStreamToParallel/"; - private static final int MAX_RETRY = 5; + /** + * The name of the directory containing resources under the project directory. + */ + private static final String RESOURCE_PATH = "resources"; private static final int RETRY_DELAY = 1000; @@ -135,8 +134,8 @@ public static Test suite() { private static void tryDeletingAllJavaClassFiles(IPackageFragment pack) throws JavaModelException { IJavaElement[] kids = pack.getChildren(); - for (int i = 0; i < kids.length; i++) { - if (kids[i] instanceof ISourceManipulation) { + for (int i = 0; i < kids.length; i++) + if (kids[i] instanceof ISourceManipulation) if (kids[i].exists() && !kids[i].isReadOnly()) { IPath path = kids[i].getPath(); @@ -175,8 +174,6 @@ private static void tryDeletingAllJavaClassFiles(IPackageFragment pack) throws J "Class file for " + kids[i].getElementName() + " does not exist.", e); } } - } - } } public ConvertStreamToParallelRefactoringTest(String name) { @@ -209,8 +206,8 @@ protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cu @Override protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cuName, boolean input) throws Exception { - String contents = input ? getFileContents(getInputTestFileName(cuName)) - : getFileContents(getOutputTestFileName(cuName)); + String contents = input ? this.getFileContents(this.getInputTestFileName(cuName)) + : this.getFileContents(this.getOutputTestFileName(cuName)); return createCU(pack, cuName + ".java", contents); } @@ -231,7 +228,7 @@ private Path getAbsolutionPath(String fileName) { */ @Override public String getFileContents(String fileName) throws IOException { - Path absolutePath = getAbsolutionPath(fileName); + Path absolutePath = this.getAbsolutionPath(fileName); byte[] encoded = Files.readAllBytes(absolutePath); return new String(encoded, Charset.defaultCharset()); } @@ -250,7 +247,7 @@ public String getRefactoringPath() { */ private void helper(StreamAnalysisExpectedResult... expectedResults) throws Exception { // compute the actual results. - ICompilationUnit cu = createCUfromTestFile(getPackageP(), "A"); + ICompilationUnit cu = this.createCUfromTestFile(this.getPackageP(), "A"); ASTParser parser = ASTParser.newParser(AST.JLS8); parser.setResolveBindings(true); @@ -288,103 +285,229 @@ private void helper(StreamAnalysisExpectedResult... expectedResults) throws Exce } private void refreshFromLocal() throws CoreException { - if (getRoot().exists()) - getRoot().getResource().refreshLocal(IResource.DEPTH_INFINITE, null); - else if (getPackageP().exists())// don't refresh package if root already - // refreshed - getPackageP().getResource().refreshLocal(IResource.DEPTH_INFINITE, null); + if (this.getRoot().exists()) + this.getRoot().getResource().refreshLocal(IResource.DEPTH_INFINITE, null); + else if (this.getPackageP().exists())// don't refresh package if root already + // refreshed + this.getPackageP().getResource().refreshLocal(IResource.DEPTH_INFINITE, null); } public void setFileContents(String fileName, String contents) throws IOException { - Path absolutePath = getAbsolutionPath(fileName); + Path absolutePath = this.getAbsolutionPath(fileName); Files.write(absolutePath, contents.getBytes()); } @Override protected void tearDown() throws Exception { - refreshFromLocal(); - performDummySearch(); + this.refreshFromLocal(); + this.performDummySearch(); - final boolean pExists = getPackageP().exists(); + final boolean pExists = this.getPackageP().exists(); if (pExists) - tryDeletingAllJavaClassFiles(getPackageP()); + tryDeletingAllJavaClassFiles(this.getPackageP()); super.tearDown(); } + /** + * 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 { + this.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); + } + /** * Test #34. */ public void testArraysAsList() throws Exception { - helper(new StreamAnalysisExpectedResult("Arrays.asList().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + this.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())); } - public void testEntrySet() throws Exception { - helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), - EnumSet.of(Ordering.UNORDERED), false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, + /** + * Test #80. + */ + public void testArraysStream() throws Exception { + this.helper(new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", + 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())); } - public void testEntrySet2() throws Exception { - helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", null, null, false, false, false, null, null, - null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + public void testBitSet() throws Exception { + this.helper(new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.ORDERED), false, false, false, + Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } - public void testEntrySet3() throws Exception { - helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", null, null, false, false, false, null, null, - null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + public void testCollectionFromParameter() throws Exception { + this.helper(new StreamAnalysisExpectedResult("h.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, + false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); } - public void testEntrySet4() throws Exception { - helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), - EnumSet.of(Ordering.UNORDERED), true, false, false, null, null, null, RefactoringStatus.ERROR, - EnumSet.of(PreconditionFailure.NON_DETERMINABLE_REDUCTION_ORDERING))); + public void testCollectionFromParameter2() throws Exception { + this.helper(new StreamAnalysisExpectedResult("h.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, + false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); } /** - * Test #80. + * Test for #98. */ - public void testArraysStream() throws Exception { - helper(new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", - 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())); + public void testCollectionFromParameter3() throws Exception { + this.helper(new StreamAnalysisExpectedResult("h.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, + false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); + } + + /** + * Test for #98. Ordering.ORDERED because we are falling back. + */ + public void testCollectionFromParameter4() throws Exception { + this.helper( + new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), + Collections.singleton(Ordering.ORDERED), false, false, false, null, null, null, + RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.STREAM_CODE_NOT_REACHABLE))); + } + + // Test #65, + public void testConcat() throws Exception { + this.helper(new StreamAnalysisExpectedResult( + "concat(new HashSet().parallelStream(),new HashSet().parallelStream())", + EnumSet.of(ExecutionMode.SEQUENTIAL), null, false, false, false, null, null, null, + RefactoringStatus.ERROR, Collections.singleton(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + } + + /** + * Test #64. Test P6 in table3. + */ + public void testConcurrentReduction() throws Exception { + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + false, true, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT), + PreconditionSuccess.P6, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, + Collections.emptySet())); + } + + /** + * Test #64. Test P7 in table 3. + */ + public void testConcurrentReduction1() throws Exception { + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, true, EnumSet.of(TransformationAction.CONVERT_TO_SEQUENTIAL), PreconditionSuccess.P7, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P8 in table 3. + */ + public void testConcurrentReduction2() throws Exception { + HashSet transformations = new HashSet<>(); + transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT); + transformations.add(TransformationAction.CONVERT_TO_SEQUENTIAL); + + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + false, true, transformations, PreconditionSuccess.P8, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, + RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P9 in table 3. + */ + public void testConcurrentReduction3() throws Exception { + HashSet transformations = new HashSet<>(); + transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT); + transformations.add(TransformationAction.CONVERT_TO_PARALLEL); + + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, false, transformations, PreconditionSuccess.P9, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, + RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P10 in table 3. + */ + public void testConcurrentReduction4() throws Exception { + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P10, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P11 in table 3. + */ + public void testConcurrentReduction5() throws Exception { + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, false, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT), PreconditionSuccess.P11, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); } public void testConstructor() throws Exception { - helper(new StreamAnalysisExpectedResult("new ArrayList().stream()", + this.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())); } - /** - * 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 testDoubleStreamOf() throws Exception { + this.helper(new StreamAnalysisExpectedResult("DoubleStream.of(1.111)", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, + false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); + } - public void testBitSet() throws Exception { - helper(new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.ORDERED), false, false, false, - Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, + public void testEntrySet() throws Exception { + this.helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + EnumSet.of(Ordering.UNORDERED), false, false, false, + EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); + } + + public void testEntrySet2() throws Exception { + this.helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", null, null, false, false, false, null, + null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + } + + public void testEntrySet3() throws Exception { + this.helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", null, null, false, false, false, null, + null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + } + + public void testEntrySet4() throws Exception { + this.helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + EnumSet.of(Ordering.UNORDERED), true, false, false, null, null, null, RefactoringStatus.ERROR, + EnumSet.of(PreconditionFailure.NON_DETERMINABLE_REDUCTION_ORDERING))); + } + + /** + * Test #125. A test case that includes a field. + */ + public void testField() throws Exception { + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, true, + false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } @@ -394,98 +517,126 @@ public void testBitSet() throws Exception { * @throws Exception */ public void testGenerate() throws Exception { - helper(new StreamAnalysisExpectedResult("Stream.generate(() -> 1)", + this.helper(new StreamAnalysisExpectedResult("Stream.generate(() -> 1)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } - public void testIntStreamGenerate() throws Exception { - helper(new StreamAnalysisExpectedResult("IntStream.generate(() -> 1)", - Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, - false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); + public void testHashSetParallelStream() throws Exception { + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, + false, null, null, null, RefactoringStatus.ERROR, + Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); + } + public void testHashSetParallelStream2() throws Exception { + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, + false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); } - public void testStreamOf() throws Exception { - helper(new StreamAnalysisExpectedResult("Stream.of(\"a\")", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.ORDERED), false, false, false, - Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); + public void testImplicitEntryPoint() throws Exception { + this.helper(new StreamAnalysisExpectedResult("IntStream.of(1)", 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())); + } + public void testIntermediateOperations() throws Exception { + this.helper(new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.ORDERED), false, true, false, + EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), + PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, + Collections.emptySet())); } - public void testIntStreamOf() throws Exception { - helper(new StreamAnalysisExpectedResult("IntStream.of(1)", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.ORDERED), false, false, false, - Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, + public void testIntStreamGenerate() throws Exception { + this.helper(new StreamAnalysisExpectedResult("IntStream.generate(() -> 1)", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, + false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } - public void testLongStreamOf() throws Exception { - helper(new StreamAnalysisExpectedResult("LongStream.of(1111)", Collections.singleton(ExecutionMode.SEQUENTIAL), + public void testIntStreamOf() throws Exception { + this.helper(new StreamAnalysisExpectedResult("IntStream.of(1)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } - public void testDoubleStreamOf() throws Exception { - helper(new StreamAnalysisExpectedResult("DoubleStream.of(1.111)", + public void testLongStreamOf() throws Exception { + this.helper(new StreamAnalysisExpectedResult("LongStream.of(1111)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } + public void testMotivatingExample() throws Exception { + this.helper(new StreamAnalysisExpectedResult("unorderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + EnumSet.of(Ordering.ORDERED), false, false, true, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), + PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, + Collections.emptySet()), + + new StreamAnalysisExpectedResult("orderedWidgets.parallelStream()", EnumSet.of(ExecutionMode.PARALLEL), + EnumSet.of(Ordering.ORDERED), false, false, false, null, null, null, RefactoringStatus.ERROR, + EnumSet.of(PreconditionFailure.NO_STATEFUL_INTERMEDIATE_OPERATIONS)), + + new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + EnumSet.of(Ordering.ORDERED), false, true, true, null, null, null, RefactoringStatus.ERROR, + EnumSet.of(PreconditionFailure.REDUCE_ORDERING_MATTERS))); + } + public void testMultipleCallsToEnclosingMethod() throws Exception { - helper(new StreamAnalysisExpectedResult("DoubleStream.of(1.111)", + this.helper(new StreamAnalysisExpectedResult("DoubleStream.of(1.111)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } - public void testHashSetParallelStream() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", - Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, - false, null, null, null, RefactoringStatus.ERROR, - Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); - } - - public void testHashSetParallelStream2() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", - Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, - false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); - } - - // Test #65, - public void testConcat() throws Exception { - helper(new StreamAnalysisExpectedResult("concat(new HashSet().parallelStream(),new HashSet().parallelStream())", - EnumSet.of(ExecutionMode.SEQUENTIAL), null, false, false, false, null, null, null, - RefactoringStatus.ERROR, Collections.singleton(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + /** + * Test #122. + */ + public void testMultipleEntryPoints() throws Exception { + this.helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.UNORDERED), false, false, false, + EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } /** * This should change once #103 is fixed. */ public void testNonInternalAPI() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); } + /** + * Related to #126. Suggested by @mbagherz. + */ + public void testNonInternalAPI10() throws Exception { + this.helper(new StreamAnalysisExpectedResult("new HashSet().stream()", + Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, true, false, + EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), + PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, + Collections.emptySet())); + } + public void testNonInternalAPI2() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, true, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } public void testNonInternalAPI3() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, true, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); @@ -499,7 +650,7 @@ public void testNonInternalAPI4() throws Exception { orderings.add(Ordering.UNORDERED); orderings.add(Ordering.ORDERED); - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), orderings, false, true, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.INCONSISTENT_POSSIBLE_ORDERINGS))); } @@ -511,7 +662,7 @@ public void testNonInternalAPI5() throws Exception { HashSet executionModes = new HashSet<>(); executionModes.add(ExecutionMode.PARALLEL); executionModes.add(ExecutionMode.SEQUENTIAL); - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", executionModes, + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", executionModes, Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.INCONSISTENT_POSSIBLE_EXECUTION_MODES))); } @@ -523,7 +674,7 @@ public void testNonInternalAPI6() throws Exception { HashSet executionModes = new HashSet<>(); executionModes.add(ExecutionMode.PARALLEL); executionModes.add(ExecutionMode.SEQUENTIAL); - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", executionModes, + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", executionModes, Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.INCONSISTENT_POSSIBLE_EXECUTION_MODES))); } @@ -533,7 +684,7 @@ public void testNonInternalAPI6() throws Exception { * Related to #126. */ public void testNonInternalAPI7() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, true, false, EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, @@ -546,7 +697,7 @@ public void testNonInternalAPI7() throws Exception { * operation is called. */ public void testNonInternalAPI8() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, true, false, EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, @@ -561,98 +712,39 @@ public void testNonInternalAPI9() throws Exception { orderings.add(Ordering.UNORDERED); orderings.add(Ordering.ORDERED); - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), orderings, false, true, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.INCONSISTENT_POSSIBLE_ORDERINGS))); } /** - * Related to #126. Suggested by @mbagherz. - */ - public void testNonInternalAPI10() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet().stream()", - Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, true, false, - EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), - PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, - Collections.emptySet())); - } - - public void testCollectionFromParameter() throws Exception { - helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), - Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); - } - - public void testCollectionFromParameter2() throws Exception { - helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), - Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); - } - - /** - * Test for #98. - */ - public void testCollectionFromParameter3() throws Exception { - helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), - Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); - } - - /** - * Test for #98. Ordering.ORDERED because we are falling back. + * Test #122. Remove an annotation from testMultipleEntryPoints(). */ - public void testCollectionFromParameter4() throws Exception { - helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), - Collections.singleton(Ordering.ORDERED), false, false, false, null, null, null, RefactoringStatus.ERROR, - EnumSet.of(PreconditionFailure.STREAM_CODE_NOT_REACHABLE))); + public void testOneEntryPoint() throws Exception { + this.helper(new StreamAnalysisExpectedResult("h2.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.UNORDERED), false, false, false, + EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } public void testStaticInitializer() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", null, null, false, false, false, - null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); - } - - public void testIntermediateOperations() throws Exception { - helper(new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.ORDERED), false, true, false, - EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), - PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, - Collections.emptySet())); - } - - public void testTypeResolution() throws Exception { - helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", - Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, - false, null, null, null, RefactoringStatus.ERROR, - Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); - } - - public void testTypeResolution2() throws Exception { - helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", - Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", null, null, false, false, false, null, null, null, RefactoringStatus.ERROR, - Collections.singleton(PreconditionFailure.UNORDERED))); + EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); } - public void testMotivatingExample() throws Exception { - helper(new StreamAnalysisExpectedResult("unorderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), - EnumSet.of(Ordering.ORDERED), false, false, true, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), - PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, - Collections.emptySet()), - - new StreamAnalysisExpectedResult("orderedWidgets.parallelStream()", EnumSet.of(ExecutionMode.PARALLEL), - EnumSet.of(Ordering.ORDERED), false, false, false, null, null, null, RefactoringStatus.ERROR, - EnumSet.of(PreconditionFailure.NO_STATEFUL_INTERMEDIATE_OPERATIONS)), + public void testStreamOf() throws Exception { + this.helper(new StreamAnalysisExpectedResult("Stream.of(\"a\")", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, + false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - new StreamAnalysisExpectedResult("orderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), - EnumSet.of(Ordering.ORDERED), false, true, true, null, null, null, RefactoringStatus.ERROR, - EnumSet.of(PreconditionFailure.REDUCE_ORDERING_MATTERS))); } public void testTerminalOp1() throws Exception { - helper(new StreamAnalysisExpectedResult("collection1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, - Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, + this.helper(new StreamAnalysisExpectedResult("collection1.stream()", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, + false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet()), new StreamAnalysisExpectedResult("collection2.stream()", @@ -662,9 +754,11 @@ public void testTerminalOp1() throws Exception { } public void testTerminalOp2() throws Exception { - helper(new StreamAnalysisExpectedResult("collection1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, null, null, null, - RefactoringStatus.ERROR, Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS)), + this.helper( + new StreamAnalysisExpectedResult("collection1.stream()", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), + false, false, false, null, null, null, RefactoringStatus.ERROR, + Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS)), new StreamAnalysisExpectedResult("collection2.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), @@ -674,9 +768,11 @@ public void testTerminalOp2() throws Exception { } public void testTerminalOp3() throws Exception { - helper(new StreamAnalysisExpectedResult("collection1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, null, null, null, - RefactoringStatus.ERROR, Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS)), + this.helper( + new StreamAnalysisExpectedResult("collection1.stream()", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), + false, false, false, null, null, null, RefactoringStatus.ERROR, + Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS)), new StreamAnalysisExpectedResult("collection2.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), @@ -684,117 +780,25 @@ public void testTerminalOp3() throws Exception { Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); } - /** - * Test #119. - */ - public void testWithoutEntryPoint() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); - } - - /** - * Test #122. - */ - public void testMultipleEntryPoints() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #122. Remove an annotation from testMultipleEntryPoints(). - */ - public void testOneEntryPoint() throws Exception { - helper(new StreamAnalysisExpectedResult("h2.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #125. A test case that includes a field. - */ - public void testField() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", - Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, true, - false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #64. Test P6 in table3. - */ - public void testConcurrentReduction() throws Exception { - helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", - EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, - false, true, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT), - PreconditionSuccess.P6, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, - Collections.emptySet())); - } - - /** - * Test #64. Test P7 in table 3. - */ - public void testConcurrentReduction1() throws Exception { - helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", - EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, - false, true, EnumSet.of(TransformationAction.CONVERT_TO_SEQUENTIAL), PreconditionSuccess.P7, - Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #64. Test P8 in table 3. - */ - public void testConcurrentReduction2() throws Exception { - HashSet transformations = new HashSet<>(); - transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT); - transformations.add(TransformationAction.CONVERT_TO_SEQUENTIAL); - - helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", - EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, - false, true, transformations, PreconditionSuccess.P8, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, - RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #64. Test P9 in table 3. - */ - public void testConcurrentReduction3() throws Exception { - HashSet transformations = new HashSet<>(); - transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT); - transformations.add(TransformationAction.CONVERT_TO_PARALLEL); - - helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", - EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, - false, false, transformations, PreconditionSuccess.P9, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, - RefactoringStatus.OK, Collections.emptySet())); + public void testTypeResolution() throws Exception { + this.helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, + false, null, null, null, RefactoringStatus.ERROR, + Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); } - /** - * Test #64. Test P10 in table 3. - */ - public void testConcurrentReduction4() throws Exception { - helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", - EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, - false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P10, - Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + public void testTypeResolution2() throws Exception { + this.helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, + false, null, null, null, RefactoringStatus.ERROR, + Collections.singleton(PreconditionFailure.UNORDERED))); } /** - * Test #64. Test P11 in table 3. + * Test #119. */ - public void testConcurrentReduction5() throws Exception { - helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", - EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, - false, false, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT), PreconditionSuccess.P11, - Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); - } - - public void testImplicitEntryPoint() throws Exception { - helper(new StreamAnalysisExpectedResult("IntStream.of(1)", 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())); + public void testWithoutEntryPoint() throws Exception { + this.helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, + RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); } } diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java index 69b2a057..12429f29 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java @@ -15,19 +15,15 @@ import edu.cuny.hunter.streamrefactoring.core.analysis.TransformationAction; class StreamAnalysisExpectedResult { + private Set expectedActions; + private String expectedCreation; private Set expectedExecutionModes; - private Set expectedOrderings; - - private boolean expectingSideEffects; - - private boolean expectingStatefulIntermediateOperation; - - private boolean expectingThatReduceOrderingMatters; + private Set expectedFailures; - private Set expectedActions; + private Set expectedOrderings; private PreconditionSuccess expectedPassingPrecondition; @@ -35,7 +31,11 @@ class StreamAnalysisExpectedResult { private int expectedStatusSeverity; - private Set expectedFailures; + private boolean expectingSideEffects; + + private boolean expectingStatefulIntermediateOperation; + + private boolean expectingThatReduceOrderingMatters; public StreamAnalysisExpectedResult(String expectedCreation, Set expectedExecutionModes, Set expectedOrderings, boolean expectingSideEffects, @@ -55,77 +55,79 @@ public StreamAnalysisExpectedResult(String expectedCreation, Set this.expectedFailures = expectedFailures; } - public String getExpectedCreation() { - return expectedCreation; + protected String errorMessage(String attribute) { + return "Unexpected " + attribute + " for " + this.getExpectedCreation() + "."; } - public Set getExpectedExecutionModes() { - return expectedExecutionModes; + public void evaluate(Stream stream) { + Set executionModes = stream.getPossibleExecutionModes(); + assertEquals(this.errorMessage("execution mode"), this.getExpectedExecutionModes(), executionModes); + + Set orderings = stream.getPossibleOrderings(); + assertEquals(this.errorMessage("orderings"), this.getExpectedOrderings(), orderings); + + assertEquals(this.errorMessage("side effects"), this.isExpectingSideEffects(), stream.hasPossibleSideEffects()); + assertEquals(this.errorMessage("stateful intermediate operations"), + this.isExpectingStatefulIntermediateOperation(), stream.hasPossibleStatefulIntermediateOperations()); + assertEquals(this.errorMessage("ROM"), this.isExpectingThatReduceOrderingMatters(), + stream.reduceOrderingPossiblyMatters()); + assertEquals(this.errorMessage("transformation actions"), this.getExpectedActions(), stream.getActions()); + assertEquals(this.errorMessage("passing precondition"), this.getExpectedPassingPrecondition(), + stream.getPassingPrecondition()); + assertEquals(this.errorMessage("refactoring"), this.getExpectedRefactoring(), stream.getRefactoring()); + assertEquals(this.errorMessage("status severity"), this.getExpectedStatusSeverity(), + stream.getStatus().getSeverity()); + + Set actualCodes = Arrays.stream(stream.getStatus().getEntries()).map(e -> e.getCode()) + .collect(Collectors.toSet()); + + Set expectedCodes = this.getExpectedFailures().stream().map(e -> e.getCode()) + .collect(Collectors.toSet()); + + assertEquals(this.errorMessage("status codes"), expectedCodes, actualCodes); } - public Set getExpectedOrderings() { - return expectedOrderings; + public Set getExpectedActions() { + return this.expectedActions; } - public boolean isExpectingSideEffects() { - return expectingSideEffects; + public String getExpectedCreation() { + return this.expectedCreation; } - public boolean isExpectingStatefulIntermediateOperation() { - return expectingStatefulIntermediateOperation; + public Set getExpectedExecutionModes() { + return this.expectedExecutionModes; } - public boolean isExpectingThatReduceOrderingMatters() { - return expectingThatReduceOrderingMatters; + public Set getExpectedFailures() { + return this.expectedFailures; } - public Set getExpectedActions() { - return expectedActions; + public Set getExpectedOrderings() { + return this.expectedOrderings; } public PreconditionSuccess getExpectedPassingPrecondition() { - return expectedPassingPrecondition; + return this.expectedPassingPrecondition; } public Refactoring getExpectedRefactoring() { - return expectedRefactoring; + return this.expectedRefactoring; } public int getExpectedStatusSeverity() { - return expectedStatusSeverity; + return this.expectedStatusSeverity; } - public Set getExpectedFailures() { - return expectedFailures; + public boolean isExpectingSideEffects() { + return this.expectingSideEffects; } - public void evaluate(Stream stream) { - Set executionModes = stream.getPossibleExecutionModes(); - assertEquals(errorMessage("execution mode"), this.getExpectedExecutionModes(), executionModes); - - Set orderings = stream.getPossibleOrderings(); - assertEquals(errorMessage("orderings"), this.getExpectedOrderings(), orderings); - - assertEquals(errorMessage("side effects"), isExpectingSideEffects(), stream.hasPossibleSideEffects()); - assertEquals(errorMessage("stateful intermediate operations"), isExpectingStatefulIntermediateOperation(), - stream.hasPossibleStatefulIntermediateOperations()); - assertEquals(errorMessage("ROM"), isExpectingThatReduceOrderingMatters(), - stream.reduceOrderingPossiblyMatters()); - assertEquals(errorMessage("transformation actions"), getExpectedActions(), stream.getActions()); - assertEquals(errorMessage("passing precondition"), getExpectedPassingPrecondition(), - stream.getPassingPrecondition()); - assertEquals(errorMessage("refactoring"), getExpectedRefactoring(), stream.getRefactoring()); - assertEquals(errorMessage("status severity"), getExpectedStatusSeverity(), stream.getStatus().getSeverity()); - - Set actualCodes = Arrays.stream(stream.getStatus().getEntries()).map(e -> e.getCode()) - .collect(Collectors.toSet()); - - Set expectedCodes = getExpectedFailures().stream().map(e -> e.getCode()).collect(Collectors.toSet()); - - assertEquals(errorMessage("status codes"), expectedCodes, actualCodes); + public boolean isExpectingStatefulIntermediateOperation() { + return this.expectingStatefulIntermediateOperation; } - protected String errorMessage(String attribute) { - return "Unexpected " + attribute + " for " + this.getExpectedCreation() + "."; + public boolean isExpectingThatReduceOrderingMatters() { + return this.expectingThatReduceOrderingMatters; } } From cf612b89b17433a4ed6d2c2846c674c57f34d817 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Tue, 30 Jan 2018 11:17:13 -0500 Subject: [PATCH 4/9] Remove FQN. --- .../edu/cuny/hunter/streamrefactoring/core/analysis/Util.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java index 4fd9b923..88f90ee9 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java @@ -598,8 +598,7 @@ else if (typeReference.isPrimitiveType()) return true; else if (typeReference.isReferenceType()) { IClass type = typeAbstraction.getType(); - return !edu.cuny.hunter.streamrefactoring.core.analysis.Util.isIterable(type) - && type.getAllImplementedInterfaces().stream().noneMatch(Util::isIterable); + return !isIterable(type) && type.getAllImplementedInterfaces().stream().noneMatch(Util::isIterable); } else throw new IllegalArgumentException("Can't tell if type is scalar: " + typeAbstraction); } From 359975660ac7d39aed831226dfea2ea54fcd683d Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Tue, 30 Jan 2018 11:26:47 -0500 Subject: [PATCH 5/9] Enhance log. --- .../streamrefactoring/core/analysis/StreamStateMachine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java index 8f5d7046..7aaa96c4 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java @@ -529,7 +529,7 @@ private boolean deriveRomForNonScalarMethod(Collection possible // default to ordered. ordering = Ordering.ORDERED; LOGGER.warning("Can't determine ordering for possible return types: " + possibleReturnTypes - + ". Defaulting to: " + ordering); + + ". Defaulting to: " + ordering + "."); } switch (ordering) { From 133e1400c8bc373a9485fd59147d845a95336703 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Tue, 6 Feb 2018 15:20:12 -0500 Subject: [PATCH 6/9] Trying to fix testConcurrentReduction() for #64. --- .../testConcurrentReduction/in/A.java | 21 +++++++++++++++---- ...onvertStreamToParallelRefactoringTest.java | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction/in/A.java index 689a533b..6f488557 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction/in/A.java +++ b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testConcurrentReduction/in/A.java @@ -2,18 +2,30 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentNavigableMap; +import java.util.concurrent.ConcurrentSkipListMap; import java.util.stream.Collectors; +import java.util.Set; + +import edu.cuny.hunter.streamrefactoring.annotations.EntryPoint; -import edu.cuny.hunter.streamrefactoring.annotations.*; import p.A.Widget.Color; public class A { static class Widget { enum Color { - RED, BLUE, GREEN, PINK, ORANGE, YELLOW + RED, + BLUE, + GREEN, + PINK, + ORANGE, + YELLOW }; public Color getColor() { @@ -27,7 +39,8 @@ public Color getColor() { @EntryPoint void m() { Collection orderedWidgets = new ArrayList<>(); - Map> widgetsByColor = orderedWidgets.stream() - .collect(Collectors.groupingByConcurrent(Widget::getColor)); + + Map> widgetsByColor2 = orderedWidgets.stream().collect(Collectors.groupingByConcurrent( + Widget::getColor, ConcurrentSkipListMap::new, Collectors.toCollection(LinkedHashSet::new))); } } diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java index a205361d..1e256e42 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java @@ -399,7 +399,7 @@ public void testConcat() throws Exception { */ public void testConcurrentReduction() throws Exception { this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", - EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, true, false, true, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT), PreconditionSuccess.P6, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); From 3cbdd67556ab74b6b6151b6e7f6b5e1cc0bb4476 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Fri, 23 Feb 2018 18:08:10 -0500 Subject: [PATCH 7/9] Revert "Merge branch 'master' into issue_138" This reverts commit 445ab67bc94e772f2512994c477f6a8116583deb, reversing changes made to e1bf90220d4b92f7289b24ea6a339da8bb437795. --- .../core/analysis/StreamAnalyzer.java | 2 +- .../core/analysis/StreamStateMachine.java | 23 ++++++------------- .../wala/EclipseProjectAnalysisEngine.java | 2 +- .../nCFAContextWithReceiversSelector.java | 4 ++-- ...onvertStreamToParallelRefactoringTest.java | 2 +- 5 files changed, 12 insertions(+), 21 deletions(-) diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java index c0a7f217..605fa1c4 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java @@ -189,7 +189,7 @@ public Map> analyze() throws CoreException * @see #analyze(). */ public Map> analyze(Optional collector) throws CoreException { - LOGGER.fine(() -> "Using N = " + this.getNForStreams() + "."); + LOGGER.info(() -> "Using N = " + this.getNForStreams() + "."); Map> ret = new HashMap<>(); diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java index 93717123..7ca8a47a 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java @@ -429,12 +429,6 @@ else if (set2.isEmpty()) return ret; } - private static void outputTypeStateStatistics(AggregateSolverResult result) { - LOGGER.info("Total instances: " + result.totalInstancesNum()); - LOGGER.info("Processed instances: " + result.processedInstancesNum()); - LOGGER.info("Skipped instances: " + result.skippedInstances()); - } - private static IDFAState selectState(IDFAState state1, IDFAState state2) { if (state1.getName().equals(BOTTOM_STATE_NAME)) return state2; @@ -989,9 +983,7 @@ public Map start(Set streamSet, EclipseProjec throw new RuntimeException("Exception caught during typestate analysis.", e); } - // record typestate statistics. - outputTypeStateStatistics(result); - + // record statistics. Statistics lastStatistics = ret.put(rule, new Statistics(result.processedInstancesNum(), result.skippedInstances())); assert lastStatistics == null : "Reassociating statistics."; @@ -1034,9 +1026,9 @@ public Map start(Set streamSet, EclipseProjec // invocations? if (isTerminalOperation(calledMethod)) { // get the basic block for the call. - IR ir = cgNode.getIR(); - ISSABasicBlock[] blocksForCall = ir.getBasicBlocksForCall(callSiteReference); + ISSABasicBlock[] blocksForCall = cgNode.getIR() + .getBasicBlocksForCall(callSiteReference); assert blocksForCall.length == 1 : "Expecting only a single basic block for the call: " + callSiteReference; @@ -1053,12 +1045,11 @@ public Map start(Set streamSet, EclipseProjec // search through each instruction in the // block. int processedInstructions = 0; - for (SSAInstruction instruction : block) { - // if it's not an invoke instruction. - if (!(instruction instanceof SSAAbstractInvokeInstruction)) - // skip it. Phi instructions will be handled by the pointer analysis - // below. + // if it's a phi instruction. + if (instruction instanceof SSAPhiInstruction) + // skip it. The pointer analysis + // below will handle it. continue; // Get the possible receivers. This diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java index 4eca7067..38b7c755 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java @@ -178,7 +178,7 @@ public CallGraphBuilder getCallGraphBuilder() { @Override protected CallGraphBuilder getCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, IAnalysisCacheView cache) { - LOGGER.fine(() -> "Using N = " + this.getNToUseForStreams() + "."); + LOGGER.info(() -> "Using N = " + this.getNToUseForStreams()); return Util.makeNCFABuilder(N, options, (AnalysisCache) cache, cha, scope, this.getNToUseForStreams()); } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java index f95fa46c..c70f2e47 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java @@ -95,7 +95,7 @@ public nCFAContextWithReceiversSelector(int n, ContextSelector base) { */ public nCFAContextWithReceiversSelector(int n, ContextSelector base, int nToUseForStreams) { super(n, base); - LOGGER.fine(() -> "Using N = " + nToUseForStreams + "."); + LOGGER.info(() -> "Using N = " + nToUseForStreams); this.contextLengthForStreams = nToUseForStreams; } @@ -171,7 +171,7 @@ protected int getLength(CGNode caller, CallSiteReference site, IMethod target) { if (implementsBaseStream) { int lengthForStreams = this.getContextLengthForStreams(); - LOGGER.finer(() -> "Using N = " + lengthForStreams + "."); + LOGGER.finer(() -> "Using N = " + lengthForStreams); return lengthForStreams; } else return super.getLength(caller, site, target); diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java index 17f3dacf..d0463f65 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java @@ -327,7 +327,7 @@ public String getRefactoringPath() { * Runs a single analysis test. */ private void helper(int nToUseForStreams, StreamAnalysisExpectedResult... expectedResults) throws Exception { - LOGGER.fine("Using N = " + nToUseForStreams + "."); + LOGGER.info("Using N = " + nToUseForStreams); // compute the actual results. ICompilationUnit cu = this.createCUfromTestFile(this.getPackageP(), "A"); From 3cdac663d9ea901098e782478f39e5ef42179ccb Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Fri, 23 Feb 2018 18:10:33 -0500 Subject: [PATCH 8/9] Revert "Merge branch 'master' into issue_138" This reverts commit e1bf90220d4b92f7289b24ea6a339da8bb437795, reversing changes made to c03b8983430938e57dcd6fa835208b0d90ab0eb5. --- ...annotDetermineStreamOrderingException.java | 10 +- .../CannotExtractSpliteratorException.java | 10 +- .../InstanceKeyNotFoundException.java | 8 +- .../NoEnclosingMethodNodeFoundException.java | 8 +- .../core/analysis/NoEntryPointException.java | 13 +- .../core/analysis/NoniterableException.java | 13 +- .../core/analysis/OrderingInference.java | 202 ++++----- .../core/analysis/PreconditionFailure.java | 17 +- .../core/analysis/Refactoring.java | 2 +- .../core/analysis/Stream.java | 84 ++-- .../core/analysis/StreamAnalyzer.java | 181 ++++---- .../StreamAttributeTypestateRule.java | 46 +- .../StreamCreationNotConsideredException.java | 8 +- .../StreamExecutionModeTypeStateRule.java | 24 +- .../analysis/StreamOrderingTypeStateRule.java | 14 +- .../core/analysis/StreamStateMachine.java | 29 +- .../core/analysis/UnhandledCaseException.java | 8 +- .../UnknownIfReduceOrderMattersException.java | 10 +- .../streamrefactoring/core/analysis/Util.java | 79 ++-- ...reamToParallelRefactoringContribution.java | 14 +- ...StreamToParallelRefactoringDescriptor.java | 14 +- .../core/messages/Messages.java | 150 +++---- ...tToParallelStreamRefactoringProcessor.java | 44 +- .../core/safe/ClientSlicingUniqueSolver.java | 4 +- .../safe/EventTrackingTypeStateProperty.java | 38 +- .../core/safe/InstructionBasedSolver.java | 12 +- .../core/safe/ModifiedBenignOracle.java | 2 +- ...ationCodeExistsInCallStringsException.java | 13 +- .../core/safe/TrackingUniqueSolver.java | 14 +- .../core/safe/TypestateSolverFactory.java | 28 +- .../streamrefactoring/core/safe/Util.java | 4 +- .../core/utils/TimeCollector.java | 22 +- .../core/wala/AnalysisUtils.java | 58 +-- .../core/wala/CallStringWithReceivers.java | 2 +- .../wala/EclipseProjectAnalysisEngine.java | 65 ++- .../wala/TestableJavaEclipseProjectPath.java | 27 +- .../streamrefactoring/core/wala/Util.java | 2 +- ...ABuilderWithActualParametersInContext.java | 10 +- .../nCFAContextWithReceiversSelector.java | 20 +- ...ertToParallelStreamRefactoringHandler.java | 156 ++++--- .../eval/messages/Messages.java | 2 +- .../streamrefactoring/eval/utils/Util.java | 24 +- ...nvertToParllelStreamRefactoringPlugin.java | 4 +- ...onvertStreamToParallelRefactoringTest.java | 406 +++++++++--------- .../tests/StreamAnalysisExpectedResult.java | 30 +- .../ConvertStreamToParallelHandler.java | 86 ++-- .../ui/messages/Messages.java | 2 +- .../OptimizeStreamRefactoringPlugin.java | 25 +- ...vertStreamToParallelRefactoringWizard.java | 30 +- 49 files changed, 999 insertions(+), 1075 deletions(-) diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CannotDetermineStreamOrderingException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CannotDetermineStreamOrderingException.java index 26ac910f..f6f81fbc 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CannotDetermineStreamOrderingException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CannotDetermineStreamOrderingException.java @@ -13,17 +13,17 @@ public CannotDetermineStreamOrderingException(String message, Class sourceTyp super(message); } - public CannotDetermineStreamOrderingException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace, Class sourceType) { - super(message, cause, enableSuppression, writableStackTrace); + public CannotDetermineStreamOrderingException(Throwable cause, Class sourceType) { + super(cause); } public CannotDetermineStreamOrderingException(String message, Throwable cause, Class sourceType) { super(message, cause); } - public CannotDetermineStreamOrderingException(Throwable cause, Class sourceType) { - super(cause); + public CannotDetermineStreamOrderingException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace, Class sourceType) { + super(message, cause, enableSuppression, writableStackTrace); } public Class getSourceType() { diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CannotExtractSpliteratorException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CannotExtractSpliteratorException.java index 76ca4ca9..726b3b26 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CannotExtractSpliteratorException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/CannotExtractSpliteratorException.java @@ -13,9 +13,8 @@ public CannotExtractSpliteratorException(String message, Class this.fromType = fromType; } - public CannotExtractSpliteratorException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); + public CannotExtractSpliteratorException(Throwable cause) { + super(cause); } public CannotExtractSpliteratorException(String message, Throwable cause, Class fromType) { @@ -23,8 +22,9 @@ public CannotExtractSpliteratorException(String message, Throwable cause, Class< this.fromType = fromType; } - public CannotExtractSpliteratorException(Throwable cause) { - super(cause); + public CannotExtractSpliteratorException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); } public Class getFromType() { diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/InstanceKeyNotFoundException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/InstanceKeyNotFoundException.java index e5089109..cbe219bd 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/InstanceKeyNotFoundException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/InstanceKeyNotFoundException.java @@ -11,6 +11,10 @@ public InstanceKeyNotFoundException(String message) { super(message); } + public InstanceKeyNotFoundException(Throwable cause) { + super(cause); + } + public InstanceKeyNotFoundException(String message, Throwable cause) { super(message, cause); } @@ -20,8 +24,4 @@ public InstanceKeyNotFoundException(String message, Throwable cause, boolean ena super(message, cause, enableSuppression, writableStackTrace); } - public InstanceKeyNotFoundException(Throwable cause) { - super(cause); - } - } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoEnclosingMethodNodeFoundException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoEnclosingMethodNodeFoundException.java index a95f0f86..18806820 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoEnclosingMethodNodeFoundException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoEnclosingMethodNodeFoundException.java @@ -16,6 +16,10 @@ public NoEnclosingMethodNodeFoundException(String message) { super(message); } + public NoEnclosingMethodNodeFoundException(Throwable cause) { + super(cause); + } + public NoEnclosingMethodNodeFoundException(String message, Throwable cause) { super(message, cause); } @@ -25,10 +29,6 @@ public NoEnclosingMethodNodeFoundException(String message, Throwable cause, bool super(message, cause, enableSuppression, writableStackTrace); } - public NoEnclosingMethodNodeFoundException(Throwable cause) { - super(cause); - } - public MethodReference getMethodReference() { return this.methodReference; } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoEntryPointException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoEntryPointException.java index 1dcd3a21..cd54e39d 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoEntryPointException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoEntryPointException.java @@ -1,13 +1,8 @@ package edu.cuny.hunter.streamrefactoring.core.analysis; public class NoEntryPointException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 3216982694001353012L; - - public NoEntryPointException(String string) { - super(string); - } + + public NoEntryPointException(String string) { + super(string); + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoniterableException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoniterableException.java index 8ec64c4f..6e5623cd 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoniterableException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/NoniterableException.java @@ -2,11 +2,6 @@ public class NoniterableException extends Exception { - /** - * - */ - private static final long serialVersionUID = 6340319816698688446L; - public NoniterableException() { super(); } @@ -15,6 +10,10 @@ public NoniterableException(String message) { super(message); } + public NoniterableException(Throwable cause) { + super(cause); + } + public NoniterableException(String message, Throwable cause) { super(message, cause); } @@ -23,8 +22,4 @@ public NoniterableException(String message, Throwable cause, boolean enableSuppr boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } - - public NoniterableException(Throwable cause) { - super(cause); - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/OrderingInference.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/OrderingInference.java index 85e99d09..de0e11dd 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/OrderingInference.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/OrderingInference.java @@ -23,102 +23,41 @@ class OrderingInference { - private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); + private Objenesis objenesis = new ObjenesisStd(); private IClassHierarchy classHierarchy; - private Objenesis objenesis = new ObjenesisStd(); + private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); public OrderingInference(IClassHierarchy classHierarchy) { this.classHierarchy = classHierarchy; } - private Object createInstance(Class clazz) throws NoninstantiableException { - try { - return clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - ObjectInstantiator instantiator = objenesis.getInstantiatorOf(clazz); - try { - return instantiator.newInstance(); - } catch (InstantiationError e2) { - throw new NoninstantiableException(clazz + " cannot be instantiated: " + e2.getCause(), e2, clazz); - } - } - } - - private String findStreamCreationMethod(Collection types) { - // find the first one. - for (TypeAbstraction typeAbstraction : types) { - String methodName = findStreamCreationMethod(typeAbstraction); - - if (methodName != null) - return methodName; - } - // not found. - return null; - } - - private String findStreamCreationMethod(IClass type) { - Collection allMethods = type.getAllMethods(); - for (com.ibm.wala.classLoader.IMethod method : allMethods) { - TypeReference typeToCheck = Util.getEvaluationType(method); - - // find the first one that returns a stream. - if (Util.implementsBaseStream(typeToCheck, this.getClassHierarchy())) - return method.getName().toString(); - } - - return null; - } - - private String findStreamCreationMethod(TypeAbstraction typeAbstraction) { - IClass type = typeAbstraction.getType(); - return findStreamCreationMethod(type); - } - - protected IClassHierarchy getClassHierarchy() { - return classHierarchy; + Ordering inferOrdering(Collection possibleTypes, IMethod calledMethod) + throws InconsistentPossibleOrderingException, NoniterableException, NoninstantiableException, + CannotExtractSpliteratorException { + return inferOrdering(possibleTypes, calledMethod.getElementName()); } - private Spliterator getSpliterator(Object instance, String calledMethodName) - throws CannotExtractSpliteratorException { - Objects.requireNonNull(instance); - Objects.requireNonNull(calledMethodName); - - Spliterator spliterator = null; + private Ordering inferOrdering(Collection possibleTypes, String calledMethodName) + throws InconsistentPossibleOrderingException, NoniterableException, NoninstantiableException, + CannotExtractSpliteratorException { + Ordering ret = null; - if (instance instanceof Iterable) { - try { - spliterator = ((Iterable) instance).spliterator(); - } catch (NullPointerException e) { - LOGGER.log(Level.WARNING, "Possible trouble creating instance (most likely private type).", e); - return null; - } - } else { - // try to call the stream() method to get the spliterator. - BaseStream baseStream = null; - try { - Method streamCreationMethod = instance.getClass().getMethod(calledMethodName); - Object stream = streamCreationMethod.invoke(instance); + for (TypeAbstraction typeAbstraction : possibleTypes) { + if (typeAbstraction != TypeAbstraction.TOP) { + Ordering ordering = inferOrdering(typeAbstraction, calledMethodName); - if (stream instanceof BaseStream) { - baseStream = (BaseStream) stream; - spliterator = baseStream.spliterator(); - } else - throw new CannotExtractSpliteratorException( - "Returned object of type: " + stream.getClass() + " doesn't implement BaseStream.", - stream.getClass()); - } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException - | InvocationTargetException e) { - throw new CannotExtractSpliteratorException( - "Cannot extract the spliterator from object of type: " + instance.getClass(), e, - instance.getClass()); - } finally { - if (baseStream != null) - baseStream.close(); + if (ret == null) + ret = ordering; + else if (ret != ordering) { + throw new InconsistentPossibleOrderingException( + "Types have inconsistent orderings: " + possibleTypes); + } } } - return spliterator; + + return ret; } Ordering inferOrdering(Collection possibleTypes) throws InconsistentPossibleOrderingException, @@ -137,31 +76,34 @@ Ordering inferOrdering(Collection possibleTypes) throws Inconsi } } - Ordering inferOrdering(Collection possibleTypes, IMethod calledMethod) - throws InconsistentPossibleOrderingException, NoniterableException, NoninstantiableException, - CannotExtractSpliteratorException { - return inferOrdering(possibleTypes, calledMethod.getElementName()); + private String findStreamCreationMethod(Collection types) { + // find the first one. + for (TypeAbstraction typeAbstraction : types) { + String methodName = findStreamCreationMethod(typeAbstraction); + + if (methodName != null) + return methodName; + } + // not found. + return null; } - private Ordering inferOrdering(Collection possibleTypes, String calledMethodName) - throws InconsistentPossibleOrderingException, NoniterableException, NoninstantiableException, - CannotExtractSpliteratorException { - Ordering ret = null; + private String findStreamCreationMethod(TypeAbstraction typeAbstraction) { + IClass type = typeAbstraction.getType(); + return findStreamCreationMethod(type); + } - for (TypeAbstraction typeAbstraction : possibleTypes) { - if (typeAbstraction != TypeAbstraction.TOP) { - Ordering ordering = inferOrdering(typeAbstraction, calledMethodName); + private String findStreamCreationMethod(IClass type) { + Collection allMethods = type.getAllMethods(); + for (com.ibm.wala.classLoader.IMethod method : allMethods) { + TypeReference typeToCheck = Util.getEvaluationType(method); - if (ret == null) - ret = ordering; - else if (ret != ordering) { - throw new InconsistentPossibleOrderingException( - "Types have inconsistent orderings: " + possibleTypes); - } - } + // find the first one that returns a stream. + if (Util.implementsBaseStream(typeToCheck, this.getClassHierarchy())) + return method.getName().toString(); } - return ret; + return null; } // TODO: Cache this? @@ -208,6 +150,60 @@ private Ordering inferOrdering(String className, String calledMethodName) } } + private Object createInstance(Class clazz) throws NoninstantiableException { + try { + return clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + ObjectInstantiator instantiator = objenesis.getInstantiatorOf(clazz); + try { + return instantiator.newInstance(); + } catch (InstantiationError e2) { + throw new NoninstantiableException(clazz + " cannot be instantiated: " + e2.getCause(), e2, clazz); + } + } + } + + private Spliterator getSpliterator(Object instance, String calledMethodName) + throws CannotExtractSpliteratorException { + Objects.requireNonNull(instance); + Objects.requireNonNull(calledMethodName); + + Spliterator spliterator = null; + + if (instance instanceof Iterable) { + try { + spliterator = ((Iterable) instance).spliterator(); + } catch (NullPointerException e) { + LOGGER.log(Level.WARNING, "Possible trouble creating instance (most likely private type).", e); + return null; + } + } else { + // try to call the stream() method to get the spliterator. + BaseStream baseStream = null; + try { + Method streamCreationMethod = instance.getClass().getMethod(calledMethodName); + Object stream = streamCreationMethod.invoke(instance); + + if (stream instanceof BaseStream) { + baseStream = (BaseStream) stream; + spliterator = baseStream.spliterator(); + } else + throw new CannotExtractSpliteratorException( + "Returned object of type: " + stream.getClass() + " doesn't implement BaseStream.", + stream.getClass()); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + throw new CannotExtractSpliteratorException( + "Cannot extract the spliterator from object of type: " + instance.getClass(), e, + instance.getClass()); + } finally { + if (baseStream != null) + baseStream.close(); + } + } + return spliterator; + } + private Ordering inferOrdering(TypeAbstraction type, String calledMethodName) throws NoniterableException, NoninstantiableException, CannotExtractSpliteratorException { TypeReference typeReference = type.getTypeReference(); @@ -219,4 +215,8 @@ private Ordering inferOrdering(TypeAbstraction type, String calledMethodName) String binaryName = Util.getBinaryName(typeReference); return inferOrdering(binaryName, calledMethodName); } + + protected IClassHierarchy getClassHierarchy() { + return classHierarchy; + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionFailure.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionFailure.java index 7135cda8..d062329b 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionFailure.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionFailure.java @@ -18,10 +18,11 @@ public enum PreconditionFailure { NO_TERMINAL_OPERATIONS(13), CURRENTLY_NOT_HANDLED(14), // should just be #97 currently. STREAM_CODE_NOT_REACHABLE(15), // either pivotal code isn't reachable or - // entry points are misconfigured. + // entry points are misconfigured. NO_ENTRY_POINT(16), // user didn't specify entry points. NO_APPLICATION_CODE_IN_CALL_STRINGS(17); // N may be too small. + private int code; static { // check that the codes are unique. @@ -30,14 +31,6 @@ public enum PreconditionFailure { throw new IllegalStateException("Codes aren't unique."); } - public static void main(String[] args) { - System.out.println("code,name"); - for (PreconditionFailure failure : PreconditionFailure.values()) - System.out.println(failure.getCode() + "," + failure); - } - - private int code; - private PreconditionFailure(int code) { this.code = code; } @@ -45,4 +38,10 @@ private PreconditionFailure(int code) { public int getCode() { return code; } + + public static void main(String[] args) { + System.out.println("code,name"); + for (PreconditionFailure failure : PreconditionFailure.values()) + System.out.println(failure.getCode() + "," + failure); + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Refactoring.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Refactoring.java index e5de7b5e..ab96bf63 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Refactoring.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Refactoring.java @@ -2,7 +2,7 @@ /** * Possible refactorings included in this plug-in. - * + * * @author Raffi Khatchadourian */ public enum Refactoring { diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java index 9af84af0..2df34b71 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java @@ -74,28 +74,30 @@ @SuppressWarnings("restriction") public class Stream { - private static final String BASE_STREAM_TYPE_NAME = "BaseStream"; - private static final String GENERATE_METHOD_ID = "generate(java.util.function.Supplier)"; private static final String JAVA_UTIL_STREAM_DOUBLE_STREAM = "java.util.stream.DoubleStream"; - private static final String JAVA_UTIL_STREAM_INT_STREAM = "java.util.stream.IntStream"; - private static final String JAVA_UTIL_STREAM_LONG_STREAM = "java.util.stream.LongStream"; - private static final String JAVA_UTIL_STREAM_STREAM = "java.util.stream.Stream"; + private static final String JAVA_UTIL_STREAM_INT_STREAM = "java.util.stream.IntStream"; - private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); + private static final String JAVA_UTIL_STREAM_STREAM = "java.util.stream.Stream"; private static final String PARALLEL_STREAM_CREATION_METHOD_ID = "parallelStream()"; + private static final String BASE_STREAM_TYPE_NAME = "BaseStream"; + + private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); + private static final String PLUGIN_ID = FrameworkUtil.getBundle(Stream.class).getSymbolicName(); private Set actions; private final MethodInvocation creation; + private Optional instructionForCreation; + private final MethodDeclaration enclosingMethodDeclaration; private IR enclosingMethodDeclarationIR; @@ -104,12 +106,12 @@ public class Stream { private CollectorKind collectorKind; - private boolean hasNoTerminalOperation; - private boolean hasPossibleSideEffects; private boolean hasPossibleStatefulIntermediateOperations; + private boolean hasNoTerminalOperation; + /** * The execution mode derived from the declaration of the stream. */ @@ -122,8 +124,6 @@ public class Stream { private InstanceKey instanceKey; - private Optional instructionForCreation; - private PreconditionSuccess passingPrecondition; /** @@ -164,6 +164,13 @@ public Stream(MethodInvocation streamCreation) throws ClassHierarchyException, I } } + public void inferInitialAttributes(EclipseProjectAnalysisEngine engine, + OrderingInference orderingInference) throws InvalidClassFileException, IOException, CoreException, + UnhandledCaseException, StreamCreationNotConsideredException { + this.inferInitialExecution(); + this.inferInitialOrdering(engine, orderingInference); + } + protected void addPossibleExecutionMode(ExecutionMode executionMode) { this.possibleExecutionModes.add(executionMode); } @@ -297,25 +304,6 @@ protected void check() { } } - protected InstanceKey computeInstanceKey(Collection trackedInstances, - EclipseProjectAnalysisEngine engine) - throws InvalidClassFileException, IOException, CoreException, UnhandledCaseException, - NoApplicationCodeExistsInCallStringsException, InstanceKeyNotFoundException { - Optional instructionForCreation = this.getInstructionForCreation(engine); - - if (instructionForCreation.isPresent()) { - SSAInvokeInstruction instruction = instructionForCreation.get(); - - for (InstanceKey ik : trackedInstances) - if (instanceKeyCorrespondsWithInstantiationInstruction(ik, instruction, - this.getEnclosingMethodReference(), engine)) - return ik; - } - - throw new InstanceKeyNotFoundException( - "Can't find instance key for: " + this.getCreation() + " using tracked instances: " + trackedInstances); - } - public Set getActions() { if (this.actions != null) return Collections.unmodifiableSet(this.actions); @@ -447,6 +435,25 @@ public InstanceKey getInstanceKey(Collection trackedInstances, return this.instanceKey; } + protected InstanceKey computeInstanceKey(Collection trackedInstances, + EclipseProjectAnalysisEngine engine) + throws InvalidClassFileException, IOException, CoreException, UnhandledCaseException, + NoApplicationCodeExistsInCallStringsException, InstanceKeyNotFoundException { + Optional instructionForCreation = this.getInstructionForCreation(engine); + + if (instructionForCreation.isPresent()) { + SSAInvokeInstruction instruction = instructionForCreation.get(); + + for (InstanceKey ik : trackedInstances) + if (instanceKeyCorrespondsWithInstantiationInstruction(ik, instruction, + this.getEnclosingMethodReference(), engine)) + return ik; + } + + throw new InstanceKeyNotFoundException( + "Can't find instance key for: " + this.getCreation() + " using tracked instances: " + trackedInstances); + } + Optional getInstructionForCreation(EclipseProjectAnalysisEngine engine) throws InvalidClassFileException, IOException, CoreException, UnhandledCaseException { if (this.instructionForCreation == null) { @@ -552,10 +559,6 @@ private int getUseValueNumberForCreation(EclipseProjectAnalysisEngine i.getUse(0)).orElse(-1); } - public boolean hasNoTerminalOperation() { - return hasNoTerminalOperation; - } - /** * Returns true iff any behavioral parameters (λ-expressions) associated with * any operations in the stream's pipeline has side-effects on any possible @@ -573,11 +576,8 @@ public boolean hasPossibleStatefulIntermediateOperations() { return hasPossibleStatefulIntermediateOperations; } - public void inferInitialAttributes(EclipseProjectAnalysisEngine engine, - OrderingInference orderingInference) throws InvalidClassFileException, IOException, CoreException, - UnhandledCaseException, StreamCreationNotConsideredException { - this.inferInitialExecution(); - this.inferInitialOrdering(engine, orderingInference); + public boolean hasNoTerminalOperation() { + return hasNoTerminalOperation; } private void inferInitialExecution() throws JavaModelException { @@ -699,10 +699,6 @@ public boolean reduceOrderingPossiblyMatters() { return this.reduceOrderingPossiblyMatters; } - public void setHasNoTerminalOperation(boolean hasNoTerminalOperation) { - this.hasNoTerminalOperation = hasNoTerminalOperation; - } - protected void setHasPossibleSideEffects(boolean hasPossibleSideEffects) { this.hasPossibleSideEffects = hasPossibleSideEffects; } @@ -711,6 +707,10 @@ protected void setHasPossibleStatefulIntermediateOperations(boolean hasPossibleS this.hasPossibleStatefulIntermediateOperations = hasPossibleStatefulIntermediateOperations; } + public void setHasNoTerminalOperation(boolean hasNoTerminalOperation) { + this.hasNoTerminalOperation = hasNoTerminalOperation; + } + protected void setInitialExecutionMode(ExecutionMode initialExecutionMode) { Objects.requireNonNull(initialExecutionMode); this.initialExecutionMode = initialExecutionMode; diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java index 605fa1c4..9e4dbcb5 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java @@ -29,7 +29,6 @@ import org.eclipse.jdt.internal.corext.util.JdtFlags; import com.ibm.safe.internal.exceptions.PropertiesException; -import com.ibm.safe.rules.TypestateRule; import com.ibm.wala.ipa.callgraph.AnalysisOptions; import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions; import com.ibm.wala.ipa.callgraph.CallGraph; @@ -43,7 +42,6 @@ import com.ibm.wala.util.CancelException; import com.ibm.wala.util.scope.JUnitEntryPoints; -import edu.cuny.hunter.streamrefactoring.core.analysis.StreamStateMachine.Statistics; import edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames; import edu.cuny.hunter.streamrefactoring.core.utils.TimeCollector; import edu.cuny.hunter.streamrefactoring.core.wala.EclipseProjectAnalysisEngine; @@ -51,65 +49,18 @@ @SuppressWarnings("restriction") public class StreamAnalyzer extends ASTVisitor { - private static final String ENTRY_POINT_FILENAME = "entry_points.txt"; - private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); private static final int N_FOR_STREAMS_DEFAULT = 2; + private static final String ENTRY_POINT_FILENAME = "entry_points.txt"; + private static void addImplicitEntryPoints(Collection target, Iterable source) { for (Entrypoint implicitEntryPoint : source) if (target.add(implicitEntryPoint)) LOGGER.info(() -> "Adding implicit entry point: " + implicitEntryPoint); } - /** - * Read entry_points.txt and get a set of method signatures, then, get entry - * points by those signatures - * - * @return a set of entry points - * @throws IOException - */ - private static Set findEntryPointsFromFile(IClassHierarchy classHierarchy, File file) - throws IOException { - Set signatures = new HashSet<>(); - - try (Scanner scanner = new Scanner(file)) { - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - signatures.add(line); - } - } - - Set entrypoints = Util.findEntryPoints(classHierarchy, signatures); - return entrypoints; - } - - /** - * Search entry_points.txt in project directory recursively. - * - * @param directory - * Project directory. - * @param fileName - * The target file. - * @return null if the file does not exist and file if we found the file. - */ - private static File getEntryPointsFile(IPath directory, String fileName) { - // If file does not exist, find the file in upper level. - Path directoryPath = Paths.get(directory.toString()); - - File file; - do { - file = new File(directoryPath.resolve(ENTRY_POINT_FILENAME).toString()); - directoryPath = directoryPath.getParent(); - } while (!file.exists() && directoryPath != null); - - if (!file.exists()) - return null; - else - return file; - } - /** * Map from {@link EclipseProjectAnalysisEngine}s that have their * {@link CallGraph}s built to the {@link Entrypoint}s that were used to build @@ -123,17 +74,13 @@ private static File getEntryPointsFile(IPath directory, String fileName) { private boolean findImplicitTestEntryPoints; + private Set streamSet = new HashSet<>(); + /** * The N to use for instances of {@link BaseStream} in the nCFA. */ private int nForStreams = N_FOR_STREAMS_DEFAULT; - private int numberOfProcessedStreamInstances; - - private int numberOfSkippedStreamInstances; - - private Set streamSet = new HashSet<>(); - public StreamAnalyzer() { this(false); } @@ -142,26 +89,26 @@ public StreamAnalyzer(boolean visitDocTags) { super(visitDocTags); } + public StreamAnalyzer(boolean visitDocTags, int nForStreams) { + super(visitDocTags); + this.nForStreams = nForStreams; + } + public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints) { this(visitDocTags); this.findImplicitEntryPoints = findImplicitEntryPoints; } - public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints, boolean findImplicitTestEntryPoints, - boolean findImplicitBenchmarkEntryPoints) { + public StreamAnalyzer(boolean visitDocTags, int nForStreams, boolean findImplicitEntryPoints) { this(visitDocTags, findImplicitEntryPoints); - this.findImplicitTestEntryPoints = findImplicitTestEntryPoints; - this.findImplicitBenchmarkEntryPoints = findImplicitBenchmarkEntryPoints; - } - - public StreamAnalyzer(boolean visitDocTags, int nForStreams) { - super(visitDocTags); this.nForStreams = nForStreams; } - public StreamAnalyzer(boolean visitDocTags, int nForStreams, boolean findImplicitEntryPoints) { + public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints, boolean findImplicitTestEntryPoints, + boolean findImplicitBenchmarkEntryPoints) { this(visitDocTags, findImplicitEntryPoints); - this.nForStreams = nForStreams; + this.findImplicitTestEntryPoints = findImplicitTestEntryPoints; + this.findImplicitBenchmarkEntryPoints = findImplicitBenchmarkEntryPoints; } public StreamAnalyzer(boolean visitDocTags, int nForStreams, boolean findImplicitEntryPoints, @@ -172,7 +119,7 @@ public StreamAnalyzer(boolean visitDocTags, int nForStreams, boolean findImplici /** * Analyzes this {@link StreamAnalyzer}'s streams. - * + * * @return A {@link Map} of project's analyzed along with the entry points used. * @see #analyze(Optional). */ @@ -261,16 +208,8 @@ public Map> analyze(Optional // start the state machine for each valid stream in the project. StreamStateMachine stateMachine = new StreamStateMachine(); try { - Map ruleToStats = stateMachine.start(projectToStreams - .get(project).parallelStream().filter(s -> s.getStatus().isOK()).collect(Collectors.toSet()), - engine, orderingInference); - - // use just one the rules. - assert !ruleToStats.isEmpty() : "Should have stats available."; - Statistics statistics = ruleToStats.values().iterator().next(); - - this.setNumberOfProcessedStreamInstances(statistics.getNumberOfStreamInstancesProcessed()); - this.setNumberOfSkippedStreamInstances(statistics.getNumberOfStreamInstancesSkipped()); + stateMachine.start(projectToStreams.get(project).parallelStream().filter(s -> s.getStatus().isOK()) + .collect(Collectors.toSet()), engine, orderingInference); } catch (PropertiesException | CancelException | NoniterableException | NoninstantiableException | CannotExtractSpliteratorException | InvalidClassFileException | IOException e) { LOGGER.log(Level.SEVERE, "Error while starting state machine.", e); @@ -282,6 +221,7 @@ public Map> analyze(Optional .collect(Collectors.toSet())) stream.check(); } // end for each stream. + return ret; } @@ -373,56 +313,79 @@ protected Collection buildCallGraph(EclipseProjectAnalysisEngine findEntryPointsFromFile(IClassHierarchy classHierarchy, File file) + throws IOException { + Set signatures = new HashSet<>(); - public int getNumberOfProcessedStreamInstances() { - return this.numberOfProcessedStreamInstances; + try (Scanner scanner = new Scanner(file)) { + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + signatures.add(line); + } + } + + Set entrypoints = Util.findEntryPoints(classHierarchy, signatures); + return entrypoints; } - public int getNumberOfSkippedStreamInstances() { - return this.numberOfSkippedStreamInstances; + /** + * Search entry_points.txt in project directory recursively. + * + * @param directory + * Project directory. + * @param fileName + * The target file. + * @return null if the file does not exist and file if we found the file. + */ + private static File getEntryPointsFile(IPath directory, String fileName) { + // If file does not exist, find the file in upper level. + Path directoryPath = Paths.get(directory.toString()); + + File file; + do { + file = new File(directoryPath.resolve(ENTRY_POINT_FILENAME).toString()); + directoryPath = directoryPath.getParent(); + } while (!file.exists() && directoryPath != null); + + if (!file.exists()) + return null; + else + return file; } public Set getStreamSet() { return this.streamSet; } - public void setFindImplicitBenchmarkEntryPoints(boolean findImplicitBenchmarkEntryPoints) { - this.findImplicitBenchmarkEntryPoints = findImplicitBenchmarkEntryPoints; - } - public void setFindImplicitEntryPoints(boolean findImplicitEntryPoints) { this.findImplicitEntryPoints = findImplicitEntryPoints; } - public void setFindImplicitTestEntryPoints(boolean findImplicitTestEntryPoints) { - this.findImplicitTestEntryPoints = findImplicitTestEntryPoints; - } - - protected void setNForStreams(int nForStreams) { - this.nForStreams = nForStreams; + public boolean shouldFindImplicitEntryPoints() { + return findImplicitEntryPoints; } - protected void setNumberOfProcessedStreamInstances(int numberOfProcessedStreamInstances) { - this.numberOfProcessedStreamInstances = numberOfProcessedStreamInstances; + public void setFindImplicitTestEntryPoints(boolean findImplicitTestEntryPoints) { + this.findImplicitTestEntryPoints = findImplicitTestEntryPoints; } - protected void setNumberOfSkippedStreamInstances(int numberOfSkippedStreamInstances) { - this.numberOfSkippedStreamInstances = numberOfSkippedStreamInstances; + public boolean shouldFindImplicitTestEntryPoints() { + return findImplicitTestEntryPoints; } public boolean shouldFindImplicitBenchmarkEntryPoints() { return findImplicitBenchmarkEntryPoints; } - public boolean shouldFindImplicitEntryPoints() { - return findImplicitEntryPoints; - } - - public boolean shouldFindImplicitTestEntryPoints() { - return findImplicitTestEntryPoints; + public void setFindImplicitBenchmarkEntryPoints(boolean findImplicitBenchmarkEntryPoints) { + this.findImplicitBenchmarkEntryPoints = findImplicitBenchmarkEntryPoints; } /** @@ -464,4 +427,12 @@ public boolean visit(MethodInvocation node) { return super.visit(node); } + + public int getNForStreams() { + return nForStreams; + } + + protected void setNForStreams(int nForStreams) { + this.nForStreams = nForStreams; + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAttributeTypestateRule.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAttributeTypestateRule.java index 4a370cfa..1987b840 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAttributeTypestateRule.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAttributeTypestateRule.java @@ -32,29 +32,6 @@ protected void addAutomaton() { bottomState = addState(BOTTOM_STATE_NAME, true); } - protected IDispatchEvent addEvent(String eventName, String eventPattern) { - IDispatchEventImpl event = new IDispatchEventImpl(); - - event.setName(eventName); - event.setPattern(eventPattern); - - this.getTypeStateAutomaton().addEvent(event); - return event; - } - - protected void addPossibleAttributes(Stream stream, Collection states) { - Objects.requireNonNull(stream); - Objects.requireNonNull(states); - } - - protected IDFAState addState(Enum constant) { - return this.addState(constant.name().toLowerCase()); - } - - protected IDFAState addState(String stateName) { - return addState(stateName, false); - } - protected IDFAState addState(String stateName, boolean initialState) { IDFAState state = new DFAState(); @@ -77,4 +54,27 @@ protected IDFATransition addTransition(IDFAState source, IDFAState destination, this.getTypeStateAutomaton().addTransition(transition); return transition; } + + protected IDispatchEvent addEvent(String eventName, String eventPattern) { + IDispatchEventImpl event = new IDispatchEventImpl(); + + event.setName(eventName); + event.setPattern(eventPattern); + + this.getTypeStateAutomaton().addEvent(event); + return event; + } + + protected IDFAState addState(String stateName) { + return addState(stateName, false); + } + + protected IDFAState addState(Enum constant) { + return this.addState(constant.name().toLowerCase()); + } + + protected void addPossibleAttributes(Stream stream, Collection states) { + Objects.requireNonNull(stream); + Objects.requireNonNull(states); + } } \ No newline at end of file diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamCreationNotConsideredException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamCreationNotConsideredException.java index 56d8a513..640953c5 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamCreationNotConsideredException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamCreationNotConsideredException.java @@ -11,6 +11,10 @@ public StreamCreationNotConsideredException(String message) { super(message); } + public StreamCreationNotConsideredException(Throwable cause) { + super(cause); + } + public StreamCreationNotConsideredException(String message, Throwable cause) { super(message, cause); } @@ -19,8 +23,4 @@ public StreamCreationNotConsideredException(String message, Throwable cause, boo boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } - - public StreamCreationNotConsideredException(Throwable cause) { - super(cause); - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamExecutionModeTypeStateRule.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamExecutionModeTypeStateRule.java index 46c8a662..0f08edd4 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamExecutionModeTypeStateRule.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamExecutionModeTypeStateRule.java @@ -23,10 +23,10 @@ protected void addAutomaton() { super.addAutomaton(); IDFAState sequentialState = addState(ExecutionMode.SEQUENTIAL); - + if (this.getDFAStateToExecutionMap() == null) this.setDFAStateToExecutionMap(new HashMap<>(2)); - + this.getDFAStateToExecutionMap().put(sequentialState, ExecutionMode.SEQUENTIAL); IDFAState parallelState = addState(ExecutionMode.PARALLEL); @@ -44,23 +44,23 @@ protected void addAutomaton() { addTransition(parallelState, parallelState, parallelEvent); } - @Override - protected void addPossibleAttributes(Stream stream, Collection states) { - super.addPossibleAttributes(stream, states); - - Set set = states.stream().map(this::getStreamExecutionMode).collect(Collectors.toSet()); - stream.addPossibleExecutionModeCollection(set); + protected ExecutionMode getStreamExecutionMode(IDFAState state) { + return this.getDFAStateToExecutionMap().get(state); } protected Map getDFAStateToExecutionMap() { return this.dfaStateToExecutionMap; } - protected ExecutionMode getStreamExecutionMode(IDFAState state) { - return this.getDFAStateToExecutionMap().get(state); - } - protected void setDFAStateToExecutionMap(HashMap dfaStateToExecutionMap) { this.dfaStateToExecutionMap = dfaStateToExecutionMap; } + + @Override + protected void addPossibleAttributes(Stream stream, Collection states) { + super.addPossibleAttributes(stream, states); + + Set set = states.stream().map(this::getStreamExecutionMode).collect(Collectors.toSet()); + stream.addPossibleExecutionModeCollection(set); + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamOrderingTypeStateRule.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamOrderingTypeStateRule.java index 36966d91..97a544f3 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamOrderingTypeStateRule.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamOrderingTypeStateRule.java @@ -23,12 +23,12 @@ protected void addAutomaton() { super.addAutomaton(); IDFAState orderedState = addState(Ordering.ORDERED); - + if (this.getDFAStateToOrderingMap() == null) this.setDFAStateToOrderingMap(new HashMap<>(2)); - + this.getDFAStateToOrderingMap().put(orderedState, Ordering.ORDERED); - + IDFAState unorderedState = addState(Ordering.UNORDERED); this.getDFAStateToOrderingMap().put(unorderedState, Ordering.UNORDERED); @@ -52,14 +52,14 @@ protected void addPossibleAttributes(Stream stream, Collection states stream.addPossibleOrderingCollection(set); } - protected Map getDFAStateToOrderingMap() { - return dfaStateToOrderingMap; - } - public Ordering getOrdering(IDFAState state) { return this.getDFAStateToOrderingMap().get(state); } + protected Map getDFAStateToOrderingMap() { + return dfaStateToOrderingMap; + } + protected void setDFAStateToOrderingMap(Map dfaStateToOrderingMap) { this.dfaStateToOrderingMap = dfaStateToOrderingMap; } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java index 7ca8a47a..0400e5f2 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java @@ -90,25 +90,6 @@ public class StreamStateMachine { - public class Statistics { - private int numberOfStreamInstancesProcessed; - private int numberOfStreamInstancesSkipped; - - public Statistics(int numberOfStreamInstancesProcessed, int numberOfStreamInstancesSkipped) { - this.numberOfStreamInstancesProcessed = numberOfStreamInstancesProcessed; - this.numberOfStreamInstancesSkipped = numberOfStreamInstancesSkipped; - } - - public int getNumberOfStreamInstancesProcessed() { - return numberOfStreamInstancesProcessed; - } - - public int getNumberOfStreamInstancesSkipped() { - return numberOfStreamInstancesSkipped; - } - } - - @SuppressWarnings("unused") private static final String ARRAYS_STREAM_CREATION_METHOD_NAME = "Arrays.stream"; private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); @@ -945,12 +926,10 @@ private void propagateStreamInstanceProperty(Collection streamInsta .flatMap(ik -> this.getAllPredecessors(ik).stream()).collect(Collectors.toSet())); } - public Map start(Set streamSet, EclipseProjectAnalysisEngine engine, + public void start(Set streamSet, EclipseProjectAnalysisEngine engine, OrderingInference orderingInference) throws PropertiesException, CancelException, IOException, CoreException, NoniterableException, NoninstantiableException, CannotExtractSpliteratorException, InvalidClassFileException { - Map ret = new HashMap<>(); - BenignOracle ora = new ModifiedBenignOracle(engine.getCallGraph(), engine.getPointerAnalysis()); PropertiesManager manager = PropertiesManager.initFromMap(Collections.emptyMap()); @@ -983,11 +962,6 @@ public Map start(Set streamSet, EclipseProjec throw new RuntimeException("Exception caught during typestate analysis.", e); } - // record statistics. - Statistics lastStatistics = ret.put(rule, - new Statistics(result.processedInstancesNum(), result.skippedInstances())); - assert lastStatistics == null : "Reassociating statistics."; - // for each instance in the typestate analysis result. for (Iterator iterator = result.iterateInstances(); iterator.hasNext();) { // get the instance's key. @@ -1246,6 +1220,5 @@ public Map start(Set streamSet, EclipseProjec this.instancesWhoseReduceOrderingPossiblyMatters.contains(streamInstanceKey)); } } - return ret; } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/UnhandledCaseException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/UnhandledCaseException.java index b5671ce4..40f98be3 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/UnhandledCaseException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/UnhandledCaseException.java @@ -11,6 +11,10 @@ public UnhandledCaseException(String message) { super(message); } + public UnhandledCaseException(Throwable cause) { + super(cause); + } + public UnhandledCaseException(String message, Throwable cause) { super(message, cause); } @@ -19,8 +23,4 @@ public UnhandledCaseException(String message, Throwable cause, boolean enableSup boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } - - public UnhandledCaseException(Throwable cause) { - super(cause); - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/UnknownIfReduceOrderMattersException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/UnknownIfReduceOrderMattersException.java index fff6e6d8..115f7f53 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/UnknownIfReduceOrderMattersException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/UnknownIfReduceOrderMattersException.java @@ -7,17 +7,17 @@ public UnknownIfReduceOrderMattersException() { super(); } - public UnknownIfReduceOrderMattersException(String message) { - super(message); + public UnknownIfReduceOrderMattersException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); } public UnknownIfReduceOrderMattersException(String message, Throwable cause) { super(message, cause); } - public UnknownIfReduceOrderMattersException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); + public UnknownIfReduceOrderMattersException(String message) { + super(message); } public UnknownIfReduceOrderMattersException(Throwable cause) { diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java index 2ed2b0e5..d85d4dbe 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java @@ -283,26 +283,6 @@ public static Set findEntryPoints(IClassHierarchy classHierarchy, Se return result; } - /** - * Returns the index of the first {@link IMethod} in methods that is client - * code. - * - * @param methods - * The {@link IMethod}s in question. - * @return The index of the first {@link IMethod} that is client code and -1 if - * none found. - */ - public static int findIndexOfFirstClientMethod(IMethod[] methods) { - for (int i = 0; i < methods.length; i++) { - IMethod meth = methods[i]; - - if (meth.getDeclaringClass().getClassLoader().getReference().equals(ClassLoaderReference.Application)) - return i; - } - - return -1; // not found. - } - static Set getAllInterfaces(ITypeBinding type) { Set ret = new HashSet<>(); ITypeBinding[] interfaces = type.getInterfaces(); @@ -337,25 +317,6 @@ public static CallStringWithReceivers getCallString(NormalAllocationInNode alloc return getCallString(node); } - /** - * If it's a ctor, return the declaring class, otherwise, return the return - * type. - * - * @param method - * The {@link IMethod} in question. - * @return The declaring class of target if target is a ctor and the return type - * otherwise. - */ - public static TypeReference getEvaluationType(IMethod method) { - // if it's a ctor. - if (method.isInit()) - // then, use the declaring type. - return method.getDeclaringClass().getReference(); - else // otherwise. - // use the return type. - return method.getReturnType(); - } - static Set getImplementedInterfaces(ITypeBinding type) { Set ret = new HashSet<>(); @@ -608,6 +569,7 @@ else if (Modifier.isAbstract(clazz.getModifiers())) else return false; } + public static boolean isBaseStream(IClass clazz) { return Util.isType(clazz, "java/util/stream", "BaseStream"); @@ -726,4 +688,43 @@ private static boolean wouldOrderingBeConsistent(final Collection> projectToEntryPoints; private SearchEngine searchEngine = new SearchEngine(); @@ -150,6 +144,8 @@ public static void setLoggingLevel(int level) { private boolean useImplicitTestEntrypoints = false; + private int nForStreams = N_FOR_STREAMS_DEFAULT; + public ConvertToParallelStreamRefactoringProcessor() throws JavaModelException { this(null, null, false, true, false, false, Optional.empty()); } @@ -246,10 +242,6 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi // analyze and set entry points. this.projectToEntryPoints = analyzer.analyze(Optional.of(this.getExcludedTimeCollector())); - // set statistics for stream instances. - this.setNumberOfProcessedStreamInstances(analyzer.getNumberOfProcessedStreamInstances()); - this.setNumberOfSkippedStreamInstances(analyzer.getNumberOfSkippedStreamInstances()); - // map empty set to unprocessed projects. for (IJavaProject project : this.getJavaProjects()) this.projectToEntryPoints.computeIfAbsent(project, p -> Collections.emptySet()); @@ -282,6 +274,14 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi } } + public int getNForStreams() { + return this.nForStreams; + } + + public void setNForStreams(int nForStreams) { + this.nForStreams = nForStreams; + } + @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { @@ -440,18 +440,6 @@ protected IJavaProject[] getJavaProjects() { return this.javaProjects; } - public int getNForStreams() { - return this.nForStreams; - } - - public int getNumberOfProcessedStreamInstances() { - return this.numberOfProcessedStreamInstances; - } - - public int getNumberOfSkippedStreamInstances() { - return this.numberOfSkippedStreamInstances; - } - public Set getOptimizableStreams() { return this.getStreamSet().parallelStream().filter(s -> !s.getStatus().hasError()).collect(Collectors.toSet()); } @@ -539,18 +527,6 @@ private void manageCompilationUnit(final TextEditBasedChangeManager manager, Com manager.manage(rewrite.getCu(), change); } - public void setNForStreams(int nForStreams) { - this.nForStreams = nForStreams; - } - - protected void setNumberOfProcessedStreamInstances(int numberOfProcessedStreamInstances) { - this.numberOfProcessedStreamInstances = numberOfProcessedStreamInstances; - } - - protected void setNumberOfSkippedStreamInstances(int numberOfSkippedStreamInstances) { - this.numberOfSkippedStreamInstances = numberOfSkippedStreamInstances; - } - protected void setStreamSet(Set streamSet) { this.streamSet = streamSet; } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/ClientSlicingUniqueSolver.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/ClientSlicingUniqueSolver.java index db0db48a..4584c17a 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/ClientSlicingUniqueSolver.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/ClientSlicingUniqueSolver.java @@ -13,6 +13,8 @@ import com.ibm.safe.typestate.options.TypeStateOptions; import com.ibm.safe.typestate.rules.ITypeStateDFA; import com.ibm.safe.typestate.unique.UniqueSolver; +import com.ibm.wala.classLoader.CallSiteReference; +import com.ibm.wala.classLoader.IClass; import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.escape.ILiveObjectAnalysis; import com.ibm.wala.ipa.callgraph.CallGraph; @@ -29,7 +31,7 @@ /** * A solver that only tracks instances created from client (non-JDK) calls. - * + * * @author Raffi Khatchadourian */ public class ClientSlicingUniqueSolver extends UniqueSolver { diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/EventTrackingTypeStateProperty.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/EventTrackingTypeStateProperty.java index cc1b346a..ec6579f0 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/EventTrackingTypeStateProperty.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/EventTrackingTypeStateProperty.java @@ -14,6 +14,11 @@ public class EventTrackingTypeStateProperty extends TypeStateProperty { + public EventTrackingTypeStateProperty(IClassHierarchy cha, Collection types) { + super(getTypeStateRule(types), cha); + types.stream().forEach(this::addType); + } + private static TypestateRule getTypeStateRule(Collection types) { TypestateRule rule = new TypestateRule(); types.stream().map(t -> t.getName()).map(n -> n.toString()).forEach(rule::addType); @@ -23,21 +28,22 @@ private static TypestateRule getTypeStateRule(Collection types) { return rule; } - protected EventTrackingTypeStateProperty(IClassHierarchy cha) { - super(cha); + public EventTrackingTypeStateProperty(TypestateRule aTypeStateRule, IClassHierarchy cha) { + super(aTypeStateRule, cha); } - public EventTrackingTypeStateProperty(IClassHierarchy cha, Collection types) { - super(getTypeStateRule(types), cha); - types.stream().forEach(this::addType); + protected EventTrackingTypeStateProperty(IClassHierarchy cha) { + super(cha); } - public EventTrackingTypeStateProperty(TypestateRule aTypeStateRule, IClassHierarchy cha) { - super(aTypeStateRule, cha); + @Override + public IDFAState successor(IDFAState state, IEvent e) { + // TODO Auto-generated method stub + return null; } @Override - public String getName() { + public Set predecessors(IDFAState state, IEvent automatonLabel) { // TODO Auto-generated method stub return null; } @@ -50,24 +56,18 @@ public IDFAState initial() { return state; } - @SuppressWarnings("rawtypes") - @Override - public IEvent match(Class eventClass, String param) { - // TODO Auto-generated method stub - System.out.println("MATCH: " + eventClass + ": " + param); - return null;// super.match(eventClass, param); - } - @Override - public Set predecessors(IDFAState state, IEvent automatonLabel) { + public String getName() { // TODO Auto-generated method stub return null; } + @SuppressWarnings("rawtypes") @Override - public IDFAState successor(IDFAState state, IEvent e) { + public IEvent match(Class eventClass, String param) { // TODO Auto-generated method stub - return null; + System.out.println("MATCH: " + eventClass + ": " + param); + return null;//super.match(eventClass, param); } @Override diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/InstructionBasedSolver.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/InstructionBasedSolver.java index 9e0a38a7..2df9fea1 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/InstructionBasedSolver.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/InstructionBasedSolver.java @@ -26,10 +26,10 @@ public class InstructionBasedSolver extends TrackingUniqueSolver { private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); - private EclipseProjectAnalysisEngine engine; - private SSAInvokeInstruction instruction; + private EclipseProjectAnalysisEngine engine; + public InstructionBasedSolver(CallGraph cg, PointerAnalysis pointerAnalysis, TypeStateProperty property, TypeStateOptions options, ILiveObjectAnalysis live, BenignOracle ora, TypeStateMetrics metrics, IReporter reporter, TraceReporter traceReporter, IMergeFunctionFactory mergeFactory, @@ -66,11 +66,11 @@ protected Collection computeTrackedInstances() throws PropertiesExc return ret; } - protected EclipseProjectAnalysisEngine getEngine() { - return this.engine; - } - protected SSAInvokeInstruction getInstruction() { return this.instruction; } + + protected EclipseProjectAnalysisEngine getEngine() { + return this.engine; + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/ModifiedBenignOracle.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/ModifiedBenignOracle.java index 4b2eacc0..d69d4b14 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/ModifiedBenignOracle.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/ModifiedBenignOracle.java @@ -17,7 +17,7 @@ import edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames; public class ModifiedBenignOracle extends BenignOracle { - + private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); public ModifiedBenignOracle(CallGraph callGraph, PointerAnalysis pointerAnalysis) { diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/NoApplicationCodeExistsInCallStringsException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/NoApplicationCodeExistsInCallStringsException.java index 34c26e15..b9aebd03 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/NoApplicationCodeExistsInCallStringsException.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/NoApplicationCodeExistsInCallStringsException.java @@ -2,15 +2,14 @@ public class NoApplicationCodeExistsInCallStringsException extends Exception { - /** - * - */ - private static final long serialVersionUID = 1L; - public NoApplicationCodeExistsInCallStringsException(String message) { super(message); } + public NoApplicationCodeExistsInCallStringsException(Throwable cause) { + super(cause); + } + public NoApplicationCodeExistsInCallStringsException(String message, Throwable cause) { super(message, cause); } @@ -19,8 +18,4 @@ public NoApplicationCodeExistsInCallStringsException(String message, Throwable c boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } - - public NoApplicationCodeExistsInCallStringsException(Throwable cause) { - super(cause); - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TrackingUniqueSolver.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TrackingUniqueSolver.java index de4f24f6..3b1e06ef 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TrackingUniqueSolver.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TrackingUniqueSolver.java @@ -27,13 +27,6 @@ public TrackingUniqueSolver(CallGraph cg, PointerAnalysis pointerAnalysis, IType super(cg, pointerAnalysis, dfa, options, live, ora, metrics, reporter, traceReporter, mergeFactory); } - @Override - protected Collection computeTrackedInstances() throws PropertiesException { - Collection instances = super.computeTrackedInstances(); - this.setTrackedInstances(instances); - return instances; - } - public Collection getTrackedInstances() { return trackedInstances; } @@ -42,4 +35,11 @@ protected void setTrackedInstances(Collection trackedInstances) { this.trackedInstances = trackedInstances; } + @Override + protected Collection computeTrackedInstances() throws PropertiesException { + Collection instances = super.computeTrackedInstances(); + this.setTrackedInstances(instances); + return instances; + } + } \ No newline at end of file diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TypestateSolverFactory.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TypestateSolverFactory.java index c903a8ef..d1054148 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TypestateSolverFactory.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TypestateSolverFactory.java @@ -25,19 +25,7 @@ public class TypestateSolverFactory extends com.ibm.safe.typestate.core.TypestateSolverFactory { - protected static ILiveObjectAnalysis getLiveObjectAnalysis(CallGraph cg, HeapGraph hg, TypeStateOptions options) - throws PropertiesException { - return options.shouldUseLiveAnalysis() ? TypeStateSolverCreator.computeLiveObjectAnalysis(cg, hg, false) : null; - } - - public static ISafeSolver getSolver(AnalysisOptions domoOptions, CallGraph cg, PointerAnalysis pointerAnalysis, - HeapGraph hg, TypeStateProperty dfa, BenignOracle ora, TypeStateOptions options, - TypeStateMetrics metrics, IReporter reporter, TraceReporter traceReporter) - throws PropertiesException, CancelException { - IMergeFunctionFactory mergeFactory = makeMergeFactory(options, TypeStateSolverKind.UNIQUE); - ILiveObjectAnalysis live = getLiveObjectAnalysis(cg, hg, options); - return new UniqueSolver(cg, pointerAnalysis, dfa, options, live, ora, metrics, reporter, traceReporter, - mergeFactory); + protected TypestateSolverFactory() { } public static TrackingUniqueSolver getSolver(CallGraph cg, PointerAnalysis pointerAnalysis, HeapGraph hg, @@ -59,6 +47,18 @@ public static TrackingUniqueSolver getSolver(TypeStateSolverKind kind, CallGraph traceReporter, mergeFactory, instruction, engine); } - protected TypestateSolverFactory() { + public static ISafeSolver getSolver(AnalysisOptions domoOptions, CallGraph cg, PointerAnalysis pointerAnalysis, + HeapGraph hg, TypeStateProperty dfa, BenignOracle ora, TypeStateOptions options, + TypeStateMetrics metrics, IReporter reporter, TraceReporter traceReporter) + throws PropertiesException, CancelException { + IMergeFunctionFactory mergeFactory = makeMergeFactory(options, TypeStateSolverKind.UNIQUE); + ILiveObjectAnalysis live = getLiveObjectAnalysis(cg, hg, options); + return new UniqueSolver(cg, pointerAnalysis, dfa, options, live, ora, metrics, reporter, traceReporter, + mergeFactory); + } + + protected static ILiveObjectAnalysis getLiveObjectAnalysis(CallGraph cg, HeapGraph hg, TypeStateOptions options) + throws PropertiesException { + return options.shouldUseLiveAnalysis() ? TypeStateSolverCreator.computeLiveObjectAnalysis(cg, hg, false) : null; } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java index 0ad32330..597a1744 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java @@ -33,8 +33,6 @@ public class Util { @SuppressWarnings("unused") private static final TypeName ARRAYS_TYPE_NAME = TypeName.string2TypeName("Ljava/util/Arrays"); - private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); - /** * {@link Atom} corresponding the the stream() method. */ @@ -48,6 +46,8 @@ public class Util { private static final TypeName STREAM_SUPPORT_TYPE_NAME = TypeName .string2TypeName("Ljava/util/stream/StreamSupport"); + private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); + /** * True iff the given {@link InstanceKey} corresponds with the given * {@link SSAInvokeInstruction} in the given {@link CallGraph}. In other words, diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/TimeCollector.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/TimeCollector.java index e93ae4c9..877c738a 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/TimeCollector.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/TimeCollector.java @@ -1,5 +1,5 @@ /** - * + * */ package edu.cuny.hunter.streamrefactoring.core.utils; @@ -13,16 +13,6 @@ public class TimeCollector { private long start; private boolean started; - public void clear() { - assert !started : "Shouldn't clear a running time collector."; - - collectedTime = 0; - } - - public long getCollectedTime() { - return collectedTime; - } - public void start() { assert !started : "Time colletor is already started."; started = true; @@ -37,4 +27,14 @@ public void stop() { final long elapsed = System.currentTimeMillis() - start; collectedTime += elapsed; } + + public long getCollectedTime() { + return collectedTime; + } + + public void clear() { + assert !started : "Shouldn't clear a running time collector."; + + collectedTime = 0; + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/AnalysisUtils.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/AnalysisUtils.java index 8a4d7577..90114522 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/AnalysisUtils.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/AnalysisUtils.java @@ -16,28 +16,28 @@ * Modified from AnalysisUtils.java, originally from Keshmesh. Authored by * Mohsen Vakilian and Stas Negara. Modified by Nicholas Chen and Raffi * Khatchadourian. - * + * */ public class AnalysisUtils { private static final String EXTENSION_CLASSLOADER_NAME = "Extension"; - private static final String OBJECT_GETCLASS_SIGNATURE = "java.lang.Object.getClass()Ljava/lang/Class;"; //$NON-NLS-1$ - public static final String PRIMORDIAL_CLASSLOADER_NAME = "Primordial"; //$NON-NLS-1$ - public static boolean isAnnotatedFactoryMethod(IMethod callee) { - Collection annotations = callee.getAnnotations(); + private static final String OBJECT_GETCLASS_SIGNATURE = "java.lang.Object.getClass()Ljava/lang/Class;"; //$NON-NLS-1$ - if (annotations == null) - return false; + /** + * All projects which the main Eclipse project depends on are in the Extension + * loader + * + * See com.ibm.wala.ide.util.EclipseProjectPath for more information. + */ + public static boolean isLibraryClass(IClass klass) { + return isExtension(klass.getClassLoader().getName()); + } - for (Annotation annotation : annotations) { - if (annotation.getType().getName().getClassName().toString().contains("JFlowFactory")) { - return true; - } - } - return false; + public static boolean isLibraryClass(TypeReference typeReference) { + return isExtension(typeReference.getClassLoader().getName()); } private static boolean isExtension(Atom classLoaderName) { @@ -49,18 +49,8 @@ public static boolean isJDKClass(IClass klass) { return isPrimordial(classLoaderName) || isExtension(classLoaderName); } - /** - * All projects which the main Eclipse project depends on are in the Extension - * loader - * - * See com.ibm.wala.ide.util.EclipseProjectPath for more information. - */ - public static boolean isLibraryClass(IClass klass) { - return isExtension(klass.getClassLoader().getName()); - } - - public static boolean isLibraryClass(TypeReference typeReference) { - return isExtension(typeReference.getClassLoader().getName()); + private static boolean isPrimordial(Atom classLoaderName) { + return classLoaderName.toString().equals(PRIMORDIAL_CLASSLOADER_NAME); } public static boolean isObjectGetClass(IMethod method) { @@ -71,10 +61,6 @@ private static boolean isObjectGetClass(String methodSignature) { return methodSignature.equals(OBJECT_GETCLASS_SIGNATURE); } - private static boolean isPrimordial(Atom classLoaderName) { - return classLoaderName.toString().equals(PRIMORDIAL_CLASSLOADER_NAME); - } - public static String walaTypeNameToJavaName(TypeName typeName) { String fullyQualifiedName = typeName.getPackage() + "." + typeName.getClassName(); @@ -82,4 +68,18 @@ public static String walaTypeNameToJavaName(TypeName typeName) { // to make it a valid class name in Java source code. return fullyQualifiedName.replace("$", ".").replace("/", "."); } + + public static boolean isAnnotatedFactoryMethod(IMethod callee) { + Collection annotations = callee.getAnnotations(); + + if (annotations == null) + return false; + + for (Annotation annotation : annotations) { + if (annotation.getType().getName().getClassName().toString().contains("JFlowFactory")) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/CallStringWithReceivers.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/CallStringWithReceivers.java index efde55e6..bb4dbee4 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/CallStringWithReceivers.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/CallStringWithReceivers.java @@ -19,7 +19,7 @@ public CallStringWithReceivers(CallSiteReference site, IMethod method) { public CallStringWithReceivers(CallSiteReference site, IMethod method, int length, CallString callString) { super(site, method, length, callString); } - + public void addPossibleReceiver(InstanceKey receiver) { this.getPossibleReceivers().add(receiver); } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java index 38b7c755..02a9f0e2 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java @@ -13,7 +13,6 @@ import java.nio.file.Path; import java.util.jar.JarFile; import java.util.logging.Logger; -import java.util.stream.BaseStream; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.NullProgressMonitor; @@ -41,7 +40,7 @@ * Modified from EclipseAnalysisEngine.java, originally from Keshmesh. Authored * by Mohsen Vakilian and Stas Negara. Modified by Nicholas Chen and Raffi * Khatchadourian. - * + * */ public class EclipseProjectAnalysisEngine extends JDTJavaSourceAnalysisEngine { @@ -61,14 +60,14 @@ public class EclipseProjectAnalysisEngine extends JDTJava private CallGraphBuilder callGraphBuilder; /** - * The N to use for instances of {@link BaseStream}. + * The project used to create this engine. */ - private int nToUseForStreams = N_FOR_STREAMS_DEFAULT; + private IJavaProject project; /** - * The project used to create this engine. + * The N to use for instances of {@link BaseStream}. */ - private IJavaProject project; + private int nToUseForStreams = N_FOR_STREAMS_DEFAULT; public EclipseProjectAnalysisEngine(IJavaProject project) throws IOException, CoreException { super(project); @@ -80,14 +79,6 @@ public EclipseProjectAnalysisEngine(IJavaProject project, int nForStreams) throw this.nToUseForStreams = nForStreams; } - void addToScopeNotWindows(String fileName, Path installPath) throws IOException { - scope.addToScope(Primordial, new JarFile(installPath.resolve("jre").resolve("lib").resolve(fileName).toFile())); - } - - void addToScopeWindows(String fileName, Path installPath) throws IOException { - scope.addToScope(Primordial, new JarFile(installPath.resolve("lib").resolve(fileName).toFile())); - } - @Override public void buildAnalysisScope() throws IOException { try { @@ -129,6 +120,26 @@ public void buildAnalysisScope() throws IOException { } } + void addToScopeWindows(String fileName, Path installPath) throws IOException { + scope.addToScope(Primordial, new JarFile(installPath.resolve("lib").resolve(fileName).toFile())); + } + + void addToScopeNotWindows(String fileName, Path installPath) throws IOException { + scope.addToScope(Primordial, new JarFile(installPath.resolve("jre").resolve("lib").resolve(fileName).toFile())); + } + + @Override + protected EclipseProjectPath createProjectPath(IJavaProject project) + throws IOException, CoreException { + project.open(new NullProgressMonitor()); + return TestableJavaEclipseProjectPath.create(project, NO_SOURCE); + } + + @Override + public CallGraph getCallGraph() { + return super.getCallGraph(); + } + @Override public IClassHierarchy buildClassHierarchy() { IClassHierarchy classHierarchy = super.buildClassHierarchy(); @@ -155,22 +166,6 @@ public CallGraph buildSafeCallGraph(Iterable entryPoints) return this.buildSafeCallGraph(getDefaultOptions(entryPoints)); } - public void clearCallGraphBuilder() { - this.callGraphBuilder = null; - } - - @Override - protected EclipseProjectPath createProjectPath(IJavaProject project) - throws IOException, CoreException { - project.open(new NullProgressMonitor()); - return TestableJavaEclipseProjectPath.create(project, NO_SOURCE); - } - - @Override - public CallGraph getCallGraph() { - return super.getCallGraph(); - } - public CallGraphBuilder getCallGraphBuilder() { return callGraphBuilder; } @@ -182,19 +177,23 @@ protected CallGraphBuilder getCallGraphBuilder(IClassHierarchy cha, AnalysisO return Util.makeNCFABuilder(N, options, (AnalysisCache) cache, cha, scope, this.getNToUseForStreams()); } - public int getNToUseForStreams() { - return nToUseForStreams; + public void clearCallGraphBuilder() { + this.callGraphBuilder = null; } /** * Get the project used to create this engine. - * + * * @return The project used to create this engine. */ public IJavaProject getProject() { return project; } + public int getNToUseForStreams() { + return nToUseForStreams; + } + protected void setNToUseForStreams(int nToUseForStreams) { this.nToUseForStreams = nToUseForStreams; } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/TestableJavaEclipseProjectPath.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/TestableJavaEclipseProjectPath.java index 267b28b3..499d488a 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/TestableJavaEclipseProjectPath.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/TestableJavaEclipseProjectPath.java @@ -19,29 +19,16 @@ public class TestableJavaEclipseProjectPath extends JavaEclipseProjectPath { - public static EclipseProjectPath create(IJavaProject project, AnalysisScopeType scopeType) - throws IOException, CoreException { - TestableJavaEclipseProjectPath path = new TestableJavaEclipseProjectPath(scopeType); - path.create(project.getProject()); - return path; - } - public TestableJavaEclipseProjectPath(EclipseProjectPath.AnalysisScopeType scopeType) throws IOException, CoreException { super(scopeType); } - @Override - protected boolean isPrimordialJarFile(JarFile j) { - return j.getName().endsWith("rtstubs18.jar"); - } - @Override protected void resolveLibraryPathEntry(EclipseProjectPath.ILoader loader, IPath p) { if (p.lastSegment().matches("rtstubs[0-9]*\\.jar")) - // Don't resolve per - // https://github.com/ponder-lab/Java-8-Stream-Refactoring/issues/83. + // Don't resolve per https://github.com/ponder-lab/Java-8-Stream-Refactoring/issues/83. return; File file = makeAbsolute(p).toFile(); @@ -62,4 +49,16 @@ protected void resolveLibraryPathEntry(EclipseProjectPath.ILoader loader, IPath List s = MapUtil.findOrCreateList(modules, loader); s.add(file.isDirectory() ? (Module) new BinaryDirectoryTreeModule(file) : (Module) new JarFileModule(j)); } + + @Override + protected boolean isPrimordialJarFile(JarFile j) { + return j.getName().endsWith("rtstubs18.jar"); + } + + public static EclipseProjectPath create(IJavaProject project, AnalysisScopeType scopeType) + throws IOException, CoreException { + TestableJavaEclipseProjectPath path = new TestableJavaEclipseProjectPath(scopeType); + path.create(project.getProject()); + return path; + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java index 752935bf..def31e2a 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java @@ -74,7 +74,7 @@ public static boolean isWindows() { * make a {@link CallGraphBuilder} that uses call-string context sensitivity, * with call-string length limited to n, and a context-sensitive * allocation-site-based heap abstraction. - * + * * @param nToUseForStreams * The N to use specifically for instances of {@link BaseStream}. */ diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java index cd4422a3..eaffbb3c 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java @@ -18,11 +18,6 @@ public class nCFABuilderWithActualParametersInContext extends SSAPropagationCall private static final int N_TO_USE_FOR_STREAMS_DEFAULT = 2; - public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, AnalysisOptions options, - AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter) { - this(n, cha, options, cache, appContextSelector, appContextInterpreter, N_TO_USE_FOR_STREAMS_DEFAULT); - } - public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter, int nToUseForStreams) { @@ -46,4 +41,9 @@ public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, Anal : new DelegatingSSAContextInterpreter(appContextInterpreter, defI); this.setContextInterpreter(contextInterpreter); } + + public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, AnalysisOptions options, + AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter) { + this(n, cha, options, cache, appContextSelector, appContextInterpreter, N_TO_USE_FOR_STREAMS_DEFAULT); + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java index c70f2e47..306d6bae 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java @@ -23,6 +23,8 @@ public class nCFAContextWithReceiversSelector extends nCFAContextSelector { + private static final Logger LOGGER = Logger.getLogger(LOGGER_NAME); + protected class CallStringTriple { CGNode node; @@ -62,18 +64,16 @@ public int hashCode() { */ protected static final int CONTEXT_LENGTH_FOR_STREAMS_DEFAULT = 2; - private static final Logger LOGGER = Logger.getLogger(LOGGER_NAME); - - protected Map callStringWithReceiversMap = new HashMap<>(); - /** * The N to use if the instance implements {@link BaseStream}. */ private int contextLengthForStreams = CONTEXT_LENGTH_FOR_STREAMS_DEFAULT; + protected Map callStringWithReceiversMap = new HashMap<>(); + /** * Create a new {@link nCFAContextWithReceiversSelector}. - * + * * @param n * The N to use generally. * @param base @@ -85,7 +85,7 @@ public nCFAContextWithReceiversSelector(int n, ContextSelector base) { /** * Create a new {@link nCFAContextWithReceiversSelector}. - * + * * @param n * The N to use generally. * @param base @@ -154,10 +154,6 @@ protected Map getCallStringWithReceiv return this.callStringWithReceiversMap; } - public int getContextLengthForStreams() { - return contextLengthForStreams; - } - /** * {@inheritDoc} * @@ -177,6 +173,10 @@ protected int getLength(CGNode caller, CallSiteReference site, IMethod target) { return super.getLength(caller, site, target); } + public int getContextLengthForStreams() { + return contextLengthForStreams; + } + protected void setContextLengthForStreams(int contextLengthForStreams) { this.contextLengthForStreams = contextLengthForStreams; } diff --git a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java index 0158a87e..855d8326 100644 --- a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java +++ b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java @@ -81,26 +81,26 @@ */ public class EvaluateConvertToParallelStreamRefactoringHandler extends AbstractHandler { - private static final boolean BUILD_WORKSPACE = false; - private static final String EVALUATION_PROPERTIES_FILE_NAME = "eval.properties"; - private static final boolean FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_DEFAULT = false; + private static final Logger LOGGER = Logger.getLogger(LOGGER_NAME); + + private static final boolean BUILD_WORKSPACE = false; + private static final boolean FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_DEFAULT = false; private static final String FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_PROPERTY_KEY = "edu.cuny.hunter.streamrefactoring.eval.findImplicitBenchmarkEntrypoints"; - private static final boolean FIND_IMPLICIT_ENTRYPOINTS_DEFAULT = false; + private static final boolean FIND_IMPLICIT_ENTRYPOINTS_DEFAULT = false; private static final String FIND_IMPLICIT_ENTRYPOINTS_PROPERTY_KEY = "edu.cuny.hunter.streamrefactoring.eval.findImplicitEntrypoints"; - private static final boolean FIND_IMPLICIT_TEST_ENTRYPOINTS_DEFAULT = false; + private static final boolean FIND_IMPLICIT_TEST_ENTRYPOINTS_DEFAULT = false; private static final String FIND_IMPLICIT_TEST_ENTRYPOINTS_PROPERTY_KEY = "edu.cuny.hunter.streamrefactoring.eval.findImplicitTestEntrypoints"; - private static final Logger LOGGER = Logger.getLogger(LOGGER_NAME); - private static final int LOGGING_LEVEL = IStatus.INFO; private static final int N_TO_USE_FOR_STREAMS_DEFAULT = 2; - private static final String N_TO_USE_FOR_STREAMS_PROPERTY_KEY = "nToUseForStreams"; + private static final int LOGGING_LEVEL = IStatus.INFO; + private static final boolean PERFORM_CHANGE_DEFAULT = false; private static final String PERFORM_CHANGE_PROPERTY_KEY = "edu.cuny.hunter.streamrefactoring.eval.performChange"; @@ -148,34 +148,6 @@ private static int getMethodLinesOfCode(IMethod method) { } } - private static int getNForStreams(IJavaProject project) throws IOException, JavaModelException { - Properties properties = new Properties(); - IPath filePath = project.getCorrespondingResource().getLocation().append(EVALUATION_PROPERTIES_FILE_NAME); - File file = filePath.toFile(); - - if (file.exists()) - try (Reader reader = new FileReader(file)) { - properties.load(reader); - - String nToUseForStreams = properties.getProperty(N_TO_USE_FOR_STREAMS_PROPERTY_KEY); - - if (nToUseForStreams == null) { - int ret = N_TO_USE_FOR_STREAMS_DEFAULT; - LOGGER.info("Using default N for streams: " + ret + "."); - return ret; - } else { - int ret = Integer.valueOf(nToUseForStreams); - LOGGER.info("Using properties file N for streams: " + ret + "."); - return ret; - } - } - else { - int ret = N_TO_USE_FOR_STREAMS_DEFAULT; - LOGGER.info("Using default N for streams: " + ret + "."); - return ret; - } - } - private static Collection getProjectEntryPoints(IJavaProject javaProject, ConvertToParallelStreamRefactoringProcessor processor) { return processor.getEntryPoints(javaProject); @@ -204,42 +176,6 @@ private static void printStreamAttributesWithMultipleValues(Set set, CSVPrint stream.getEnclosingType().getFullyQualifiedName(), object.toString()); } - private static boolean shouldFindImplicitBenchmarkEntrypoints() { - String findImplicitBenchmarkEntrypoints = System.getenv(FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_PROPERTY_KEY); - - if (findImplicitBenchmarkEntrypoints == null) - return FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_DEFAULT; - else - return Boolean.valueOf(findImplicitBenchmarkEntrypoints); - } - - private static boolean shouldFindImplicitEntrypoints() { - String findImplicitEntrypoits = System.getenv(FIND_IMPLICIT_ENTRYPOINTS_PROPERTY_KEY); - - if (findImplicitEntrypoits == null) - return FIND_IMPLICIT_ENTRYPOINTS_DEFAULT; - else - return Boolean.valueOf(findImplicitEntrypoits); - } - - private static boolean shouldFindImplicitTestEntrypoints() { - String findImplicitTestEntrypoints = System.getenv(FIND_IMPLICIT_TEST_ENTRYPOINTS_PROPERTY_KEY); - - if (findImplicitTestEntrypoints == null) - return FIND_IMPLICIT_TEST_ENTRYPOINTS_DEFAULT; - else - return Boolean.valueOf(findImplicitTestEntrypoints); - } - - private static boolean shouldPerformChange() { - String performChangePropertyValue = System.getenv(PERFORM_CHANGE_PROPERTY_KEY); - - if (performChangePropertyValue == null) - return PERFORM_CHANGE_DEFAULT; - else - return Boolean.valueOf(performChangePropertyValue); - } - /** * the command has been executed, so extract extract the needed information from * the application context. @@ -271,9 +207,9 @@ public Object execute(ExecutionEvent event) throws ExecutionException { IJavaProject[] javaProjects = Util.getSelectedJavaProjectsFromEvent(event); - List resultsHeader = new ArrayList<>(Arrays.asList("subject", "SLOC", "#entrypoints", "N", - "#streams", "#optimization available streams", "#optimizable streams", "#failed preconditions", - "stream instances processed", "stream instances skipped")); + List resultsHeader = new ArrayList<>( + Arrays.asList("subject", "SLOC", "#entrypoints", "N", "#streams", + "#optimization available streams", "#optimizable streams", "#failed preconditions")); for (Refactoring refactoring : Refactoring.values()) resultsHeader.add(refactoring.toString()); @@ -466,12 +402,6 @@ public Object execute(ExecutionEvent event) throws ExecutionException { entry.getCode(), entry.getMessage()); } - // #stream instances analyzed. - resultsPrinter.print(processor.getNumberOfProcessedStreamInstances()); - - // #stream instances skipped. - resultsPrinter.print(processor.getNumberOfSkippedStreamInstances()); - // Refactoring type counts. for (Refactoring refactoring : Refactoring.values()) resultsPrinter.print(processor.getStreamSet().parallelStream().map(Stream::getRefactoring) @@ -580,4 +510,68 @@ public void acceptSearchMatch(SearchMatch match) throws CoreException { }, new NullProgressMonitor()); return ret; } + + private static boolean shouldFindImplicitBenchmarkEntrypoints() { + String findImplicitBenchmarkEntrypoints = System.getenv(FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_PROPERTY_KEY); + + if (findImplicitBenchmarkEntrypoints == null) + return FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_DEFAULT; + else + return Boolean.valueOf(findImplicitBenchmarkEntrypoints); + } + + private static boolean shouldFindImplicitEntrypoints() { + String findImplicitEntrypoits = System.getenv(FIND_IMPLICIT_ENTRYPOINTS_PROPERTY_KEY); + + if (findImplicitEntrypoits == null) + return FIND_IMPLICIT_ENTRYPOINTS_DEFAULT; + else + return Boolean.valueOf(findImplicitEntrypoits); + } + + private static boolean shouldFindImplicitTestEntrypoints() { + String findImplicitTestEntrypoints = System.getenv(FIND_IMPLICIT_TEST_ENTRYPOINTS_PROPERTY_KEY); + + if (findImplicitTestEntrypoints == null) + return FIND_IMPLICIT_TEST_ENTRYPOINTS_DEFAULT; + else + return Boolean.valueOf(findImplicitTestEntrypoints); + } + + private static boolean shouldPerformChange() { + String performChangePropertyValue = System.getenv(PERFORM_CHANGE_PROPERTY_KEY); + + if (performChangePropertyValue == null) + return PERFORM_CHANGE_DEFAULT; + else + return Boolean.valueOf(performChangePropertyValue); + } + + private static int getNForStreams(IJavaProject project) throws IOException, JavaModelException { + Properties properties = new Properties(); + IPath filePath = project.getCorrespondingResource().getLocation().append(EVALUATION_PROPERTIES_FILE_NAME); + File file = filePath.toFile(); + + if (file.exists()) + try (Reader reader = new FileReader(file)) { + properties.load(reader); + + String nToUseForStreams = properties.getProperty(N_TO_USE_FOR_STREAMS_PROPERTY_KEY); + + if (nToUseForStreams == null) { + int ret = N_TO_USE_FOR_STREAMS_DEFAULT; + LOGGER.info("Using default N for streams: " + ret + "."); + return ret; + } else { + int ret = Integer.valueOf(nToUseForStreams); + LOGGER.info("Using properties file N for streams: " + ret + "."); + return ret; + } + } + else { + int ret = N_TO_USE_FOR_STREAMS_DEFAULT; + LOGGER.info("Using default N for streams: " + ret + "."); + return ret; + } + } } diff --git a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/messages/Messages.java b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/messages/Messages.java index e2260d2f..8eed2c04 100644 --- a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/messages/Messages.java +++ b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/messages/Messages.java @@ -1,5 +1,5 @@ /** - * + * */ package edu.cuny.hunter.streamrefactoring.eval.messages; diff --git a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/utils/Util.java b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/utils/Util.java index 59edf1be..c15a535e 100644 --- a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/utils/Util.java +++ b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/utils/Util.java @@ -13,6 +13,18 @@ import org.eclipse.ui.handlers.HandlerUtil; public class Util { + private Util() { + } + + public static IJavaProject[] getSelectedJavaProjectsFromEvent(ExecutionEvent event) throws ExecutionException { + ISelection currentSelection = HandlerUtil.getCurrentSelectionChecked(event); + + List list = SelectionUtil.toList(currentSelection); + IJavaProject[] javaProjects = list.stream().filter(e -> e instanceof IJavaProject) + .toArray(length -> new IJavaProject[length]); + return javaProjects; + } + public static String getMethodIdentifier(IMethod method) throws JavaModelException { if (method == null) return null; @@ -30,16 +42,4 @@ public static String getMethodIdentifier(IMethod method) throws JavaModelExcepti sb.append(")"); return sb.toString(); } - - public static IJavaProject[] getSelectedJavaProjectsFromEvent(ExecutionEvent event) throws ExecutionException { - ISelection currentSelection = HandlerUtil.getCurrentSelectionChecked(event); - - List list = SelectionUtil.toList(currentSelection); - IJavaProject[] javaProjects = list.stream().filter(e -> e instanceof IJavaProject) - .toArray(length -> new IJavaProject[length]); - return javaProjects; - } - - private Util() { - } } diff --git a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/ui/plugins/EvaluateConvertToParllelStreamRefactoringPlugin.java b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/ui/plugins/EvaluateConvertToParllelStreamRefactoringPlugin.java index b621b4db..f1449c18 100644 --- a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/ui/plugins/EvaluateConvertToParllelStreamRefactoringPlugin.java +++ b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/ui/plugins/EvaluateConvertToParllelStreamRefactoringPlugin.java @@ -4,9 +4,9 @@ import org.osgi.framework.BundleContext; public class EvaluateConvertToParllelStreamRefactoringPlugin extends Plugin { - + private static EvaluateConvertToParllelStreamRefactoringPlugin plugin; - + public static Plugin getDefault() { return plugin; } diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java index d0463f65..f1db76b2 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java @@ -60,16 +60,9 @@ public class ConvertStreamToParallelRefactoringTest extends RefactoringTest { private static final Class CLAZZ = ConvertStreamToParallelRefactoringTest.class; - private static final String ENTRY_POINT_FILENAME = "entry_points.txt"; - private static final Logger LOGGER = Logger.getLogger(CLAZZ.getName()); - /** - * The name of the directory containing resources under the project directory. - */ - private static final String RESOURCE_PATH = "resources"; - - private static final int N_TO_USE_FOR_STREAMS_DEFAULT = 2; + private static final int MAX_RETRY = 5; private static final String REFACTORING_PATH = "ConvertStreamToParallel/"; @@ -80,6 +73,10 @@ public class ConvertStreamToParallelRefactoringTest extends RefactoringTest { private static final int RETRY_DELAY = 1000; + private static final String ENTRY_POINT_FILENAME = "entry_points.txt"; + + private static final int N_TO_USE_FOR_STREAMS_DEFAULT = 2; + static { LOGGER.setLevel(Level.FINER); } @@ -108,21 +105,6 @@ private static boolean compiles(String source, Path directory) throws IOExceptio return compileSuccess; } - /** - * Copy entry_points.txt from current directory to the corresponding directory - * in junit-workspace - * - * @return true: copy successfully / false: the source file does not exist - */ - private static boolean copyEntryPointFile(Path source, Path target) throws IOException { - File file = getEntryPointFile(source); - if (file != null) { - Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); - return true; - } else - return false; - } - public static ICompilationUnit createCU(IPackageFragment pack, String name, String contents) throws Exception { ICompilationUnit compilationUnit = pack.getCompilationUnit(name); @@ -146,31 +128,38 @@ public static ICompilationUnit createCU(IPackageFragment pack, String name, Stri return cu; } - private static String errorMessage(String attribute, StreamAnalysisExpectedResult result) { - return "Unexpected " + attribute + " for " + result.getExpectedCreation() + "."; + public static Test setUpTest(Test test) { + return new Java18Setup(test); } - private static Path getAbsolutePath(String fileName) { - Path path = Paths.get(RESOURCE_PATH, fileName); - Path absolutePath = path.toAbsolutePath(); - return absolutePath; + /** + * @return an absolute path of entry_points.txt in the project directory. + */ + private Path getEntryPointFileProjectSourcePath() { + return getAbsolutePath(this.getTestPath() + this.getName()).resolve(ENTRY_POINT_FILENAME); } /** - * get the entry_points.txt + * @return The {@link Path} of where the entry points file should be copied to + * for the current project under test. */ - private static File getEntryPointFile(Path filePath) { - File file = new File(filePath.toString()); - if (file.exists()) - return file; - else - return null; + private Path getEntryPointFileProjectDestinationPath() { + return getEntryPointFileDestinationPath(this.getPackageP().getJavaProject()); + } + + /** + * @return The {@link Path} of where the entry_points.txt file should be copied + * to in the junit workspace. + */ + @SuppressWarnings("unused") + private Path getDestinationWorkspacePath() { + return getEntryPointFileDestinationPath(this.getPackageP().getJavaProject().getParent()); } /** * Returns the path of where the entry points file should be copied relative to * the given {@link IJavaElement}. - * + * * @param element * The {@link IJavaElement} in question. * @return The {@link Path} where the entry points file should be copied @@ -180,8 +169,47 @@ private static Path getEntryPointFileDestinationPath(IJavaElement element) { return Paths.get(element.getResource().getLocation().toString() + File.separator + ENTRY_POINT_FILENAME); } - public static Test setUpTest(Test test) { - return new Java18Setup(test); + @Override + protected void setUp() throws Exception { + super.setUp(); + + // this is the source path. + Path entryPointFileProjectSourcePath = getEntryPointFileProjectSourcePath(); + Path entryPointFileProjectDestinationPath = getEntryPointFileProjectDestinationPath(); + + // TODO: we also need to copy entry_points.txt to workspace directory here + // something like copyEntryPointFile(absoluteProjectPath, + // getDestinationWorkSpacePath()) + if (copyEntryPointFile(entryPointFileProjectSourcePath, entryPointFileProjectDestinationPath)) + LOGGER.info("Copied " + ENTRY_POINT_FILENAME + " successfully."); + else + LOGGER.info(ENTRY_POINT_FILENAME + " does not exist."); + } + + /** + * Copy entry_points.txt from current directory to the corresponding directory + * in junit-workspace + * + * @return true: copy successfully / false: the source file does not exist + */ + private static boolean copyEntryPointFile(Path source, Path target) throws IOException { + File file = getEntryPointFile(source); + if (file != null) { + Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); + return true; + } else + return false; + } + + /** + * get the entry_points.txt + */ + private static File getEntryPointFile(Path filePath) { + File file = new File(filePath.toString()); + if (file.exists()) + return file; + else + return null; } public static Test suite() { @@ -274,28 +302,10 @@ protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cu return createCU(pack, cuName + ".java", contents); } - /** - * @return The {@link Path} of where the entry_points.txt file should be copied - * to in the junit workspace. - */ - @SuppressWarnings("unused") - private Path getDestinationWorkspacePath() { - return getEntryPointFileDestinationPath(this.getPackageP().getJavaProject().getParent()); - } - - /** - * @return The {@link Path} of where the entry points file should be copied to - * for the current project under test. - */ - private Path getEntryPointFileProjectDestinationPath() { - return getEntryPointFileDestinationPath(this.getPackageP().getJavaProject()); - } - - /** - * @return an absolute path of entry_points.txt in the project directory. - */ - private Path getEntryPointFileProjectSourcePath() { - return getAbsolutePath(this.getTestPath() + this.getName()).resolve(ENTRY_POINT_FILENAME); + private static Path getAbsolutePath(String fileName) { + Path path = Paths.get(RESOURCE_PATH, fileName); + Path absolutePath = path.toAbsolutePath(); + return absolutePath; } /* @@ -323,6 +333,13 @@ public String getRefactoringPath() { return REFACTORING_PATH; } + /** + * Runs a single analysis test. + */ + private void helper(StreamAnalysisExpectedResult... expectedResults) throws Exception { + helper(N_TO_USE_FOR_STREAMS_DEFAULT, expectedResults); + } + /** * Runs a single analysis test. */ @@ -367,13 +384,6 @@ private void helper(int nToUseForStreams, StreamAnalysisExpectedResult... expect } } - /** - * Runs a single analysis test. - */ - private void helper(StreamAnalysisExpectedResult... expectedResults) throws Exception { - helper(N_TO_USE_FOR_STREAMS_DEFAULT, expectedResults); - } - private void refreshFromLocal() throws CoreException { if (this.getRoot().exists()) this.getRoot().getResource().refreshLocal(IResource.DEPTH_INFINITE, null); @@ -387,23 +397,6 @@ public void setFileContents(String fileName, String contents) throws IOException Files.write(absolutePath, contents.getBytes()); } - @Override - protected void setUp() throws Exception { - super.setUp(); - - // this is the source path. - Path entryPointFileProjectSourcePath = getEntryPointFileProjectSourcePath(); - Path entryPointFileProjectDestinationPath = getEntryPointFileProjectDestinationPath(); - - // TODO: we also need to copy entry_points.txt to workspace directory here - // something like copyEntryPointFile(absoluteProjectPath, - // getDestinationWorkSpacePath()) - if (copyEntryPointFile(entryPointFileProjectSourcePath, entryPointFileProjectDestinationPath)) - LOGGER.info("Copied " + ENTRY_POINT_FILENAME + " successfully."); - else - LOGGER.info(ENTRY_POINT_FILENAME + " does not exist."); - } - @Override protected void tearDown() throws Exception { this.refreshFromLocal(); @@ -430,7 +423,7 @@ protected void tearDown() throws Exception { public void testAnonymousInnerClass() throws Exception { boolean passed = false; try { - helper(new StreamAnalysisExpectedResult("new ArrayList().stream()", + this.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())); @@ -452,145 +445,88 @@ public void testArraysAsList() throws Exception { } /** - * Test for #98. + * Test #80. */ public void testArraysStream() throws Exception { - helper(new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", - Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, false, false, - null, null, null, RefactoringStatus.ERROR, - EnumSet.of(PreconditionFailure.NO_APPLICATION_CODE_IN_CALL_STRINGS))); - } - - /** - * Test #80. We need to increase N here to 3. - */ - public void testArraysStream2() throws Exception { - helper(3, new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", + this.helper(new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", 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())); } public void testBitSet() throws Exception { - helper(new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + this.helper(new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } public void testCollectionFromParameter() throws Exception { - helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), - Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); + this.helper(new StreamAnalysisExpectedResult("h.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, + false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); } public void testCollectionFromParameter2() throws Exception { - helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), - Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); + this.helper(new StreamAnalysisExpectedResult("h.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, + false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); } /** * Test for #98. */ - public void testCollectionFromParameter3() throws Exception { - helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), - Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); + public void testArraysStream() throws Exception { + helper(new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", + Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, false, false, + null, null, null, RefactoringStatus.ERROR, + EnumSet.of(PreconditionFailure.NO_APPLICATION_CODE_IN_CALL_STRINGS))); } /** - * Test for #98. Ordering.ORDERED because we are falling back. + * Test #80. We need to increase N here to 3. */ - public void testCollectionFromParameter4() throws Exception { - helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), - Collections.singleton(Ordering.ORDERED), false, false, false, null, null, null, RefactoringStatus.ERROR, - EnumSet.of(PreconditionFailure.STREAM_CODE_NOT_REACHABLE))); - } - - // Test #65, - public void testConcat() throws Exception { - helper(new StreamAnalysisExpectedResult("concat(new HashSet().parallelStream(),new HashSet().parallelStream())", - EnumSet.of(ExecutionMode.SEQUENTIAL), null, false, false, false, null, null, null, - RefactoringStatus.ERROR, Collections.singleton(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + public void testArraysStream2() throws Exception { + helper(3, new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", + 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())); } public void testConstructor() throws Exception { - helper(new StreamAnalysisExpectedResult("new ArrayList().stream()", + this.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())); } public void testDoubleStreamOf() throws Exception { - helper(new StreamAnalysisExpectedResult("DoubleStream.of(1.111)", + this.helper(new StreamAnalysisExpectedResult("DoubleStream.of(1.111)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - public void testHashSetParallelStream2() throws Exception { - this.helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", - Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, - false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); - } - - /** - * Test #172. This is a control group for testing entry point file. - */ - public void testEntryPointFile() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #172. Test correct entry point file. - */ - public void testEntryPointFile1() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #172. Test entry point file which is not corresponding to the source - * code. - */ - public void testEntryPointFile2() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); - } - - /** - * Test #172. Test whether the tool can ignore the explicit entry points in the - * source code when the entry_points.txt exists - */ - public void testEntryPointFile3() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); } public void testEntrySet() throws Exception { - helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + this.helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.UNORDERED), false, false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } public void testEntrySet2() throws Exception { - helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", null, null, false, false, false, null, null, - null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + this.helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", null, null, false, false, false, null, + null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); } public void testEntrySet3() throws Exception { - helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", null, null, false, false, false, null, null, - null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + this.helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", null, null, false, false, false, null, + null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); } public void testEntrySet4() throws Exception { - helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + this.helper(new StreamAnalysisExpectedResult("map.entrySet().stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.UNORDERED), true, false, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NON_DETERMINABLE_REDUCTION_ORDERING))); } @@ -599,7 +535,7 @@ public void testEntrySet4() throws Exception { * Test #125. A test case that includes a field. */ public void testField() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, true, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); @@ -611,7 +547,7 @@ public void testField() throws Exception { * @throws Exception */ public void testGenerate() throws Exception { - helper(new StreamAnalysisExpectedResult("Stream.generate(() -> 1)", + this.helper(new StreamAnalysisExpectedResult("Stream.generate(() -> 1)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); @@ -619,37 +555,35 @@ public void testGenerate() throws Exception { } public void testHashSetParallelStream() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, false, null, null, null, RefactoringStatus.ERROR, Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); } public void testHashSetParallelStream2() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); } public void testImplicitEntryPoint() throws Exception { - helper(new StreamAnalysisExpectedResult("IntStream.of(1)", EnumSet.of(ExecutionMode.SEQUENTIAL), + this.helper(new StreamAnalysisExpectedResult("IntStream.of(1)", 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())); } - // N needs to be 3 here. public void testIntermediateOperations() throws Exception { - helper(3, - new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.ORDERED), false, true, false, - EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), - PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, - Collections.emptySet())); + this.helper(new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.ORDERED), false, true, false, + EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), + PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, + Collections.emptySet())); } public void testIntStreamGenerate() throws Exception { - helper(new StreamAnalysisExpectedResult("IntStream.generate(() -> 1)", + this.helper(new StreamAnalysisExpectedResult("IntStream.generate(() -> 1)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); @@ -657,7 +591,7 @@ public void testIntStreamGenerate() throws Exception { } public void testIntStreamOf() throws Exception { - helper(new StreamAnalysisExpectedResult("IntStream.of(1)", Collections.singleton(ExecutionMode.SEQUENTIAL), + this.helper(new StreamAnalysisExpectedResult("IntStream.of(1)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); @@ -665,15 +599,15 @@ public void testIntStreamOf() throws Exception { } public void testLongStreamOf() throws Exception { - helper(new StreamAnalysisExpectedResult("LongStream.of(1111)", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.ORDERED), false, false, false, - Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, + this.helper(new StreamAnalysisExpectedResult("LongStream.of(1111)", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, + false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } public void testMotivatingExample() throws Exception { - helper(new StreamAnalysisExpectedResult("unorderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), + this.helper(new StreamAnalysisExpectedResult("unorderedWidgets.stream()", EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, false, true, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet()), @@ -688,7 +622,7 @@ public void testMotivatingExample() throws Exception { } public void testMultipleCallsToEnclosingMethod() throws Exception { - helper(new StreamAnalysisExpectedResult("DoubleStream.of(1.111)", + this.helper(new StreamAnalysisExpectedResult("DoubleStream.of(1.111)", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); @@ -698,7 +632,7 @@ public void testMultipleCallsToEnclosingMethod() throws Exception { * Test #122. */ public void testMultipleEntryPoints() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + this.helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); @@ -717,7 +651,7 @@ public void testNonInternalAPI() throws Exception { * Related to #126. Suggested by @mbagherz. */ public void testNonInternalAPI10() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet().stream()", + this.helper(new StreamAnalysisExpectedResult("new HashSet().stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, true, false, EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, @@ -817,7 +751,7 @@ public void testNonInternalAPI9() throws Exception { * Test #122. Remove an annotation from testMultipleEntryPoints(). */ public void testOneEntryPoint() throws Exception { - helper(new StreamAnalysisExpectedResult("h2.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + this.helper(new StreamAnalysisExpectedResult("h2.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); @@ -828,10 +762,27 @@ public void testStaticInitializer() throws Exception { null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); } + // N needs to be 3 here. + public void testIntermediateOperations() throws Exception { + helper(3, + new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.ORDERED), false, true, false, + EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), + PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, + Collections.emptySet())); + } + + public void testTypeResolution() throws Exception { + helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, + false, null, null, null, RefactoringStatus.ERROR, + EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + } + public void testStreamOf() throws Exception { - helper(new StreamAnalysisExpectedResult("Stream.of(\"a\")", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.ORDERED), false, false, false, - Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, + this.helper(new StreamAnalysisExpectedResult("Stream.of(\"a\")", + Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.ORDERED), false, false, + false, Collections.singleton(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P2, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } @@ -875,15 +826,64 @@ public void testTerminalOp3() throws Exception { Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); } - public void testTypeResolution() throws Exception { - helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", - Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, - false, null, null, null, RefactoringStatus.ERROR, - Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); + /** + * Test #119. + */ + public void testWithoutEntryPoint() throws Exception { + helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, + RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); + } + + /** + * Test #172. This is a control group for testing entry point file. + */ + public void testEntryPointFile() throws Exception { + helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.UNORDERED), false, false, false, + EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #172. Test correct entry point file. + */ + public void testEntryPointFile1() throws Exception { + helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.UNORDERED), false, false, false, + EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #172. Test entry point file which is not corresponding to the source + * code. + */ + public void testEntryPointFile2() throws Exception { + helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, + RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); + } + + /** + * Test #172. Test whether the tool can ignore the explicit entry points in the + * source code when the entry_points.txt exists + */ + public void testEntryPointFile3() throws Exception { + helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, + RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); + } + + /** + * Test #122. + */ + public void testMultipleEntryPoints() throws Exception { + helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), + Collections.singleton(Ordering.UNORDERED), false, false, false, + EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, + Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); } public void testTypeResolution2() throws Exception { - helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", + this.helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, false, null, null, null, RefactoringStatus.ERROR, Collections.singleton(PreconditionFailure.UNORDERED))); @@ -893,7 +893,7 @@ public void testTypeResolution2() throws Exception { * Test #119. */ public void testWithoutEntryPoint() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, + this.helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); } } diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java index e4e9d90f..12429f29 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/StreamAnalysisExpectedResult.java @@ -55,12 +55,8 @@ public StreamAnalysisExpectedResult(String expectedCreation, Set this.expectedFailures = expectedFailures; } - public Set getExpectedActions() { - return expectedActions; - } - - public String getExpectedCreation() { - return expectedCreation; + protected String errorMessage(String attribute) { + return "Unexpected " + attribute + " for " + this.getExpectedCreation() + "."; } public void evaluate(Stream stream) { @@ -91,12 +87,24 @@ public void evaluate(Stream stream) { assertEquals(this.errorMessage("status codes"), expectedCodes, actualCodes); } + public Set getExpectedActions() { + return this.expectedActions; + } + + public String getExpectedCreation() { + return this.expectedCreation; + } + + public Set getExpectedExecutionModes() { + return this.expectedExecutionModes; + } + public Set getExpectedFailures() { - return expectedFailures; + return this.expectedFailures; } public Set getExpectedOrderings() { - return expectedOrderings; + return this.expectedOrderings; } public PreconditionSuccess getExpectedPassingPrecondition() { @@ -112,14 +120,14 @@ public int getExpectedStatusSeverity() { } public boolean isExpectingSideEffects() { - return expectingSideEffects; + return this.expectingSideEffects; } public boolean isExpectingStatefulIntermediateOperation() { - return expectingStatefulIntermediateOperation; + return this.expectingStatefulIntermediateOperation; } public boolean isExpectingThatReduceOrderingMatters() { - return expectingThatReduceOrderingMatters; + return this.expectingThatReduceOrderingMatters; } } diff --git a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/handlers/ConvertStreamToParallelHandler.java b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/handlers/ConvertStreamToParallelHandler.java index dbe7ec49..202024e2 100644 --- a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/handlers/ConvertStreamToParallelHandler.java +++ b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/handlers/ConvertStreamToParallelHandler.java @@ -28,6 +28,7 @@ import org.eclipse.ui.handlers.HandlerUtil; import org.osgi.framework.FrameworkUtil; +import edu.cuny.hunter.streamrefactoring.core.utils.RefactoringAvailabilityTester; import edu.cuny.hunter.streamrefactoring.ui.wizards.ConvertStreamToParallelRefactoringWizard; public class ConvertStreamToParallelHandler extends AbstractHandler { @@ -40,7 +41,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { Optional monitor = Optional.empty(); ISelection currentSelection = HandlerUtil.getCurrentSelectionChecked(event); List list = SelectionUtil.toList(currentSelection); - + Set javaProjectSet = new HashSet<>(); if (list != null) { @@ -60,15 +61,15 @@ public Object execute(ExecutionEvent event) throws ExecutionException { case IJavaElement.PACKAGE_FRAGMENT_ROOT: break; case IJavaElement.JAVA_PROJECT: - javaProjectSet.add((IJavaProject) jElem); + javaProjectSet.add((IJavaProject)jElem); break; } } } Shell shell = HandlerUtil.getActiveShellChecked(event); - ConvertStreamToParallelRefactoringWizard.startRefactoring( - javaProjectSet.toArray(new IJavaProject[javaProjectSet.size()]), shell, Optional.empty()); + ConvertStreamToParallelRefactoringWizard + .startRefactoring(javaProjectSet.toArray(new IJavaProject[javaProjectSet.size()]), shell, Optional.empty()); } catch (JavaModelException e) { JavaPlugin.log(e); throw new ExecutionException("Failed to start refactoring", e); @@ -79,70 +80,77 @@ public Object execute(ExecutionEvent event) throws ExecutionException { return null; } - private Set extractMethodsFromClass(IType type, Optional monitor) + private Set extractMethodsFromJavaProject(IJavaProject jProj, Optional monitor) throws JavaModelException { Set methodSet = new HashSet<>(); - if (type.isClass()) { - for (IMethod method : type.getMethods()) - // if (RefactoringAvailabilityTester.isInterfaceMigrationAvailable(method, - // monitor)) { - if (true) { - logPossiblyMigratableMethod(method); - methodSet.add(method); - } else - logNonMigratableMethod(method); - - } + IPackageFragmentRoot[] roots = jProj.getPackageFragmentRoots(); + for (IPackageFragmentRoot iPackageFragmentRoot : roots) + methodSet.addAll(extractMethodsFromPackageFragmentRoot(iPackageFragmentRoot, monitor)); return methodSet; } - private Set extractMethodsFromCompilationUnit(ICompilationUnit cu, Optional monitor) - throws JavaModelException { + private Set extractMethodsFromPackageFragmentRoot(IPackageFragmentRoot root, + Optional monitor) throws JavaModelException { Set methodSet = new HashSet<>(); - IType[] types = cu.getTypes(); - for (IType iType : types) - methodSet.addAll(extractMethodsFromClass(iType, monitor)); + IJavaElement[] children = root.getChildren(); + for (IJavaElement child : children) + if (child.getElementType() == IJavaElement.PACKAGE_FRAGMENT) + methodSet.addAll(extractMethodsFromPackageFragment((IPackageFragment) child, monitor)); return methodSet; } - private Set extractMethodsFromJavaProject(IJavaProject jProj, Optional monitor) + private Set extractMethodsFromPackageFragment(IPackageFragment frag, Optional monitor) throws JavaModelException { Set methodSet = new HashSet<>(); + ICompilationUnit[] units = frag.getCompilationUnits(); - IPackageFragmentRoot[] roots = jProj.getPackageFragmentRoots(); - for (IPackageFragmentRoot iPackageFragmentRoot : roots) - methodSet.addAll(extractMethodsFromPackageFragmentRoot(iPackageFragmentRoot, monitor)); + for (ICompilationUnit iCompilationUnit : units) + methodSet.addAll(extractMethodsFromCompilationUnit(iCompilationUnit, monitor)); return methodSet; } - private Set extractMethodsFromPackageFragment(IPackageFragment frag, Optional monitor) + private Set extractMethodsFromCompilationUnit(ICompilationUnit cu, Optional monitor) throws JavaModelException { Set methodSet = new HashSet<>(); - ICompilationUnit[] units = frag.getCompilationUnits(); + IType[] types = cu.getTypes(); - for (ICompilationUnit iCompilationUnit : units) - methodSet.addAll(extractMethodsFromCompilationUnit(iCompilationUnit, monitor)); + for (IType iType : types) + methodSet.addAll(extractMethodsFromClass(iType, monitor)); return methodSet; } - private Set extractMethodsFromPackageFragmentRoot(IPackageFragmentRoot root, - Optional monitor) throws JavaModelException { + private Set extractMethodsFromClass(IType type, Optional monitor) + throws JavaModelException { Set methodSet = new HashSet<>(); - IJavaElement[] children = root.getChildren(); - for (IJavaElement child : children) - if (child.getElementType() == IJavaElement.PACKAGE_FRAGMENT) - methodSet.addAll(extractMethodsFromPackageFragment((IPackageFragment) child, monitor)); + if (type.isClass()) { + for (IMethod method : type.getMethods()) +// if (RefactoringAvailabilityTester.isInterfaceMigrationAvailable(method, monitor)) { + if (true) { + logPossiblyMigratableMethod(method); + methodSet.add(method); + } else + logNonMigratableMethod(method); + + } return methodSet; } + private void logPossiblyMigratableMethod(IMethod method) { + logMethod(method, "Method: %s is possibly migratable."); + } + + private void logNonMigratableMethod(IMethod method) { + logMethod(method, "Method: %s is not migratable."); + } + private void logMethod(IMethod method, String format) { Formatter formatter = new Formatter(); @@ -153,12 +161,4 @@ private void logMethod(IMethod method, String format) { formatter.close(); } - - private void logNonMigratableMethod(IMethod method) { - logMethod(method, "Method: %s is not migratable."); - } - - private void logPossiblyMigratableMethod(IMethod method) { - logMethod(method, "Method: %s is possibly migratable."); - } } \ No newline at end of file diff --git a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/messages/Messages.java b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/messages/Messages.java index 0a852886..82a4fbab 100644 --- a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/messages/Messages.java +++ b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/messages/Messages.java @@ -1,5 +1,5 @@ /** - * + * */ package edu.cuny.hunter.streamrefactoring.ui.messages; diff --git a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/plugins/OptimizeStreamRefactoringPlugin.java b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/plugins/OptimizeStreamRefactoringPlugin.java index 5d624da5..199f918f 100644 --- a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/plugins/OptimizeStreamRefactoringPlugin.java +++ b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/plugins/OptimizeStreamRefactoringPlugin.java @@ -2,28 +2,17 @@ import org.osgi.framework.BundleContext; -import edu.cuny.citytech.refactoring.common.ui.RefactoringPlugin; import edu.cuny.hunter.streamrefactoring.core.descriptors.ConvertStreamToParallelRefactoringDescriptor; +import edu.cuny.citytech.refactoring.common.ui.RefactoringPlugin; public class OptimizeStreamRefactoringPlugin extends RefactoringPlugin { - + private static OptimizeStreamRefactoringPlugin plugin; - + public static RefactoringPlugin getDefault() { return plugin; } - /* - * (non-Javadoc) - * - * @see - * edu.cuny.citytech.refactoring.common.ui.RefactoringPlugin#getRefactoringId() - */ - @Override - protected String getRefactoringId() { - return ConvertStreamToParallelRefactoringDescriptor.REFACTORING_ID; - } - @Override public void start(BundleContext context) throws Exception { plugin = this; @@ -35,4 +24,12 @@ public void stop(BundleContext context) throws Exception { plugin = null; super.stop(context); } + + /* (non-Javadoc) + * @see edu.cuny.citytech.refactoring.common.ui.RefactoringPlugin#getRefactoringId() + */ + @Override + protected String getRefactoringId() { + return ConvertStreamToParallelRefactoringDescriptor.REFACTORING_ID; + } } \ No newline at end of file diff --git a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/wizards/ConvertStreamToParallelRefactoringWizard.java b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/wizards/ConvertStreamToParallelRefactoringWizard.java index d102d87b..bafb5502 100644 --- a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/wizards/ConvertStreamToParallelRefactoringWizard.java +++ b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/wizards/ConvertStreamToParallelRefactoringWizard.java @@ -1,5 +1,5 @@ /** - * + * */ package edu.cuny.hunter.streamrefactoring.ui.wizards; @@ -7,15 +7,31 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages; import org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter; import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.ltk.core.refactoring.Refactoring; +import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring; +import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; import org.eclipse.ltk.ui.refactoring.RefactoringWizard; +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; import edu.cuny.hunter.streamrefactoring.core.messages.Messages; +import edu.cuny.hunter.streamrefactoring.core.refactorings.ConvertToParallelStreamRefactoringProcessor; import edu.cuny.hunter.streamrefactoring.core.utils.Util; /** @@ -25,6 +41,12 @@ */ public class ConvertStreamToParallelRefactoringWizard extends RefactoringWizard { + public ConvertStreamToParallelRefactoringWizard(Refactoring refactoring) { + super(refactoring, + RefactoringWizard.DIALOG_BASED_USER_INTERFACE & RefactoringWizard.CHECK_INITIAL_CONDITIONS_ON_OPEN); + this.setWindowTitle(Messages.Name); + } + public static void startRefactoring(IJavaProject[] javaProjects, Shell shell, Optional monitor) throws JavaModelException { // TODO: Will need to set the target type at some point but see #23. @@ -35,12 +57,6 @@ public static void startRefactoring(IJavaProject[] javaProjects, Shell shell, Op RefactoringSaveHelper.SAVE_REFACTORING); } - public ConvertStreamToParallelRefactoringWizard(Refactoring refactoring) { - super(refactoring, - RefactoringWizard.DIALOG_BASED_USER_INTERFACE & RefactoringWizard.CHECK_INITIAL_CONDITIONS_ON_OPEN); - this.setWindowTitle(Messages.Name); - } - // TODO: Need to add an option for N here #183. @Override protected void addUserInputPages() { From d90d8ac844e60d3f123d625216a9ec16972b573c Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Fri, 23 Feb 2018 18:11:18 -0500 Subject: [PATCH 9/9] Revert "Merge branch 'master' into issue_138" This reverts commit c03b8983430938e57dcd6fa835208b0d90ab0eb5, reversing changes made to 133e1400c8bc373a9485fd59147d845a95336703. --- README.md | 11 +- .../core/analysis/OrderingInference.java | 5 +- .../core/analysis/PreconditionFailure.java | 3 +- .../core/analysis/Stream.java | 38 +-- .../core/analysis/StreamAnalyzer.java | 167 +--------- .../core/analysis/StreamStateMachine.java | 135 ++++---- .../streamrefactoring/core/analysis/Util.java | 235 +++++--------- ...tToParallelStreamRefactoringProcessor.java | 35 +- .../core/safe/InstructionBasedSolver.java | 22 +- ...ationCodeExistsInCallStringsException.java | 21 -- .../core/safe/TypestateSolverFactory.java | 26 +- .../streamrefactoring/core/safe/Util.java | 119 ++----- .../core/utils/TimeCollector.java | 9 - .../streamrefactoring/core/utils/Util.java | 14 +- .../wala/EclipseProjectAnalysisEngine.java | 51 +-- .../streamrefactoring/core/wala/Util.java | 98 +++--- ...ABuilderWithActualParametersInContext.java | 22 +- .../nCFAContextWithReceiversSelector.java | 120 ++----- ...ertToParallelStreamRefactoringHandler.java | 80 +---- .../testArraysStream2/in/A.java | 12 - .../testEntryPointFile/in/A.java | 13 - .../testEntryPointFile1/entry_points.txt | 2 - .../testEntryPointFile1/in/A.java | 12 - .../testEntryPointFile2/entry_points.txt | 2 - .../testEntryPointFile2/in/A.java | 12 - .../testEntryPointFile3/entry_points.txt | 2 - .../testEntryPointFile3/in/A.java | 13 - ...onvertStreamToParallelRefactoringTest.java | 299 ++++++------------ ...vertStreamToParallelRefactoringWizard.java | 1 - 29 files changed, 429 insertions(+), 1150 deletions(-) delete mode 100644 edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/NoApplicationCodeExistsInCallStringsException.java delete mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testArraysStream2/in/A.java delete mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile/in/A.java delete mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile1/entry_points.txt delete mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile1/in/A.java delete mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile2/entry_points.txt delete mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile2/in/A.java delete mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile3/entry_points.txt delete mode 100644 edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile3/in/A.java diff --git a/README.md b/README.md index 14d14a6f..5a486e33 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,6 @@ This prototype refactoring plug-in for [Eclipse](http://eclipse.org) represents Explicit entry points may be marked using the appropriate annotation found in the corresponding [annotation library][annotations]. -Explicit entry points can also be marked using importing entry points from a txt file. Each time we run the tool, a txt file named "entry_points.txt" is generated and contained in the current directory of workspace. Then, before next time we run tool to evaluate the same project, move or copy "entry_points.txt" into project directory or workspace directory of the project. While evaluating the project, the tool will ignore the explicit entry points which are added manually and recognize the explicit entry points through the file automatically. - ### Limitations 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. @@ -41,17 +39,10 @@ You should have the following projects in your workspace: ### Running the Evaluator -#### Configuring the Evaluation - -A file named `eval.properties` can be placed at the project root. The following keys are available: - -Key | Value Type | Description ----------------- | ---------- | ---------- -nToUseForStreams | Integer | The value of N to use while building the nCFA for stream types. +[annotations]: https://github.com/ponder-lab/edu.cuny.hunter.streamrefactoring.annotations ### Further Information See the [wiki][wiki] for further information. [wiki]: https://github.com/ponder-lab/Java-8-Stream-Refactoring/wiki -[annotations]: https://github.com/ponder-lab/edu.cuny.hunter.streamrefactoring.annotations diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/OrderingInference.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/OrderingInference.java index de0e11dd..998f1640 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/OrderingInference.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/OrderingInference.java @@ -96,10 +96,9 @@ private String findStreamCreationMethod(TypeAbstraction typeAbstraction) { private String findStreamCreationMethod(IClass type) { Collection allMethods = type.getAllMethods(); for (com.ibm.wala.classLoader.IMethod method : allMethods) { - TypeReference typeToCheck = Util.getEvaluationType(method); - + TypeReference returnType = method.getReturnType(); // find the first one that returns a stream. - if (Util.implementsBaseStream(typeToCheck, this.getClassHierarchy())) + if (Util.implementsBaseStream(returnType, this.getClassHierarchy())) return method.getName().toString(); } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionFailure.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionFailure.java index d062329b..81780239 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionFailure.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/PreconditionFailure.java @@ -19,8 +19,7 @@ public enum PreconditionFailure { CURRENTLY_NOT_HANDLED(14), // should just be #97 currently. STREAM_CODE_NOT_REACHABLE(15), // either pivotal code isn't reachable or // entry points are misconfigured. - NO_ENTRY_POINT(16), // user didn't specify entry points. - NO_APPLICATION_CODE_IN_CALL_STRINGS(17); // N may be too small. + NO_ENTRY_POINT(16); // user didn't specify entry points. private int code; diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java index 2df34b71..b24a6461 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Stream.java @@ -59,7 +59,6 @@ import com.ibm.wala.types.TypeReference; import com.ibm.wala.util.CancelException; -import edu.cuny.hunter.streamrefactoring.core.safe.NoApplicationCodeExistsInCallStringsException; import edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames; import edu.cuny.hunter.streamrefactoring.core.utils.Util; import edu.cuny.hunter.streamrefactoring.core.wala.EclipseProjectAnalysisEngine; @@ -425,33 +424,18 @@ protected Ordering getInitialOrdering() { } public InstanceKey getInstanceKey(Collection trackedInstances, - EclipseProjectAnalysisEngine engine) - throws InvalidClassFileException, IOException, CoreException, InstanceKeyNotFoundException, - UnhandledCaseException, NoApplicationCodeExistsInCallStringsException { - // if not present. - if (this.instanceKey == null) - // compute it. - this.instanceKey = computeInstanceKey(trackedInstances, engine); - return this.instanceKey; - } - - protected InstanceKey computeInstanceKey(Collection trackedInstances, - EclipseProjectAnalysisEngine engine) - throws InvalidClassFileException, IOException, CoreException, UnhandledCaseException, - NoApplicationCodeExistsInCallStringsException, InstanceKeyNotFoundException { - Optional instructionForCreation = this.getInstructionForCreation(engine); - - if (instructionForCreation.isPresent()) { - SSAInvokeInstruction instruction = instructionForCreation.get(); - - for (InstanceKey ik : trackedInstances) - if (instanceKeyCorrespondsWithInstantiationInstruction(ik, instruction, - this.getEnclosingMethodReference(), engine)) - return ik; + EclipseProjectAnalysisEngine engine) throws InvalidClassFileException, IOException, + CoreException, InstanceKeyNotFoundException, UnhandledCaseException { + if (instanceKey == null) { + instanceKey = this.getInstructionForCreation(engine) + .flatMap(instruction -> trackedInstances.stream() + .filter(ik -> instanceKeyCorrespondsWithInstantiationInstruction(ik, instruction, + this.getEnclosingMethodReference(), engine.getCallGraph())) + .findFirst()) + .orElseThrow(() -> new InstanceKeyNotFoundException("Can't find instance key for: " + + this.getCreation() + " using tracked instances: " + trackedInstances)); } - - throw new InstanceKeyNotFoundException( - "Can't find instance key for: " + this.getCreation() + " using tracked instances: " + trackedInstances); + return instanceKey; } Optional getInstructionForCreation(EclipseProjectAnalysisEngine engine) diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java index 9e4dbcb5..90b9978f 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java @@ -2,25 +2,18 @@ import static com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints; -import java.io.File; import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; -import java.util.Optional; -import java.util.Scanner; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.BaseStream; import java.util.stream.Collectors; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.IMethodBinding; @@ -36,14 +29,12 @@ import com.ibm.wala.ipa.callgraph.Entrypoint; import com.ibm.wala.ipa.callgraph.propagation.InstanceKey; import com.ibm.wala.ipa.cha.ClassHierarchyException; -import com.ibm.wala.ipa.cha.IClassHierarchy; import com.ibm.wala.shrikeCT.InvalidClassFileException; import com.ibm.wala.ssa.SSAOptions; import com.ibm.wala.util.CancelException; import com.ibm.wala.util.scope.JUnitEntryPoints; import edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames; -import edu.cuny.hunter.streamrefactoring.core.utils.TimeCollector; import edu.cuny.hunter.streamrefactoring.core.wala.EclipseProjectAnalysisEngine; @SuppressWarnings("restriction") @@ -51,10 +42,6 @@ public class StreamAnalyzer extends ASTVisitor { private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); - private static final int N_FOR_STREAMS_DEFAULT = 2; - - private static final String ENTRY_POINT_FILENAME = "entry_points.txt"; - private static void addImplicitEntryPoints(Collection target, Iterable source) { for (Entrypoint implicitEntryPoint : source) if (target.add(implicitEntryPoint)) @@ -76,11 +63,6 @@ private static void addImplicitEntryPoints(Collection target, Iterab private Set streamSet = new HashSet<>(); - /** - * The N to use for instances of {@link BaseStream} in the nCFA. - */ - private int nForStreams = N_FOR_STREAMS_DEFAULT; - public StreamAnalyzer() { this(false); } @@ -89,21 +71,11 @@ public StreamAnalyzer(boolean visitDocTags) { super(visitDocTags); } - public StreamAnalyzer(boolean visitDocTags, int nForStreams) { - super(visitDocTags); - this.nForStreams = nForStreams; - } - public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints) { this(visitDocTags); this.findImplicitEntryPoints = findImplicitEntryPoints; } - public StreamAnalyzer(boolean visitDocTags, int nForStreams, boolean findImplicitEntryPoints) { - this(visitDocTags, findImplicitEntryPoints); - this.nForStreams = nForStreams; - } - public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints, boolean findImplicitTestEntryPoints, boolean findImplicitBenchmarkEntryPoints) { this(visitDocTags, findImplicitEntryPoints); @@ -111,33 +83,12 @@ public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints, boo this.findImplicitBenchmarkEntryPoints = findImplicitBenchmarkEntryPoints; } - public StreamAnalyzer(boolean visitDocTags, int nForStreams, boolean findImplicitEntryPoints, - boolean findImplicitTestEntryPoints, boolean findImplicitBenchmarkEntryPoints) { - this(visitDocTags, findImplicitEntryPoints, findImplicitTestEntryPoints, findImplicitBenchmarkEntryPoints); - this.nForStreams = nForStreams; - } - - /** - * Analyzes this {@link StreamAnalyzer}'s streams. - * - * @return A {@link Map} of project's analyzed along with the entry points used. - * @see #analyze(Optional). - */ - public Map> analyze() throws CoreException { - return this.analyze(Optional.empty()); - } - /** * Analyzes this {@link StreamAnalyzer}'s streams. * - * @param collector - * To exclude from the time certain parts of the analysis. - * @return A {@link Map} of project's analyzed along with the entry points used. - * @see #analyze(). + * @return {@link Map} of project's analyzed along with the entry points used. */ - public Map> analyze(Optional collector) throws CoreException { - LOGGER.info(() -> "Using N = " + this.getNForStreams() + "."); - + public Map> analyze() throws CoreException { Map> ret = new HashMap<>(); // collect the projects to be analyzed. @@ -147,23 +98,19 @@ public Map> analyze(Optional // process each project. for (IJavaProject project : projectToStreams.keySet()) { // create the analysis engine for the project. - // exclude from the analysis because the IR will be built here. - - collector.ifPresent(TimeCollector::start); EclipseProjectAnalysisEngine engine = null; try { - engine = new EclipseProjectAnalysisEngine<>(project, this.getNForStreams()); + engine = new EclipseProjectAnalysisEngine<>(project); engine.buildAnalysisScope(); } catch (IOException e) { LOGGER.log(Level.SEVERE, "Could not create analysis engine for: " + project.getElementName(), e); throw new RuntimeException(e); } - collector.ifPresent(TimeCollector::stop); // build the call graph for the project. Collection entryPoints = null; try { - entryPoints = this.buildCallGraph(engine, collector); + entryPoints = this.buildCallGraph(engine); } catch (IOException | CoreException | CancelException e) { LOGGER.log(Level.SEVERE, "Exception encountered while building call graph for: " + project.getElementName() + ".", e); @@ -232,36 +179,17 @@ public Map> analyze(Optional * @param engine * The EclipseProjectAnalysisEngine for which to build the call * graph. - * @param collector - * A {@link TimeCollector} to exclude entry point finding. * @return The {@link Entrypoint}s used in building the {@link CallGraph}. */ - protected Collection buildCallGraph(EclipseProjectAnalysisEngine engine, - Optional collector) + protected Collection buildCallGraph(EclipseProjectAnalysisEngine engine) throws IOException, CoreException, CallGraphBuilderCancelException, CancelException { // if we haven't built the call graph yet. if (!this.enginesWithBuiltCallGraphsToEntrypointsUsed.keySet().contains(engine)) { - // find entry points (but exclude it from the time). - collector.ifPresent(TimeCollector::start); - Set entryPoints; - - // find the entry_points.txt in the project directory - File entryPointFile = getEntryPointsFile(engine.getProject().getResource().getLocation(), - ENTRY_POINT_FILENAME); - - // if the file was found, - if (entryPointFile != null) { - // find explicit entry points from entry_points.txt. Ignore the explicit - // (annotation-based) entry points. - entryPoints = findEntryPointsFromFile(engine.getClassHierarchy(), entryPointFile); - entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point from file: " + ep)); - } else { - // find explicit entry points. - entryPoints = Util.findEntryPoints(engine.getClassHierarchy()); - entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point: " + ep)); - } + // find explicit entry points. + Set entryPoints = Util.findEntryPoints(engine.getClassHierarchy()); + entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point: " + ep)); - if (this.shouldFindImplicitEntryPoints()) { + if (this.findImplicitEntryPoints) { // also find implicit entry points. Iterable mainEntrypoints = makeMainEntrypoints(engine.getClassHierarchy().getScope(), engine.getClassHierarchy()); @@ -270,7 +198,7 @@ protected Collection buildCallGraph(EclipseProjectAnalysisEngine jUnitEntryPoints = JUnitEntryPoints.make(engine.getClassHierarchy()); @@ -278,7 +206,7 @@ protected Collection buildCallGraph(EclipseProjectAnalysisEngine benchmarkEntryPoints = Util.findBenchmarkEntryPoints(engine.getClassHierarchy()); @@ -291,8 +219,6 @@ protected Collection buildCallGraph(EclipseProjectAnalysisEngine buildCallGraph(EclipseProjectAnalysisEngine findEntryPointsFromFile(IClassHierarchy classHierarchy, File file) - throws IOException { - Set signatures = new HashSet<>(); - - try (Scanner scanner = new Scanner(file)) { - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - signatures.add(line); - } - } - - Set entrypoints = Util.findEntryPoints(classHierarchy, signatures); - return entrypoints; - } - - /** - * Search entry_points.txt in project directory recursively. - * - * @param directory - * Project directory. - * @param fileName - * The target file. - * @return null if the file does not exist and file if we found the file. - */ - private static File getEntryPointsFile(IPath directory, String fileName) { - // If file does not exist, find the file in upper level. - Path directoryPath = Paths.get(directory.toString()); - - File file; - do { - file = new File(directoryPath.resolve(ENTRY_POINT_FILENAME).toString()); - directoryPath = directoryPath.getParent(); - } while (!file.exists() && directoryPath != null); - - if (!file.exists()) - return null; - else - return file; - } - public Set getStreamSet() { return this.streamSet; } @@ -368,26 +247,10 @@ public void setFindImplicitEntryPoints(boolean findImplicitEntryPoints) { this.findImplicitEntryPoints = findImplicitEntryPoints; } - public boolean shouldFindImplicitEntryPoints() { - return findImplicitEntryPoints; - } - public void setFindImplicitTestEntryPoints(boolean findImplicitTestEntryPoints) { this.findImplicitTestEntryPoints = findImplicitTestEntryPoints; } - public boolean shouldFindImplicitTestEntryPoints() { - return findImplicitTestEntryPoints; - } - - public boolean shouldFindImplicitBenchmarkEntryPoints() { - return findImplicitBenchmarkEntryPoints; - } - - public void setFindImplicitBenchmarkEntryPoints(boolean findImplicitBenchmarkEntryPoints) { - this.findImplicitBenchmarkEntryPoints = findImplicitBenchmarkEntryPoints; - } - /** * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation) */ @@ -427,12 +290,4 @@ public boolean visit(MethodInvocation node) { return super.visit(node); } - - public int getNForStreams() { - return nForStreams; - } - - protected void setNForStreams(int nForStreams) { - this.nForStreams = nForStreams; - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java index 0400e5f2..7aaa96c4 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamStateMachine.java @@ -82,7 +82,6 @@ import com.ibm.wala.util.strings.Atom; import edu.cuny.hunter.streamrefactoring.core.safe.ModifiedBenignOracle; -import edu.cuny.hunter.streamrefactoring.core.safe.NoApplicationCodeExistsInCallStringsException; import edu.cuny.hunter.streamrefactoring.core.safe.TypestateSolverFactory; import edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames; import edu.cuny.hunter.streamrefactoring.core.wala.CallStringWithReceivers; @@ -202,16 +201,18 @@ private static boolean deriveRomForScalarMethod(SSAInvokeInstruction invokeInstr return deriveRomForVoidMethod(invokeInstruction); } - private static boolean deriveRomForVoidMethod(SSAInvokeInstruction invokeInstruction) - throws UnknownIfReduceOrderMattersException { + private static boolean deriveRomForVoidMethod(SSAInvokeInstruction invokeInstruction) { MethodReference declaredTarget = invokeInstruction.getCallSite().getDeclaredTarget(); if (isTerminalOperationWhereReduceOrderMatters(declaredTarget)) return true; else if (isTerminalOperationWhereReduceOrderDoesNotMatter(declaredTarget)) return false; - else - throw new UnknownIfReduceOrderMattersException("Can't decipher ROM for method: " + declaredTarget + "."); + else { + boolean ret = true; + LOGGER.warning(() -> "Can't decipher ROM for method: " + declaredTarget + ". Defaulting to: " + ret); + return ret; + } } /** @@ -273,10 +274,10 @@ private static Collection getAdditionalNecessaryReceivers // who's the caller? LOGGER.fine(() -> "Called method is: " + calledMethod); - TypeReference evaluationType = Util.getEvaluationType(calledMethod); - LOGGER.fine(() -> "Evaluation type is: " + evaluationType); + TypeReference returnType = calledMethod.getReturnType(); + LOGGER.fine(() -> "Return type is: " + returnType); - boolean implementsBaseStream = Util.implementsBaseStream(evaluationType, hierarchy); + boolean implementsBaseStream = Util.implementsBaseStream(returnType, hierarchy); LOGGER.fine(() -> "Is it a stream? " + implementsBaseStream); if (implementsBaseStream) { @@ -575,39 +576,41 @@ private void discoverIfReduceOrderingPossiblyMatters(EclipseProjectAnalysisEngin Boolean rom = null; - try { - if (isVoid(possibleReturnTypes)) - rom = deriveRomForVoidMethod(invokeInstruction); - else { - boolean scalar = Util.isScalar(possibleReturnTypes); - if (scalar) + if (isVoid(possibleReturnTypes)) + rom = deriveRomForVoidMethod(invokeInstruction); + else { + boolean scalar = Util.isScalar(possibleReturnTypes); + if (scalar) + try { rom = deriveRomForScalarMethod(invokeInstruction); - else // !scalar - rom = this.deriveRomForNonScalarMethod(possibleReturnTypes, orderingInference); - } - } catch (UnknownIfReduceOrderMattersException e) { - // for each possible receiver associated with the terminal block. - OrdinalSet receivers = this.terminalBlockToPossibleReceivers.get(block); - - for (InstanceKey instanceKey : receivers) { - // get the stream for the instance key. - Set originStreams = this.computePossibleOriginStreams(instanceKey); - - // for each origin stream. - for (InstanceKey origin : originStreams) { - // get the "Stream" representing it. - Stream stream = this.instanceToStreamMap.get(origin); - - if (stream == null) - LOGGER.warning(() -> "Can't find Stream instance for instance key: " + instanceKey - + " using origin: " + origin); - else { - LOGGER.log(Level.WARNING, "Unable to derive ROM for: " + stream.getCreation(), e); - stream.addStatusEntry(PreconditionFailure.NON_DETERMINABLE_REDUCTION_ORDERING, - "Cannot derive reduction ordering for stream: " + stream.getCreation() + "."); + } catch (UnknownIfReduceOrderMattersException e) { + // for each possible receiver associated with the terminal block. + OrdinalSet receivers = this.terminalBlockToPossibleReceivers.get(block); + + for (InstanceKey instanceKey : receivers) { + // get the stream for the instance key. + Set originStreams = this.computePossibleOriginStreams(instanceKey); + + // for each origin stream. + for (InstanceKey origin : originStreams) { + // get the "Stream" representing it. + Stream stream = this.instanceToStreamMap.get(origin); + + if (stream == null) + LOGGER.warning(() -> "Can't find Stream instance for instance key: " + + instanceKey + " using origin: " + origin); + else { + LOGGER.log(Level.WARNING, "Unable to derive ROM for : " + stream.getCreation(), + e); + stream.addStatusEntry(PreconditionFailure.NON_DETERMINABLE_REDUCTION_ORDERING, + "Cannot derive reduction ordering for stream: " + stream.getCreation() + + "."); + } + } } } - } + else // !scalar + rom = this.deriveRomForNonScalarMethod(possibleReturnTypes, orderingInference); } // if reduce ordering matters. @@ -746,17 +749,37 @@ private void discoverPossibleSideEffects(EclipseProjectAnalysisEngine= 1 : "Expecting call sites at least one-deep."; + CallSiteReference[] callSiteRefs = callString.getCallSiteRefs(); + assert callSiteRefs.length == 2 : "Expecting call sites two-deep."; + + // get the target of the caller. + MethodReference callerDeclaredTarget = callSiteRefs[1].getDeclaredTarget(); + + // get it's IR. + IMethod callerTargetMethod = engine.getClassHierarchy().resolveMethod(callerDeclaredTarget); + boolean fallback = false; - IR ir = engine.getCache().getIR(callString.getMethods()[0]); + if (callerTargetMethod == null) { + LOGGER.warning("Cannot resolve caller declared target method: " + callerDeclaredTarget); + + // fall back. + callerTargetMethod = callString.getMethods()[1]; + LOGGER.warning("Falling back to method: " + callerTargetMethod); + fallback = true; + } + + IR ir = engine.getCache().getIR(callerTargetMethod); if (ir == null) { - LOGGER.warning("Can't find IR for target: " + callString.getMethods()[0]); + LOGGER.warning("Can't find IR for target: " + callerTargetMethod); continue; // next instance. } // get calls to the caller target. - SSAAbstractInvokeInstruction[] calls = ir.getCalls(callString.getCallSiteRefs()[0]); + // if we are falling back, use index 1, otherwise stick with index + // 0. + int callSiteRefsInx = fallback ? 1 : 0; + SSAAbstractInvokeInstruction[] calls = ir.getCalls(callSiteRefs[callSiteRefsInx]); assert calls.length == 1 : "Are we only expecting one call here?"; // I guess we're only interested in ones with a single behavioral @@ -764,8 +787,8 @@ private void discoverPossibleSideEffects(EclipseProjectAnalysisEngine streamSet, EclipseProjectAnalys try { instanceKey = stream.getInstanceKey(this.trackedInstances, engine); } catch (InstanceKeyNotFoundException e) { - LOGGER.log(Level.WARNING, - "Encountered unreachable code while processing: " + stream.getCreation() + ".", e); + LOGGER.log(Level.WARNING, "Encountered unreachable code while processing: " + stream.getCreation(), e); stream.addStatusEntry(PreconditionFailure.STREAM_CODE_NOT_REACHABLE, "Either pivital code isn't reachable for stream: " + stream.getCreation() + " or entry points are misconfigured."); ++skippedStreams; continue; // next stream. } catch (UnhandledCaseException e) { - String msg = "Encountered possible unhandled case (AIC #155) while processing: " + stream.getCreation() - + "."; + 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. - } catch (NoApplicationCodeExistsInCallStringsException e) { - LOGGER.log(Level.WARNING, "Did not encounter application code in call strings while processing: " - + stream.getCreation() + ".", e); - stream.addStatusEntry(PreconditionFailure.NO_APPLICATION_CODE_IN_CALL_STRINGS, - "No application code in the call strings generated for stream: " + stream.getCreation() - + " was found. The maximum call string length may need to be increased."); - ++skippedStreams; - continue; // next stream. } // add the mapping. @@ -906,15 +919,7 @@ private Set getAllPredecessors(InstanceKey instanceKey) { } public Collection getStates(StreamAttributeTypestateRule rule, InstanceKey instanceKey) { - Map> mergedTypeState = this.originStreamToMergedTypeStateMap.get(instanceKey); - - if (mergedTypeState == null) { - LOGGER.warning( - () -> "Can't find merged type state for rule: " + rule + " and instance key: " + instanceKey); - return Collections.emptySet(); - } - - return mergedTypeState.get(rule); + return this.originStreamToMergedTypeStateMap.get(instanceKey).get(rule); } public Collection getTrackedInstances() { diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java index d85d4dbe..88f90ee9 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java @@ -60,7 +60,6 @@ import com.ibm.wala.ssa.SSAInvokeInstruction; import com.ibm.wala.ssa.SSAPhiInstruction; import com.ibm.wala.ssa.Value; -import com.ibm.wala.types.ClassLoaderReference; import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeReference; @@ -265,24 +264,6 @@ public static Set findEntryPoints(IClassHierarchy classHierarchy) { return result; } - /** - * find entry points from file - */ - public static Set findEntryPoints(IClassHierarchy classHierarchy, Set signatures) { - final Set result = new HashSet<>(); - - for (IClass klass : classHierarchy) - if (!(isJDKClass(klass) || isLibraryClass(klass))) { - // iterate over all declared methods - for (com.ibm.wala.classLoader.IMethod method : klass.getDeclaredMethods()) { - if (signatures.contains(method.getSignature())) { - addEntryPoint(result, method, classHierarchy); - } - } - } - return result; - } - static Set getAllInterfaces(ITypeBinding type) { Set ret = new HashSet<>(); ITypeBinding[] interfaces = type.getInterfaces(); @@ -393,100 +374,98 @@ public static Collection getPossibleTypesInterprocedurally(CGNo // Find the return type of the instruction. TypeInference inference = TypeInference.make(node.getIR(), false); Collection returnTypes = Util.getPossibleTypes(valueNumber, inference); + assert returnTypes.size() == 1 : "Not expecting more than one return type."; + TypeAbstraction rType = returnTypes.iterator().next(); - // for each return type. - for (TypeAbstraction rType : returnTypes) { - PointType concreteType = new PointType(concreteClass); - - if (rType.getType().getReference().equals(TypeReference.JavaLangObject)) { - IR ir = node.getIR(); - IMethod method = ir.getMethod(); - IBytecodeMethod bytecodeMethod = (IBytecodeMethod) method; - - // get the definition instruction. - SSAInvokeInstruction def = (SSAInvokeInstruction) node.getDU().getDef(valueNumber); - - // which index is it into the instruction array? - int instructionIndex = Util.indexOf(ir.getInstructions(), def); - - // get the bytecode index. - int bytecodeIndex; - try { - bytecodeIndex = bytecodeMethod.getBytecodeIndex(instructionIndex); - } catch (InvalidClassFileException e) { - throw new IllegalArgumentException( - "Value number: " + valueNumber + " does not have a definition (" + instructionIndex - + ") corresponding to a bytecode index.", - e); - } + PointType concreteType = new PointType(concreteClass); - // get the source information - SourcePosition sourcePosition; - try { - sourcePosition = method.getSourcePosition(bytecodeIndex); - } catch (InvalidClassFileException e) { - throw new IllegalArgumentException( - "Value number: " + valueNumber + " does not have bytecode index (" + bytecodeIndex - + ") corresponding to a bytecode index.", - e); - } + if (rType.getType().getReference().equals(TypeReference.JavaLangObject)) { + IR ir = node.getIR(); + IMethod method = ir.getMethod(); + IBytecodeMethod bytecodeMethod = (IBytecodeMethod) method; + + // get the definition instruction. + SSAInvokeInstruction def = (SSAInvokeInstruction) node.getDU().getDef(valueNumber); + + // which index is it into the instruction array? + int instructionIndex = Util.indexOf(ir.getInstructions(), def); + + // get the bytecode index. + int bytecodeIndex; + try { + bytecodeIndex = bytecodeMethod.getBytecodeIndex(instructionIndex); + } catch (InvalidClassFileException e) { + throw new IllegalArgumentException( + "Value number: " + valueNumber + " does not have a definition (" + instructionIndex + + ") corresponding to a bytecode index.", + e); + } + + // get the source information + SourcePosition sourcePosition; + try { + sourcePosition = method.getSourcePosition(bytecodeIndex); + } catch (InvalidClassFileException e) { + throw new IllegalArgumentException( + "Value number: " + valueNumber + " does not have bytecode index (" + bytecodeIndex + + ") corresponding to a bytecode index.", + e); + } - // let's assume that the source file is in the same project. - IJavaProject enclosingProject = engine.getProject(); - - String fqn = method.getDeclaringClass().getName().getPackage().toUnicodeString() + "." - + method.getDeclaringClass().getName().getClassName().toUnicodeString(); - IType type = enclosingProject.findType(fqn.replace('/', '.')); - // FIXME: Need to (i) exclude from result timer and (ii) use the cache in - // ConvertToParallelStreamRefactoringProcessor #141. - CompilationUnit unit = RefactoringASTParser.parseWithASTProvider(type.getTypeRoot(), true, - null); - - // We have the CompilationUnit corresponding to the instruction's file. Can we - // correlate the instruction to the method invocation in the AST? - MethodInvocation correspondingInvocation = findCorrespondingMethodInvocation(unit, - sourcePosition, def.getCallSite().getDeclaredTarget()); - - // what does the method return? - ITypeBinding genericReturnType = correspondingInvocation.resolveMethodBinding().getReturnType(); - - // Is it compatible with the concrete type we got from WALA? But first, we'll - // need to translate the Eclipse JDT type over to a IClass. - TypeReference genericTypeRef = getJDTIdentifyMapper(correspondingInvocation) - .getTypeRef(genericReturnType); - IClass genericClass = node.getClassHierarchy().lookupClass(genericTypeRef); - - boolean assignableFrom = node.getClassHierarchy().isAssignableFrom(genericClass, concreteClass); - - // if it's assignable. - if (assignableFrom) - // would the ordering be consistent? - if (wouldOrderingBeConsistent(Collections.unmodifiableCollection(ret), concreteType, + // let's assume that the source file is in the same project. + IJavaProject enclosingProject = engine.getProject(); + + String fqn = method.getDeclaringClass().getName().getPackage().toUnicodeString() + "." + + method.getDeclaringClass().getName().getClassName().toUnicodeString(); + IType type = enclosingProject.findType(fqn.replace('/', '.')); + // FIXME: Need to (i) exclude from result timer and (ii) use the cache in + // ConvertToParallelStreamRefactoringProcessor #141. + CompilationUnit unit = RefactoringASTParser.parseWithASTProvider(type.getTypeRoot(), true, null); + + // We have the CompilationUnit corresponding to the instruction's file. Can we + // correlate the instruction to the method invocation in the AST? + MethodInvocation correspondingInvocation = findCorrespondingMethodInvocation(unit, sourcePosition, + def.getCallSite().getDeclaredTarget()); + + // what does the method return? + ITypeBinding genericReturnType = correspondingInvocation.resolveMethodBinding().getReturnType(); + + // Is it compatible with the concrete type we got from WALA? But first, we'll + // need to translate the Eclipse JDT type over to a IClass. + TypeReference genericTypeRef = getJDTIdentifyMapper(correspondingInvocation) + .getTypeRef(genericReturnType); + IClass genericClass = node.getClassHierarchy().lookupClass(genericTypeRef); + + boolean assignableFrom = node.getClassHierarchy().isAssignableFrom(genericClass, concreteClass); + + // if it's assignable. + if (assignableFrom) + // would the ordering be consistent? + if (wouldOrderingBeConsistent(Collections.unmodifiableCollection(ret), concreteType, + orderingInference)) { + // if so, add it. + LOGGER.fine("Add type straight up: " + concreteType); + ret.add(concreteType); + } else { + // otherwise, would the generic type cause the + // ordering to be inconsistent? + PointType genericType = new PointType(genericClass); + + if (wouldOrderingBeConsistent(Collections.unmodifiableCollection(ret), genericType, orderingInference)) { - // if so, add it. - LOGGER.fine("Add type straight up: " + concreteType); - ret.add(concreteType); + LOGGER.fine("Defaulting to generic type: " + genericType); + ret.add(genericType); } else { - // otherwise, would the generic type cause the - // ordering to be inconsistent? - PointType genericType = new PointType(genericClass); - - if (wouldOrderingBeConsistent(Collections.unmodifiableCollection(ret), genericType, - orderingInference)) { - LOGGER.fine("Defaulting to generic type: " + genericType); - ret.add(genericType); - } else { - // fall back to the concrete type. - LOGGER.fine("Defaulting to concrete type eventhough it isn't consistent: " - + concreteType); - ret.add(concreteType); - } + // fall back to the concrete type. + LOGGER.fine( + "Defaulting to concrete type eventhough it isn't consistent: " + concreteType); + ret.add(concreteType); } - } else { - // just add it. - LOGGER.fine("Add type straight up: " + concreteType); - ret.add(concreteType); - } + } + } else { + // just add it. + LOGGER.fine("Add type straight up: " + concreteType); + ret.add(concreteType); } } } @@ -569,7 +548,6 @@ else if (Modifier.isAbstract(clazz.getModifiers())) else return false; } - public static boolean isBaseStream(IClass clazz) { return Util.isType(clazz, "java/util/stream", "BaseStream"); @@ -688,43 +666,4 @@ private static boolean wouldOrderingBeConsistent(final Collection monitor) throws JavaModelException { - this(javaProjects, settings, layer, useImplicitEntrypoints, useImplicitTestEntrypoints, - useImplicitBenchmarkEntrypoints, monitor); - try { - this.nForStreams = nForStreams; - } finally { - monitor.ifPresent(IProgressMonitor::done); - } - } - public ConvertToParallelStreamRefactoringProcessor(IJavaProject[] javaProjects, final CodeGenerationSettings settings, boolean useImplicitJoinpoints, Optional monitor) throws JavaModelException { this(javaProjects, settings, false, useImplicitJoinpoints, false, false, monitor); } - public ConvertToParallelStreamRefactoringProcessor(IJavaProject[] javaProjects, - final CodeGenerationSettings settings, int nForStreams, boolean useImplicitJoinpoints, - Optional monitor) throws JavaModelException { - this(javaProjects, settings, false, nForStreams, useImplicitJoinpoints, false, false, monitor); - } - public ConvertToParallelStreamRefactoringProcessor(IJavaProject[] javaProjects, final CodeGenerationSettings settings, Optional monitor) throws JavaModelException { this(javaProjects, settings, false, true, false, false, monitor); @@ -219,7 +196,7 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.CheckingPreconditions, this.getJavaProjects().length * 1000); final RefactoringStatus status = new RefactoringStatus(); - StreamAnalyzer analyzer = new StreamAnalyzer(false, this.getNForStreams(), this.getUseImplicitEntrypoints(), + StreamAnalyzer analyzer = new StreamAnalyzer(false, this.getUseImplicitEntrypoints(), this.getUseImplicitTestEntrypoints(), this.getUseImplicitBenchmarkEntrypoints()); this.setStreamSet(analyzer.getStreamSet()); @@ -240,7 +217,7 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi } // analyze and set entry points. - this.projectToEntryPoints = analyzer.analyze(Optional.of(this.getExcludedTimeCollector())); + this.projectToEntryPoints = analyzer.analyze(); // map empty set to unprocessed projects. for (IJavaProject project : this.getJavaProjects()) @@ -274,14 +251,6 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi } } - public int getNForStreams() { - return this.nForStreams; - } - - public void setNForStreams(int nForStreams) { - this.nForStreams = nForStreams; - } - @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/InstructionBasedSolver.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/InstructionBasedSolver.java index 2df9fea1..27e73ddf 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/InstructionBasedSolver.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/InstructionBasedSolver.java @@ -2,7 +2,6 @@ import java.util.Collection; import java.util.HashSet; -import java.util.logging.Level; import java.util.logging.Logger; import com.ibm.safe.internal.exceptions.PropertiesException; @@ -20,7 +19,6 @@ import com.ibm.wala.ssa.SSAInvokeInstruction; import edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames; -import edu.cuny.hunter.streamrefactoring.core.wala.EclipseProjectAnalysisEngine; public class InstructionBasedSolver extends TrackingUniqueSolver { @@ -28,15 +26,12 @@ public class InstructionBasedSolver extends TrackingUniqueSolver { private SSAInvokeInstruction instruction; - private EclipseProjectAnalysisEngine engine; - public InstructionBasedSolver(CallGraph cg, PointerAnalysis pointerAnalysis, TypeStateProperty property, TypeStateOptions options, ILiveObjectAnalysis live, BenignOracle ora, TypeStateMetrics metrics, IReporter reporter, TraceReporter traceReporter, IMergeFunctionFactory mergeFactory, - SSAInvokeInstruction instruction, EclipseProjectAnalysisEngine engine) { + SSAInvokeInstruction instruction) { super(cg, pointerAnalysis, property, options, live, ora, metrics, reporter, traceReporter, mergeFactory); this.instruction = instruction; - this.engine = engine; } @Override @@ -48,14 +43,9 @@ protected Collection computeTrackedInstances() throws PropertiesExc for (InstanceKey instanceKey : trackedInstancesByType) { LOGGER.info("Examining instance: " + instanceKey); - try { - if (Util.instanceKeyCorrespondsWithInstantiationInstruction(instanceKey, this.getInstruction(), null, - this.getEngine())) - ret.add(instanceKey); - } catch (NoApplicationCodeExistsInCallStringsException e) { - LOGGER.log(Level.SEVERE, e, () -> "Encountered NoApplicationCodeExistsInCallStringsException."); - throw new RuntimeException(e); - } + if (Util.instanceKeyCorrespondsWithInstantiationInstruction(instanceKey, this.getInstruction(), null, + this.getCallGraph())) + ret.add(instanceKey); } if (ret.size() != 1) @@ -69,8 +59,4 @@ protected Collection computeTrackedInstances() throws PropertiesExc protected SSAInvokeInstruction getInstruction() { return this.instruction; } - - protected EclipseProjectAnalysisEngine getEngine() { - return this.engine; - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/NoApplicationCodeExistsInCallStringsException.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/NoApplicationCodeExistsInCallStringsException.java deleted file mode 100644 index b9aebd03..00000000 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/NoApplicationCodeExistsInCallStringsException.java +++ /dev/null @@ -1,21 +0,0 @@ -package edu.cuny.hunter.streamrefactoring.core.safe; - -public class NoApplicationCodeExistsInCallStringsException extends Exception { - - public NoApplicationCodeExistsInCallStringsException(String message) { - super(message); - } - - public NoApplicationCodeExistsInCallStringsException(Throwable cause) { - super(cause); - } - - public NoApplicationCodeExistsInCallStringsException(String message, Throwable cause) { - super(message, cause); - } - - public NoApplicationCodeExistsInCallStringsException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TypestateSolverFactory.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TypestateSolverFactory.java index d1054148..7f34818b 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TypestateSolverFactory.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/TypestateSolverFactory.java @@ -16,13 +16,10 @@ import com.ibm.wala.escape.ILiveObjectAnalysis; import com.ibm.wala.ipa.callgraph.AnalysisOptions; import com.ibm.wala.ipa.callgraph.CallGraph; -import com.ibm.wala.ipa.callgraph.propagation.InstanceKey; import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; import com.ibm.wala.ssa.SSAInvokeInstruction; import com.ibm.wala.util.CancelException; -import edu.cuny.hunter.streamrefactoring.core.wala.EclipseProjectAnalysisEngine; - public class TypestateSolverFactory extends com.ibm.safe.typestate.core.TypestateSolverFactory { protected TypestateSolverFactory() { @@ -30,35 +27,34 @@ protected TypestateSolverFactory() { public static TrackingUniqueSolver getSolver(CallGraph cg, PointerAnalysis pointerAnalysis, HeapGraph hg, TypeStateProperty dfa, BenignOracle ora, TypeStateOptions options, TypeStateMetrics metrics, - IReporter reporter, TraceReporter traceReporter, SSAInvokeInstruction instruction, - EclipseProjectAnalysisEngine engine) throws PropertiesException, CancelException { + IReporter reporter, TraceReporter traceReporter, SSAInvokeInstruction instruction) + throws PropertiesException, CancelException { return getSolver(options.getTypeStateSolverKind(), cg, pointerAnalysis, hg, dfa, ora, options, metrics, - reporter, traceReporter, instruction, engine); + reporter, traceReporter, instruction); } public static TrackingUniqueSolver getSolver(TypeStateSolverKind kind, CallGraph cg, PointerAnalysis pointerAnalysis, HeapGraph hg, TypeStateProperty dfa, BenignOracle ora, TypeStateOptions options, TypeStateMetrics metrics, IReporter reporter, TraceReporter traceReporter, - SSAInvokeInstruction instruction, EclipseProjectAnalysisEngine engine) - throws PropertiesException { + SSAInvokeInstruction instruction) throws PropertiesException { IMergeFunctionFactory mergeFactory = makeMergeFactory(options, kind); ILiveObjectAnalysis live = getLiveObjectAnalysis(cg, hg, options); return new InstructionBasedSolver(cg, pointerAnalysis, dfa, options, live, ora, metrics, reporter, - traceReporter, mergeFactory, instruction, engine); + traceReporter, mergeFactory, instruction); } - public static ISafeSolver getSolver(AnalysisOptions domoOptions, CallGraph cg, PointerAnalysis pointerAnalysis, - HeapGraph hg, TypeStateProperty dfa, BenignOracle ora, TypeStateOptions options, - TypeStateMetrics metrics, IReporter reporter, TraceReporter traceReporter) + public static ISafeSolver getSolver(AnalysisOptions domoOptions, CallGraph cg, + PointerAnalysis pointerAnalysis, HeapGraph hg, TypeStateProperty dfa, BenignOracle ora, + TypeStateOptions options, TypeStateMetrics metrics, IReporter reporter, TraceReporter traceReporter) throws PropertiesException, CancelException { IMergeFunctionFactory mergeFactory = makeMergeFactory(options, TypeStateSolverKind.UNIQUE); ILiveObjectAnalysis live = getLiveObjectAnalysis(cg, hg, options); - return new UniqueSolver(cg, pointerAnalysis, dfa, options, live, ora, metrics, reporter, traceReporter, - mergeFactory); + return new UniqueSolver(cg, pointerAnalysis, dfa, options, live, ora, metrics, reporter, traceReporter, mergeFactory); } protected static ILiveObjectAnalysis getLiveObjectAnalysis(CallGraph cg, HeapGraph hg, TypeStateOptions options) throws PropertiesException { - return options.shouldUseLiveAnalysis() ? TypeStateSolverCreator.computeLiveObjectAnalysis(cg, hg, false) : null; + return options.shouldUseLiveAnalysis() + ? TypeStateSolverCreator.computeLiveObjectAnalysis(cg, hg, false) : null; } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java index 597a1744..eab6cbbc 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/safe/Util.java @@ -1,7 +1,6 @@ package edu.cuny.hunter.streamrefactoring.core.safe; import java.util.Iterator; -import java.util.logging.Logger; import com.ibm.wala.classLoader.CallSiteReference; import com.ibm.wala.classLoader.IMethod; @@ -10,49 +9,24 @@ import com.ibm.wala.ipa.callgraph.CallGraph; import com.ibm.wala.ipa.callgraph.ContextItem; import com.ibm.wala.ipa.callgraph.propagation.InstanceKey; -import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder; import com.ibm.wala.ipa.callgraph.propagation.cfa.CallString; import com.ibm.wala.ipa.callgraph.propagation.cfa.CallStringContextSelector; import com.ibm.wala.ssa.SSAInvokeInstruction; -import com.ibm.wala.types.ClassLoaderReference; import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.TypeName; -import com.ibm.wala.types.TypeReference; import com.ibm.wala.util.collections.Pair; import com.ibm.wala.util.strings.Atom; -import edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames; -import edu.cuny.hunter.streamrefactoring.core.wala.EclipseProjectAnalysisEngine; -import edu.cuny.hunter.streamrefactoring.core.wala.nCFAContextWithReceiversSelector; - public class Util { - /** - * The {@link TypeName} of the type {@link java.util.Arrays}. - */ - @SuppressWarnings("unused") - private static final TypeName ARRAYS_TYPE_NAME = TypeName.string2TypeName("Ljava/util/Arrays"); - - /** - * {@link Atom} corresponding the the stream() method. - */ - @SuppressWarnings("unused") - private static final Atom STREAM_METHOD_NAME_ATOM = Atom.findOrCreateAsciiAtom("stream"); - - /** - * The {@link TypeName} for the type {@link java.util.stream.StreamSupport}. - */ - @SuppressWarnings("unused") - private static final TypeName STREAM_SUPPORT_TYPE_NAME = TypeName - .string2TypeName("Ljava/util/stream/StreamSupport"); - - private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); + private Util() { + } /** * True iff the given {@link InstanceKey} corresponds with the given * {@link SSAInvokeInstruction} in the given {@link CallGraph}. In other words, * the result is true iff the instruction is used to create the instance. - * + * * @param instanceKey * An instance in question. * @param instruction @@ -62,25 +36,12 @@ public class Util { * The corresponding call graph. * @return True iff the given instruction was used to instantiate the given * instance key according to the given call graph. - * @throws NoApplicationCodeExistsInCallStringsException - * Iff application code was not found while processing call strings. */ public static boolean instanceKeyCorrespondsWithInstantiationInstruction(InstanceKey instanceKey, - SSAInvokeInstruction instruction, MethodReference instructionEnclosingMethod, - EclipseProjectAnalysisEngine engine) throws NoApplicationCodeExistsInCallStringsException { + SSAInvokeInstruction instruction, MethodReference instructionEnclosingMethod, CallGraph callGraph) { // Creation sites for the instance with the given key in the given call // graph. - Iterator> creationSites = instanceKey.getCreationSites(engine.getCallGraph()); - - CallSiteReference instructionCallSite = instruction.getCallSite(); - LOGGER.fine("instruction call site is: " + instructionCallSite); - - // did we see an application code entity in a call string? If not, this could - // indicate that N is too small. - boolean applicationCodeInCallString = false; - - // true iff all non-application code in the call strings return streams. - boolean allNonApplicationCodeReturnsStreams = true; + Iterator> creationSites = instanceKey.getCreationSites(callGraph); // for each creation site. while (creationSites.hasNext()) { @@ -102,71 +63,31 @@ public static boolean instanceKeyCorrespondsWithInstantiationInstruction(Instanc // for each call site reference. for (int i = 0; i < callSiteRefs.length; i++) { CallSiteReference callSiteReference = callSiteRefs[i]; - LOGGER.fine("Call site reference at " + i + " is: " + callSiteReference); - IMethod method = methods[i]; - LOGGER.fine("Method at " + i + " is: " + method); - - ClassLoaderReference callSiteReferenceClassLoaderReference = callSiteReference.getDeclaredTarget() - .getDeclaringClass().getClassLoader(); - ClassLoaderReference methodClassLoader = method.getReference().getDeclaringClass().getClassLoader(); - - // if we haven't encountered application code in the call string yet. - if (!applicationCodeInCallString) { - // get the class loaders. - - // if either the call site reference class loader or the (enclosing) method - // class loader is of type Application. - if (callSiteReferenceClassLoaderReference.equals(ClassLoaderReference.Application) - || methodClassLoader.equals(ClassLoaderReference.Application)) - // then, we've seen application code. - applicationCodeInCallString = true; - } - - // if all non-application code in the call strings return streams. - if (allNonApplicationCodeReturnsStreams) { - // find out if this one does as well. - if (!callSiteReferenceClassLoaderReference.equals(ClassLoaderReference.Application)) { - IMethod target = engine.getClassHierarchy() - .resolveMethod(callSiteReference.getDeclaredTarget()); - TypeReference type = edu.cuny.hunter.streamrefactoring.core.analysis.Util - .getEvaluationType(target); - - boolean implementsBaseStream = edu.cuny.hunter.streamrefactoring.core.analysis.Util - .implementsBaseStream(type, engine.getClassHierarchy()); - - if (!implementsBaseStream) - // we found one that doesn't. - allNonApplicationCodeReturnsStreams = false; - } - } + CallSiteReference instructionCallSite = instruction.getCallSite(); // if the call site reference equals the call site corresponding // to the creation instruction. if (callSiteReference.equals(instructionCallSite) - && method.getReference().getSignature().equals(instructionEnclosingMethod.getSignature())) { - LOGGER.fine("Match found. Instance key: " + instanceKey + " corresponds with instruction: " - + instruction + "."); + && method.getReference().getSignature().equals(instructionEnclosingMethod.getSignature())) return true; + // workaround #80. + else if (callSiteReference.getProgramCounter() == instructionCallSite.getProgramCounter()) { + // compare declared targets. + MethodReference callSiteDeclaredTarget = callSiteReference.getDeclaredTarget(); + MethodReference instructionCallDeclaredTarget = instructionCallSite.getDeclaredTarget(); + + if (callSiteDeclaredTarget.getDeclaringClass().getName() + .equals(instructionCallDeclaredTarget.getDeclaringClass().getName()) + && callSiteDeclaredTarget.getDeclaringClass().getName() + .equals(TypeName.string2TypeName("Ljava/util/Arrays")) + && callSiteDeclaredTarget.getName().equals(instructionCallDeclaredTarget.getName()) + && callSiteDeclaredTarget.getName().equals(Atom.findOrCreateAsciiAtom("stream"))) + return true; } } } - LOGGER.fine("No match found. Instance key: " + instanceKey + " does not correspond with instruction: " - + instruction + "."); - - // if we did not encounter application code in the call strings and if all - // of the non-application code all return streams. - if (!applicationCodeInCallString && allNonApplicationCodeReturnsStreams) - throw new NoApplicationCodeExistsInCallStringsException( - "Could not find application code in call string while processing instance key: " + instanceKey - + " and instruction: " + instruction + ". This may indicate that the current value of N (" - + ((nCFAContextWithReceiversSelector) ((PropagationCallGraphBuilder) engine - .getCallGraphBuilder()).getContextSelector()).getContextLengthForStreams() - + ") is too small."); - return false; } - private Util() { - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/TimeCollector.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/TimeCollector.java index 877c738a..60c27c88 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/TimeCollector.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/TimeCollector.java @@ -11,19 +11,12 @@ public class TimeCollector { private long collectedTime; private long start; - private boolean started; public void start() { - assert !started : "Time colletor is already started."; - started = true; - start = System.currentTimeMillis(); } public void stop() { - assert started : "Trying to stop a time collector that isn't started."; - started = false; - final long elapsed = System.currentTimeMillis() - start; collectedTime += elapsed; } @@ -33,8 +26,6 @@ public long getCollectedTime() { } public void clear() { - assert !started : "Shouldn't clear a running time collector."; - collectedTime = 0; } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/Util.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/Util.java index 75d89100..a1bae0d4 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/Util.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/utils/Util.java @@ -3,8 +3,6 @@ */ package edu.cuny.hunter.streamrefactoring.core.utils; -import static org.eclipse.jdt.core.dom.ASTNode.PARENTHESIZED_EXPRESSION; - import java.util.Optional; import org.eclipse.core.runtime.CoreException; @@ -45,16 +43,6 @@ public static ConvertToParallelStreamRefactoringProcessor createConvertToParalle return processor; } - public static ConvertToParallelStreamRefactoringProcessor createConvertToParallelStreamRefactoringProcessor( - IJavaProject[] projects, int nForStreams, boolean useImplicitEntrypoints, - boolean useImplicitTestEntrypoints, boolean useImplicitBenchmarkEntrypoints, - Optional monitor) throws JavaModelException { - ConvertToParallelStreamRefactoringProcessor processor = createConvertToParallelStreamRefactoringProcessor( - projects, useImplicitEntrypoints, useImplicitTestEntrypoints, useImplicitBenchmarkEntrypoints, monitor); - processor.setNForStreams(nForStreams); - return processor; - } - public static ConvertToParallelStreamRefactoringProcessor createConvertToParallelStreamRefactoringProcessor( IJavaProject[] projects, Optional monitor) throws JavaModelException { CodeGenerationSettings settings = JavaPreferencesSettings.getCodeGenerationSettings(projects[0]); @@ -157,7 +145,7 @@ public static String getQualifiedNameFromTypeSignature(String typeSignature, ITy } public static ASTNode stripParenthesizedExpressions(ASTNode node) { - if (node != null && node.getNodeType() == PARENTHESIZED_EXPRESSION) { + if (node != null && node.getNodeType() == ASTNode.PARENTHESIZED_EXPRESSION) { ParenthesizedExpression parenthesizedExpression = (ParenthesizedExpression) node; return stripParenthesizedExpressions(parenthesizedExpression.getExpression()); } else diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java index 02a9f0e2..68122c18 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/EclipseProjectAnalysisEngine.java @@ -3,14 +3,9 @@ */ package edu.cuny.hunter.streamrefactoring.core.wala; -import static com.ibm.wala.ide.util.EclipseProjectPath.AnalysisScopeType.NO_SOURCE; -import static com.ibm.wala.types.ClassLoaderReference.Primordial; -import static edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames.LOGGER_NAME; - import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.nio.file.Path; import java.util.jar.JarFile; import java.util.logging.Logger; @@ -22,6 +17,7 @@ import com.ibm.wala.cast.java.client.JDTJavaSourceAnalysisEngine; import com.ibm.wala.ide.util.EclipseProjectPath; +import com.ibm.wala.ide.util.EclipseProjectPath.AnalysisScopeType; import com.ibm.wala.ipa.callgraph.AnalysisCache; import com.ibm.wala.ipa.callgraph.AnalysisOptions; import com.ibm.wala.ipa.callgraph.CallGraph; @@ -36,6 +32,8 @@ import com.ibm.wala.util.CancelException; import com.ibm.wala.util.config.FileOfClasses; +import edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames; + /** * Modified from EclipseAnalysisEngine.java, originally from Keshmesh. Authored * by Mohsen Vakilian and Stas Negara. Modified by Nicholas Chen and Raffi @@ -44,19 +42,13 @@ */ public class EclipseProjectAnalysisEngine extends JDTJavaSourceAnalysisEngine { - private static final Logger LOGGER = Logger.getLogger(LOGGER_NAME); + private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME); /** * The N value used to create the {@link nCFABuilder}. */ private static final int N = 1; - /** - * The default N value used for instances of {@link BaseStream} to create the - * {@link nCFABuilder}. - */ - private static final int N_FOR_STREAMS_DEFAULT = 2; - private CallGraphBuilder callGraphBuilder; /** @@ -64,21 +56,11 @@ public class EclipseProjectAnalysisEngine extends JDTJava */ private IJavaProject project; - /** - * The N to use for instances of {@link BaseStream}. - */ - private int nToUseForStreams = N_FOR_STREAMS_DEFAULT; - public EclipseProjectAnalysisEngine(IJavaProject project) throws IOException, CoreException { super(project); this.project = project; } - public EclipseProjectAnalysisEngine(IJavaProject project, int nForStreams) throws IOException, CoreException { - this(project); - this.nToUseForStreams = nForStreams; - } - @Override public void buildAnalysisScope() throws IOException { try { @@ -96,7 +78,7 @@ public void buildAnalysisScope() throws IOException { IVMInstall defaultVMInstall = JavaRuntime.getDefaultVMInstall(); File installLocation = defaultVMInstall.getInstallLocation(); - Path installPath = installLocation.toPath(); + java.nio.file.Path installPath = installLocation.toPath(); if (Util.isWindows()) { addToScopeWindows("resources.jar", installPath); @@ -120,19 +102,21 @@ public void buildAnalysisScope() throws IOException { } } - void addToScopeWindows(String fileName, Path installPath) throws IOException { - scope.addToScope(Primordial, new JarFile(installPath.resolve("lib").resolve(fileName).toFile())); + void addToScopeWindows(String fileName, java.nio.file.Path installPath) throws IOException { + scope.addToScope(ClassLoaderReference.Primordial, + new JarFile(installPath.resolve("lib").resolve(fileName).toFile())); } - void addToScopeNotWindows(String fileName, Path installPath) throws IOException { - scope.addToScope(Primordial, new JarFile(installPath.resolve("jre").resolve("lib").resolve(fileName).toFile())); + void addToScopeNotWindows(String fileName, java.nio.file.Path installPath) throws IOException { + scope.addToScope(ClassLoaderReference.Primordial, + new JarFile(installPath.resolve("jre").resolve("lib").resolve(fileName).toFile())); } @Override protected EclipseProjectPath createProjectPath(IJavaProject project) throws IOException, CoreException { project.open(new NullProgressMonitor()); - return TestableJavaEclipseProjectPath.create(project, NO_SOURCE); + return TestableJavaEclipseProjectPath.create(project, AnalysisScopeType.NO_SOURCE); } @Override @@ -173,8 +157,7 @@ public CallGraphBuilder getCallGraphBuilder() { @Override protected CallGraphBuilder getCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, IAnalysisCacheView cache) { - LOGGER.info(() -> "Using N = " + this.getNToUseForStreams()); - return Util.makeNCFABuilder(N, options, (AnalysisCache) cache, cha, scope, this.getNToUseForStreams()); + return Util.makeNCFABuilder(N, options, (AnalysisCache) cache, cha, scope); } public void clearCallGraphBuilder() { @@ -189,12 +172,4 @@ public void clearCallGraphBuilder() { public IJavaProject getProject() { return project; } - - public int getNToUseForStreams() { - return nToUseForStreams; - } - - protected void setNToUseForStreams(int nToUseForStreams) { - this.nToUseForStreams = nToUseForStreams; - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java index def31e2a..50bf7b9b 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/Util.java @@ -2,19 +2,10 @@ import static com.ibm.wala.ipa.callgraph.impl.Util.addDefaultBypassLogic; import static com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors; -import static com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys.ALLOCATIONS; -import static com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys.SMUSH_MANY; -import static com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys.SMUSH_PRIMITIVE_HOLDERS; -import static com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys.SMUSH_STRINGS; -import static com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys.SMUSH_THROWABLES; -import static com.ibm.wala.types.ClassLoaderReference.Application; -import static com.ibm.wala.types.ClassLoaderReference.Extension; -import static com.ibm.wala.types.ClassLoaderReference.Primordial; import java.io.File; import java.io.IOException; import java.util.Collection; -import java.util.stream.BaseStream; import com.ibm.wala.classLoader.Module; import com.ibm.wala.ide.util.EclipseProjectPath; @@ -32,13 +23,21 @@ public final class Util { - private static final String OS_NAME = "os.name"; - private static final String WINDOWS = "Windows"; + private Util() { + } + + public static String getOSName() { + return System.getProperty("os.name"); + } + + public static boolean isWindows() { + return getOSName().startsWith("Windows"); + } /** - * Enhance an {@link AnalysisScope} to include in a particular loader, elements - * from a set of Eclipse projects - * + * Enhance an {@link AnalysisScope} to include in a particular loader, + * elements from a set of Eclipse projects + * * @param loader * the class loader in which new {@link Module}s will live * @param projectPaths @@ -47,54 +46,22 @@ public final class Util { * the {@link AnalysisScope} under construction. This will be * mutated. * @param seen - * set of {@link Module}s which have already been seen, and should - * not be added to the analysis scope + * set of {@link Module}s which have already been seen, and + * should not be added to the analysis scope */ private static void buildScope(ClassLoaderReference loader, Collection projectPaths, AnalysisScope scope, Collection seen) throws IOException { for (EclipseProjectPath path : projectPaths) { AnalysisScope pScope = path.toAnalysisScope((File) null); - for (Module m : pScope.getModules(loader)) + for (Module m : pScope.getModules(loader)) { if (!seen.contains(m)) { seen.add(m); scope.addToScope(loader, m); } + } } } - public static String getOSName() { - return System.getProperty(OS_NAME); - } - - public static boolean isWindows() { - return getOSName().startsWith(WINDOWS); - } - - /** - * make a {@link CallGraphBuilder} that uses call-string context sensitivity, - * with call-string length limited to n, and a context-sensitive - * allocation-site-based heap abstraction. - * - * @param nToUseForStreams - * The N to use specifically for instances of {@link BaseStream}. - */ - public static SSAPropagationCallGraphBuilder makeNCFABuilder(int n, AnalysisOptions options, AnalysisCache cache, - IClassHierarchy cha, AnalysisScope scope, int nToUseForStreams) { - if (options == null) - throw new IllegalArgumentException("options is null"); - addDefaultSelectors(options, cha); - addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha); - ContextSelector appSelector = null; - SSAContextInterpreter appInterpreter = null; - SSAPropagationCallGraphBuilder result = new nCFABuilderWithActualParametersInContext(n, cha, options, cache, - appSelector, appInterpreter, nToUseForStreams); - // nCFABuilder uses type-based heap abstraction by default, but we want - // allocation sites - result.setInstanceKeys(new ZeroXInstanceKeys(options, cha, result.getContextInterpreter(), - ALLOCATIONS | SMUSH_MANY | SMUSH_PRIMITIVE_HOLDERS | SMUSH_STRINGS | SMUSH_THROWABLES)); - return result; - } - /** * create an analysis scope as the union of a bunch of EclipseProjectPath */ @@ -105,12 +72,31 @@ public static AnalysisScope mergeProjectPaths(Collection pro // to avoid duplicates, we first add all application modules, then // extension // modules, then primordial - buildScope(Application, projectPaths, scope, seen); - buildScope(Extension, projectPaths, scope, seen); - buildScope(Primordial, projectPaths, scope, seen); + buildScope(ClassLoaderReference.Application, projectPaths, scope, seen); + buildScope(ClassLoaderReference.Extension, projectPaths, scope, seen); + buildScope(ClassLoaderReference.Primordial, projectPaths, scope, seen); return scope; } - - private Util() { - } + + /** + * make a {@link CallGraphBuilder} that uses call-string context sensitivity, + * with call-string length limited to n, and a context-sensitive + * allocation-site-based heap abstraction. + */ + public static SSAPropagationCallGraphBuilder makeNCFABuilder(int n, AnalysisOptions options, AnalysisCache cache, + IClassHierarchy cha, AnalysisScope scope) { + if (options == null) { + throw new IllegalArgumentException("options is null"); + } + addDefaultSelectors(options, cha); + addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha); + ContextSelector appSelector = null; + SSAContextInterpreter appInterpreter = null; + SSAPropagationCallGraphBuilder result = new nCFABuilderWithActualParametersInContext(n, cha, options, cache, appSelector, appInterpreter); + // nCFABuilder uses type-based heap abstraction by default, but we want allocation sites + result.setInstanceKeys(new ZeroXInstanceKeys(options, cha, result.getContextInterpreter(), ZeroXInstanceKeys.ALLOCATIONS + | ZeroXInstanceKeys.SMUSH_MANY | ZeroXInstanceKeys.SMUSH_PRIMITIVE_HOLDERS | ZeroXInstanceKeys.SMUSH_STRINGS + | ZeroXInstanceKeys.SMUSH_THROWABLES)); + return result; + } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java index eaffbb3c..7edf90e5 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFABuilderWithActualParametersInContext.java @@ -16,34 +16,28 @@ public class nCFABuilderWithActualParametersInContext extends SSAPropagationCallGraphBuilder { - private static final int N_TO_USE_FOR_STREAMS_DEFAULT = 2; - public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, AnalysisOptions options, - AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter, - int nToUseForStreams) { + AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter) { super(cha, options, cache, new DefaultPointerKeyFactory()); - if (options == null) + if (options == null) { throw new IllegalArgumentException("options is null"); + } - this.setInstanceKeys(new ClassBasedInstanceKeys(options, cha)); + setInstanceKeys(new ClassBasedInstanceKeys(options, cha)); ContextSelector def = new DefaultContextSelector(options, cha); ContextSelector contextSelector = appContextSelector == null ? def : new DelegatingContextSelector(appContextSelector, def); - contextSelector = new nCFAContextWithReceiversSelector(n, contextSelector, nToUseForStreams); - this.setContextSelector(contextSelector); + contextSelector = new nCFAContextWithReceiversSelector(n, contextSelector); + setContextSelector(contextSelector); SSAContextInterpreter defI = new DefaultSSAInterpreter(options, cache); defI = new DelegatingSSAContextInterpreter( - ReflectionContextInterpreter.createReflectionContextInterpreter(cha, options, this.getAnalysisCache()), + ReflectionContextInterpreter.createReflectionContextInterpreter(cha, options, getAnalysisCache()), defI); SSAContextInterpreter contextInterpreter = appContextInterpreter == null ? defI : new DelegatingSSAContextInterpreter(appContextInterpreter, defI); - this.setContextInterpreter(contextInterpreter); + setContextInterpreter(contextInterpreter); } - public nCFABuilderWithActualParametersInContext(int n, IClassHierarchy cha, AnalysisOptions options, - AnalysisCache cache, ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter) { - this(n, cha, options, cache, appContextSelector, appContextInterpreter, N_TO_USE_FOR_STREAMS_DEFAULT); - } } diff --git a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java index 306d6bae..5ba87c1f 100644 --- a/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java +++ b/edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/wala/nCFAContextWithReceiversSelector.java @@ -1,10 +1,7 @@ package edu.cuny.hunter.streamrefactoring.core.wala; -import static edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames.LOGGER_NAME; - import java.util.HashMap; import java.util.Map; -import java.util.logging.Logger; import java.util.stream.BaseStream; import com.ibm.wala.classLoader.CallSiteReference; @@ -17,35 +14,22 @@ import com.ibm.wala.ipa.callgraph.propagation.cfa.CallString; import com.ibm.wala.ipa.callgraph.propagation.cfa.CallStringContext; import com.ibm.wala.ipa.callgraph.propagation.cfa.nCFAContextSelector; -import com.ibm.wala.types.TypeReference; import edu.cuny.hunter.streamrefactoring.core.analysis.Util; public class nCFAContextWithReceiversSelector extends nCFAContextSelector { - private static final Logger LOGGER = Logger.getLogger(LOGGER_NAME); - protected class CallStringTriple { - CGNode node; - - CallSiteReference site; - IMethod target; - public CallStringTriple(CGNode node, CallSiteReference site, IMethod target) { this.node = node; this.site = site; this.target = target; } - @Override - public boolean equals(Object obj) { - if (obj instanceof CallStringTriple) { - CallStringTriple rhs = (CallStringTriple) obj; - return this.node.equals(rhs.node) && this.site.equals(rhs.site) && this.target.equals(rhs.target); - } else - return false; - } + CGNode node; + CallSiteReference site; + IMethod target; @Override public int hashCode() { @@ -57,59 +41,35 @@ public int hashCode() { return builder.toString().hashCode(); } - } - /** - * The default N to use if the instance implements BaseStream. - */ - protected static final int CONTEXT_LENGTH_FOR_STREAMS_DEFAULT = 2; - - /** - * The N to use if the instance implements {@link BaseStream}. - */ - private int contextLengthForStreams = CONTEXT_LENGTH_FOR_STREAMS_DEFAULT; + @Override + public boolean equals(Object obj) { + if (obj instanceof CallStringTriple) { + CallStringTriple rhs = (CallStringTriple) obj; + return this.node.equals(rhs.node) && this.site.equals(rhs.site) && this.target.equals(rhs.target); + } else + return false; + } + } protected Map callStringWithReceiversMap = new HashMap<>(); - /** - * Create a new {@link nCFAContextWithReceiversSelector}. - * - * @param n - * The N to use generally. - * @param base - * The base {@link ContextSelector}. - */ public nCFAContextWithReceiversSelector(int n, ContextSelector base) { super(n, base); } - /** - * Create a new {@link nCFAContextWithReceiversSelector}. - * - * @param n - * The N to use generally. - * @param base - * The base {@link ContextSelector}. - * @param nToUseForStreams - * The particular N to use if the instance is ok {@link BaseStream}. - */ - public nCFAContextWithReceiversSelector(int n, ContextSelector base, int nToUseForStreams) { - super(n, base); - LOGGER.info(() -> "Using N = " + nToUseForStreams); - this.contextLengthForStreams = nToUseForStreams; - } - @Override public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] actualParameters) { - Context baseContext = this.base.getCalleeTarget(caller, site, callee, actualParameters); - CallStringWithReceivers cs = this.getCallString(caller, site, callee, actualParameters); - if (cs == null) + Context baseContext = base.getCalleeTarget(caller, site, callee, actualParameters); + CallStringWithReceivers cs = getCallString(caller, site, callee, actualParameters); + if (cs == null) { return baseContext; - else if (baseContext == Everywhere.EVERYWHERE) + } else if (baseContext == Everywhere.EVERYWHERE) { return new CallStringContext(cs); - else + } else { return new CallStringContextPair(cs, baseContext); + } } protected CallStringWithReceivers getCallString(CGNode caller, CallSiteReference site, IMethod target, @@ -128,17 +88,18 @@ protected CallStringWithReceivers getCallString(CGNode caller, CallSiteReference } else { // not found. Compute it. CallStringWithReceivers ret = null; - int length = this.getLength(caller, site, target); + int length = getLength(caller, site, target); if (length > 0) { - CallString callString = (CallString) caller.getContext().get(CALL_STRING); - - if (callString != null) - ret = new CallStringWithReceivers(site, caller.getMethod(), length, callString); - else + if (caller.getContext().get(CALL_STRING) != null) { + ret = new CallStringWithReceivers(site, caller.getMethod(), length, + (CallString) caller.getContext().get(CALL_STRING)); + } else { ret = new CallStringWithReceivers(site, caller.getMethod()); - } else + } + } else { ret = null; + } // if we have a receiver. if (ret != null && actualParameters != null && actualParameters.length > 0) @@ -151,33 +112,22 @@ protected CallStringWithReceivers getCallString(CGNode caller, CallSiteReference } protected Map getCallStringWithReceiversMap() { - return this.callStringWithReceiversMap; + return callStringWithReceiversMap; } /** * {@inheritDoc} - * - * @return CONTEXT_LENGTH_FOR_STREAMS if the target's return type implements - * {@link BaseStream}, otherwise, return the original value. + * + * @return 2 if the target's return type implements {@link BaseStream}, + * otherwise, return the original value. */ @Override protected int getLength(CGNode caller, CallSiteReference site, IMethod target) { - TypeReference typeToCheck = Util.getEvaluationType(target); - boolean implementsBaseStream = Util.implementsBaseStream(typeToCheck, target.getClassHierarchy()); - - if (implementsBaseStream) { - int lengthForStreams = this.getContextLengthForStreams(); - LOGGER.finer(() -> "Using N = " + lengthForStreams); - return lengthForStreams; - } else - return super.getLength(caller, site, target); - } - - public int getContextLengthForStreams() { - return contextLengthForStreams; - } + boolean implementsBaseStream = Util.implementsBaseStream(target.getReturnType(), target.getClassHierarchy()); - protected void setContextLengthForStreams(int contextLengthForStreams) { - this.contextLengthForStreams = contextLengthForStreams; + if (implementsBaseStream) + return 2; + else + return super.getLength(caller, site, target); } } \ No newline at end of file diff --git a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java index 855d8326..0ac81722 100644 --- a/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java +++ b/edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java @@ -1,14 +1,9 @@ package edu.cuny.hunter.streamrefactoring.eval.handlers; -import static edu.cuny.hunter.streamrefactoring.core.utils.LoggerNames.LOGGER_NAME; import static edu.cuny.hunter.streamrefactoring.core.utils.Util.createConvertToParallelStreamRefactoringProcessor; -import java.io.File; -import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.io.PrintWriter; -import java.io.Reader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -17,9 +12,7 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.Properties; import java.util.Set; -import java.util.logging.Logger; import java.util.stream.Collectors; import org.apache.commons.csv.CSVFormat; @@ -30,7 +23,6 @@ import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; @@ -81,26 +73,14 @@ */ public class EvaluateConvertToParallelStreamRefactoringHandler extends AbstractHandler { - private static final String EVALUATION_PROPERTIES_FILE_NAME = "eval.properties"; - - private static final Logger LOGGER = Logger.getLogger(LOGGER_NAME); - private static final boolean BUILD_WORKSPACE = false; - private static final boolean FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_DEFAULT = false; private static final String FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_PROPERTY_KEY = "edu.cuny.hunter.streamrefactoring.eval.findImplicitBenchmarkEntrypoints"; - private static final boolean FIND_IMPLICIT_ENTRYPOINTS_DEFAULT = false; private static final String FIND_IMPLICIT_ENTRYPOINTS_PROPERTY_KEY = "edu.cuny.hunter.streamrefactoring.eval.findImplicitEntrypoints"; - private static final boolean FIND_IMPLICIT_TEST_ENTRYPOINTS_DEFAULT = false; private static final String FIND_IMPLICIT_TEST_ENTRYPOINTS_PROPERTY_KEY = "edu.cuny.hunter.streamrefactoring.eval.findImplicitTestEntrypoints"; - - private static final int N_TO_USE_FOR_STREAMS_DEFAULT = 2; - private static final String N_TO_USE_FOR_STREAMS_PROPERTY_KEY = "nToUseForStreams"; - private static final int LOGGING_LEVEL = IStatus.INFO; - private static final boolean PERFORM_CHANGE_DEFAULT = false; private static final String PERFORM_CHANGE_PROPERTY_KEY = "edu.cuny.hunter.streamrefactoring.eval.performChange"; @@ -193,7 +173,6 @@ public Object execute(ExecutionEvent event) throws ExecutionException { CSVPrinter streamExecutionModePrinter = null; CSVPrinter streamOrderingPrinter = null; CSVPrinter entryPointsPrinter = null; - PrintWriter entryPointsTXTPrinter = null; ConvertToParallelStreamRefactoringProcessor processor = null; @@ -208,8 +187,8 @@ public Object execute(ExecutionEvent event) throws ExecutionException { IJavaProject[] javaProjects = Util.getSelectedJavaProjectsFromEvent(event); List resultsHeader = new ArrayList<>( - Arrays.asList("subject", "SLOC", "#entrypoints", "N", "#streams", - "#optimization available streams", "#optimizable streams", "#failed preconditions")); + Arrays.asList("subject", "SLOC", "#entrypoints", "#streams", "#optimization available streams", + "#optimizable streams", "#failed preconditions")); for (Refactoring refactoring : Refactoring.values()) resultsHeader.add(refactoring.toString()); @@ -252,13 +231,6 @@ public Object execute(ExecutionEvent event) throws ExecutionException { entryPointsPrinter = createCSVPrinter("entry_points.csv", new String[] { "subject", "method", "type FQN" }); - entryPointsTXTPrinter = new PrintWriter("entry_points.txt"); - - // set up analysis parameters for all projects. - boolean shouldFindImplicitEntrypoints = shouldFindImplicitEntrypoints(); - boolean shouldFindImplicitTestEntrypoints = shouldFindImplicitTestEntrypoints(); - boolean shouldFindImplicitBenchmarkEntrypoints = shouldFindImplicitBenchmarkEntrypoints(); - for (IJavaProject javaProject : javaProjects) { if (!javaProject.isStructureKnown()) throw new IllegalStateException( @@ -270,14 +242,12 @@ public Object execute(ExecutionEvent event) throws ExecutionException { // lines of code resultsPrinter.print(getProjectLinesOfCode(javaProject)); - // set up analysis for single project. TimeCollector resultsTimeCollector = new TimeCollector(); - int nToUseForStreams = getNForStreams(javaProject); resultsTimeCollector.start(); processor = createConvertToParallelStreamRefactoringProcessor(new IJavaProject[] { javaProject }, - nToUseForStreams, shouldFindImplicitEntrypoints, shouldFindImplicitTestEntrypoints, - shouldFindImplicitBenchmarkEntrypoints, Optional.of(monitor)); + this.shouldFindImplicitEntrypoints(), this.shouldFindImplicitTestEntrypoints(), + this.shouldFindImplicitBenchmarkEntrypoints(), Optional.of(monitor)); resultsTimeCollector.stop(); ConvertToParallelStreamRefactoringProcessor.setLoggingLevel(LOGGING_LEVEL); @@ -295,12 +265,8 @@ public Object execute(ExecutionEvent event) throws ExecutionException { com.ibm.wala.classLoader.IMethod method = entryPoint.getMethod(); entryPointsPrinter.printRecord(javaProject.getElementName(), method.getSignature(), method.getDeclaringClass().getName()); - entryPointsTXTPrinter.println(method.getSignature()); } - // N. - resultsPrinter.print(nToUseForStreams); - // #streams. resultsPrinter.print(processor.getStreamSet().size()); @@ -476,8 +442,6 @@ public Object execute(ExecutionEvent event) throws ExecutionException { streamOrderingPrinter.close(); if (entryPointsPrinter != null) entryPointsPrinter.close(); - if (entryPointsTXTPrinter != null) - entryPointsTXTPrinter.close(); // clear cache. if (processor != null) @@ -511,7 +475,7 @@ public void acceptSearchMatch(SearchMatch match) throws CoreException { return ret; } - private static boolean shouldFindImplicitBenchmarkEntrypoints() { + private boolean shouldFindImplicitBenchmarkEntrypoints() { String findImplicitBenchmarkEntrypoints = System.getenv(FIND_IMPLICIT_BENCHMARK_ENTRYPOINTS_PROPERTY_KEY); if (findImplicitBenchmarkEntrypoints == null) @@ -520,7 +484,7 @@ private static boolean shouldFindImplicitBenchmarkEntrypoints() { return Boolean.valueOf(findImplicitBenchmarkEntrypoints); } - private static boolean shouldFindImplicitEntrypoints() { + private boolean shouldFindImplicitEntrypoints() { String findImplicitEntrypoits = System.getenv(FIND_IMPLICIT_ENTRYPOINTS_PROPERTY_KEY); if (findImplicitEntrypoits == null) @@ -529,7 +493,7 @@ private static boolean shouldFindImplicitEntrypoints() { return Boolean.valueOf(findImplicitEntrypoits); } - private static boolean shouldFindImplicitTestEntrypoints() { + private boolean shouldFindImplicitTestEntrypoints() { String findImplicitTestEntrypoints = System.getenv(FIND_IMPLICIT_TEST_ENTRYPOINTS_PROPERTY_KEY); if (findImplicitTestEntrypoints == null) @@ -538,7 +502,7 @@ private static boolean shouldFindImplicitTestEntrypoints() { return Boolean.valueOf(findImplicitTestEntrypoints); } - private static boolean shouldPerformChange() { + private boolean shouldPerformChange() { String performChangePropertyValue = System.getenv(PERFORM_CHANGE_PROPERTY_KEY); if (performChangePropertyValue == null) @@ -546,32 +510,4 @@ private static boolean shouldPerformChange() { else return Boolean.valueOf(performChangePropertyValue); } - - private static int getNForStreams(IJavaProject project) throws IOException, JavaModelException { - Properties properties = new Properties(); - IPath filePath = project.getCorrespondingResource().getLocation().append(EVALUATION_PROPERTIES_FILE_NAME); - File file = filePath.toFile(); - - if (file.exists()) - try (Reader reader = new FileReader(file)) { - properties.load(reader); - - String nToUseForStreams = properties.getProperty(N_TO_USE_FOR_STREAMS_PROPERTY_KEY); - - if (nToUseForStreams == null) { - int ret = N_TO_USE_FOR_STREAMS_DEFAULT; - LOGGER.info("Using default N for streams: " + ret + "."); - return ret; - } else { - int ret = Integer.valueOf(nToUseForStreams); - LOGGER.info("Using properties file N for streams: " + ret + "."); - return ret; - } - } - else { - int ret = N_TO_USE_FOR_STREAMS_DEFAULT; - LOGGER.info("Using default N for streams: " + ret + "."); - return ret; - } - } } diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testArraysStream2/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testArraysStream2/in/A.java deleted file mode 100644 index 38041f3c..00000000 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testArraysStream2/in/A.java +++ /dev/null @@ -1,12 +0,0 @@ -package p; - -import java.util.Arrays; - -import edu.cuny.hunter.streamrefactoring.annotations.*; - -class A { - @EntryPoint - void m() { - Arrays.stream(new Object[1]).count(); - } -} \ No newline at end of file diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile/in/A.java deleted file mode 100644 index 204f1f78..00000000 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile/in/A.java +++ /dev/null @@ -1,13 +0,0 @@ -package p; - -import java.util.HashSet; - -import edu.cuny.hunter.streamrefactoring.annotations.*; - -class A { - @EntryPoint - void m() { - HashSet h1 = new HashSet(); - h1.stream().count(); - } -} diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile1/entry_points.txt b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile1/entry_points.txt deleted file mode 100644 index e5903f06..00000000 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile1/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -p.A.()V -p.A.m()V diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile1/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile1/in/A.java deleted file mode 100644 index 098660f1..00000000 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile1/in/A.java +++ /dev/null @@ -1,12 +0,0 @@ -package p; - -import java.util.HashSet; - -import edu.cuny.hunter.streamrefactoring.annotations.*; - -class A { - void m() { - HashSet h1 = new HashSet(); - h1.stream().count(); - } -} diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile2/entry_points.txt b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile2/entry_points.txt deleted file mode 100644 index 82cb7434..00000000 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile2/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -q.A.()V -q.A.m()V diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile2/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile2/in/A.java deleted file mode 100644 index 098660f1..00000000 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile2/in/A.java +++ /dev/null @@ -1,12 +0,0 @@ -package p; - -import java.util.HashSet; - -import edu.cuny.hunter.streamrefactoring.annotations.*; - -class A { - void m() { - HashSet h1 = new HashSet(); - h1.stream().count(); - } -} diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile3/entry_points.txt b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile3/entry_points.txt deleted file mode 100644 index 82cb7434..00000000 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile3/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -q.A.()V -q.A.m()V diff --git a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile3/in/A.java b/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile3/in/A.java deleted file mode 100644 index 204f1f78..00000000 --- a/edu.cuny.hunter.streamrefactoring.tests/resources/ConvertStreamToParallel/testEntryPointFile3/in/A.java +++ /dev/null @@ -1,13 +0,0 @@ -package p; - -import java.util.HashSet; - -import edu.cuny.hunter.streamrefactoring.annotations.*; - -class A { - @EntryPoint - void m() { - HashSet h1 = new HashSet(); - h1.stream().count(); - } -} diff --git a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java index f1db76b2..1e256e42 100644 --- a/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java +++ b/edu.cuny.hunter.streamrefactoring.tests/test cases/edu/cuny/hunter/streamrefactoring/ui/tests/ConvertStreamToParallelRefactoringTest.java @@ -1,3 +1,6 @@ +/** + * + */ package edu.cuny.hunter.streamrefactoring.ui.tests; import java.io.File; @@ -6,8 +9,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; @@ -52,7 +53,6 @@ /** * @author Raffi * Khatchadourian - * @author Yiming Tang * */ @SuppressWarnings("restriction") @@ -73,10 +73,6 @@ public class ConvertStreamToParallelRefactoringTest extends RefactoringTest { private static final int RETRY_DELAY = 1000; - private static final String ENTRY_POINT_FILENAME = "entry_points.txt"; - - private static final int N_TO_USE_FOR_STREAMS_DEFAULT = 2; - static { LOGGER.setLevel(Level.FINER); } @@ -132,86 +128,6 @@ public static Test setUpTest(Test test) { return new Java18Setup(test); } - /** - * @return an absolute path of entry_points.txt in the project directory. - */ - private Path getEntryPointFileProjectSourcePath() { - return getAbsolutePath(this.getTestPath() + this.getName()).resolve(ENTRY_POINT_FILENAME); - } - - /** - * @return The {@link Path} of where the entry points file should be copied to - * for the current project under test. - */ - private Path getEntryPointFileProjectDestinationPath() { - return getEntryPointFileDestinationPath(this.getPackageP().getJavaProject()); - } - - /** - * @return The {@link Path} of where the entry_points.txt file should be copied - * to in the junit workspace. - */ - @SuppressWarnings("unused") - private Path getDestinationWorkspacePath() { - return getEntryPointFileDestinationPath(this.getPackageP().getJavaProject().getParent()); - } - - /** - * Returns the path of where the entry points file should be copied relative to - * the given {@link IJavaElement}. - * - * @param element - * The {@link IJavaElement} in question. - * @return The {@link Path} where the entry points file should be copied - * relative to the given {@link IJavaElement}. - */ - private static Path getEntryPointFileDestinationPath(IJavaElement element) { - return Paths.get(element.getResource().getLocation().toString() + File.separator + ENTRY_POINT_FILENAME); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - // this is the source path. - Path entryPointFileProjectSourcePath = getEntryPointFileProjectSourcePath(); - Path entryPointFileProjectDestinationPath = getEntryPointFileProjectDestinationPath(); - - // TODO: we also need to copy entry_points.txt to workspace directory here - // something like copyEntryPointFile(absoluteProjectPath, - // getDestinationWorkSpacePath()) - if (copyEntryPointFile(entryPointFileProjectSourcePath, entryPointFileProjectDestinationPath)) - LOGGER.info("Copied " + ENTRY_POINT_FILENAME + " successfully."); - else - LOGGER.info(ENTRY_POINT_FILENAME + " does not exist."); - } - - /** - * Copy entry_points.txt from current directory to the corresponding directory - * in junit-workspace - * - * @return true: copy successfully / false: the source file does not exist - */ - private static boolean copyEntryPointFile(Path source, Path target) throws IOException { - File file = getEntryPointFile(source); - if (file != null) { - Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); - return true; - } else - return false; - } - - /** - * get the entry_points.txt - */ - private static File getEntryPointFile(Path filePath) { - File file = new File(filePath.toString()); - if (file.exists()) - return file; - else - return null; - } - public static Test suite() { return setUpTest(new TestSuite(CLAZZ)); } @@ -290,19 +206,12 @@ protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cu @Override protected ICompilationUnit createCUfromTestFile(IPackageFragment pack, String cuName, boolean input) throws Exception { - String testFileName; - - if (input) { - testFileName = getInputTestFileName(cuName); - } else // output case. - testFileName = getOutputTestFileName(cuName); - - String contents = getFileContents(testFileName); - + String contents = input ? this.getFileContents(this.getInputTestFileName(cuName)) + : this.getFileContents(this.getOutputTestFileName(cuName)); return createCU(pack, cuName + ".java", contents); } - private static Path getAbsolutePath(String fileName) { + private Path getAbsolutionPath(String fileName) { Path path = Paths.get(RESOURCE_PATH, fileName); Path absolutePath = path.toAbsolutePath(); return absolutePath; @@ -319,7 +228,7 @@ private static Path getAbsolutePath(String fileName) { */ @Override public String getFileContents(String fileName) throws IOException { - Path absolutePath = getAbsolutePath(fileName); + Path absolutePath = this.getAbsolutionPath(fileName); byte[] encoded = Files.readAllBytes(absolutePath); return new String(encoded, Charset.defaultCharset()); } @@ -337,15 +246,6 @@ public String getRefactoringPath() { * Runs a single analysis test. */ private void helper(StreamAnalysisExpectedResult... expectedResults) throws Exception { - helper(N_TO_USE_FOR_STREAMS_DEFAULT, expectedResults); - } - - /** - * Runs a single analysis test. - */ - private void helper(int nToUseForStreams, StreamAnalysisExpectedResult... expectedResults) throws Exception { - LOGGER.info("Using N = " + nToUseForStreams); - // compute the actual results. ICompilationUnit cu = this.createCUfromTestFile(this.getPackageP(), "A"); @@ -355,7 +255,7 @@ private void helper(int nToUseForStreams, StreamAnalysisExpectedResult... expect ASTNode ast = parser.createAST(new NullProgressMonitor()); - StreamAnalyzer analyzer = new StreamAnalyzer(false, nToUseForStreams); + StreamAnalyzer analyzer = new StreamAnalyzer(false); ast.accept(analyzer); analyzer.analyze(); @@ -393,7 +293,7 @@ else if (this.getPackageP().exists())// don't refresh package if root already } public void setFileContents(String fileName, String contents) throws IOException { - Path absolutePath = getAbsolutePath(fileName); + Path absolutePath = this.getAbsolutionPath(fileName); Files.write(absolutePath, contents.getBytes()); } @@ -404,12 +304,6 @@ protected void tearDown() throws Exception { final boolean pExists = this.getPackageP().exists(); - // this is destination path. - Path destinationProjectPath = getEntryPointFileProjectDestinationPath(); - - if (getEntryPointFile(destinationProjectPath) != null) - Files.delete(destinationProjectPath); - if (pExists) tryDeletingAllJavaClassFiles(this.getPackageP()); @@ -476,21 +370,97 @@ public void testCollectionFromParameter2() throws Exception { /** * Test for #98. */ - public void testArraysStream() throws Exception { - helper(new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", - Collections.singleton(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), false, false, false, - null, null, null, RefactoringStatus.ERROR, - EnumSet.of(PreconditionFailure.NO_APPLICATION_CODE_IN_CALL_STRINGS))); + public void testCollectionFromParameter3() throws Exception { + this.helper(new StreamAnalysisExpectedResult("h.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, true, + false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.UNORDERED))); } /** - * Test #80. We need to increase N here to 3. + * Test for #98. Ordering.ORDERED because we are falling back. */ - public void testArraysStream2() throws Exception { - helper(3, new StreamAnalysisExpectedResult("Arrays.stream(new Object[1])", - 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())); + public void testCollectionFromParameter4() throws Exception { + this.helper( + new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL), + Collections.singleton(Ordering.ORDERED), false, false, false, null, null, null, + RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.STREAM_CODE_NOT_REACHABLE))); + } + + // Test #65, + public void testConcat() throws Exception { + this.helper(new StreamAnalysisExpectedResult( + "concat(new HashSet().parallelStream(),new HashSet().parallelStream())", + EnumSet.of(ExecutionMode.SEQUENTIAL), null, false, false, false, null, null, null, + RefactoringStatus.ERROR, Collections.singleton(PreconditionFailure.CURRENTLY_NOT_HANDLED))); + } + + /** + * Test #64. Test P6 in table3. + */ + public void testConcurrentReduction() throws Exception { + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, true, + false, true, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT), + PreconditionSuccess.P6, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, + Collections.emptySet())); + } + + /** + * Test #64. Test P7 in table 3. + */ + public void testConcurrentReduction1() throws Exception { + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, true, EnumSet.of(TransformationAction.CONVERT_TO_SEQUENTIAL), PreconditionSuccess.P7, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P8 in table 3. + */ + public void testConcurrentReduction2() throws Exception { + HashSet transformations = new HashSet<>(); + transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_NON_CONCURRENT); + transformations.add(TransformationAction.CONVERT_TO_SEQUENTIAL); + + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + false, true, transformations, PreconditionSuccess.P8, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, + RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P9 in table 3. + */ + public void testConcurrentReduction3() throws Exception { + HashSet transformations = new HashSet<>(); + transformations.add(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT); + transformations.add(TransformationAction.CONVERT_TO_PARALLEL); + + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, false, transformations, PreconditionSuccess.P9, Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, + RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P10 in table 3. + */ + public void testConcurrentReduction4() throws Exception { + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.SEQUENTIAL), EnumSet.of(Ordering.ORDERED), CollectorKind.CONCURRENT, false, + false, false, EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P10, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); + } + + /** + * Test #64. Test P11 in table 3. + */ + public void testConcurrentReduction5() throws Exception { + this.helper(new StreamAnalysisExpectedResultWithCollectorKind("orderedWidgets.stream()", + EnumSet.of(ExecutionMode.PARALLEL), EnumSet.of(Ordering.ORDERED), CollectorKind.NONCONCURRENT, false, + false, false, EnumSet.of(TransformationAction.CONVERT_COLLECTOR_TO_CONCURRENT), PreconditionSuccess.P11, + Refactoring.OPTIMIZE_COMPLEX_MUTABLE_REDUCTION, RefactoringStatus.OK, Collections.emptySet())); } public void testConstructor() throws Exception { @@ -758,23 +728,7 @@ public void testOneEntryPoint() throws Exception { } public void testStaticInitializer() throws Exception { - helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", null, null, false, false, false, - null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); - } - - // N needs to be 3 here. - public void testIntermediateOperations() throws Exception { - helper(3, - new StreamAnalysisExpectedResult("set.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.ORDERED), false, true, false, - EnumSet.of(TransformationAction.UNORDER, TransformationAction.CONVERT_TO_PARALLEL), - PreconditionSuccess.P3, Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, - Collections.emptySet())); - } - - public void testTypeResolution() throws Exception { - helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", - Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, + this.helper(new StreamAnalysisExpectedResult("new HashSet<>().parallelStream()", null, null, false, false, false, null, null, null, RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.CURRENTLY_NOT_HANDLED))); } @@ -826,60 +780,11 @@ public void testTerminalOp3() throws Exception { Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); } - /** - * Test #119. - */ - public void testWithoutEntryPoint() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); - } - - /** - * Test #172. This is a control group for testing entry point file. - */ - public void testEntryPointFile() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #172. Test correct entry point file. - */ - public void testEntryPointFile1() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); - } - - /** - * Test #172. Test entry point file which is not corresponding to the source - * code. - */ - public void testEntryPointFile2() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); - } - - /** - * Test #172. Test whether the tool can ignore the explicit entry points in the - * source code when the entry_points.txt exists - */ - public void testEntryPointFile3() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", null, null, false, false, false, null, null, null, - RefactoringStatus.ERROR, EnumSet.of(PreconditionFailure.NO_ENTRY_POINT))); - } - - /** - * Test #122. - */ - public void testMultipleEntryPoints() throws Exception { - helper(new StreamAnalysisExpectedResult("h1.stream()", Collections.singleton(ExecutionMode.SEQUENTIAL), - Collections.singleton(Ordering.UNORDERED), false, false, false, - EnumSet.of(TransformationAction.CONVERT_TO_PARALLEL), PreconditionSuccess.P1, - Refactoring.CONVERT_SEQUENTIAL_STREAM_TO_PARALLEL, RefactoringStatus.OK, Collections.emptySet())); + public void testTypeResolution() throws Exception { + this.helper(new StreamAnalysisExpectedResult("anotherSet.parallelStream()", + Collections.singleton(ExecutionMode.PARALLEL), Collections.singleton(Ordering.UNORDERED), false, false, + false, null, null, null, RefactoringStatus.ERROR, + Collections.singleton(PreconditionFailure.NO_TERMINAL_OPERATIONS))); } public void testTypeResolution2() throws Exception { diff --git a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/wizards/ConvertStreamToParallelRefactoringWizard.java b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/wizards/ConvertStreamToParallelRefactoringWizard.java index bafb5502..a5c7730f 100644 --- a/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/wizards/ConvertStreamToParallelRefactoringWizard.java +++ b/edu.cuny.hunter.streamrefactoring.ui/src/edu/cuny/hunter/streamrefactoring/ui/wizards/ConvertStreamToParallelRefactoringWizard.java @@ -57,7 +57,6 @@ public static void startRefactoring(IJavaProject[] javaProjects, Shell shell, Op RefactoringSaveHelper.SAVE_REFACTORING); } - // TODO: Need to add an option for N here #183. @Override protected void addUserInputPages() { }