check for assignment to final field inside lambda (IDEA-123308)

This commit is contained in:
Anna Kozlova
2014-04-02 17:52:07 +02:00
parent 4bbe4247a7
commit 565b28a089
3 changed files with 20 additions and 1 deletions

View File

@@ -582,7 +582,7 @@ public class HighlightControlFlowUtil {
final PsiElement resolved = reference == null ? null : reference.resolve();
PsiVariable variable = resolved instanceof PsiVariable ? (PsiVariable)resolved : null;
if (variable == null || !variable.hasModifierProperty(PsiModifier.FINAL)) return null;
final boolean canWrite = canWriteToFinal(variable, expression, reference, containingFile);
final boolean canWrite = canWriteToFinal(variable, expression, reference, containingFile) && checkWriteToFinalInsideLambda(variable, reference) == null;
if (readBeforeWrite || !canWrite) {
final String name = variable.getName();
String description = canWrite ?
@@ -661,6 +661,10 @@ public class HighlightControlFlowUtil {
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createVariableAccessFromInnerClassFix(variable, innerClass));
return highlightInfo;
}
return checkWriteToFinalInsideLambda(variable, context);
}
private static HighlightInfo checkWriteToFinalInsideLambda(PsiVariable variable, PsiJavaCodeReferenceElement context) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(context, PsiLambdaExpression.class);
if (lambdaExpression != null && !PsiTreeUtil.isAncestor(lambdaExpression, variable, true)) {
final PsiElement parent = variable.getParent();

View File

@@ -0,0 +1,14 @@
class Test {
private final int a;
public Test() {
a = 1;
run(() -> {
<error descr="Cannot assign a value to final variable 'a'">a</error> = 2;
});
}
public void run(Runnable r) {
r.run();
}
}

View File

@@ -99,6 +99,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testFinalInitializer() {doTest();}
public void testBreakContinueInside() {doTest();}
public void testSameLambdaParamNames() {doTest();}
public void testIDEA123308() {doTest();}
private void doTest() {
doTest(false);