JavaSourceCompilationStep.kt
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.room.compiler.processing.util.compiler.steps
import androidx.room.compiler.processing.util.Source
import androidx.room.compiler.processing.util.getSystemClasspathFiles
import androidx.room.compiler.processing.util.toDiagnosticMessages
import com.google.testing.compile.Compilation
import com.google.testing.compile.Compiler
import java.io.File
import javax.tools.JavaFileObject
/**
* Compiles java sources. Note that this does not run java annotation processors. They are run in
* the KAPT step for consistency. When a test is run with purely java sources, it uses the google
* compile testing library directly instead of the kotlin compilation pipeline.
*/
internal object JavaSourceCompilationStep : KotlinCompilationStep {
override val name = "javaSourceCompilation"
override fun execute(
workingDir: File,
arguments: CompilationStepArguments
): CompilationStepResult {
val javaSources: Map<JavaFileObject, Source> = arguments.sourceSets
.asSequence()
.flatMap {
it.javaSources
}.associateBy {
it.toJFO()
}
if (javaSources.isEmpty()) {
return CompilationStepResult.skip(arguments)
}
val classpaths = if (arguments.inheritClasspaths) {
arguments.additionalClasspaths + getSystemClasspathFiles()
} else {
arguments.additionalClasspaths
}.filter { it.exists() }
val compiler = Compiler.javac()
.withOptions(arguments.javacArguments + "-Xlint")
.withClasspath(classpaths)
val result = compiler.compile(javaSources.keys)
val generatedClasses = if (result.status() == Compilation.Status.SUCCESS) {
val classpathOut = workingDir.resolve(GEN_CLASS_OUT)
result.generatedFiles().map {
val targetFile = classpathOut.resolve(
it.toUri().path.substringAfter("CLASS_OUTPUT/")
).also { file ->
file.parentFile.mkdirs()
}
it.openInputStream().use { inputStream ->
targetFile.outputStream().use { outputStream ->
inputStream.copyTo(outputStream)
}
}
}
listOf(
classpathOut
)
} else {
emptyList()
}
return CompilationStepResult(
success = result.status() == Compilation.Status.SUCCESS,
generatedSourceRoots = emptyList(),
diagnostics = result.diagnostics().toDiagnosticMessages(javaSources),
nextCompilerArguments = arguments.copy(
// NOTE: ideally, we should remove java sources but we know that there are no next
// steps so we skip unnecessary work
sourceSets = arguments.sourceSets
),
outputClasspath = generatedClasses
)
}
private const val GEN_CLASS_OUT = "classOut"
}