anonymous -> lambda: accept anonymous classes with inferred another type and ref to a parameter as the cast would be inserted (IDEA-157457)

This commit is contained in:
Anna Kozlova
2016-06-15 13:44:38 +03:00
parent fc4bbbde7c
commit f7fbc4b4bc
5 changed files with 36 additions and 43 deletions

View File

@@ -148,7 +148,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
return true;
}
final ForbiddenRefsChecker checker = new ForbiddenRefsChecker(method, aClass, inferredType != PsiType.NULL ? inferredType : null);
final ForbiddenRefsChecker checker = new ForbiddenRefsChecker(method, aClass);
final PsiCodeBlock body = method.getBody();
LOG.assertTrue(body != null);
body.accept(checker);
@@ -466,15 +466,9 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
private final PsiMethod myMethod;
private final PsiAnonymousClass myAnonymClass;
private final PsiType myInferredType;
public ForbiddenRefsChecker(PsiMethod method,
PsiAnonymousClass aClass,
PsiType inferredType) {
public ForbiddenRefsChecker(PsiMethod method, PsiAnonymousClass aClass) {
myMethod = method;
myAnonymClass = aClass;
final PsiClassType baseClassType = aClass.getBaseClassType();
myInferredType = !baseClassType.equals(inferredType) ? inferredType : null;
}
@Override
@@ -537,7 +531,6 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
resolved == member ||
initializer.getTextOffset() > myAnonymClass.getTextOffset() && ((PsiField)resolved).hasModifierProperty(PsiModifier.STATIC) == member.hasModifierProperty(PsiModifier.STATIC)) {
myBodyContainsForbiddenRefs = true;
return;
}
}
} else {
@@ -556,43 +549,11 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
final Collection<PsiVariable> writtenVariables = ControlFlowUtil.getWrittenVariables(flow, 0, startOffset, false);
if (!writtenVariables.contains(resolved)) {
myBodyContainsForbiddenRefs = true;
return;
}
}
}
catch (AnalysisCanceledException e) {
myBodyContainsForbiddenRefs = true;
return;
}
}
}
}
}
if (myInferredType != null) {
final PsiElement resolved = expression.resolve();
if (resolved instanceof PsiParameter && ((PsiParameter)resolved).getDeclarationScope() == myMethod) {
if (!(myInferredType instanceof PsiClassType)) {
myBodyContainsForbiddenRefs = true;
return;
}
final int parameterIndex = myMethod.getParameterList().getParameterIndex((PsiParameter)resolved);
for (PsiMethod superMethod : myMethod.findDeepestSuperMethods()) {
final PsiType paramType = superMethod.getParameterList().getParameters()[parameterIndex].getType();
final PsiClass superClass = superMethod.getContainingClass();
if (superClass != null) {
final PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType)myInferredType).resolveGenerics();
final PsiClass classCandidate = classResolveResult.getElement();
if (classCandidate == null) {
myBodyContainsForbiddenRefs = true;
return;
}
final PsiSubstitutor inferredSubstitutor = TypeConversionUtil.getClassSubstitutor(superClass, classCandidate, classResolveResult.getSubstitutor());
final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, myAnonymClass.getBaseClassType());
if (inferredSubstitutor != null &&
!Comparing.equal(inferredSubstitutor.substitute(paramType), substitutor.substitute(paramType))) {
myBodyContainsForbiddenRefs = true;
return;
}
}
}

View File

@@ -0,0 +1,12 @@
// "Replace with lambda" "true"
import java.util.function.Function;
class Test {
void ab() {
comparing((Function<Integer, String>) pObj -> Integer.toString(pObj));
}
static <T> void comparing(Function<T, String> keyExtractor){}
}

View File

@@ -0,0 +1,20 @@
// "Replace with lambda" "true"
class DbTableBinder {
public Binder build() {
return (Binder<DbTable>) (q, dbTable) -> q.bind("name", dbTable.name);
}
}
class DbTable {
String name;
}
interface Binder <ArgType> {
void bind(A<?> sqlStatement, ArgType argType);
}
interface A<P> {
void bind(String s, String p);
}

View File

@@ -1,4 +1,4 @@
// "Replace with lambda" "false"
// "Replace with lambda" "true"
import java.util.function.Function;
class Test {

View File

@@ -1,4 +1,4 @@
// "Replace with lambda" "false"
// "Replace with lambda" "true"
class DbTableBinder {
public Binder build() {