IDEA-56701 'Assignment not used' for variables passed into an anonymous class constructor

This commit is contained in:
Maxim Medvedev
2010-07-27 14:57:26 +04:00
parent d5ecb668bb
commit 6cee0d855f
5 changed files with 47 additions and 27 deletions
@@ -15,25 +15,35 @@
*/
package org.jetbrains.plugins.groovy.codeInspection.unusedDef;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Processor;
import gnu.trove.*;
import org.jetbrains.annotations.*;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntObjectHashMap;
import gnu.trove.TIntProcedure;
import gnu.trove.TObjectProcedure;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle;
import org.jetbrains.plugins.groovy.codeInspection.GroovyLocalInspectionBase;
import org.jetbrains.plugins.groovy.lang.psi.*;
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrPostfixExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.DFAEngine;
@@ -105,22 +115,27 @@ public class UnusedDefInspection extends GroovyLocalInspectionBase {
unusedDefs.forEach(new TIntProcedure() {
public boolean execute(int num) {
final ReadWriteVariableInstruction instruction = (ReadWriteVariableInstruction) flow[num];
final ReadWriteVariableInstruction instruction = (ReadWriteVariableInstruction)flow[num];
final PsiElement element = instruction.getElement();
if (element == null) return true;
PsiElement toHighlight = null;
if (isLocalAssignment(element) && isUsedInToplevelFlowOnly(element)) {
if (element instanceof GrReferenceExpression) {
PsiElement parent = element.getParent();
PsiElement toHighlight = null;
if (parent instanceof GrAssignmentExpression) {
toHighlight = ((GrAssignmentExpression) parent).getLValue();
} if (parent instanceof GrPostfixExpression) {
toHighlight = ((GrAssignmentExpression)parent).getRValue();
}
if (parent instanceof GrPostfixExpression) {
toHighlight = parent;
}
if (toHighlight == null) toHighlight = element;
problemsHolder.registerProblem(toHighlight, GroovyInspectionBundle.message("unused.assignment.tooltip"), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
} else if (element instanceof GrVariable) {
problemsHolder.registerProblem(((GrVariable) element).getNameIdentifierGroovy(), GroovyInspectionBundle.message("unused.assignment.tooltip"), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
}
else if (element instanceof GrVariable) {
toHighlight = ((GrVariable)element).getInitializerGroovy();
if (toHighlight == null) toHighlight = ((GrVariable)element).getNameIdentifierGroovy();
}
if (toHighlight == null) toHighlight = element;
problemsHolder.registerProblem(toHighlight, GroovyInspectionBundle.message("unused.assignment.tooltip"),
ProblemHighlightType.LIKE_UNUSED_SYMBOL);
}
return true;
}
@@ -39,6 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClaus
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.*;
@@ -60,7 +61,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
private class ExceptionInfo {
private static class ExceptionInfo {
GrCatchClause myClause;
List<InstructionImpl> myThrowers = new ArrayList<InstructionImpl>();
@@ -181,7 +182,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
myHead = instruction;
}
void addEdge(InstructionImpl beg, InstructionImpl end) {
static void addEdge(InstructionImpl beg, InstructionImpl end) {
if (!beg.mySucc.contains(end)) {
beg.mySucc.add(end);
}
@@ -281,7 +282,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
@Nullable
private ExceptionInfo findCatch(PsiType thrownType) {
for (int i = myCatchedExceptionInfos.size() - 1; i >= 0; i--) {
final ControlFlowBuilder.ExceptionInfo info = myCatchedExceptionInfos.get(i);
final ExceptionInfo info = myCatchedExceptionInfos.get(i);
final GrCatchClause clause = info.myClause;
final GrParameter parameter = clause.getParameter();
if (parameter != null) {
@@ -363,7 +364,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
}
private boolean isIncOrDecOperand(GrReferenceExpression referenceExpression) {
private static boolean isIncOrDecOperand(GrReferenceExpression referenceExpression) {
final PsiElement parent = referenceExpression.getParent();
if (parent instanceof GrPostfixExpression) return true;
if (parent instanceof GrUnaryExpression) {
@@ -667,6 +668,9 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
if (typeDefinition instanceof GrAnonymousClassDefinition) {
super.visitTypeDefinition(typeDefinition);
}
}
public void visitVariable(GrVariable variable) {
@@ -678,6 +682,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
}
@Nullable
private InstructionImpl findInstruction(PsiElement element) {
for (int i = myProcessingStack.size() - 1; i >= 0; i--) {
InstructionImpl instruction = myProcessingStack.get(i);
@@ -686,7 +691,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
return null;
}
class CallInstructionImpl extends InstructionImpl implements CallInstruction {
static class CallInstructionImpl extends InstructionImpl implements CallInstruction {
private final InstructionImpl myCallee;
public String toString() {
@@ -712,7 +717,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
}
class PostCallInstructionImpl extends InstructionImpl implements AfterCallInstruction {
static class PostCallInstructionImpl extends InstructionImpl implements AfterCallInstruction {
private final CallInstructionImpl myCall;
private RetInstruction myReturnInsn;
@@ -743,7 +748,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
}
class RetInstruction extends InstructionImpl {
static class RetInstruction extends InstructionImpl {
RetInstruction(int num) {
super(null, num);
}
@@ -10,4 +10,4 @@ int numPermutationsPrinted = 1;
}
def <warning descr="Assignment is not used">x</warning> = 2
def x = <warning descr="Assignment is not used">2</warning>
@@ -1,5 +1,5 @@
int idx
<warning descr="Assignment is not used">idx</warning> = 2
idx = <warning descr="Assignment is not used">2</warning>
idx = 3
if (++idx == 8) { //Assignment is used here
idx = 33
+1 -1
View File
@@ -1 +1 @@
Class <warning descr="Assignment is not used">clazz</warning> = null
Class clazz = <warning descr="Assignment is not used">null</warning>