Report unused local variables inside lambda expressions with expression bodies

for the global "Unused declaration" inspection

GitOrigin-RevId: a6f9f2de0b53f254312a07c43190502731d995e2
This commit is contained in:
Bas Leijdekkers
2022-04-30 10:21:06 +00:00
committed by intellij-monorepo-bot
parent 64cb9b88cf
commit 42ca138d64
3 changed files with 37 additions and 24 deletions
@@ -266,35 +266,30 @@ public final class UnusedDeclarationInspection extends UnusedDeclarationInspecti
UField field = ((RefField)refElement).getUastElement();
if (field != null) {
UExpression initializer = field.getUastInitializer();
if (initializer != null) {
initializer = UastUtils.skipParenthesizedExprDown(initializer);
if (initializer instanceof ULambdaExpression) {
findUnusedLocalVariables(((ULambdaExpression)initializer).getBody(), refElement);
}
}
findUnusedLocalVariables(initializer, refElement);
}
}
}
private void findUnusedLocalVariables(UExpression body, RefElement refElement) {
if (body == null) return;
PsiCodeBlock bodySourcePsi = ObjectUtils.tryCast(body.getSourcePsi(), PsiCodeBlock.class);
if (bodySourcePsi == null) return;
if (!myTools.isEnabled(bodySourcePsi)) return;
InspectionToolWrapper toolWrapper = myTools.getInspectionTool(bodySourcePsi);
PsiElement psiBody = body.getSourcePsi();
if (psiBody == null) return;
if (!myTools.isEnabled(psiBody)) return;
InspectionToolWrapper toolWrapper = myTools.getInspectionTool(psiBody);
InspectionToolPresentation presentation = myContext.getPresentation(toolWrapper);
if (((UnusedDeclarationInspection)toolWrapper.getTool()).getSharedLocalInspectionTool().LOCAL_VARIABLE) {
List<CommonProblemDescriptor> descriptors = new ArrayList<>();
findUnusedLocalVariablesInCodeBlock(bodySourcePsi, descriptors);
findUnusedLocalVariablesInElement(psiBody, descriptors);
if (!descriptors.isEmpty()) {
presentation.addProblemElement(refElement, descriptors.toArray(CommonProblemDescriptor.EMPTY_ARRAY));
}
}
}
private void findUnusedLocalVariablesInCodeBlock(@NotNull PsiCodeBlock codeBlock, @NotNull List<CommonProblemDescriptor> descriptors) {
private void findUnusedLocalVariablesInElement(@NotNull PsiElement element, @NotNull List<CommonProblemDescriptor> descriptors) {
Set<PsiVariable> usedVariables = new HashSet<>();
List<DefUseUtil.Info> unusedDefs = DefUseUtil.getUnusedDefs(codeBlock, usedVariables);
List<DefUseUtil.Info> unusedDefs = DefUseUtil.getUnusedDefs(element, usedVariables);
if (unusedDefs != null && !unusedDefs.isEmpty()) {
for (DefUseUtil.Info varDefInfo : unusedDefs) {
PsiElement parent = varDefInfo.getContext();
@@ -306,7 +301,7 @@ public final class UnusedDeclarationInspection extends UnusedDeclarationInspecti
}
}
}
codeBlock.accept(new JavaRecursiveElementWalkingVisitor() {
element.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitClass(PsiClass aClass) {
// prevent going to local classes
@@ -314,16 +309,9 @@ public final class UnusedDeclarationInspection extends UnusedDeclarationInspecti
@Override
public void visitLambdaExpression(PsiLambdaExpression lambdaExpr) {
RefElement lambdaRef = myContext.getRefManager().getReference(lambdaExpr);
if (lambdaRef instanceof RefFunctionalExpression) {
ULambdaExpression lambda = ObjectUtils.tryCast(((RefFunctionalExpression)lambdaRef).getUastElement(), ULambdaExpression.class);
if (lambda != null) {
PsiCodeBlock lambdaBody = ObjectUtils.tryCast(lambda.getBody().getSourcePsi(), PsiCodeBlock.class);
if (lambdaBody != null) {
findUnusedLocalVariablesInCodeBlock(lambdaBody, descriptors);
}
}
}
final PsiElement body = lambdaExpr.getBody();
if (body == null) return;
findUnusedLocalVariablesInElement(body, descriptors);
}
@Override
@@ -76,6 +76,21 @@
<line>29</line>
<description>Variable &lt;code&gt;i3&lt;/code&gt; is never used</description>
</problem>
<problem>
<file>Lambda.java</file>
<line>38</line>
<description>Variable &lt;code&gt;r&lt;/code&gt; is never used</description>
</problem>
<problem>
<file>Lambda.java</file>
<line>41</line>
<description>Variable &lt;code&gt;s&lt;/code&gt; is never used</description>
</problem>
<problem>
<file>Lambda.java</file>
<line>42</line>
<description>Variable &lt;code&gt;t&lt;/code&gt; is never used</description>
</problem>
<problem>
<file>AnonymousClass.java</file>
@@ -35,6 +35,16 @@ class Test {
System.out.println(lambda2);
return false;
});
java.util.function.IntSupplier r = () ->
switch (args[0]) {
default -> {
String s = "";
String t;
String u = "";
System.out.println(u);
yield 1;
}
};
}
static void bar(Unused unused) {