diff --git a/java/java-analysis-impl/src/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspection.java index 4e2a885c8c80..d52e4d1ca77b 100644 --- a/java/java-analysis-impl/src/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspection.java +++ b/java/java-analysis-impl/src/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspection.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.siyeh.ig.numeric; import com.intellij.codeInspection.CleanupLocalInspectionTool; @@ -9,6 +9,7 @@ import com.intellij.modcommand.ModPsiUpdater; import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.text.LiteralFormatUtil; import com.siyeh.InspectionGadgetsBundle; @@ -55,8 +56,8 @@ public final class UnpredictableBigDecimalConstructorCallInspection extends Base return null; } final PsiExpression firstArgument = PsiUtil.skipParenthesizedExprDown(arguments[0]); - if (firstArgument instanceof PsiLiteralExpression) { - return new ReplaceDoubleArgumentWithStringFix("new BigDecimal(\"" + getLiteralText((PsiLiteralExpression)firstArgument) + "\")"); + if (firstArgument instanceof PsiLiteralExpression expression) { + return new ReplaceDoubleArgumentWithStringFix("new BigDecimal(\"" + getLiteralText(expression) + "\")"); } if (arguments.length == 1 && firstArgument != null) { return new ReplaceDoubleArgumentWithStringFix("BigDecimal.valueOf(" + firstArgument.getText() + ')'); @@ -67,9 +68,7 @@ public final class UnpredictableBigDecimalConstructorCallInspection extends Base static String getLiteralText(PsiLiteralExpression firstArgument) { final String text = LiteralFormatUtil.removeUnderscores(firstArgument.getText()); final char c = text.charAt(text.length() - 1); - return c == 'd' || c == 'D' || c == 'f' || c == 'F' - ? text.substring(0, text.length() - 1) - : text; + return (c == 'd' || c == 'D' || c == 'f' || c == 'F') ? text.substring(0, text.length() - 1) : text; } private static class ReplaceDoubleArgumentWithStringFix extends PsiUpdateModCommandQuickFix { @@ -102,8 +101,8 @@ public final class UnpredictableBigDecimalConstructorCallInspection extends Base } final PsiExpression[] arguments = argumentList.getExpressions(); final PsiExpression firstArgument = PsiUtil.skipParenthesizedExprDown(arguments[0]); - if (firstArgument instanceof PsiLiteralExpression) { - PsiReplacementUtil.replaceExpression(firstArgument, '"' + getLiteralText((PsiLiteralExpression)firstArgument) + '"'); + if (firstArgument instanceof PsiLiteralExpression expression) { + PsiReplacementUtil.replaceExpression(firstArgument, '"' + getLiteralText(expression) + '"'); } else if (arguments.length == 1 && firstArgument != null) { PsiReplacementUtil.replaceExpression(newExpression, "java.math.BigDecimal.valueOf(" + firstArgument.getText() + ')'); @@ -114,9 +113,7 @@ public final class UnpredictableBigDecimalConstructorCallInspection extends Base final PsiMethod constructor = newExpression.resolveConstructor(); if (constructor == null) return false; final PsiParameter[] parameters = constructor.getParameterList().getParameters(); - if (parameters.length == 0) return false; - if (!PsiTypes.doubleType().equals(parameters[0].getType())) return false; - return true; + return parameters.length != 0 && PsiTypes.doubleType().equals(parameters[0].getType()); } } @@ -165,13 +162,12 @@ public final class UnpredictableBigDecimalConstructorCallInspection extends Base } private boolean checkExpression(@Nullable PsiExpression expression) { + expression = PsiUtil.deparenthesizeExpression(expression); if (expression == null) { return false; } - if (expression instanceof PsiReferenceExpression) { - if (ignoreReferences) { - return false; - } + if (ignoreReferences && PsiTreeUtil.findChildOfType(expression, PsiReferenceExpression.class, false) != null) { + return false; } else if (expression instanceof PsiPolyadicExpression polyadicExpression) { if (ignoreComplexLiterals) { diff --git a/java/java-tests/testSrc/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspectionTest.java b/java/java-tests/testSrc/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspectionTest.java index b3576c8e3224..800a2a659b3f 100644 --- a/java/java-tests/testSrc/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspectionTest.java +++ b/java/java-tests/testSrc/com/siyeh/ig/numeric/UnpredictableBigDecimalConstructorCallInspectionTest.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2014 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. - */ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.siyeh.ig.numeric; import com.intellij.codeInspection.InspectionProfileEntry; @@ -56,4 +42,27 @@ public class UnpredictableBigDecimalConstructorCallInspectionTest extends LightJ " }" + "}"); } + + public void testReferences() { + doTest(""" + import java.math.BigDecimal; + class X { + void one(double expectedMultiplier) { + final BigDecimal n = new BigDecimal(expectedMultiplier); + final BigDecimal m = new BigDecimal(getVal()); + final BigDecimal o = new /*Unpredictable 'new BigDecimal()' call*/BigDecimal/**/(new Double[] {0.1}[0]); + final BigDecimal p = new /*Unpredictable 'new BigDecimal()' call*/BigDecimal/**/((0.1 + (0.2))); + } + + private static double getVal() { + return 0.1; + } + + protected void two(double... expectedMultipliers) { + for (int i = 0; i < expectedMultipliers.length; i++) { + final BigDecimal n = new BigDecimal(expectedMultipliers[i]); + } + } + }"""); + } } \ No newline at end of file