From a29179f53fa5dfad0f40a666084f5c36b01c62f9 Mon Sep 17 00:00:00 2001 From: Jonathan Bluett-Duncan Date: Mon, 17 Feb 2025 18:09:32 +0000 Subject: [PATCH] Add `java.util.Calendar` to `DenyListedApiDetector` (#351) * Improve code coverage of DenyListedApiDetector * Add deny list entries for java.util.Calendar * Improve deny list error messages for java.util.Calendar --- .../denylistedapis/DenyListedApiDetector.kt | 12 ++ .../DenyListedApiDetectorTest.kt | 203 ++++++++++++++++++ 2 files changed, 215 insertions(+) diff --git a/slack-lint-checks/src/main/java/slack/lint/denylistedapis/DenyListedApiDetector.kt b/slack-lint-checks/src/main/java/slack/lint/denylistedapis/DenyListedApiDetector.kt index e8385943..8d63e02c 100644 --- a/slack-lint-checks/src/main/java/slack/lint/denylistedapis/DenyListedApiDetector.kt +++ b/slack-lint-checks/src/main/java/slack/lint/denylistedapis/DenyListedApiDetector.kt @@ -421,6 +421,18 @@ internal class DenyListedApiDetector : Detector(), SourceCodeScanner, XmlScanner errorMessage = "Use java.time.Instant or java.time.ZonedDateTime instead. There is no reason to use java.util.Date in Java 8+.", ), + DenyListedEntry( + className = "java.util.Calendar", + fieldName = MatchAll, + errorMessage = + "Use java.time.Instant or java.time.ZonedDateTime instead. There is no reason to use java.util.Calendar in Java 8+.", + ), + DenyListedEntry( + className = "java.util.Calendar", + functionName = MatchAll, + errorMessage = + "Use java.time.Instant or java.time.ZonedDateTime instead. There is no reason to use java.util.Calendar in Java 8+.", + ), DenyListedEntry( className = "java.text.DateFormat", fieldName = MatchAll, diff --git a/slack-lint-checks/src/test/java/slack/lint/denylistedapis/DenyListedApiDetectorTest.kt b/slack-lint-checks/src/test/java/slack/lint/denylistedapis/DenyListedApiDetectorTest.kt index 559aa7fc..35eef29b 100644 --- a/slack-lint-checks/src/test/java/slack/lint/denylistedapis/DenyListedApiDetectorTest.kt +++ b/slack-lint-checks/src/test/java/slack/lint/denylistedapis/DenyListedApiDetectorTest.kt @@ -423,6 +423,209 @@ class DenyListedApiDetectorTest : BaseSlackLintTest() { ) } + @Test + fun javaUtilDate() { + lint() + .files( + kotlin( + """ + package foo + + import java.util.Date + + class SomeClass { + val now = Date() + } + """ + ) + .indented() + ) + .run() + .expect( + """ + src/foo/SomeClass.kt:6: Error: Use java.time.Instant or java.time.ZonedDateTime instead. There is no reason to use java.util.Date in Java 8+. [DenyListedApi] + val now = Date() + ~~~~ + 1 errors, 0 warnings + """ + .trimIndent() + ) + } + + @Test + fun javaTextDateFormatField() { + lint() + .files( + kotlin( + """ + package foo + + import java.text.DateFormat + + class SomeClass { + val yearField = DateFormat.YEAR_FIELD + } + """ + ) + .indented() + ) + .run() + .expect( + """ + src/foo/SomeClass.kt:6: Error: Use java.time.DateTimeFormatter instead. There is no reason to use java.text.DateFormat in Java 8+. [DenyListedApi] + val yearField = DateFormat.YEAR_FIELD + ~~~~~~~~~~~~~~~~~~~~~ + 1 errors, 0 warnings + """ + .trimIndent() + ) + } + + @Test + fun javaTextDateFormatFunction() { + lint() + .files( + kotlin( + """ + package foo + + import java.text.DateFormat + + class SomeClass { + val dateFormat = DateFormat.getDateInstance() + } + """ + ) + .indented() + ) + .run() + .expect( + """ + src/foo/SomeClass.kt:6: Error: Use java.time.DateTimeFormatter instead. There is no reason to use java.text.DateFormat in Java 8+. [DenyListedApi] + val dateFormat = DateFormat.getDateInstance() + ~~~~~~~~~~~~~~~ + 1 errors, 0 warnings + """ + .trimIndent() + ) + } + + @Test + fun javaTextSimpleDateFormatField() { + lint() + .files( + kotlin( + """ + package foo + + import java.text.SimpleDateFormat + + class SomeClass { + val yearField = SimpleDateFormat.YEAR_FIELD + } + """ + ) + .indented() + ) + .run() + .expect( + """ + src/foo/SomeClass.kt:6: Error: Use java.time.DateTimeFormatter instead. There is no reason to use java.text.DateFormat in Java 8+. [DenyListedApi] + val yearField = SimpleDateFormat.YEAR_FIELD + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 1 errors, 0 warnings + """ + .trimIndent() + ) + } + + @Test + fun javaTextSimpleDateFormatFunction() { + lint() + .files( + kotlin( + """ + package foo + + import java.text.SimpleDateFormat + + class SomeClass { + val dateFormat = SimpleDateFormat.getDateInstance() + } + """ + ) + .indented() + ) + .run() + .expect( + """ + src/foo/SomeClass.kt:6: Error: Use java.time.DateTimeFormatter instead. There is no reason to use java.text.DateFormat in Java 8+. [DenyListedApi] + val dateFormat = SimpleDateFormat.getDateInstance() + ~~~~~~~~~~~~~~~ + 1 errors, 0 warnings + """ + .trimIndent() + ) + } + + @Test + fun javaUtilCalendarField() { + lint() + .files( + kotlin( + """ + package foo + + import java.util.Calendar + + class SomeClass { + val hourOfDay = Calendar.HOUR_OF_DAY + } + """ + ) + .indented() + ) + .run() + .expect( + """ + src/foo/SomeClass.kt:6: Error: Use java.time.Instant or java.time.ZonedDateTime instead. There is no reason to use java.util.Calendar in Java 8+. [DenyListedApi] + val hourOfDay = Calendar.HOUR_OF_DAY + ~~~~~~~~~~~~~~~~~~~~ + 1 errors, 0 warnings + """ + .trimIndent() + ) + } + + @Test + fun javaUtilCalendarFunction() { + lint() + .files( + kotlin( + """ + package foo + + import java.util.Calendar + + class SomeClass { + val calendar = Calendar.getInstance() + } + """ + ) + .indented() + ) + .run() + .expect( + """ + src/foo/SomeClass.kt:6: Error: Use java.time.Instant or java.time.ZonedDateTime instead. There is no reason to use java.util.Calendar in Java 8+. [DenyListedApi] + val calendar = Calendar.getInstance() + ~~~~~~~~~~~ + 1 errors, 0 warnings + """ + .trimIndent() + ) + } + @Test fun rxCompletableParameterless() { lint()