lambda -> method reference: ensure functional type was not changed after transformation (IDEA-136163)

This commit is contained in:
Anna Kozlova
2015-02-17 12:57:22 +01:00
parent 6482dfe733
commit bcbc25e1de
3 changed files with 41 additions and 7 deletions

View File

@@ -422,6 +422,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
if (lambdaExpression == null) return;
PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType();
if (functionalInterfaceType == null || !functionalInterfaceType.isValid()) return;
String functionalTypeText = functionalInterfaceType.getCanonicalText();
final String methodRefText = createMethodReferenceText(element, functionalInterfaceType,
lambdaExpression.getParameterList().getParameters());
@@ -430,14 +431,13 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
final PsiExpression psiExpression = factory.createExpressionFromText(methodRefText, lambdaExpression);
final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(project).createSmartTypePointer(functionalInterfaceType);
PsiElement replace = lambdaExpression.replace(psiExpression);
if (((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType() == null) { //ambiguity
final PsiType functionalTypeAfterReplacement = ((PsiMethodReferenceExpression)replace).getFunctionalInterfaceType();
functionalInterfaceType = typePointer.getType();
if (functionalTypeAfterReplacement == null || functionalInterfaceType != null && !functionalTypeAfterReplacement.equals(functionalInterfaceType)) { //ambiguity
final PsiTypeCastExpression cast = (PsiTypeCastExpression)factory.createExpressionFromText("(A)a", replace);
functionalInterfaceType = typePointer.getType();
if (functionalInterfaceType != null) {
cast.getCastType().replace(factory.createTypeElement(functionalInterfaceType));
cast.getOperand().replace(replace);
replace = replace.replace(cast);
}
cast.getCastType().replace(factory.createTypeElement(functionalInterfaceType));
cast.getOperand().replace(replace);
replace = replace.replace(cast);
}
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace);
}

View File

@@ -0,0 +1,17 @@
// "Replace lambda with method reference" "true"
import java.util.prefs.Preferences;
class Test {
private Preferences preferences;
{
foo(short.class, (Writer<Short>) Preferences::putInt);
}
private <T> void foo(Class<T> type, Writer<T> writer) {}
interface Writer<T> {
void write(Preferences preferences, String key, T value);
}
}

View File

@@ -0,0 +1,17 @@
// "Replace lambda with method reference" "true"
import java.util.prefs.Preferences;
class Test {
private Preferences preferences;
{
foo(short.class, (p, k, v) -> p.put<caret>Int(k, v));
}
private <T> void foo(Class<T> type, Writer<T> writer) {}
interface Writer<T> {
void write(Preferences preferences, String key, T value);
}
}