Support Kotlin in Robolectric test

Currently, Robolectric test written in Kotlin may not run, especially
when shards are in used, for example SettingsRoboTests has 10 shards.

This is because Robolectric test currently only recognize java files,
adding kt files to fix.

Rename current uniqueSrcFiles to uniqueJavaFiles, and compiledJavaSrcs
to uniqueSrcFiles. uniqueSrcFiles will contains both Java and Kotlin
files.

Note: android.FirstUniquePaths cannot be used, seems the behavior is
different and cause build error.

Bug: 252355400
Test: cd build/soong && mm
Test: m RunSettingsRoboTests with Kotlin tests
Change-Id: Id530ae4dcabffe01a06f44fe4234ffc67b73a601
diff --git a/java/base.go b/java/base.go
index bcb7226..ab5a7d9 100644
--- a/java/base.go
+++ b/java/base.go
@@ -447,9 +447,11 @@
 	// installed file for hostdex copy
 	hostdexInstallFile android.InstallPath
 
-	// list of .java files and srcjars that was passed to javac
-	compiledJavaSrcs android.Paths
-	compiledSrcJars  android.Paths
+	// list of unique .java and .kt source files
+	uniqueSrcFiles android.Paths
+
+	// list of srcjars that was passed to javac
+	compiledSrcJars android.Paths
 
 	// manifest file to use instead of properties.Manifest
 	overrideManifest android.OptionalPath
@@ -1078,15 +1080,26 @@
 
 	jarName := ctx.ModuleName() + ".jar"
 
-	javaSrcFiles := srcFiles.FilterByExt(".java")
-	var uniqueSrcFiles android.Paths
+	var uniqueJavaFiles android.Paths
 	set := make(map[string]bool)
-	for _, v := range javaSrcFiles {
+	for _, v := range srcFiles.FilterByExt(".java") {
 		if _, found := set[v.String()]; !found {
 			set[v.String()] = true
-			uniqueSrcFiles = append(uniqueSrcFiles, v)
+			uniqueJavaFiles = append(uniqueJavaFiles, v)
 		}
 	}
+	var uniqueKtFiles android.Paths
+	for _, v := range srcFiles.FilterByExt(".kt") {
+		if _, found := set[v.String()]; !found {
+			set[v.String()] = true
+			uniqueKtFiles = append(uniqueKtFiles, v)
+		}
+	}
+
+	var uniqueSrcFiles android.Paths
+	uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...)
+	uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...)
+	j.uniqueSrcFiles = uniqueSrcFiles
 
 	// We don't currently run annotation processors in turbine, which means we can't use turbine
 	// generated header jars when an annotation processor that generates API is enabled.  One
@@ -1094,7 +1107,7 @@
 	//  is used to run all of the annotation processors.
 	disableTurbine := deps.disableTurbine
 
-	// Collect .java files for AIDEGen
+	// Collect .java and .kt files for AIDEGen
 	j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
 
 	var kotlinJars android.Paths
@@ -1132,12 +1145,7 @@
 			flags.kotlincFlags += "$kotlincFlags"
 		}
 
-		var kotlinSrcFiles android.Paths
-		kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
-		kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)
-
-		// Collect .kt files for AIDEGen
-		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...)
+		// Collect common .kt files for AIDEGen
 		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
 
 		flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
@@ -1150,7 +1158,7 @@
 			// Use kapt for annotation processing
 			kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
 			kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
-			kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
+			kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
 			srcJars = append(srcJars, kaptSrcJar)
 			kotlinJars = append(kotlinJars, kaptResJar)
 			// Disable annotation processing in javac, it's already been handled by kapt
@@ -1160,7 +1168,7 @@
 
 		kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
 		kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
-		kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
+		kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
 		if ctx.Failed() {
 			return
 		}
@@ -1185,8 +1193,6 @@
 
 	jars := append(android.Paths(nil), kotlinJars...)
 
-	// Store the list of .java files that was passed to javac
-	j.compiledJavaSrcs = uniqueSrcFiles
 	j.compiledSrcJars = srcJars
 
 	enableSharding := false
@@ -1201,12 +1207,12 @@
 			// with sharding enabled. See: b/77284273.
 		}
 		headerJarFileWithoutDepsOrJarjar, j.headerJarFile =
-			j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinHeaderJars)
+			j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, kotlinHeaderJars)
 		if ctx.Failed() {
 			return
 		}
 	}
-	if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
+	if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 {
 		hasErrorproneableFiles := false
 		for _, ext := range j.sourceExtensions {
 			if ext != ".proto" && ext != ".aidl" {
@@ -1231,7 +1237,7 @@
 			errorproneFlags := enableErrorproneFlags(flags)
 			errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
 
-			transformJavaToClasses(ctx, errorprone, -1, uniqueSrcFiles, srcJars, errorproneFlags, nil,
+			transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneFlags, nil,
 				"errorprone", "errorprone")
 
 			extraJarDeps = append(extraJarDeps, errorprone)
@@ -1243,8 +1249,8 @@
 			}
 			shardSize := int(*(j.properties.Javac_shard_size))
 			var shardSrcs []android.Paths
-			if len(uniqueSrcFiles) > 0 {
-				shardSrcs = android.ShardPaths(uniqueSrcFiles, shardSize)
+			if len(uniqueJavaFiles) > 0 {
+				shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize)
 				for idx, shardSrc := range shardSrcs {
 					classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
 						nil, flags, extraJarDeps)
@@ -1257,7 +1263,7 @@
 				jars = append(jars, classes)
 			}
 		} else {
-			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
+			classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
 			jars = append(jars, classes)
 		}
 		if ctx.Failed() {
diff --git a/java/java_test.go b/java/java_test.go
index 7f0cea7..d2373e3 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -588,8 +588,8 @@
 	sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
 
 	fooLibrary := fooModule.Module().(*Library)
-	assertDeepEquals(t, "foo java sources incorrect",
-		[]string{"a.java"}, fooLibrary.compiledJavaSrcs.Strings())
+	assertDeepEquals(t, "foo unique sources incorrect",
+		[]string{"a.java"}, fooLibrary.uniqueSrcFiles.Strings())
 
 	assertDeepEquals(t, "foo java source jars incorrect",
 		[]string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"},
diff --git a/java/robolectric.go b/java/robolectric.go
index 7f2981f..b6116ec 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -188,9 +188,9 @@
 
 	// TODO: this could all be removed if tradefed was used as the test runner, it will find everything
 	// annotated as a test and run it.
-	for _, src := range r.compiledJavaSrcs {
+	for _, src := range r.uniqueSrcFiles {
 		s := src.Rel()
-		if !strings.HasSuffix(s, "Test.java") {
+		if !strings.HasSuffix(s, "Test.java") && !strings.HasSuffix(s, "Test.kt") {
 			continue
 		} else if strings.HasSuffix(s, "/BaseRobolectricTest.java") {
 			continue