Merge "Use DRI as the key for the sourceFilesPaths map." into main
diff --git a/gradle.properties b/gradle.properties
index 6fe3c42..0c5dd54 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-org.gradle.jvmargs=-Xmx8g -XX:+HeapDumpOnOutOfMemoryError
+org.gradle.jvmargs=-Xmx16g -XX:+HeapDumpOnOutOfMemoryError
 org.gradle.parallel=true
 org.gradle.caching=true
 org.gradle.configuration-cache=true
diff --git a/src/main/java/com/google/devsite/DevsitePlugin.kt b/src/main/java/com/google/devsite/DevsitePlugin.kt
index 9a4273b..589be48 100644
--- a/src/main/java/com/google/devsite/DevsitePlugin.kt
+++ b/src/main/java/com/google/devsite/DevsitePlugin.kt
@@ -57,6 +57,10 @@
         } override dokkaBase.htmlRenderer
     }
 
+    val docTagsForCheckedExceptions by extending {
+        CoreExtensions.documentableTransformer with DocTagsForCheckedExceptionsTransformer()
+    }
+
     val privateAnnotationFilter by extending {
         dokkaBase.preMergeDocumentableTransformer with PreMergePrivateAnnotationRecorder() order {
             before(dokkaBase.documentableVisibilityFilter)
@@ -72,10 +76,6 @@
     val hiddenPackageFilter by extending {
         CoreExtensions.documentableTransformer with PostMergePackageDocumentableFilter()
     }
-
-    val docTagsForCheckedExceptions by extending {
-        CoreExtensions.documentableTransformer with DocTagsForCheckedExceptionsTransformer()
-    }
 }
 internal fun getDevsiteConfiguration(dokkaContext: DokkaContext): DevsiteConfiguration {
     return checkNotNull(configuration<DevsitePlugin, DevsiteConfiguration>(dokkaContext)) {
diff --git a/src/main/java/com/google/devsite/renderer/converters/DocTagConverter.kt b/src/main/java/com/google/devsite/renderer/converters/DocTagConverter.kt
index 49e5b34..6b1089e 100644
--- a/src/main/java/com/google/devsite/renderer/converters/DocTagConverter.kt
+++ b/src/main/java/com/google/devsite/renderer/converters/DocTagConverter.kt
@@ -572,7 +572,8 @@
                     // TODO(KMP) we currently have no plan to provide KMP samples b/181224204
                     // As such, we currently assume that all samples are in common
                     val sample = docsHolder.sampleAnalysisEnvironment
-                        .resolveSample(docsHolder.commonSourceSet, dri)!!
+                        .resolveSample(docsHolder.commonSourceSet, dri)
+                        ?: throw RuntimeException("Unable to resolve sample $dri")
                     val imports = processImports(sample)
 
                     components.add(
diff --git a/src/test/java/com/google/devsite/integration/AndroidxTest.kt b/src/test/java/com/google/devsite/integration/AndroidxTest.kt
index 9daf256..d56ec8d 100644
--- a/src/test/java/com/google/devsite/integration/AndroidxTest.kt
+++ b/src/test/java/com/google/devsite/integration/AndroidxTest.kt
@@ -41,13 +41,14 @@
     fun `Run dackka against partial androidx tip-of-tree`() {
         val base = getAndroidxPath()
         executionTest(
+            testName = "partialAndroidx",
             paths = listOf(
                 "$base/appcompat/",
                 "$base/fragment/",
                 "$base/leanback/",
                 "$base/media/",
-                "$base/media2/",
             ),
+            sampleLocations = listOf("$base/samples/", "$base/fragment/fragment-compose/samples"),
         )
     }
 
@@ -66,7 +67,7 @@
             "generator", // material-icons-generator
             "appsearch-builtin-types",
         )
-        crawlingExecTest(getAndroidxPath(), excludedPaths)
+        crawlingExecTest("fullAndroidx", getAndroidxPath(), excludedPaths, maxFolders = 200)
     }
 
     @Ignore // Must be run manually
@@ -80,7 +81,7 @@
     fun `Run dackka against many AndroidX prebuilts`() {
         failOnMissingSamples = false // We do not (yet) publish samples source jars; b/149006789
         executePrebuilts(
-            testName = "all",
+            testName = "manyAndroidxPrebuilts",
             // A list of the first few source jars alphabetically, some of their dependencies, and
             // other projects chosen on as-available or as-useful-for-testing bases.
             artifactNames = listOf(
@@ -97,7 +98,7 @@
                 "appsearch",
                 "appsearch-ktx",
                 "appsearch-compiler",
-                "appsearch-builtin-types",
+                // "appsearch-builtin-types", // still broken until the next release
                 "appsearch-debug-view",
                 "appsearch-platform-storage",
                 "appsearch-local-storage",
diff --git a/src/test/java/com/google/devsite/testing/IntegrationTestBase.kt b/src/test/java/com/google/devsite/testing/IntegrationTestBase.kt
index 513cdf9..a98442c 100644
--- a/src/test/java/com/google/devsite/testing/IntegrationTestBase.kt
+++ b/src/test/java/com/google/devsite/testing/IntegrationTestBase.kt
@@ -18,6 +18,7 @@
 
 import com.google.common.truth.Truth.assertWithMessage
 import com.google.devsite.DevsiteConfiguration
+import com.google.devsite.defaultValidNullabilityAnnotations
 import com.google.devsite.renderer.converters.isRunningInDackkasTests
 import org.jetbrains.dokka.DokkaConfiguration
 import org.jetbrains.dokka.DokkaConfigurationImpl
@@ -84,6 +85,7 @@
         versionMetadataFilesnames: List<String>? = null,
         hidingAnnotations: List<String> = listOf("androidx.annotation.RestrictTo"),
         includeHiddenParentSymbols: Boolean = false,
+        validNullabilityAnnotations: List<String> = defaultValidNullabilityAnnotations,
     ): DokkaConfigurationImpl {
         sources.forEach { check(it.isDirectory) { "$it does not exist or is not a directory" } }
         val externalLinks = mapOf(
@@ -148,6 +150,7 @@
                         ),
                         hidingAnnotations = hidingAnnotations,
                         includeHiddenParentSymbols = includeHiddenParentSymbols,
+                        validNullabilityAnnotations = validNullabilityAnnotations,
                     ).toCompactJsonString(),
                 ),
             )
@@ -189,6 +192,7 @@
 
     /** Executes dackka on source from an androidx checkout on the same machine. No validation. */
     fun executionTest(
+        testName: String,
         paths: List<String>,
         sampleLocations: List<String> = emptyList(),
         includeFiles: List<String> = emptyList(),
@@ -202,6 +206,8 @@
             javaDocsPath = "",
             kotlinDocsPath = "kotlin",
             useAndroidxBaseSourceLink = true,
+            validNullabilityAnnotations = defaultValidNullabilityAnnotations +
+                "org.checkerframework.checker.nullness.qual.Nullable",
         )
 
         val writerPlugin = TestOutputWriterPlugin()
@@ -209,7 +215,11 @@
         testFromData(
             configuration,
             pluginOverrides = listOf(writerPlugin),
-        ) { }
+        ) {
+            renderingStage = { _: RootPageNode, _: DokkaContext ->
+                dump(writerPlugin.writer.contents, File("build/docs/$testName").absolutePath)
+            }
+        }
     }
 
     /**
@@ -217,6 +227,7 @@
      * @param maxFolders limits the source files run against, in case of performance issues
      */
     fun crawlingExecTest(
+        testName: String,
         checkoutRoot: String,
         excludedPaths: MutableList<String> = mutableListOf(),
         maxFolders: Int = 999999,
@@ -265,6 +276,8 @@
             javaDocsPath = "",
             kotlinDocsPath = "kotlin",
             useAndroidxBaseSourceLink = true,
+            validNullabilityAnnotations = defaultValidNullabilityAnnotations +
+                "org.checkerframework.checker.nullness.qual.Nullable",
         )
 
         val writerPlugin = TestOutputWriterPlugin()
@@ -272,7 +285,11 @@
         testFromData(
             configuration,
             pluginOverrides = listOf(writerPlugin),
-        ) { }
+        ) {
+            renderingStage = { _: RootPageNode, _: DokkaContext ->
+                dump(writerPlugin.writer.contents, File("build/docs/$testName").absolutePath)
+            }
+        }
     }
 
     /**
@@ -304,7 +321,11 @@
         testFromData(
             configuration,
             pluginOverrides = listOf(writerPlugin),
-        ) { }
+        ) {
+            renderingStage = { _: RootPageNode, _: DokkaContext ->
+                dump(writerPlugin.writer.contents, File("build/docs/$testName").absolutePath)
+            }
+        }
     }
 
     /**