From ab585108daf036effd2e806680b05f8eed0bd132 Mon Sep 17 00:00:00 2001 From: gtoison Date: Tue, 11 Nov 2025 14:04:52 +0100 Subject: [PATCH] Extend SelfComparison to support time types --- .../bugpatterns/SelfComparison.java | 8 +- .../bugpatterns/SelfComparisonTest.java | 99 +++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/SelfComparison.java b/core/src/main/java/com/google/errorprone/bugpatterns/SelfComparison.java index 2a0102911a5..02d3c1be68b 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/SelfComparison.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/SelfComparison.java @@ -18,6 +18,7 @@ import static com.google.errorprone.BugPattern.SeverityLevel.ERROR; import static com.google.errorprone.matchers.Matchers.allOf; +import static com.google.errorprone.matchers.Matchers.anyOf; import static com.google.errorprone.matchers.Matchers.instanceMethod; import static com.google.errorprone.matchers.Matchers.receiverSameAsArgument; @@ -44,7 +45,12 @@ public class SelfComparison extends BugChecker implements MethodInvocationTreeMa */ private static final Matcher COMPARE_TO_MATCHER = allOf( - instanceMethod().onDescendantOf("java.lang.Comparable").named("compareTo"), + anyOf( + instanceMethod().onDescendantOf("java.lang.Comparable").named("compareTo"), + instanceMethod().onDescendantOf("java.util.Date").namedAnyOf("after", "before"), + instanceMethod().onDescendantOf("java.time.Instant").namedAnyOf("isAfter", "isBefore"), + instanceMethod().onDescendantOf("java.time.chrono.ChronoLocalDate").namedAnyOf("isAfter", "isBefore"), + instanceMethod().onDescendantOf("java.time.chrono.ChronoLocalDateTime").namedAnyOf("isAfter", "isBefore")), receiverSameAsArgument(0)); @Override diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/SelfComparisonTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/SelfComparisonTest.java index 5cff2449df4..e77f0c804fd 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/SelfComparisonTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/SelfComparisonTest.java @@ -167,4 +167,103 @@ public int compareTo(CopmarisonTest obj) { """) .doTest(); } + + @Test + public void localDatePositiveCase() { + compilationHelper + .addSourceLines( + "LocalDateSelfComparisonPositiveCase.java", + """ + package com.google.errorprone.bugpatterns.testdata; + + import java.time.LocalDate; + + public class LocalDateSelfComparisonPositiveCase { + + public boolean test1() { + LocalDate date = LocalDate.of(2025, 11, 10); + // BUG: Diagnostic contains: An object is compared to itself + return date.isAfter(date); + } + + private LocalDate date = LocalDate.of(2025, 11, 10); + + public boolean test2() { + // BUG: Diagnostic contains: An object is compared to itself + return date.isAfter(this.date); + } + + public boolean test3() { + // BUG: Diagnostic contains: An object is compared to itself + return this.date.isBefore(date); + } + + public boolean test4() { + // BUG: Diagnostic contains: An object is compared to itself + return this.date.isBefore(this.date); + } + }\ + """) + .doTest(); + } + + @Test + public void timeTypesPositiveCase() { + compilationHelper + .addSourceLines( + "TimeTypesSelfComparisonPositiveCase.java", + """ + package com.google.errorprone.bugpatterns.testdata; + + import java.time.Instant; + import java.time.LocalDate; + import java.time.LocalDateTime; + import java.time.LocalDate; + import java.util.Date; + + public class TimeTypesSelfComparisonPositiveCase { + + public boolean testInstantAfter(Instant x) { + // BUG: Diagnostic contains: An object is compared to itself + return x.isAfter(x); + } + + public boolean testInstantBefore(Instant x) { + // BUG: Diagnostic contains: An object is compared to itself + return x.isBefore(x); + } + + public boolean testLocalDateAfter(LocalDate x) { + // BUG: Diagnostic contains: An object is compared to itself + return x.isAfter(x); + } + + public boolean testLocalDateBefore(LocalDate x) { + // BUG: Diagnostic contains: An object is compared to itself + return x.isBefore(x); + } + + public boolean testLocalDateTimeAfter(LocalDateTime x) { + // BUG: Diagnostic contains: An object is compared to itself + return x.isAfter(x); + } + + public boolean testLocalDateTimeBefore(LocalDateTime x) { + // BUG: Diagnostic contains: An object is compared to itself + return x.isBefore(x); + } + + public boolean testDateAfter(Date x) { + // BUG: Diagnostic contains: An object is compared to itself + return x.after(x); + } + + public boolean testDateBefore(Date x) { + // BUG: Diagnostic contains: An object is compared to itself + return x.before(x); + } + }\ + """) + .doTest(); + } }