mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
revert incorrect UnusedDefInspection
This commit is contained in:
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
Detects local variables and private members that are declared but not used, never accessed for reading or not initialized in a class.
|
||||
</body>
|
||||
</html>
|
||||
@@ -407,9 +407,6 @@
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.secondUnsafeCall.SecondUnsafeCallInspection"/>
|
||||
<localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedAssignment" bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
|
||||
key="unused.assignment" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedAssignmentInspection"/>
|
||||
<localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedSymbol" bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
|
||||
key="unused.symbol" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection"/>
|
||||
<localInspection language="Groovy" groupPath="Groovy" shortName="GroovyUnusedIncOrDec" bundle="org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle"
|
||||
key="unused.inc.dec" groupKey="groovy.dfa.issues" enabledByDefault="true" level="WARNING"
|
||||
|
||||
-3
@@ -84,6 +84,3 @@ remove.0=Remove {0}
|
||||
replace.postfix.0.with.prefix.0=Replace postfix {0} with prefix {0}
|
||||
replace.0.with.1=Replace {0} with binary {1}
|
||||
gr.deprecated.api.usage=Deprecated API inspection
|
||||
unused.symbol=Unused symbol
|
||||
remove.variable=Remove variable ''{0}''
|
||||
remove.unused.variable=Remove unused variable
|
||||
|
||||
-211
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.unusedDef;
|
||||
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.Processor;
|
||||
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.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.GroovyPsiElement;
|
||||
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.GrAssignmentExpression;
|
||||
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.api.statements.params.GrParameter;
|
||||
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;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsDfaInstance;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsSemilattice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
& @author ven
|
||||
*/
|
||||
public class UnusedAssignmentInspection extends GroovyLocalInspectionBase {
|
||||
private static final Logger LOG = Logger.getInstance(UnusedAssignmentInspection.class);
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
return GroovyInspectionBundle.message("groovy.dfa.issues");
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return GroovyInspectionBundle.message("unused.assignment");
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "GroovyUnusedAssignment";
|
||||
}
|
||||
|
||||
|
||||
protected void check(final GrControlFlowOwner owner, final ProblemsHolder problemsHolder) {
|
||||
final Instruction[] flow = owner.getControlFlow();
|
||||
final ReachingDefinitionsDfaInstance dfaInstance = new ReachingDefinitionsDfaInstance(flow);
|
||||
final ReachingDefinitionsSemilattice lattice = new ReachingDefinitionsSemilattice();
|
||||
final DFAEngine<TIntObjectHashMap<TIntHashSet>> engine = new DFAEngine<TIntObjectHashMap<TIntHashSet>>(flow, dfaInstance, lattice);
|
||||
final List<TIntObjectHashMap<TIntHashSet>> dfaResult = engine.performDFAWithTimeout();
|
||||
if (dfaResult == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TIntHashSet unusedDefs = new TIntHashSet();
|
||||
for (Instruction instruction : flow) {
|
||||
if (instruction instanceof ReadWriteVariableInstruction && ((ReadWriteVariableInstruction) instruction).isWrite()) {
|
||||
unusedDefs.add(instruction.num());
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < dfaResult.size(); i++) {
|
||||
final Instruction instruction = flow[i];
|
||||
if (instruction instanceof ReadWriteVariableInstruction) {
|
||||
final ReadWriteVariableInstruction varInst = (ReadWriteVariableInstruction) instruction;
|
||||
if (!varInst.isWrite()) {
|
||||
final String varName = varInst.getVariableName();
|
||||
TIntObjectHashMap<TIntHashSet> e = dfaResult.get(i);
|
||||
e.forEachValue(new TObjectProcedure<TIntHashSet>() {
|
||||
public boolean execute(TIntHashSet reaching) {
|
||||
reaching.forEach(new TIntProcedure() {
|
||||
public boolean execute(int defNum) {
|
||||
final String defName = ((ReadWriteVariableInstruction) flow[defNum]).getVariableName();
|
||||
if (varName.equals(defName)) {
|
||||
unusedDefs.remove(defNum);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unusedDefs.forEach(new TIntProcedure() {
|
||||
public boolean execute(int num) {
|
||||
final ReadWriteVariableInstruction instruction = (ReadWriteVariableInstruction)flow[num];
|
||||
final PsiElement element = instruction.getElement();
|
||||
if (element == null) return true;
|
||||
if (isLocalAssignment(element) && isUsedInTopLevelFlowOnly(element) && !isIncOrDec(element)) {
|
||||
PsiElement toHighlight = getHighlightElement(element);
|
||||
problemsHolder.registerProblem(toHighlight, GroovyInspectionBundle.message("unused.assignment.tooltip"),
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static PsiElement getHighlightElement(PsiElement element) {
|
||||
PsiElement toHighlight = null;
|
||||
if (element instanceof GrReferenceExpression) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof GrAssignmentExpression) {
|
||||
toHighlight = ((GrAssignmentExpression)parent).getLValue();
|
||||
}
|
||||
if (parent instanceof GrUnaryExpression && ((GrUnaryExpression)parent).isPostfix()) {
|
||||
toHighlight = parent;
|
||||
}
|
||||
}
|
||||
else if (element instanceof GrVariable) {
|
||||
toHighlight = ((GrVariable)element).getNameIdentifierGroovy();
|
||||
}
|
||||
if (toHighlight == null) toHighlight = element;
|
||||
return toHighlight;
|
||||
}
|
||||
|
||||
private static boolean isIncOrDec(PsiElement element) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (!(parent instanceof GrUnaryExpression)) return false;
|
||||
|
||||
IElementType type = ((GrUnaryExpression)parent).getOperationTokenType();
|
||||
return type == GroovyTokenTypes.mINC || type == GroovyTokenTypes.mDEC;
|
||||
}
|
||||
|
||||
private static boolean isUsedInTopLevelFlowOnly(PsiElement element) {
|
||||
GrVariable var = null;
|
||||
if (element instanceof GrVariable) {
|
||||
var = (GrVariable)element;
|
||||
}
|
||||
else if (element instanceof GrReferenceExpression) {
|
||||
final PsiElement resolved = ((GrReferenceExpression)element).resolve();
|
||||
if (resolved instanceof GrVariable) var = (GrVariable)resolved;
|
||||
}
|
||||
|
||||
if (var != null) {
|
||||
final GroovyPsiElement scope = ControlFlowUtils.findControlFlowOwner(var);
|
||||
if (scope == null) {
|
||||
PsiFile file = var.getContainingFile();
|
||||
LOG.error(file == null ? "no file??? var of type" + var.getClass().getCanonicalName() : DebugUtil.psiToString(file, true, false));
|
||||
}
|
||||
|
||||
return ReferencesSearch.search(var, new LocalSearchScope(scope)).forEach(new Processor<PsiReference>() {
|
||||
public boolean process(PsiReference ref) {
|
||||
return ControlFlowUtils.findControlFlowOwner(ref.getElement()) == scope;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static boolean isLocalAssignment(PsiElement element) {
|
||||
if (element instanceof GrVariable) {
|
||||
return isLocalVariable((GrVariable)element, false);
|
||||
}
|
||||
else if (element instanceof GrReferenceExpression) {
|
||||
final PsiElement resolved = ((GrReferenceExpression)element).resolve();
|
||||
return resolved instanceof GrVariable && isLocalVariable((GrVariable)resolved, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isLocalVariable(GrVariable var, boolean parametersAllowed) {
|
||||
return !(var instanceof GrField || var instanceof GrParameter && !parametersAllowed);
|
||||
}
|
||||
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+143
-104
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,38 +15,49 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.codeInspection.unusedDef;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.Processor;
|
||||
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.BaseInspection;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.GroovyInspectionBundle;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.GroovyLocalInspectionBase;
|
||||
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.GroovyPsiElement;
|
||||
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.GrAssignmentExpression;
|
||||
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.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
|
||||
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;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsDfaInstance;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsSemilattice;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
& @author ven
|
||||
*/
|
||||
public class UnusedDefInspection extends BaseInspection {
|
||||
public class UnusedDefInspection extends GroovyLocalInspectionBase {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection");
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@@ -57,116 +68,144 @@ public class UnusedDefInspection extends BaseInspection {
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return GroovyInspectionBundle.message("unused.symbol");
|
||||
return GroovyInspectionBundle.message("unused.assignment");
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "GroovyUnusedSymbol";
|
||||
return "GroovyUnusedAssignment";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BaseInspectionVisitor buildVisitor() {
|
||||
return new BaseInspectionVisitor() {
|
||||
@Override
|
||||
public void visitVariable(GrVariable variable) {
|
||||
super.visitVariable(variable);
|
||||
if (variable instanceof GrParameter) {
|
||||
PsiElement scope = ((GrParameter)variable).getDeclarationScope();
|
||||
if (scope instanceof GrMethod) {
|
||||
if (((GrMethod)scope).getBlock() == null) return;
|
||||
|
||||
if (((GrMethod)scope).getHierarchicalMethodSignature().getSuperSignatures().size() > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void check(final GrControlFlowOwner owner, final ProblemsHolder problemsHolder) {
|
||||
final Instruction[] flow = owner.getControlFlow();
|
||||
final ReachingDefinitionsDfaInstance dfaInstance = new ReachingDefinitionsDfaInstance(flow);
|
||||
final ReachingDefinitionsSemilattice lattice = new ReachingDefinitionsSemilattice();
|
||||
final DFAEngine<TIntObjectHashMap<TIntHashSet>> engine = new DFAEngine<TIntObjectHashMap<TIntHashSet>>(flow, dfaInstance, lattice);
|
||||
final List<TIntObjectHashMap<TIntHashSet>> dfaResult = engine.performDFAWithTimeout();
|
||||
if (dfaResult == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(variable instanceof GrField)) {
|
||||
checkVar(variable);
|
||||
}
|
||||
final TIntHashSet unusedDefs = new TIntHashSet();
|
||||
for (Instruction instruction : flow) {
|
||||
if (instruction instanceof ReadWriteVariableInstruction && ((ReadWriteVariableInstruction) instruction).isWrite()) {
|
||||
unusedDefs.add(instruction.num());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkVar(GrVariable var) {
|
||||
AccessToken lock = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
boolean isNotAccessedForRead = ReferencesSearch.search(var).forEach(new Processor<PsiReference>() {
|
||||
@Override
|
||||
public boolean process(PsiReference reference) {
|
||||
PsiElement element = reference.getElement();
|
||||
return !(element instanceof GrExpression && PsiUtil.isAccessedForReading((GrExpression)element));
|
||||
for (int i = 0; i < dfaResult.size(); i++) {
|
||||
final Instruction instruction = flow[i];
|
||||
if (instruction instanceof ReadWriteVariableInstruction) {
|
||||
final ReadWriteVariableInstruction varInst = (ReadWriteVariableInstruction) instruction;
|
||||
if (!varInst.isWrite()) {
|
||||
final String varName = varInst.getVariableName();
|
||||
TIntObjectHashMap<TIntHashSet> e = dfaResult.get(i);
|
||||
e.forEachValue(new TObjectProcedure<TIntHashSet>() {
|
||||
public boolean execute(TIntHashSet reaching) {
|
||||
reaching.forEach(new TIntProcedure() {
|
||||
public boolean execute(int defNum) {
|
||||
final String defName = ((ReadWriteVariableInstruction) flow[defNum]).getVariableName();
|
||||
if (varName.equals(defName)) {
|
||||
unusedDefs.remove(defNum);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (isNotAccessedForRead) {
|
||||
registerError(var.getNameIdentifierGroovy(), GroovyInspectionBundle.message("unused.symbol"),
|
||||
getFixes(var),
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
lock.finish();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
unusedDefs.forEach(new TIntProcedure() {
|
||||
public boolean execute(int num) {
|
||||
final ReadWriteVariableInstruction instruction = (ReadWriteVariableInstruction)flow[num];
|
||||
final PsiElement element = instruction.getElement();
|
||||
if (element == null) return true;
|
||||
if (isLocalAssignment(element) && isUsedInTopLevelFlowOnly(element) && !isIncOrDec(element)) {
|
||||
PsiElement toHighlight = getHighlightElement(element);
|
||||
problemsHolder.registerProblem(toHighlight, GroovyInspectionBundle.message("unused.assignment.tooltip"),
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static LocalQuickFix[] getFixes(GrVariable var) {
|
||||
if (GroovyRefactoringUtil.isLocalVariable(var)) {
|
||||
return new LocalQuickFix[]{new RemoveVarFix(var.getName())};
|
||||
private static PsiElement getHighlightElement(PsiElement element) {
|
||||
PsiElement toHighlight = null;
|
||||
if (element instanceof GrReferenceExpression) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof GrAssignmentExpression) {
|
||||
toHighlight = ((GrAssignmentExpression)parent).getLValue();
|
||||
}
|
||||
if (parent instanceof GrUnaryExpression && ((GrUnaryExpression)parent).isPostfix()) {
|
||||
toHighlight = parent;
|
||||
}
|
||||
}
|
||||
return LocalQuickFix.EMPTY_ARRAY;
|
||||
else if (element instanceof GrVariable) {
|
||||
toHighlight = ((GrVariable)element).getNameIdentifierGroovy();
|
||||
}
|
||||
if (toHighlight == null) toHighlight = element;
|
||||
return toHighlight;
|
||||
}
|
||||
|
||||
private static boolean isIncOrDec(PsiElement element) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (!(parent instanceof GrUnaryExpression)) return false;
|
||||
|
||||
IElementType type = ((GrUnaryExpression)parent).getOperationTokenType();
|
||||
return type == GroovyTokenTypes.mINC || type == GroovyTokenTypes.mDEC;
|
||||
}
|
||||
|
||||
private static boolean isUsedInTopLevelFlowOnly(PsiElement element) {
|
||||
GrVariable var = null;
|
||||
if (element instanceof GrVariable) {
|
||||
var = (GrVariable)element;
|
||||
}
|
||||
else if (element instanceof GrReferenceExpression) {
|
||||
final PsiElement resolved = ((GrReferenceExpression)element).resolve();
|
||||
if (resolved instanceof GrVariable) var = (GrVariable)resolved;
|
||||
}
|
||||
|
||||
if (var != null) {
|
||||
final GroovyPsiElement scope = ControlFlowUtils.findControlFlowOwner(var);
|
||||
if (scope == null) {
|
||||
PsiFile file = var.getContainingFile();
|
||||
LOG.error(file == null ? "no file??? var of type" + var.getClass().getCanonicalName() : DebugUtil.psiToString(file, true, false));
|
||||
}
|
||||
|
||||
return ReferencesSearch.search(var, new LocalSearchScope(scope)).forEach(new Processor<PsiReference>() {
|
||||
public boolean process(PsiReference ref) {
|
||||
return ControlFlowUtils.findControlFlowOwner(ref.getElement()) == scope;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static boolean isLocalAssignment(PsiElement element) {
|
||||
if (element instanceof GrVariable) {
|
||||
return isLocalVariable((GrVariable)element, false);
|
||||
}
|
||||
else if (element instanceof GrReferenceExpression) {
|
||||
final PsiElement resolved = ((GrReferenceExpression)element).resolve();
|
||||
return resolved instanceof GrVariable && isLocalVariable((GrVariable)resolved, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isLocalVariable(GrVariable var, boolean parametersAllowed) {
|
||||
return !(var instanceof GrField || var instanceof GrParameter && !parametersAllowed);
|
||||
}
|
||||
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class RemoveVarFix implements LocalQuickFix {
|
||||
private String myName;
|
||||
|
||||
public RemoveVarFix(String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return GroovyInspectionBundle.message("remove.variable", myName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return GroovyInspectionBundle.message("remove.unused.variable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiElement element = descriptor.getPsiElement();
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof GrVariable) {
|
||||
Collection<PsiReference> all = ReferencesSearch.search(parent).findAll();
|
||||
|
||||
for (PsiReference reference : all) {
|
||||
PsiElement e = reference.getElement();
|
||||
if (e instanceof GrReferenceExpression) {
|
||||
PsiElement p = e.getParent();
|
||||
if (p instanceof GrAssignmentExpression) {
|
||||
if (PsiUtil.isExpressionUsed(p)) {
|
||||
((GrAssignmentExpression)p).replaceWithExpression(((GrAssignmentExpression)p).getRValue(), true);
|
||||
}
|
||||
else {
|
||||
p.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
e.delete();
|
||||
}
|
||||
}
|
||||
parent.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,8 +115,7 @@ class GroovyDebuggerTest extends GroovyCompilerTestCase {
|
||||
}
|
||||
|
||||
public void testVariableInScript() {
|
||||
myFixture.addFileToProject("Foo.groovy", """\
|
||||
def a = 2
|
||||
myFixture.addFileToProject("Foo.groovy", """def a = 2
|
||||
a""");
|
||||
addBreakpoint 'Foo.groovy', 1
|
||||
runDebugger 'Foo', {
|
||||
@@ -242,7 +241,6 @@ new Runnable() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private def addBreakpoint(String fileName, int line) {
|
||||
VirtualFile file = null
|
||||
edt {
|
||||
@@ -293,7 +291,7 @@ new Runnable() {
|
||||
semaphore.up()
|
||||
}
|
||||
})
|
||||
def finished = semaphore.waitFor(200000)
|
||||
def finished = semaphore.waitFor(20000)
|
||||
assert finished : 'Too long debugger action'
|
||||
return result
|
||||
}
|
||||
@@ -311,7 +309,7 @@ new Runnable() {
|
||||
item.setContext(ctx)
|
||||
item.updateRepresentation(ctx, { semaphore.up() } as DescriptorLabelListener)
|
||||
}
|
||||
assert semaphore.waitFor(200000): "too long evaluation: $item.label $item.evaluateException"
|
||||
assert semaphore.waitFor(10000): "too long evaluation: $item.label $item.evaluateException"
|
||||
|
||||
String result = managed { DebuggerUtils.getValueAsString(ctx, item.value) }
|
||||
assert result == expected
|
||||
|
||||
+14
-14
@@ -43,7 +43,7 @@ import org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyLongMetho
|
||||
import org.jetbrains.plugins.groovy.codeInspection.unassignedVariable.UnassignedVariableAccessInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUnresolvedAccessInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedAssignmentInspection
|
||||
import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection
|
||||
import org.jetbrains.plugins.groovy.util.TestUtils
|
||||
import org.jetbrains.plugins.groovy.codeInspection.bugs.*
|
||||
import org.jetbrains.plugins.groovy.codeInspection.confusing.*
|
||||
@@ -186,10 +186,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 UnusedAssignmentInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testDefinitionUsedInClosure() throws Exception { doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testDefinitionUsedInClosure2() throws Exception { doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testDefinitionUsedInSwitchCase() throws Exception { doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection()); }
|
||||
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();}
|
||||
@@ -246,8 +246,8 @@ class A {
|
||||
public void testByteArrayArgument() throws Exception {doTest(new GroovyAssignabilityCheckInspection());}
|
||||
|
||||
public void testForLoopWithNestedEndlessLoop() throws Exception {doTest(new UnassignedVariableAccessInspection());}
|
||||
public void testPrefixIncrementCfa() throws Exception {doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection());}
|
||||
public void testIfIncrementElseReturn() throws Exception {doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testPrefixIncrementCfa() throws Exception {doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection());}
|
||||
public void testIfIncrementElseReturn() throws Exception {doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection()); }
|
||||
|
||||
public void testArrayLikeAccess() throws Exception {doTest();}
|
||||
|
||||
@@ -313,7 +313,7 @@ class A {
|
||||
|
||||
public void testBuiltInTypeInstantiation() {doTest();}
|
||||
|
||||
public void testSwitchControlFlow() {doTest(new UnusedAssignmentInspection(), new GroovyResultOfAssignmentUsedInspection(), new GrUnusedIncDecInspection());}
|
||||
public void testSwitchControlFlow() {doTest(new UnusedDefInspection(), new GroovyResultOfAssignmentUsedInspection(), new GrUnusedIncDecInspection());}
|
||||
|
||||
public void testRawTypeInAssignment() {doTest(new GroovyAssignabilityCheckInspection());}
|
||||
|
||||
@@ -323,7 +323,7 @@ class A {
|
||||
IdeaTestUtil.assertTiming("", 10000, 1, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doTest(new GroovyAssignabilityCheckInspection(), new UnusedAssignmentInspection(), new GrUnusedIncDecInspection());
|
||||
doTest(new GroovyAssignabilityCheckInspection(), new UnusedDefInspection(), new GrUnusedIncDecInspection());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -395,7 +395,7 @@ class A {
|
||||
doTest(new GroovyUnresolvedAccessInspection(), new GroovyUntypedAccessInspection());
|
||||
}
|
||||
|
||||
public void testUsageInInjection() { doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection()); }
|
||||
public void testUsageInInjection() { doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection()); }
|
||||
|
||||
public void testDuplicatedNamedArgs() {doTest();}
|
||||
|
||||
@@ -417,19 +417,19 @@ class A {
|
||||
}
|
||||
|
||||
public void testUnusedDefsForArgs() {
|
||||
doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection());
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection());
|
||||
}
|
||||
|
||||
public void testUsedDefBeforeTry1() {
|
||||
doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection());
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection());
|
||||
}
|
||||
|
||||
public void testUsedDefBeforeTry2() {
|
||||
doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection());
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection());
|
||||
}
|
||||
|
||||
public void testUnusedInc() {
|
||||
doTest(new UnusedAssignmentInspection(), new GrUnusedIncDecInspection())
|
||||
doTest(new UnusedDefInspection(), new GrUnusedIncDecInspection())
|
||||
}
|
||||
|
||||
public void testStringAssignableToChar() {
|
||||
|
||||
Reference in New Issue
Block a user