Move SSD file list fallbacks to typed Kotlin

ober

a0700918befab4820ce712391e51dbc2eefbcc6e

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 4250a8e..ab988d9 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -8601,10 +8601,13 @@
        "    @Synchronized"
        "    private fun truthIndexEntries(): List<TruthIndexEntry> {"
        "        truthIndexCache?.let { return it }"
-       "        val entries = groundTruthDir.listFiles { f -> truthJsonFileName(f.name) }"
-       "            ?.sortedBy { it.name }"
-       "            ?.mapNotNull { truthIndexEntry(it) }"
-       "            ?: emptyList()"
+       "        val entries = if (fileListFilesPresent(groundTruthDir)) {"
+       "            checkNotNull(groundTruthDir.listFiles { f -> truthJsonFileName(f.name) })"
+       "                .sortedBy { it.name }"
+       "                .mapNotNull { truthIndexEntry(it) }"
+       "        } else {"
+       "            emptyList()"
+       "        }"
        "        truthIndexCache = entries"
        "        return entries"
        "    }"
@@ -8726,7 +8729,9 @@
        "            if (treeDepthExceeded(depth, 32)) throw IllegalStateException(\"Storage tree too deep\")"
        "            if (fileIsSymbolicLink(file)) throw IllegalStateException(\"Storage symlink rejected\")"
        "            if (fileIsDirectory(file)) {"
-       "                file.listFiles()?.forEach { walk(it, depth + 1) }"
+       "                if (fileListFilesPresent(file)) {"
+       "                    checkNotNull(file.listFiles()).forEach { walk(it, depth + 1) }"
+       "                }"
        "            } else if (fileIsRegular(file)) {"
        "                stats.files += 1"
        "                stats.bytes += fileSizeBytes(file)"
@@ -9147,8 +9152,8 @@
        "    }"
        ""
        "    fun storageSummary(): String {"
-       "        val truthCount = groundTruthDir.listFiles { f -> truthJsonFileName(f.name) }?.size ?: 0"
-       "        val eventCount = eventsDir.listFiles()?.size ?: 0"
+       "        val truthCount = if (fileListFilesPresent(groundTruthDir)) checkNotNull(groundTruthDir.listFiles { f -> truthJsonFileName(f.name) }).size else 0"
+       "        val eventCount = if (fileListFilesPresent(eventsDir)) checkNotNull(eventsDir.listFiles()).size else 0"
        "        return storageSummaryText(truthCount, eventCount)"
        "    }"
        ""
@@ -9163,9 +9168,12 @@
        ""
        "    private fun rebuildLearnedExamples() {"
        "        val examples = learnedExamplesEmpty()"
-       "        val files = groundTruthDir.listFiles { f -> truthJsonFileName(f.name) }"
-       "            ?.sortedWith(compareByDescending<File> { it.lastModified() }.thenBy { it.name })"
-       "            ?: emptyList()"
+       "        val files = if (fileListFilesPresent(groundTruthDir)) {"
+       "            checkNotNull(groundTruthDir.listFiles { f -> truthJsonFileName(f.name) })"
+       "                .sortedWith(compareByDescending<File> { it.lastModified() }.thenBy { it.name })"
+       "        } else {"
+       "            emptyList()"
+       "        }"
        "        fileLoop@ for (file in files) {"
        "            val truth = try {"
        "                jsonObjectFromText(readLocalText(file))"