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 031590492d9f..b626b08ef7ad 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
@@ -675,7 +675,7 @@ public class HighlightControlFlowUtil {
return null;
}
- public static boolean isEffectivelyFinal(PsiVariable variable, PsiElement scope, PsiJavaCodeReferenceElement context) {
+ public static boolean isEffectivelyFinal(PsiVariable variable, PsiElement scope, @Nullable PsiJavaCodeReferenceElement context) {
boolean effectivelyFinal;
if (variable instanceof PsiParameter) {
effectivelyFinal = notAccessedForWriting(variable, new LocalSearchScope(((PsiParameter)variable).getDeclarationScope()));
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionBase.java
index 4c82119a3483..ad4273156865 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionBase.java
@@ -15,16 +15,18 @@
*/
package com.siyeh.ig.dataflow;
+import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
-import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.util.xmlb.XmlSerializer;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -162,11 +164,17 @@ public class UnnecessaryLocalVariableInspectionBase extends BaseInspection {
VariableAccessUtils.variableIsAssigned(initialization, containingScope, false)) {
return false;
}
- if (!initialization.hasModifierProperty(PsiModifier.FINAL) && variable.hasModifierProperty(PsiModifier.FINAL)) {
- if (VariableAccessUtils.variableIsUsedInInnerClass(variable, containingScope)) {
- return false;
+
+ if (!initialization.hasModifierProperty(PsiModifier.FINAL) && variable.hasModifierProperty(PsiModifier.FINAL) ||
+ PsiUtil.isLanguageLevel8OrHigher(initialization) && !HighlightControlFlowUtil.isEffectivelyFinal(initialization, containingScope, null) && HighlightControlFlowUtil.isEffectivelyFinal(variable, containingScope, null)) {
+ for (PsiReference ref : ReferencesSearch.search(variable, new LocalSearchScope(containingScope))) {
+ final PsiElement element = PsiTreeUtil.getParentOfType(ref.getElement(), PsiClass.class, PsiLambdaExpression.class);
+ if (element != null && PsiTreeUtil.isAncestor(containingScope, element, true)) {
+ return false;
+ }
}
}
+
return !TypeConversionUtil.boxingConversionApplicable(variable.getType(), initialization.getType());
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/C.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/C.java
index da4b4b43181c..c316742bb3e9 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/C.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/C.java
@@ -115,4 +115,15 @@ class C {
System.out.println(k);
}
+ void usedIn8Inner(int j) {
+ for (int i = 0; i < 7; i++) {
+ int k = i;
+ int n = j;
+ class F {
+ {
+ System.out.println(k + n);
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/expected.xml
index 70ce7071c30e..aa7bda34c4c4 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/unnecessary_local_vars/expected.xml
@@ -119,4 +119,10 @@
Local variable <code>k</code> is redundant #loc
+
+ C.java
+ 121
+ Redundant local variable
+ Local variable <code>n</code> is redundant #loc
+
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionTest.java
index b7f1fb4ff67f..4efbf1a23d4b 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/dataflow/UnnecessaryLocalVariableInspectionTest.java
@@ -15,18 +15,17 @@
*/
package com.siyeh.ig.dataflow;
-import com.intellij.testFramework.IdeaTestUtil;
-import com.siyeh.ig.IGInspectionTestCase;
import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
+import com.intellij.testFramework.IdeaTestUtil;
+import com.siyeh.ig.IGInspectionTestCase;
public class UnnecessaryLocalVariableInspectionTest extends IGInspectionTestCase {
@Override
protected Sdk getTestProjectSdk() {
final Sdk sdk = IdeaTestUtil.getMockJdk17();
- LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_7);
+ LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.HIGHEST);
return sdk;
}