Skip to content

Fix for #103 #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 16, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package p;

import java.util.HashSet;
import java.util.stream.*;

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

class A {

Stream<Object> m() {
Stream<Object> stream = new HashSet<>().stream().distinct();
return stream;
}

@EntryPoint
void n() {
Stream<Object> s = m();
s.count();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package p;

import java.util.HashSet;
import java.util.stream.*;

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

class A {

Stream<Object> m() {
Stream<Object> stream = new HashSet<>().stream();
return stream;
}

@EntryPoint
void n() {
Stream<Object> s = m();
s.distinct().count();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package p;

import java.util.HashSet;
import java.util.stream.*;

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

class A {

Stream<Object> m() {
Stream<Object> stream = new HashSet<>().stream().sorted();
return stream;
}

@EntryPoint
void n() {
Stream<Object> s = m();
s.distinct().count();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,27 @@ public void testNonInternalAPI() throws Exception {
EnumSet.of(PreconditionFailure.NO_TERMINAL_OPERATIONS)));
}

public void testNonInternalAPI2() throws Exception {
helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()",
Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, false,
false, null, null, null, RefactoringStatus.ERROR,
EnumSet.of(PreconditionFailure.NO_TERMINAL_OPERATIONS)));
}

public void testNonInternalAPI3() throws Exception {
helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()",
Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, false,
false, null, null, null, RefactoringStatus.ERROR,
EnumSet.of(PreconditionFailure.NO_TERMINAL_OPERATIONS)));
}

public void testNonInternalAPI4() throws Exception {
helper(new StreamAnalysisExpectedResult("new HashSet<>().stream()",
Collections.singleton(ExecutionMode.SEQUENTIAL), Collections.singleton(Ordering.UNORDERED), false, false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@saledouble This should be ordered, correct?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@saledouble I'm confused as to why the the ordering is UNORDERED. Do you know why? I am wondering if it is the case that we determine ordering upon a terminal operation and when we think there's none, we are just using some default value. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the test case is

class A {

	Stream<Object> m() {
		Stream<Object> stream = new HashSet<>().stream();
		return stream;
	}

	@EntryPoint
	void n() {
		Stream<Object> s = m();
		s.sorted().distinct().count();
	}
}

the ordering is 'UNORDERED' and the project throws an exception requiring terminal operations.

If the test case is

class A {

	@EntryPoint
	void n() {
		Stream<Object> s = new HashSet<>().stream();;
		s.sorted().distinct().count();
	}
}

the ordering is 'ORDERED' and the project doesn't throw an exception.

Then, I found a sentence from https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html :
"When the terminal operation is initiated, the stream pipeline is executed sequentially or in parallel depending on the orientation of the stream on which it is invoked."

I think the project doesn't find the terminal operations, so the stream pipeline has never been executed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you replace HashSet() with ArrayList, is it still UNORDERED? That would answer whether it is just accepting a default value.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any insight as to why it is not finding the terminal operation? Do you have ideas how to fix it? Let's discuss it prior to executing a particular strategy.

Copy link
Contributor Author

@yiming-tang-cs yiming-tang-cs Dec 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the test case is:

class A {

	Stream<Object> m() {
		Stream<Object> stream = new ArrayList<>().stream().sorted();
		return stream;
	}

	@EntryPoint
	void n() {
		Stream<Object> s = m();
		s.distinct().count();
	}
}

the ordering is 'Ordered' and the project throws an exception (require terminal operations).

image

If you replace HashSet() with ArrayList, is it still UNORDERED? That would answer whether it is just accepting a default value.

According to the test result above, the answer should be yes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any insight as to why it is not finding the terminal operation? Do you have ideas how to fix it? Let's discuss it prior to executing a particular strategy.

I came up with a question in #103 . I found the instance of stream just processes the operations in the method of enclosingMethodDeclaration.

For the example below:

class A {

	Stream<Object> m() {
		Stream<Object> stream = new HashSet<>().parallelStream();
		return stream;
	}

	@EntryPoint
	void n() {
		Stream<Object> s = m();
		s.count();
	}
}

Do we need to create an instance of stream for n()? Can we reuse the instance of stream for m()? Those are what I am thinking.

false, null, null, null, RefactoringStatus.ERROR,
EnumSet.of(PreconditionFailure.NO_TERMINAL_OPERATIONS)));
}

public void testCollectionFromParameter() throws Exception {
helper(new StreamAnalysisExpectedResult("h.parallelStream()", Collections.singleton(ExecutionMode.PARALLEL),
Collections.singleton(Ordering.UNORDERED), false, true, false, null, null, null,
Expand Down