mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-142317 ("Use of the variable which is known to be constant" false positive)
This commit is contained in:
+10
-231
@@ -179,8 +179,7 @@ public class ConstantValueVariableUseInspection extends BaseInspection {
|
||||
return false;
|
||||
}
|
||||
final PsiVariable variable = (PsiVariable)target;
|
||||
final VariableReadVisitor visitor =
|
||||
new VariableReadVisitor(variable);
|
||||
final VariableReadVisitor visitor = new VariableReadVisitor(variable);
|
||||
body.accept(visitor);
|
||||
if (!visitor.isRead()) {
|
||||
return false;
|
||||
@@ -190,8 +189,7 @@ public class ConstantValueVariableUseInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private static class VariableReadVisitor
|
||||
extends JavaRecursiveElementVisitor {
|
||||
private static class VariableReadVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
|
||||
@NotNull
|
||||
private final PsiVariable variable;
|
||||
@@ -212,197 +210,23 @@ public class ConstantValueVariableUseInspection extends BaseInspection {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssignmentExpression(
|
||||
@NotNull PsiAssignmentExpression assignment) {
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitAssignmentExpression(assignment);
|
||||
final PsiExpression lhs = assignment.getLExpression();
|
||||
if (lhs instanceof PsiReferenceExpression) {
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
if (variable.equals(target)) {
|
||||
written = true;
|
||||
final PsiElement target = expression.resolve();
|
||||
if (variable.equals(target)) {
|
||||
if (PsiUtil.isAccessedForWriting(expression)) {
|
||||
written = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
final PsiExpression rhs = assignment.getRExpression();
|
||||
if (rhs == null) {
|
||||
return;
|
||||
}
|
||||
final VariableUsedVisitor visitor =
|
||||
new VariableUsedVisitor(variable);
|
||||
rhs.accept(visitor);
|
||||
read = visitor.isUsed();
|
||||
reference = visitor.getReference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPrefixExpression(
|
||||
@NotNull PsiPrefixExpression prefixExpression) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitPrefixExpression(prefixExpression);
|
||||
final IElementType tokenType = prefixExpression.getOperationTokenType();
|
||||
if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
|
||||
!tokenType.equals(JavaTokenType.MINUSMINUS)) {
|
||||
return;
|
||||
}
|
||||
final PsiExpression operand = prefixExpression.getOperand();
|
||||
if (!(operand instanceof PsiReferenceExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression =
|
||||
(PsiReferenceExpression)operand;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
if (!variable.equals(target)) {
|
||||
return;
|
||||
}
|
||||
written = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPostfixExpression(
|
||||
@NotNull PsiPostfixExpression postfixExpression) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitPostfixExpression(postfixExpression);
|
||||
final IElementType tokenType = postfixExpression.getOperationTokenType();
|
||||
if (!tokenType.equals(JavaTokenType.PLUSPLUS) &&
|
||||
!tokenType.equals(JavaTokenType.MINUSMINUS)) {
|
||||
return;
|
||||
}
|
||||
final PsiExpression operand = postfixExpression.getOperand();
|
||||
if (!(operand instanceof PsiReferenceExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression =
|
||||
(PsiReferenceExpression)operand;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
if (!variable.equals(target)) {
|
||||
return;
|
||||
}
|
||||
written = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVariable(@NotNull PsiVariable variable) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitVariable(variable);
|
||||
final PsiExpression initalizer = variable.getInitializer();
|
||||
if (initalizer == null) {
|
||||
return;
|
||||
}
|
||||
final VariableUsedVisitor visitor =
|
||||
new VariableUsedVisitor(variable);
|
||||
initalizer.accept(visitor);
|
||||
read = visitor.isUsed();
|
||||
reference = visitor.getReference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(
|
||||
@NotNull PsiMethodCallExpression call) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitMethodCallExpression(call);
|
||||
final PsiExpressionList argumentList = call.getArgumentList();
|
||||
final PsiExpression[] arguments = argumentList.getExpressions();
|
||||
for (final PsiExpression argument : arguments) {
|
||||
final VariableUsedVisitor visitor =
|
||||
new VariableUsedVisitor(variable);
|
||||
argument.accept(visitor);
|
||||
if (visitor.isUsed()) {
|
||||
if (PsiUtil.isAccessedForReading(expression)) {
|
||||
reference = expression;
|
||||
read = true;
|
||||
reference = visitor.getReference();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(
|
||||
@NotNull PsiNewExpression newExpression) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitNewExpression(newExpression);
|
||||
final PsiExpressionList argumentList =
|
||||
newExpression.getArgumentList();
|
||||
if (argumentList == null) {
|
||||
return;
|
||||
}
|
||||
final PsiExpression[] arguments = argumentList.getExpressions();
|
||||
for (final PsiExpression argument : arguments) {
|
||||
final VariableUsedVisitor visitor =
|
||||
new VariableUsedVisitor(variable);
|
||||
argument.accept(visitor);
|
||||
if (visitor.isUsed()) {
|
||||
read = true;
|
||||
reference = visitor.getReference();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitArrayInitializerExpression(
|
||||
PsiArrayInitializerExpression expression) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitArrayInitializerExpression(expression);
|
||||
final PsiExpression[] arguments = expression.getInitializers();
|
||||
for (final PsiExpression argument : arguments) {
|
||||
final VariableUsedVisitor visitor =
|
||||
new VariableUsedVisitor(variable);
|
||||
argument.accept(visitor);
|
||||
if (visitor.isUsed()) {
|
||||
read = true;
|
||||
reference = visitor.getReference();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReturnStatement(
|
||||
@NotNull PsiReturnStatement returnStatement) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitReturnStatement(returnStatement);
|
||||
final PsiExpression returnValue = returnStatement.getReturnValue();
|
||||
if (returnValue == null) {
|
||||
return;
|
||||
}
|
||||
final VariableUsedVisitor visitor =
|
||||
new VariableUsedVisitor(variable);
|
||||
returnValue.accept(visitor);
|
||||
read = visitor.isUsed();
|
||||
reference = visitor.getReference();
|
||||
}
|
||||
|
||||
/**
|
||||
* check if variable is used in nested/inner class.
|
||||
*/
|
||||
@Override
|
||||
public void visitClass(PsiClass aClass) {
|
||||
if (read || written) {
|
||||
return;
|
||||
}
|
||||
super.visitClass(aClass);
|
||||
final VariableUsedVisitor visitor =
|
||||
new VariableUsedVisitor(variable);
|
||||
aClass.accept(visitor);
|
||||
read = visitor.isUsed();
|
||||
reference = visitor.getReference();
|
||||
super.visitReferenceExpression(expression);
|
||||
}
|
||||
|
||||
public boolean isRead() {
|
||||
@@ -413,49 +237,4 @@ public class ConstantValueVariableUseInspection extends BaseInspection {
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
|
||||
private static class VariableUsedVisitor
|
||||
extends JavaRecursiveElementVisitor {
|
||||
|
||||
private final PsiVariable variable;
|
||||
private boolean used = false;
|
||||
private PsiReferenceExpression reference = null;
|
||||
|
||||
VariableUsedVisitor(PsiVariable variable) {
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (used) {
|
||||
return;
|
||||
}
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(
|
||||
@NotNull PsiReferenceExpression expression) {
|
||||
if (used) {
|
||||
return;
|
||||
}
|
||||
super.visitReferenceExpression(expression);
|
||||
final PsiElement referent = expression.resolve();
|
||||
if (referent == null) {
|
||||
return;
|
||||
}
|
||||
if (referent.equals(variable)) {
|
||||
reference = expression;
|
||||
used = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUsed() {
|
||||
return used;
|
||||
}
|
||||
|
||||
public PsiReferenceExpression getReference() {
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
@@ -20,6 +20,30 @@ public class ConstantValueVariableUse {
|
||||
if ((i) == 2 && true && true) { // polyadic
|
||||
f(<warning descr="Value of 'i' is known to be constant">i</warning>);
|
||||
}
|
||||
|
||||
int j = 10;
|
||||
while (i < 10 && j == 10) {
|
||||
f(<warning descr="Value of 'j' is known to be constant">j</warning>);
|
||||
}
|
||||
for (; i < 10 && j == 10; ) {
|
||||
f(<warning descr="Value of 'j' is known to be constant">j</warning>);
|
||||
}
|
||||
|
||||
if (i == 3) {
|
||||
i = 4;
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
class C {
|
||||
private int hash;
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int h = hash;
|
||||
if (h == 0) {
|
||||
hash = h = "StringUtil.stringHashCode(this, 0, length())".hashCode();
|
||||
}
|
||||
return h;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user