show error if uninitialized field is referenced from lambda inside inner/anonymous class in another field initializer; disable anonymous -> lambda for such places

This commit is contained in:
Anna.Kozlova
2016-03-21 21:11:36 +01:00
parent fb50cf14b5
commit 6fc9953a82
4 changed files with 48 additions and 1 deletions
@@ -402,6 +402,7 @@ public class HighlightControlFlowUtil {
private static boolean inInnerClass(@NotNull PsiElement psiElement, @Nullable PsiClass containingClass, @NotNull PsiFile containingFile) {
PsiElement element = psiElement;
while (element != null) {
if (element instanceof PsiLambdaExpression) return false;
if (element instanceof PsiClass) return !containingFile.getManager().areElementsEquivalent(element, containingClass);
element = element.getParent();
}
@@ -500,8 +500,10 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
final PsiMember member = PsiTreeUtil.getParentOfType(myAnonymClass, PsiMember.class);
if (member instanceof PsiField || member instanceof PsiClassInitializer) {
final PsiElement resolved = expression.resolve();
final PsiClass memberContainingClass = member.getContainingClass();
if (resolved instanceof PsiField &&
((PsiField)resolved).getContainingClass() == member.getContainingClass() &&
memberContainingClass != null &&
PsiTreeUtil.isAncestor(((PsiField)resolved).getContainingClass(), memberContainingClass, false) &&
expression.getQualifierExpression() == null) {
final PsiExpression initializer = ((PsiField)resolved).getInitializer();
if (initializer == null ||
@@ -64,3 +64,28 @@ abstract class TestInnerAnonymous {
}
}
interface Fun<A, B> {
B m(A a);
}
class TestAnonymousWithRefToTheTopLevelUninitializedField {
private final int myId;
private Runnable r = new Runnable() {
final int localId;
{
localId = 0;
}
Fun<Integer, Integer> ff = (a) -> <error descr="Variable 'myId' might not have been initialized">myId</error>;
Fun<Integer, Integer> ffLocal = (a) -> localId;
public void run() {
}
};
public TestAnonymousWithRefToTheTopLevelUninitializedField(int id) {
myId = id;
}
}
@@ -0,0 +1,19 @@
// "Replace with lambda" "false"
class Test {
private final int myId;
private final Runnable myModels = new Runnable() {
private Comparable<String> myMapping = new Compa<caret>rable<String>() {
@Override
public String apply(final String s) {
return myId;
}
};
public void run() {}
};
public Test(final int i) {
myId = i;
}
}