Skip to content

Commit

Permalink
Fixed #35.
Browse files Browse the repository at this point in the history
  • Loading branch information
Raffi Khatchadourian committed Dec 18, 2015
1 parent 661cce9 commit 39fa911
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public class Messages extends NLS {
public static String DeclaringTypeHierarchyContainsInvalidInterface;
public static String DeclaringTypeContainsSubtype;
public static String DeclaringTypeContainsInvalidSupertype;
public static String DestinationInterfaceIsFunctional;

static {
// initialize resource bundle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,5 @@ DestinationInterfaceHasInvalidImplementingClass=Destination interface ''{0}'' ha
DestinationInterfaceHasInvalidImplementingClass=Destination interface ''{0}'' has an invalid implementing class.
DeclaringTypeHierarchyContainsInvalidClass=Declaring type ''{0}'''s hierarchy contains an invalid class.
DeclaringTypeHierarchyContainsInvalidInterface=Declaring type ''{0}'''s hierarchy contains an invalid interface.
DeclaringTypeContainsInvalidSupertype=Declaring type ''{0}''' has an invalid super type.
DeclaringTypeContainsInvalidSupertype=Declaring type ''{0}''' has an invalid super type.
DestinationInterfaceIsFunctional=Destination interface ''{0}'' is functional.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
Expand Down Expand Up @@ -81,6 +82,8 @@
@SuppressWarnings({ "restriction" })
public class MigrateSkeletalImplementationToInterfaceRefactoringProcessor extends HierarchyProcessor {

private static final String FUNCTIONAL_INTERFACE_ANNOTATION_NAME = "FunctionalInterface";

/**
* The destination interface.
*/
Expand Down Expand Up @@ -272,6 +275,10 @@ protected RefactoringStatus checkDestinationInterface(IProgressMonitor monitor)
if (targetInterface.getAnnotations().length != 0)
addWarning(status, Messages.DestinationInterfaceHasAnnotations, targetInterface);

// #35: The target interface should not be a @FunctionalInterface.
if (isInterfaceFunctional(targetInterface))
addWarning(status, Messages.DestinationInterfaceIsFunctional, targetInterface);

// TODO: For now, only top-level types.
if (targetInterface.getDeclaringType() != null)
addWarning(status, Messages.DestinationInterfaceIsNotTopLevel, targetInterface);
Expand Down Expand Up @@ -304,6 +311,11 @@ protected RefactoringStatus checkDestinationInterface(IProgressMonitor monitor)
return status;
}

private static boolean isInterfaceFunctional(final IType anInterface) throws JavaModelException {
return Stream.of(anInterface.getAnnotations()).parallel().map(IAnnotation::getElementName)
.anyMatch(s -> s.contains(FUNCTIONAL_INTERFACE_ANNOTATION_NAME));
}

protected RefactoringStatus checkDestinationInterfaceHierarchy(IProgressMonitor monitor) throws JavaModelException {
RefactoringStatus status = new RefactoringStatus();
monitor.subTask("Checking destination interface hierarchy...");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package p;

@FunctionalInterface
interface I {
void m();
}

abstract class A implements I {
public void m() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package p;

@FunctionalInterface
interface I {
void m();
String toString();
}

abstract class A implements I {
public void m() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package p;

@FunctionalInterface
interface I {
void m();
default void n() {
}
}

abstract class A implements I {
public void m() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,31 @@ public void testNonTopLevelDestinationInterface2() throws Exception {
public void testDestinationInterfaceWithFields() throws Exception {
helperFail(new String[] { "m" }, new String[][] { new String[0] });
}

/**
* The destination interface should not be marked as an @FunctionalInterface
* since we only convert abstract methods to default methods and it is
* not allowed for a valid @FunctionalInterface to loose an abstract method.
*/
public void testDestinationFunctionalInterface() throws Exception {
helperFail(new String[] { "m" }, new String[][] { new String[0] });
}

/**
* Same as {@link MigrateSkeletalImplementationToInterfaceRefactoringTest#testDestinationFunctionalInterface()}
* but with non-abstract methods also included in the interface.
*/
public void testDestinationFunctionalInterfaceWithNonAbstractMethods() throws Exception {
helperFail(new String[] { "m" }, new String[][] { new String[0] });
}

/**
* Same as {@link MigrateSkeletalImplementationToInterfaceRefactoringTest#testDestinationFunctionalInterface()}
* but with non-abstract methods also included in the interface.
*/
public void testDestinationFunctionalInterfaceWithNonAbstractMethods2() throws Exception {
helperFail(new String[] { "m" }, new String[][] { new String[0] });
}

public void testDestinationInterfaceThatExtendsInterface() throws Exception {
helperFail(new String[] { "m" }, new String[][] { new String[0] });
Expand Down
5 changes: 3 additions & 2 deletions examples/PlainMethodTest0Before/src/p/A.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package p;

interface I {
void m();
}

abstract class A implements I {
void m() {
public void m() {
}
}
}

0 comments on commit 39fa911

Please sign in to comment.