From 4aee5efcaa47b828b87cf74a4d6ca458d81c2c98 Mon Sep 17 00:00:00 2001 From: nathsou Date: Tue, 18 Aug 2026 11:45:18 +0200 Subject: [PATCH 1/5] SONARJAVA-6787 Implement new rule S9351: "BigDecimal.compareTo()" should be used instead of "equals()" for numerical comparison --- .../checks/BigDecimalEqualsCheckSample.java | 75 +++++++++++++ .../java/checks/BigDecimalEqualsCheck.java | 100 ++++++++++++++++++ .../checks/BigDecimalEqualsCheckTest.java | 33 ++++++ .../org/sonar/l10n/java/rules/java/S9351.html | 39 +++++++ .../org/sonar/l10n/java/rules/java/S9351.json | 24 +++++ .../main/resources/profiles/Sonar_way/S9351 | 0 6 files changed, 271 insertions(+) create mode 100644 java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java create mode 100644 java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java create mode 100644 java-checks/src/test/java/org/sonar/java/checks/BigDecimalEqualsCheckTest.java create mode 100644 sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.html create mode 100644 sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.json create mode 100644 sonar-java-plugin/src/main/resources/profiles/Sonar_way/S9351 diff --git a/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java b/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java new file mode 100644 index 00000000000..8602eca485d --- /dev/null +++ b/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java @@ -0,0 +1,75 @@ +package checks; + +import java.math.BigDecimal; +import java.util.Objects; + +class BigDecimalEqualsCheckSample { + + void method(BigDecimal a, BigDecimal b, Object o, String s) { + boolean res; + + res = a.equals(b); // Noncompliant [["BigDecimal.equals()" compares scale as well as value; use "compareTo() == 0" for numerical comparison.]] +// ^^^^^^ + res = !a.equals(b); // Noncompliant +// ^^^^^^ + res = a.equals(o); // Noncompliant + res = o.equals(a); // Noncompliant + + res = Objects.equals(a, b); // Noncompliant +// ^^^^^^ + res = Objects.equals(a, o); // Noncompliant + res = Objects.equals(o, a); // Noncompliant + res = com.google.common.base.Objects.equal(a, b); // Noncompliant +// ^^^^^ + res = com.google.common.base.Objects.equal(a, o); // Noncompliant + + // Compliant + res = a.compareTo(b) == 0; + res = a.compareTo(b) != 0; + res = s.equals("hello"); + res = Objects.equals(s, "hello"); + res = com.google.common.base.Objects.equal(s, "hello"); + } + + static class Account { + private BigDecimal balance; + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof Account other)) return false; + return balance != null && balance.equals(other.balance); // Compliant: inside equals method override + } + + @Override + public int hashCode() { + return Objects.hashCode(balance); + } + } + + static class AccountWithStaticEquals { + private BigDecimal balance; + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof AccountWithStaticEquals other)) return false; + return Objects.equals(balance, other.balance); // Compliant: inside equals method override + } + + @Override + public int hashCode() { + return Objects.hashCode(balance); + } + } + + static class MyBigDecimal extends BigDecimal { + public MyBigDecimal(String val) { + super(val); + } + + void testCustom(MyBigDecimal other) { + boolean r = this.equals(other); // Noncompliant + } + } +} diff --git a/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java b/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java new file mode 100644 index 00000000000..9f4d256aa0d --- /dev/null +++ b/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java @@ -0,0 +1,100 @@ +/* + * SonarQube Java + * Copyright (C) SonarSource Sàrl + * mailto:info AT sonarsource DOT com + * + * You can redistribute and/or modify this program under the terms of + * the Sonar Source-Available License Version 1, as published by SonarSource Sàrl. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Sonar Source-Available License for more details. + * + * You should have received a copy of the Sonar Source-Available License + * along with this program; if not, see https://sonarsource.com/license/ssal/ + */ +package org.sonar.java.checks; + +import java.util.Collections; +import java.util.List; +import org.sonar.check.Rule; +import org.sonar.java.checks.helpers.MethodTreeUtils; +import org.sonar.java.model.ExpressionUtils; +import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; +import org.sonar.plugins.java.api.semantic.MethodMatchers; +import org.sonar.plugins.java.api.semantic.Type; +import org.sonar.plugins.java.api.tree.Arguments; +import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; +import org.sonar.plugins.java.api.tree.MethodInvocationTree; +import org.sonar.plugins.java.api.tree.MethodTree; +import org.sonar.plugins.java.api.tree.Tree; + +@Rule(key = "S9351") +public class BigDecimalEqualsCheck extends IssuableSubscriptionVisitor { + + private static final String MESSAGE = "\"BigDecimal.equals()\" compares scale as well as value; use \"compareTo() == 0\" for numerical comparison."; + private static final String BIG_DECIMAL = "java.math.BigDecimal"; + + private static final MethodMatchers INSTANCE_EQUALS = MethodMatchers.create() + .ofAnyType() + .names("equals") + .addParametersMatcher("java.lang.Object") + .build(); + + private static final MethodMatchers STATIC_EQUALS = MethodMatchers.create() + .ofTypes("java.util.Objects", "com.google.common.base.Objects") + .names("equals", "equal") + .addParametersMatcher("java.lang.Object", "java.lang.Object") + .build(); + + @Override + public List nodesToVisit() { + return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); + } + + @Override + public void visitNode(Tree tree) { + MethodInvocationTree mit = (MethodInvocationTree) tree; + if (isInsideEqualsMethod(mit)) { + return; + } + if (INSTANCE_EQUALS.matches(mit)) { + Type ownerType = getMethodOwnerType(mit); + Arguments arguments = mit.arguments(); + Type argumentType = arguments.get(0).symbolType(); + if (isBigDecimal(ownerType) || isBigDecimal(argumentType)) { + reportIssue(ExpressionUtils.methodName(mit), MESSAGE); + } + } else if (STATIC_EQUALS.matches(mit)) { + Arguments arguments = mit.arguments(); + Type firstType = arguments.get(0).symbolType(); + Type secondType = arguments.get(1).symbolType(); + if (isBigDecimal(firstType) || isBigDecimal(secondType)) { + reportIssue(ExpressionUtils.methodName(mit), MESSAGE); + } + } + } + + private static boolean isBigDecimal(Type type) { + return !type.isUnknown() && type.isSubtypeOf(BIG_DECIMAL); + } + + private static Type getMethodOwnerType(MethodInvocationTree mit) { + if (mit.methodSelect().is(Tree.Kind.MEMBER_SELECT)) { + return ((MemberSelectExpressionTree) mit.methodSelect()).expression().symbolType(); + } + return mit.methodSymbol().owner().type(); + } + + private static boolean isInsideEqualsMethod(Tree tree) { + Tree parent = tree.parent(); + while (parent != null && !parent.is(Tree.Kind.CLASS, Tree.Kind.RECORD, Tree.Kind.INTERFACE, Tree.Kind.ENUM)) { + if (parent.is(Tree.Kind.METHOD)) { + return MethodTreeUtils.isEqualsMethod((MethodTree) parent); + } + parent = parent.parent(); + } + return false; + } +} diff --git a/java-checks/src/test/java/org/sonar/java/checks/BigDecimalEqualsCheckTest.java b/java-checks/src/test/java/org/sonar/java/checks/BigDecimalEqualsCheckTest.java new file mode 100644 index 00000000000..4ec921c54a0 --- /dev/null +++ b/java-checks/src/test/java/org/sonar/java/checks/BigDecimalEqualsCheckTest.java @@ -0,0 +1,33 @@ +/* + * SonarQube Java + * Copyright (C) SonarSource Sàrl + * mailto:info AT sonarsource DOT com + * + * You can redistribute and/or modify this program under the terms of + * the Sonar Source-Available License Version 1, as published by SonarSource Sàrl. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Sonar Source-Available License for more details. + * + * You should have received a copy of the Sonar Source-Available License + * along with this program; if not, see https://sonarsource.com/license/ssal/ + */ +package org.sonar.java.checks; + +import org.junit.jupiter.api.Test; +import org.sonar.java.checks.verifier.CheckVerifier; + +import static org.sonar.java.checks.verifier.TestUtils.mainCodeSourcesPath; + +class BigDecimalEqualsCheckTest { + + @Test + void test() { + CheckVerifier.newVerifier() + .onFile(mainCodeSourcesPath("checks/BigDecimalEqualsCheckSample.java")) + .withCheck(new BigDecimalEqualsCheck()) + .verifyIssues(); + } +} diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.html new file mode 100644 index 00000000000..7862d8f2d69 --- /dev/null +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.html @@ -0,0 +1,39 @@ +

BigDecimal.equals(Object) compares both the numerical value and the scale of the BigDecimal objects.

+

Why is this an issue?

+

In Java, BigDecimal.equals(Object) returns true only if two BigDecimal objects have the same numerical value +and the same scale (number of digits to the right of the decimal point). Consequently, new BigDecimal("2.0").equals(new +BigDecimal("2.00")) evaluates to false even though both instances represent the same numerical value.

+

In financial, commerce, and scientific applications, comparisons usually intend to verify numerical equivalence regardless of representation +differences. Using equals() or Objects.equals() can introduce subtle bugs when values are formatted, serialized, or computed +with different scale factors. To compare BigDecimal values for numerical equality, use compareTo(other) == 0 instead.

+

Code examples

+

Noncompliant code example

+
+BigDecimal priceA = new BigDecimal("10.0");
+BigDecimal priceB = new BigDecimal("10.00");
+
+if (priceA.equals(priceB)) { // Noncompliant: "BigDecimal.equals()" compares scale as well as value; use "compareTo() == 0" for numerical comparison
+  applyDiscount();
+}
+
+

Compliant solution

+
+BigDecimal priceA = new BigDecimal("10.0");
+BigDecimal priceB = new BigDecimal("10.00");
+
+if (priceA.compareTo(priceB) == 0) {
+  applyDiscount();
+}
+
+

Exceptions

+

This rule ignores BigDecimal.equals() calls inside equals(Object) method declarations. Classes implementing +equals(Object) and hashCode() often require scale-sensitive comparison to satisfy the hashCode contract.

+

Resources

+

Documentation

+ + diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.json new file mode 100644 index 00000000000..d3a7c01dfa6 --- /dev/null +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.json @@ -0,0 +1,24 @@ +{ + "title": "\"BigDecimal.compareTo()\" should be used instead of \"equals()\" for numerical comparison", + "type": "BUG", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "unpredictable", + "bad-practice" + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-9351", + "sqKey": "S9351", + "scope": "Main", + "quickfix": "targeted", + "code": { + "impacts": { + "RELIABILITY": "HIGH" + }, + "attribute": "LOGICAL" + } +} diff --git a/sonar-java-plugin/src/main/resources/profiles/Sonar_way/S9351 b/sonar-java-plugin/src/main/resources/profiles/Sonar_way/S9351 new file mode 100644 index 00000000000..e69de29bb2d From 1fe33ca43d7924bd59d3c776a5220b23a607faf3 Mon Sep 17 00:00:00 2001 From: nathsou Date: Tue, 18 Aug 2026 11:57:43 +0200 Subject: [PATCH 2/5] SONARJAVA-6787 Update S9351 HTML documentation for NOSONAR exception rationale --- .../main/resources/org/sonar/l10n/java/rules/java/S9351.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.html index 7862d8f2d69..00efb7cc1a5 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.html +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.html @@ -28,6 +28,9 @@

Compliant solution

Exceptions

This rule ignores BigDecimal.equals() calls inside equals(Object) method declarations. Classes implementing equals(Object) and hashCode() often require scale-sensitive comparison to satisfy the hashCode contract.

+

If scale-sensitive equality is intentionally desired in other contexts, suppress the issue with an inline // NOSONAR comment and +provide a short rationale explaining why scale sensitivity is necessary (e.g., // NOSONAR: scale-sensitive comparison is +intentional).

Resources

Documentation

    From 106f248d05b803f5975d5b7061c2a2b5e1f022a2 Mon Sep 17 00:00:00 2001 From: nathsou Date: Tue, 18 Aug 2026 14:24:29 +0200 Subject: [PATCH 3/5] SONARJAVA-6787 Extract JAVA_LANG_OBJECT constant to fix java:S1192 code smell --- .../java/org/sonar/java/checks/BigDecimalEqualsCheck.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java b/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java index 9f4d256aa0d..18cfc74cc8a 100644 --- a/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java +++ b/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java @@ -35,17 +35,18 @@ public class BigDecimalEqualsCheck extends IssuableSubscriptionVisitor { private static final String MESSAGE = "\"BigDecimal.equals()\" compares scale as well as value; use \"compareTo() == 0\" for numerical comparison."; private static final String BIG_DECIMAL = "java.math.BigDecimal"; + private static final String JAVA_LANG_OBJECT = "java.lang.Object"; private static final MethodMatchers INSTANCE_EQUALS = MethodMatchers.create() .ofAnyType() .names("equals") - .addParametersMatcher("java.lang.Object") + .addParametersMatcher(JAVA_LANG_OBJECT) .build(); private static final MethodMatchers STATIC_EQUALS = MethodMatchers.create() .ofTypes("java.util.Objects", "com.google.common.base.Objects") .names("equals", "equal") - .addParametersMatcher("java.lang.Object", "java.lang.Object") + .addParametersMatcher(JAVA_LANG_OBJECT, JAVA_LANG_OBJECT) .build(); @Override From c520554bf97f749b4a07baadfd8edf3a333ca2f8 Mon Sep 17 00:00:00 2001 From: nathsou Date: Tue, 18 Aug 2026 14:31:56 +0200 Subject: [PATCH 4/5] SONARJAVA-6787 Restrict instance equals matcher to BigDecimal subtypes and mark quickfix infeasible --- .../checks/BigDecimalEqualsCheckSample.java | 3 ++- .../java/checks/BigDecimalEqualsCheck.java | 17 ++--------------- .../org/sonar/l10n/java/rules/java/S9351.json | 2 +- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java b/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java index 8602eca485d..83c9fb10b19 100644 --- a/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java +++ b/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java @@ -13,7 +13,6 @@ void method(BigDecimal a, BigDecimal b, Object o, String s) { res = !a.equals(b); // Noncompliant // ^^^^^^ res = a.equals(o); // Noncompliant - res = o.equals(a); // Noncompliant res = Objects.equals(a, b); // Noncompliant // ^^^^^^ @@ -26,6 +25,8 @@ void method(BigDecimal a, BigDecimal b, Object o, String s) { // Compliant res = a.compareTo(b) == 0; res = a.compareTo(b) != 0; + res = o.equals(a); + res = s.equals(a); res = s.equals("hello"); res = Objects.equals(s, "hello"); res = com.google.common.base.Objects.equal(s, "hello"); diff --git a/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java b/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java index 18cfc74cc8a..5845603d28a 100644 --- a/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java +++ b/java-checks/src/main/java/org/sonar/java/checks/BigDecimalEqualsCheck.java @@ -25,7 +25,6 @@ import org.sonar.plugins.java.api.semantic.MethodMatchers; import org.sonar.plugins.java.api.semantic.Type; import org.sonar.plugins.java.api.tree.Arguments; -import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; import org.sonar.plugins.java.api.tree.MethodInvocationTree; import org.sonar.plugins.java.api.tree.MethodTree; import org.sonar.plugins.java.api.tree.Tree; @@ -38,7 +37,7 @@ public class BigDecimalEqualsCheck extends IssuableSubscriptionVisitor { private static final String JAVA_LANG_OBJECT = "java.lang.Object"; private static final MethodMatchers INSTANCE_EQUALS = MethodMatchers.create() - .ofAnyType() + .ofSubTypes(BIG_DECIMAL) .names("equals") .addParametersMatcher(JAVA_LANG_OBJECT) .build(); @@ -61,12 +60,7 @@ public void visitNode(Tree tree) { return; } if (INSTANCE_EQUALS.matches(mit)) { - Type ownerType = getMethodOwnerType(mit); - Arguments arguments = mit.arguments(); - Type argumentType = arguments.get(0).symbolType(); - if (isBigDecimal(ownerType) || isBigDecimal(argumentType)) { - reportIssue(ExpressionUtils.methodName(mit), MESSAGE); - } + reportIssue(ExpressionUtils.methodName(mit), MESSAGE); } else if (STATIC_EQUALS.matches(mit)) { Arguments arguments = mit.arguments(); Type firstType = arguments.get(0).symbolType(); @@ -81,13 +75,6 @@ private static boolean isBigDecimal(Type type) { return !type.isUnknown() && type.isSubtypeOf(BIG_DECIMAL); } - private static Type getMethodOwnerType(MethodInvocationTree mit) { - if (mit.methodSelect().is(Tree.Kind.MEMBER_SELECT)) { - return ((MemberSelectExpressionTree) mit.methodSelect()).expression().symbolType(); - } - return mit.methodSymbol().owner().type(); - } - private static boolean isInsideEqualsMethod(Tree tree) { Tree parent = tree.parent(); while (parent != null && !parent.is(Tree.Kind.CLASS, Tree.Kind.RECORD, Tree.Kind.INTERFACE, Tree.Kind.ENUM)) { diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.json index d3a7c01dfa6..7d40226e1d8 100644 --- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.json +++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9351.json @@ -14,7 +14,7 @@ "ruleSpecification": "RSPEC-9351", "sqKey": "S9351", "scope": "Main", - "quickfix": "targeted", + "quickfix": "infeasible", "code": { "impacts": { "RELIABILITY": "HIGH" From e5cbc3468c9833313ce39f90f1ae701f09771e70 Mon Sep 17 00:00:00 2001 From: nathsou Date: Tue, 18 Aug 2026 16:50:55 +0200 Subject: [PATCH 5/5] SONARJAVA-6787 Add withoutSemantic tests for BigDecimalEqualsCheck --- .../BigDecimalEqualsCheckGuavaSample.java | 34 +++++++++++++++++++ .../checks/BigDecimalEqualsCheckSample.java | 4 --- .../checks/BigDecimalEqualsCheckTest.java | 26 ++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckGuavaSample.java diff --git a/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckGuavaSample.java b/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckGuavaSample.java new file mode 100644 index 00000000000..2246839b5d9 --- /dev/null +++ b/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckGuavaSample.java @@ -0,0 +1,34 @@ +package checks; + +import java.math.BigDecimal; + +class BigDecimalEqualsCheckGuavaSample { + + void method(BigDecimal a, BigDecimal b, Object o, String s) { + boolean res; + + res = com.google.common.base.Objects.equal(a, b); // Noncompliant [["BigDecimal.equals()" compares scale as well as value; use "compareTo() == 0" for numerical comparison.]] +// ^^^^^ + res = com.google.common.base.Objects.equal(a, o); // Noncompliant + res = com.google.common.base.Objects.equal(o, a); // Noncompliant + + // Compliant + res = com.google.common.base.Objects.equal(s, "hello"); + } + + static class AccountWithGuavaEquals { + private BigDecimal balance; + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof AccountWithGuavaEquals other)) return false; + return com.google.common.base.Objects.equal(balance, other.balance); // Compliant: inside equals method override + } + + @Override + public int hashCode() { + return com.google.common.base.Objects.hashCode(balance); + } + } +} diff --git a/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java b/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java index 83c9fb10b19..7d66cb41507 100644 --- a/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java +++ b/java-checks-test-sources/default/src/main/java/checks/BigDecimalEqualsCheckSample.java @@ -18,9 +18,6 @@ void method(BigDecimal a, BigDecimal b, Object o, String s) { // ^^^^^^ res = Objects.equals(a, o); // Noncompliant res = Objects.equals(o, a); // Noncompliant - res = com.google.common.base.Objects.equal(a, b); // Noncompliant -// ^^^^^ - res = com.google.common.base.Objects.equal(a, o); // Noncompliant // Compliant res = a.compareTo(b) == 0; @@ -29,7 +26,6 @@ void method(BigDecimal a, BigDecimal b, Object o, String s) { res = s.equals(a); res = s.equals("hello"); res = Objects.equals(s, "hello"); - res = com.google.common.base.Objects.equal(s, "hello"); } static class Account { diff --git a/java-checks/src/test/java/org/sonar/java/checks/BigDecimalEqualsCheckTest.java b/java-checks/src/test/java/org/sonar/java/checks/BigDecimalEqualsCheckTest.java index 4ec921c54a0..8ac02419b2c 100644 --- a/java-checks/src/test/java/org/sonar/java/checks/BigDecimalEqualsCheckTest.java +++ b/java-checks/src/test/java/org/sonar/java/checks/BigDecimalEqualsCheckTest.java @@ -30,4 +30,30 @@ void test() { .withCheck(new BigDecimalEqualsCheck()) .verifyIssues(); } + + @Test + void test_without_semantic() { + CheckVerifier.newVerifier() + .onFile(mainCodeSourcesPath("checks/BigDecimalEqualsCheckSample.java")) + .withCheck(new BigDecimalEqualsCheck()) + .withoutSemantic() + .verifyIssues(); + } + + @Test + void test_guava() { + CheckVerifier.newVerifier() + .onFile(mainCodeSourcesPath("checks/BigDecimalEqualsCheckGuavaSample.java")) + .withCheck(new BigDecimalEqualsCheck()) + .verifyIssues(); + } + + @Test + void test_guava_without_semantic() { + CheckVerifier.newVerifier() + .onFile(mainCodeSourcesPath("checks/BigDecimalEqualsCheckGuavaSample.java")) + .withCheck(new BigDecimalEqualsCheck()) + .withoutSemantic() + .verifyNoIssues(); + } }