diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
index 1c5a0f38a921..b7e4bf4fe5ab 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java
@@ -649,14 +649,8 @@ public class HighlightControlFlowUtil {
@NotNull PsiField field,
@NotNull PsiReferenceExpression reference,
@NotNull PsiFile containingFile) {
-
if (!containingFile.getManager().areElementsEquivalent(enclosingCtrOrInitializer.getContainingClass(), field.getContainingClass())) return false;
- PsiExpression qualifierExpression = reference.getQualifierExpression();
- // JLS 16: "Such an assignment is defined to occur if and only if either the simple name of the variable
- // (or, for a field, its simple name qualified by this) occurs on the left hand side of an assignment operator"
- // Qualified this is not allowed by spec
- return qualifierExpression == null || (qualifierExpression instanceof PsiThisExpression &&
- ((PsiThisExpression)qualifierExpression).getQualifier() == null);
+ return LocalsOrMyInstanceFieldsControlFlowPolicy.isLocalOrMyInstanceReference(reference);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java
index 25521743ad54..86b82a0bc4ec 100644
--- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsOrMyInstanceFieldsControlFlowPolicy.java
@@ -17,7 +17,7 @@
package com.intellij.psi.controlFlow;
import com.intellij.psi.*;
-import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
public class LocalsOrMyInstanceFieldsControlFlowPolicy implements ControlFlowPolicy {
@@ -28,13 +28,9 @@ public class LocalsOrMyInstanceFieldsControlFlowPolicy implements ControlFlowPol
@Override
public PsiVariable getUsedVariable(@NotNull PsiReferenceExpression refExpr) {
- PsiExpression qualifier = PsiUtil.skipParenthesizedExprDown(refExpr.getQualifierExpression());
- if (qualifier == null || (qualifier instanceof PsiThisExpression && ((PsiThisExpression)qualifier).getQualifier() == null)) {
- PsiElement resolved = refExpr.resolve();
- if (!(resolved instanceof PsiVariable)) return null;
- return (PsiVariable)resolved;
+ if (isLocalOrMyInstanceReference(refExpr)) {
+ return ObjectUtils.tryCast(refExpr.resolve(), PsiVariable.class);
}
-
return null;
}
@@ -51,4 +47,19 @@ public class LocalsOrMyInstanceFieldsControlFlowPolicy implements ControlFlowPol
public static LocalsOrMyInstanceFieldsControlFlowPolicy getInstance() {
return INSTANCE;
}
+
+ /**
+ * @param variableReference variable reference to check
+ * @return true if given variable reference refers to local variable or the field which participates in
+ * definitive assignment analysis, as specified in JLS, chapter 16. The method does not check whether
+ * the reference actually resolves to variable.
+ */
+ public static boolean isLocalOrMyInstanceReference(PsiReferenceExpression variableReference) {
+ PsiExpression qualifierExpression = variableReference.getQualifierExpression();
+ // JLS 16: "Such an assignment is defined to occur if and only if either the simple name of the variable
+ // (or, for a field, its simple name qualified by this) occurs on the left hand side of an assignment operator"
+ // Qualified this is not allowed by spec
+ return qualifierExpression == null || (qualifierExpression instanceof PsiThisExpression &&
+ ((PsiThisExpression)qualifierExpression).getQualifier() == null);
+ }
}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AssignToFinal.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AssignToFinal.java
index 60d0a0f233fc..c648224d9818 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AssignToFinal.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/AssignToFinal.java
@@ -251,4 +251,14 @@ class QualifiedThis {
QualifiedThis.this.x = 5;
this.x = 5;
}
+}
+
+class ParenthesizedThis {
+ final int x;
+ final int y = (this).x + 1; // allowed as qualifier is not naked 'this'!
+
+ ParenthesizedThis() {
+ (this).x = 5;
+ this.x = 6;
+ }
}
\ No newline at end of file