mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
correct GrUnusedIncDecInpection
This commit is contained in:
+25
-1
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.codeInspection.confusing;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -30,21 +31,25 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
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.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryExpression;
|
||||
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.util.PsiUtil;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrUnusedIncDecInspection extends BaseInspection {
|
||||
private static final Logger LOG = Logger.getInstance(GrUnusedIncDecInspection.class);
|
||||
@Override
|
||||
protected BaseInspectionVisitor buildVisitor() {
|
||||
return new GrUnusedIncDecInspectionVisitor();
|
||||
@@ -87,7 +92,26 @@ public class GrUnusedIncDecInspection extends BaseInspection {
|
||||
PsiElement resolved = ((GrReferenceExpression)operand).resolve();
|
||||
if (!(resolved instanceof GrVariable) || resolved instanceof GrField) return;
|
||||
|
||||
List<ReadWriteVariableInstruction> accesses = ControlFlowUtils.findAccess((GrVariable)resolved, expression.getOperand(), true, false);
|
||||
final GrControlFlowOwner owner = ControlFlowUtils.findControlFlowOwner(expression);
|
||||
assert owner != null;
|
||||
GrControlFlowOwner ownerOfDeclaration = ControlFlowUtils.findControlFlowOwner(resolved);
|
||||
if (ownerOfDeclaration != owner) return;
|
||||
|
||||
final Instruction cur = ControlFlowUtils.findInstruction(operand, owner.getControlFlow());
|
||||
|
||||
if (cur == null) {
|
||||
LOG.error("no instruction found in flow." + "operand: " + operand.getText() + " cfo: " + owner.getText());
|
||||
}
|
||||
|
||||
//get write access for inc or dec
|
||||
Iterable<? extends Instruction> successors = cur.allSuccessors();
|
||||
Iterator<? extends Instruction> iterator = successors.iterator();
|
||||
LOG.assertTrue(iterator.hasNext());
|
||||
Instruction writeAccess = iterator.next();
|
||||
LOG.assertTrue(!iterator.hasNext());
|
||||
|
||||
List<ReadWriteVariableInstruction> accesses = ControlFlowUtils.findAccess((GrVariable)resolved, true, false, writeAccess);
|
||||
|
||||
boolean allAreWrite = true;
|
||||
for (ReadWriteVariableInstruction access : accesses) {
|
||||
if (!access.isWrite()) {
|
||||
|
||||
+16
-10
@@ -679,15 +679,21 @@ public class ControlFlowUtils {
|
||||
|
||||
final Instruction cur = findInstruction(place, owner.getControlFlow());
|
||||
|
||||
if (cur == null) throw new IllegalArgumentException("place is not in the flow");
|
||||
if (cur == null) {
|
||||
throw new IllegalArgumentException("place is not in the flow");
|
||||
}
|
||||
|
||||
return findAccess(local, ahead, writeAccessOnly, cur);
|
||||
}
|
||||
|
||||
public static List<ReadWriteVariableInstruction> findAccess(GrVariable local, boolean ahead, boolean writeAccessOnly, Instruction cur) {
|
||||
String name = local.getName();
|
||||
|
||||
|
||||
final ArrayList<ReadWriteVariableInstruction> result = new ArrayList<ReadWriteVariableInstruction>();
|
||||
final HashSet<Instruction> visited = new HashSet<Instruction>();
|
||||
|
||||
|
||||
visited.add(cur);
|
||||
|
||||
|
||||
Queue<Instruction> queue = new ArrayDeque<Instruction>();
|
||||
|
||||
for (Instruction i : ahead ? cur.allSuccessors() : cur.allPredecessors()) {
|
||||
@@ -695,11 +701,11 @@ public class ControlFlowUtils {
|
||||
queue.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (true) {
|
||||
Instruction instruction = queue.poll();
|
||||
if (instruction == null) break;
|
||||
|
||||
|
||||
if (instruction instanceof ReadWriteVariableInstruction) {
|
||||
ReadWriteVariableInstruction rw = (ReadWriteVariableInstruction)instruction;
|
||||
if (name.equals(rw.getVariableName())) {
|
||||
@@ -707,13 +713,13 @@ public class ControlFlowUtils {
|
||||
result.add(rw);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!writeAccessOnly) {
|
||||
result.add(rw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (Instruction i : ahead ? instruction.allSuccessors() : instruction.allPredecessors()) {
|
||||
if (visited.add(i)) {
|
||||
queue.add(i);
|
||||
@@ -723,9 +729,9 @@ public class ControlFlowUtils {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static Instruction findInstruction(final PsiElement place, Instruction[] controlFlow) {
|
||||
public static Instruction findInstruction(final PsiElement place, Instruction[] controlFlow) {
|
||||
return ContainerUtil.find(controlFlow, new Condition<Instruction>() {
|
||||
@Override
|
||||
public boolean value(Instruction instruction) {
|
||||
|
||||
+14
-10
@@ -189,10 +189,10 @@ public class GroovyHighlightingTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testUnassigned3() throws Exception { doTest(new UnassignedVariableAccessInspection()); }
|
||||
public void testUnassignedTryFinally() throws Exception { doTest(new UnassignedVariableAccessInspection()); }
|
||||
|
||||
public void testUnusedVariable() throws Exception { doTest(new UnusedDefInspection()); }
|
||||
public void testDefinitionUsedInClosure() throws Exception { doTest(new UnusedDefInspection()); }
|
||||
public void testDefinitionUsedInClosure2() throws Exception { doTest(new UnusedDefInspection()); }
|
||||
public void testDefinitionUsedInSwitchCase() throws Exception { doTest(new UnusedDefInspection()); }
|
||||
public void testUnusedVariable() throws Exception { doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testDefinitionUsedInClosure() throws Exception { doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testDefinitionUsedInClosure2() throws Exception { doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testDefinitionUsedInSwitchCase() throws Exception { doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testDuplicateInnerClass() throws Throwable{doTest();}
|
||||
|
||||
public void testThisInStaticContext() throws Throwable {doTest();}
|
||||
@@ -316,7 +316,7 @@ class A {
|
||||
|
||||
public void testBuiltInTypeInstantiation() {doTest();}
|
||||
|
||||
public void testSwitchControlFlow() {doTest(new UnusedDefInspection(), new GroovyResultOfAssignmentUsedInspection());}
|
||||
public void testSwitchControlFlow() {doTest(new UnusedDefInspection(), new GroovyResultOfAssignmentUsedInspection(), new GrUnusedIncDecInspection());}
|
||||
|
||||
public void testRawTypeInAssignment() {doTest(new GroovyAssignabilityCheckInspection());}
|
||||
|
||||
@@ -326,7 +326,7 @@ class A {
|
||||
IdeaTestUtil.assertTiming("", 10000, 1, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doTest(new GroovyAssignabilityCheckInspection(), new UnusedDefInspection());
|
||||
doTest(new GroovyAssignabilityCheckInspection(), new UnusedDefInspection(), new GrUnusedIncDecInspection());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -398,7 +398,7 @@ class A {
|
||||
doTest(new GroovyUnresolvedAccessInspection(), new GroovyUntypedAccessInspection());
|
||||
}
|
||||
|
||||
public void testUsageInInjection() { doTest(new UnusedDefInspection()); }
|
||||
public void testUsageInInjection() { doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection()); }
|
||||
|
||||
public void testDuplicatedNamedArgs() {doTest();}
|
||||
|
||||
@@ -420,15 +420,19 @@ class A {
|
||||
}
|
||||
|
||||
public void testUnusedDefsForArgs() {
|
||||
doTest(new UnusedDefInspection());
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection());
|
||||
}
|
||||
|
||||
public void testUsedDefBeforeTry1() {
|
||||
doTest(new UnusedDefInspection());
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection());
|
||||
}
|
||||
|
||||
public void testUsedDefBeforeTry2() {
|
||||
doTest(new UnusedDefInspection());
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection());
|
||||
}
|
||||
|
||||
public void testUnusedInc() {
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection())
|
||||
}
|
||||
|
||||
public void testStringAssignableToChar() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
int numPermutationsPrinted = 1;
|
||||
for ( int pos_right = 2; pos_right <= n; pos_right++ ) {
|
||||
|
||||
if (numPermutationsPrinted<warning descr="Unused ++">++</warning> < 30)
|
||||
if (numPermutationsPrinted++ < 30)
|
||||
{
|
||||
println "a"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
def a = 4
|
||||
print (++a)
|
||||
print (a<warning descr="Unused ++">++</warning>)
|
||||
|
||||
def b = 3
|
||||
b<warning descr="Unused ++">++</warning>
|
||||
<warning descr="Assignment is not used">b</warning> = 3
|
||||
Reference in New Issue
Block a user