introduce code block parameter: filter out functional interfaces which are not compatible by thrown types

This commit is contained in:
Anna Kozlova
2014-12-11 11:16:45 +01:00
parent 1053a96872
commit 474e0fef6f
7 changed files with 95 additions and 1 deletions
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.NullableFunction;
@@ -87,6 +88,21 @@ public class FunctionalInterfaceSuggester {
return null;
}
final PsiClassType[] interfaceThrownTypes = interfaceMethod.getThrowsList().getReferencedTypes();
final PsiClassType[] thrownTypes = method.getThrowsList().getReferencedTypes();
for (PsiClassType thrownType : thrownTypes) {
if (!ExceptionUtil.isHandledBy(thrownType, interfaceThrownTypes, substitutor)) {
return null;
}
}
for (PsiClassType thrownType : interfaceThrownTypes) {
final PsiCodeBlock codeBlock = PsiTreeUtil.getContextOfType(method, PsiCodeBlock.class);
if (codeBlock == null || !ExceptionUtil.isHandled(thrownType, codeBlock)) {
return null;
}
}
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(aClass.getProject());
final PsiType type = elementFactory.createType(aClass, substitutor);
return type;
@@ -541,7 +541,9 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase {
if (!processor.prepare()) return false;
processor.showDialog();
final PsiMethod emptyMethod = processor.generateEmptyMethod("name");
//provide context for generated method to check exceptions compatibility
final PsiMethod emptyMethod = JavaPsiFacade.getElementFactory(project)
.createMethodFromText(processor.generateEmptyMethod("name").getText(), elements[0]);
final Collection<? extends PsiType> types = FunctionalInterfaceSuggester.suggestFunctionalInterfaces(emptyMethod);
if (types.isEmpty()) {
return false;
@@ -0,0 +1,19 @@
class Test {
@FunctionalInterface
interface I {
void f() throws Exception;
}
void bar() {
foo(new Runnable() {
public void run() {
System.out.println("");
System.out.println("");
}
});
}
void foo(Runnable anObject) {
anObject.run();
}
}
@@ -0,0 +1,19 @@
class Test {
@FunctionalInterface
interface I {
void f() throws Exception;
}
void bar() throws Exception {
foo(new I() {
public void f() {
System.out.println("");
System.out.println("");
}
});
}
void foo(I anObject) throws Exception {
anObject.f();
}
}
@@ -0,0 +1,15 @@
class Test {
@FunctionalInterface
interface I {
void f() throws Exception;
}
void bar() {
foo();
}
void foo() {
<selection>System.out.println("");
System.out.println("");</selection>
}
}
@@ -0,0 +1,15 @@
class Test {
@FunctionalInterface
interface I {
void f() throws Exception;
}
void bar() throws Exception {
foo();
}
void foo() throws Exception {
<selection>System.out.println("");
System.out.println("");</selection>
}
}
@@ -41,6 +41,14 @@ public class IntroduceFunctionalParameterTest extends LightRefactoringTestCase
doTest();
}
public void testExceptionPreventFromCompatibility() throws Exception {
doTest();
}
public void testThrownExceptionsAgree() throws Exception {
doTest();
}
@NotNull
@Override
protected String getTestDataPath() {