mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
DivideByZeroInspection: add fix for 0.0/0.0 (replace with NaN)
Fixes IDEA-117884 Inspection "Divide by zero": Recognize 0.0/0.0
This commit is contained in:
+6
@@ -0,0 +1,6 @@
|
||||
// "Replace with 'NaN'" "true"
|
||||
class Test {
|
||||
public void test() {
|
||||
double nan = Double.NaN;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Replace with 'NaN'" "false"
|
||||
class Test {
|
||||
public void test() {
|
||||
double nan = 0/<caret>0;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Replace with 'NaN'" "true"
|
||||
class Test {
|
||||
public void test() {
|
||||
double nan = 0.0/<caret>0.0;
|
||||
}
|
||||
}
|
||||
+50
-9
@@ -15,17 +15,24 @@
|
||||
*/
|
||||
package com.siyeh.ig.numeric;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.dataFlow.CommonDataflow;
|
||||
import com.intellij.codeInspection.dataFlow.DfaFactType;
|
||||
import com.intellij.codeInspection.dataFlow.rangeSet.LongRangeSet;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.ConstantExpressionUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class DivideByZeroInspection extends BaseInspection {
|
||||
private static final LongRangeSet ZERO_RANGE = LongRangeSet.point(0);
|
||||
@@ -49,6 +56,21 @@ public class DivideByZeroInspection extends BaseInspection {
|
||||
return InspectionGadgetsBundle.message("divide.by.zero.problem.descriptor");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionGadgetsFix buildFix(Object... infos) {
|
||||
if (infos.length > 0 && infos[0] instanceof PsiBinaryExpression) {
|
||||
PsiBinaryExpression binOp = (PsiBinaryExpression)infos[0];
|
||||
if (binOp.getOperationTokenType().equals(JavaTokenType.DIV) && isZero(binOp.getLOperand())) {
|
||||
PsiType type = binOp.getType();
|
||||
if (PsiType.DOUBLE.equals(type) || PsiType.FLOAT.equals(type)) {
|
||||
return new ReplaceWithNaNFix();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor() {
|
||||
return new DivisionByZeroVisitor();
|
||||
@@ -67,7 +89,7 @@ public class DivideByZeroInspection extends BaseInspection {
|
||||
for (int i = 1; i < operands.length; i++) {
|
||||
final PsiExpression operand = operands[i];
|
||||
if (isZero(operand)) {
|
||||
registerError(operand);
|
||||
registerError(operand, expression);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -86,15 +108,34 @@ public class DivideByZeroInspection extends BaseInspection {
|
||||
}
|
||||
registerError(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isZero(PsiExpression expression) {
|
||||
final Object value = ConstantExpressionUtil.computeCastTo(expression, PsiType.DOUBLE);
|
||||
if (value instanceof Double) {
|
||||
final double constantValue = ((Double)value).doubleValue();
|
||||
if (constantValue == 0.0) return true;
|
||||
}
|
||||
LongRangeSet range = CommonDataflow.getExpressionFact(expression, DfaFactType.RANGE);
|
||||
return ZERO_RANGE.equals(range);
|
||||
private static boolean isZero(PsiExpression expression) {
|
||||
final Object value = ConstantExpressionUtil.computeCastTo(expression, PsiType.DOUBLE);
|
||||
if (value instanceof Double) {
|
||||
final double constantValue = ((Double)value).doubleValue();
|
||||
if (constantValue == 0.0) return true;
|
||||
}
|
||||
LongRangeSet range = CommonDataflow.getExpressionFact(expression, DfaFactType.RANGE);
|
||||
return ZERO_RANGE.equals(range);
|
||||
}
|
||||
|
||||
private static class ReplaceWithNaNFix extends InspectionGadgetsFix {
|
||||
@Override
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
PsiBinaryExpression division = PsiTreeUtil.getNonStrictParentOfType(descriptor.getStartElement(), PsiBinaryExpression.class);
|
||||
if (division == null) return;
|
||||
PsiType type = division.getType();
|
||||
if (!(type instanceof PsiPrimitiveType)) return;
|
||||
String className = ((PsiPrimitiveType)type).getBoxedTypeName();
|
||||
new CommentTracker().replaceAndRestoreComments(division, className+".NaN");
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Replace with 'NaN'";
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.siyeh.ig.numeric;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DivideByZeroInspectionFixTest extends LightQuickFixParameterizedTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{new DivideByZeroInspection()};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/divideByZero";
|
||||
}
|
||||
|
||||
public void test() { doAllTests(); }
|
||||
}
|
||||
Reference in New Issue
Block a user