Add Thread.stop(Throwable) and java.sql.Time APIs to the DoNotCallChecker. #badtime ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=316152032
diff --git a/check_api/src/main/java/com/google/errorprone/util/RuntimeVersion.java b/check_api/src/main/java/com/google/errorprone/util/RuntimeVersion.java index 372deeb..cf7e0af 100644 --- a/check_api/src/main/java/com/google/errorprone/util/RuntimeVersion.java +++ b/check_api/src/main/java/com/google/errorprone/util/RuntimeVersion.java
@@ -55,6 +55,11 @@ return MAJOR >= 10; } + /** Returns true if the current runtime is JDK 10 or earlier. */ + public static boolean isAtMost10() { + return MAJOR <= 10; + } + /** Returns true if the current runtime is JDK 11 or newer. */ public static boolean isAtLeast11() { return MAJOR >= 11;
diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/DoNotCallChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/DoNotCallChecker.java index 2721cdd..7ee693c 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/DoNotCallChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/DoNotCallChecker.java
@@ -73,6 +73,12 @@ + "String, expected, actual, delta) to compare floating-point numbers") .put( instanceMethod() + .onExactClass("java.lang.Thread") + .named("stop") + .withParameters("java.lang.Throwable"), + "Thread.stop(Throwable) always throws an UnsupportedOperationException") + .put( + instanceMethod() .onExactClass("java.sql.Date") .namedAnyOf( "getHours", @@ -89,6 +95,17 @@ "sqlDate.toInstant() is not supported. Did you mean to call toLocalDate() instead?") .put( instanceMethod() + .onExactClass("java.sql.Time") + .namedAnyOf( + "getYear", "getMonth", "getDay", "getDate", "setYear", "setMonth", "setDate"), + "The year/month/day getters and setters on java.sql.Time are guaranteed to throw" + + " IllegalArgumentException because java.sql.Time does not have a date" + + " component.") + .put( + instanceMethod().onExactClass("java.sql.Time").named("toInstant"), + "sqlTime.toInstant() is not supported. Did you mean to call toLocalTime() instead?") + .put( + instanceMethod() .onExactClass("java.util.concurrent.ThreadLocalRandom") .named("setSeed"), "ThreadLocalRandom does not support setting a seed.")
diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/DoNotCallCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/DoNotCallCheckerTest.java index 24a3c6c..8203e8c 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/DoNotCallCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/DoNotCallCheckerTest.java
@@ -17,10 +17,13 @@ package com.google.errorprone.bugpatterns; import static org.junit.Assert.assertThrows; +import static org.junit.Assume.assumeTrue; import com.google.errorprone.CompilationTestHelper; import com.google.errorprone.annotations.DoNotCall; +import com.google.errorprone.util.RuntimeVersion; import java.sql.Date; +import java.sql.Time; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.junit.Test; @@ -208,8 +211,7 @@ @Test public void javaSqlDate_toInstant() { - Date date = new Date(1234567890L); - assertThrows(UnsupportedOperationException.class, () -> date.toInstant()); + assertThrows(UnsupportedOperationException.class, () -> new Date(1234567890L).toInstant()); testHelper .addSourceLines( "TestClass.java", @@ -234,7 +236,6 @@ .addSourceLines( "TestClass.java", "import java.sql.Date;", - "import java.time.Instant;", "public class TestClass {", " public void badApis(Date date) {", " // BUG: Diagnostic contains: DoNotCall", @@ -258,7 +259,6 @@ .addSourceLines( "TestClass.java", "import java.sql.Date;", - "import java.time.Instant;", "public class TestClass {", " public void badApis(Date date) {", " // BUG: Diagnostic contains: DoNotCall", @@ -295,6 +295,95 @@ } @Test + public void javaSqlTime_toInstant() { + assertThrows(UnsupportedOperationException.class, () -> new Time(1234567890L).toInstant()); + testHelper + .addSourceLines( + "TestClass.java", + "import java.sql.Time;", + "import java.time.Instant;", + "public class TestClass {", + " public void badApis(Time time) {", + " // BUG: Diagnostic contains: toLocalTime()", + " Instant instant = time.toInstant();", + " }", + "}") + .doTest(); + } + + @Test + public void javaSqlTime_dateGetters() { + Time time = new Time(1234567890L); + assertThrows(IllegalArgumentException.class, () -> time.getYear()); + assertThrows(IllegalArgumentException.class, () -> time.getMonth()); + assertThrows(IllegalArgumentException.class, () -> time.getDay()); + assertThrows(IllegalArgumentException.class, () -> time.getDate()); + testHelper + .addSourceLines( + "TestClass.java", + "import java.sql.Time;", + "public class TestClass {", + " public void badApis(Time time) {", + " // BUG: Diagnostic contains: DoNotCall", + " int year = time.getYear();", + " // BUG: Diagnostic contains: DoNotCall", + " int month = time.getMonth();", + " // BUG: Diagnostic contains: DoNotCall", + " int day = time.getDay();", + " // BUG: Diagnostic contains: DoNotCall", + " int date = time.getDate();", + " }", + "}") + .doTest(); + } + + @Test + public void javaSqlTime_dateSetters() { + Time time = new Time(1234567890L); + assertThrows(IllegalArgumentException.class, () -> time.setYear(1)); + assertThrows(IllegalArgumentException.class, () -> time.setMonth(1)); + assertThrows(IllegalArgumentException.class, () -> time.setDate(1)); + testHelper + .addSourceLines( + "TestClass.java", + "import java.sql.Time;", + "public class TestClass {", + " public void badApis(Time time) {", + " // BUG: Diagnostic contains: DoNotCall", + " time.setYear(1);", + " // BUG: Diagnostic contains: DoNotCall", + " time.setMonth(1);", + " // BUG: Diagnostic contains: DoNotCall", + " time.setDate(1);", + " }", + "}") + .doTest(); + } + + @Test + public void javaSqlTime_staticallyTypedAsJavaUtilDate() { + testHelper + .addSourceLines( + "TestClass.java", + "import java.time.Instant;", + "import java.util.Date;", + "public class TestClass {", + " public void badApis() {", + " Date time = new java.sql.Time(1234567890L);", + " Instant instant = time.toInstant();", + " int year = time.getYear();", + " int month = time.getMonth();", + " int date = time.getDate();", + " int day = time.getDay();", + " time.setYear(1);", + " time.setMonth(1);", + " time.setDate(1);", + " }", + "}") + .doTest(); + } + + @Test public void readLock_newCondition() { assertThrows( UnsupportedOperationException.class, @@ -330,4 +419,21 @@ "}") .doTest(); } + + @Test + public void thread_stop() { + // Thread.stop(Throwable) was removed in JDK11: + // https://bugs.openjdk.java.net/browse/JDK-8204243 + assumeTrue(RuntimeVersion.isAtMost10()); + testHelper + .addSourceLines( + "Test.java", + "public class Test {", + " public void foo() {", + " // BUG: Diagnostic contains: DoNotCall", + " Thread.currentThread().stop(new Throwable());", + " }", + "}") + .doTest(); + } }