IDEA-148491 (False positive "Field may be final")

This commit is contained in:
Bas Leijdekkers
2015-12-03 14:55:02 +01:00
parent e8005e8796
commit 4458e75efc
2 changed files with 59 additions and 0 deletions
@@ -525,6 +525,13 @@ public final class DefiniteAssignmentUtil {
final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression)expression;
checkExpression(instanceOfExpression.getOperand(), definiteAssignment, value);
}
else if (expression instanceof PsiLambdaExpression) {
final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)expression;
final boolean du = definiteAssignment.isDefinitelyUnassigned();
definiteAssignment.set(definiteAssignment.isDefinitelyAssigned(), false);
checkLambdaExpression(lambdaExpression, definiteAssignment);
definiteAssignment.set(definiteAssignment.isDefinitelyAssigned(), du);
}
else if (expression instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
checkMethodCallExpression(methodCallExpression, definiteAssignment, value);
@@ -653,6 +660,18 @@ public final class DefiniteAssignmentUtil {
definiteAssignment.and(resultDa, resultDu);
}
private static void checkLambdaExpression(PsiLambdaExpression lambdaExpression, DefiniteAssignment definiteAssignment) {
final PsiElement body = lambdaExpression.getBody();
if (body instanceof PsiExpression) {
final PsiExpression bodyExpression = (PsiExpression)body;
checkExpression(bodyExpression, definiteAssignment, BooleanExpressionValue.UNDEFINED);
}
else if (body instanceof PsiCodeBlock) {
final PsiCodeBlock codeBlock = (PsiCodeBlock)body;
checkCodeBlock(codeBlock, definiteAssignment);
}
}
private static void checkMethodCallExpression(PsiMethodCallExpression methodCallExpression,
DefiniteAssignment definiteAssignment,
BooleanExpressionValue value) {
@@ -923,6 +923,46 @@ class T64 {
s="";
}
}
class T65 {
private Runnable r; // may not be final
T65() {
r = () -> System.out.println(r);
}
}
class T66 {
private String <warning descr="Field 's' may be 'final'">s</warning>; // may be final
T66() {
s = "10";
Runnable r = () -> System.out.println(s);
}
}
class T67 {
private String s; // may not be final
T67() {
Runnable r = () -> System.out.println(s);
s = "10";
}
}
class T68 {
private Runnable <warning descr="Field 'r' may be 'final'">r</warning>; // may be final, compare to T65
T68() {
r = () -> System.out.println((this).r);
}
}
class T69 {
private String s; // may not be final
T69() {
Runnable r = () -> s = "asdf";
}
}
class T70 {
private String s; // may not be final
T70() {
Runnable r = () -> s = "asdf";
s = "";
}
}
class Foo {
public interface Accessor<T> {