Reformat kotlin-gradle-plugin according to code style

This commit is contained in:
Alexey Tsvetkov
2018-10-17 15:52:50 +03:00
parent 47b8e54f84
commit a44d70e79d
64 changed files with 696 additions and 573 deletions
@@ -194,7 +194,9 @@ private fun Printer.generateImpl(
generatePropertyDeclaration(property, modifiers = "override") generatePropertyDeclaration(property, modifiers = "override")
withIndent { withIndent {
println("get() = $backingField ?: ${property.gradleDefaultValue}") println("get() = $backingField ?: ${property.gradleDefaultValue}")
println("set(value) { $backingField = value }") println("set(value) {")
withIndent { println("$backingField = value") }
println("}")
} }
} }
@@ -13,9 +13,13 @@ import java.rmi.RemoteException
import java.rmi.server.UnicastRemoteObject import java.rmi.server.UnicastRemoteObject
internal class GradleCompilationResults( internal class GradleCompilationResults(
project: Project project: Project
): CompilationResults, ) : CompilationResults,
UnicastRemoteObject(SOCKET_ANY_FREE_PORT, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) { UnicastRemoteObject(
SOCKET_ANY_FREE_PORT,
LoopbackNetworkInterface.clientLoopbackSocketFactory,
LoopbackNetworkInterface.serverLoopbackSocketFactory
) {
private val log = project.logger private val log = project.logger
private val projectRootFile = project.rootProject.projectDir private val projectRootFile = project.rootProject.projectDir
@@ -15,28 +15,28 @@ import java.io.File
import java.net.URL import java.net.URL
internal open class GradleCompilerEnvironment( internal open class GradleCompilerEnvironment(
val compilerClasspath: List<File>, val compilerClasspath: List<File>,
messageCollector: GradleMessageCollector, messageCollector: GradleMessageCollector,
outputItemsCollector: OutputItemsCollector, outputItemsCollector: OutputItemsCollector,
val compilerArgs: CommonCompilerArguments val compilerArgs: CommonCompilerArguments
) : CompilerEnvironment(Services.EMPTY, messageCollector, outputItemsCollector) { ) : CompilerEnvironment(Services.EMPTY, messageCollector, outputItemsCollector) {
val toolsJar: File? by lazy { findToolsJar() } val toolsJar: File? by lazy { findToolsJar() }
val compilerFullClasspath: List<File> val compilerFullClasspath: List<File>
get() = (compilerClasspath + toolsJar).filterNotNull() get() = (compilerClasspath + toolsJar).filterNotNull()
val compilerClasspathURLs: List<URL> val compilerClasspathURLs: List<URL>
get() = compilerFullClasspath.map { it.toURI().toURL() } get() = compilerFullClasspath.map { it.toURI().toURL() }
} }
internal class GradleIncrementalCompilerEnvironment( internal class GradleIncrementalCompilerEnvironment(
compilerClasspath: List<File>, compilerClasspath: List<File>,
val changedFiles: ChangedFiles, val changedFiles: ChangedFiles,
val workingDir: File, val workingDir: File,
messageCollector: GradleMessageCollector, messageCollector: GradleMessageCollector,
outputItemsCollector: OutputItemsCollector, outputItemsCollector: OutputItemsCollector,
compilerArgs: CommonCompilerArguments, compilerArgs: CommonCompilerArguments,
val usePreciseJavaTracking: Boolean = false, val usePreciseJavaTracking: Boolean = false,
val localStateDirs: List<File> = emptyList(), val localStateDirs: List<File> = emptyList(),
val multiModuleICSettings: MultiModuleICSettings val multiModuleICSettings: MultiModuleICSettings
) : GradleCompilerEnvironment(compilerClasspath, messageCollector, outputItemsCollector, compilerArgs) ) : GradleCompilerEnvironment(compilerClasspath, messageCollector, outputItemsCollector, compilerArgs)
@@ -16,9 +16,9 @@ import java.rmi.Remote
import java.rmi.server.UnicastRemoteObject import java.rmi.server.UnicastRemoteObject
internal open class GradleCompilerServicesFacadeImpl( internal open class GradleCompilerServicesFacadeImpl(
project: Project, project: Project,
val compilerMessageCollector: MessageCollector, val compilerMessageCollector: MessageCollector,
port: Int = SOCKET_ANY_FREE_PORT port: Int = SOCKET_ANY_FREE_PORT
) : UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory), ) : UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory),
CompilerServicesFacadeBase, CompilerServicesFacadeBase,
Remote { Remote {
@@ -35,19 +35,20 @@ internal open class GradleCompilerServicesFacadeImpl(
} }
else -> { else -> {
compilerMessageCollector.reportFromDaemon( compilerMessageCollector.reportFromDaemon(
outputsCollector = null, outputsCollector = null,
category = category, category = category,
severity = severity, severity = severity,
message = message, message = message,
attachment = attachment) attachment = attachment
)
} }
} }
} }
} }
internal class GradleIncrementalCompilerServicesFacadeImpl( internal class GradleIncrementalCompilerServicesFacadeImpl(
project: Project, project: Project,
environment: GradleIncrementalCompilerEnvironment, environment: GradleIncrementalCompilerEnvironment,
port: Int = SOCKET_ANY_FREE_PORT port: Int = SOCKET_ANY_FREE_PORT
) : GradleCompilerServicesFacadeImpl(project, environment.messageCollector, port), ) : GradleCompilerServicesFacadeImpl(project, environment.messageCollector, port),
IncrementalCompilerServicesFacade IncrementalCompilerServicesFacade
@@ -90,12 +90,12 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
} }
fun runJvmCompiler( fun runJvmCompiler(
sourcesToCompile: List<File>, sourcesToCompile: List<File>,
commonSources: List<File>, commonSources: List<File>,
javaSourceRoots: Iterable<File>, javaSourceRoots: Iterable<File>,
javaPackagePrefix: String?, javaPackagePrefix: String?,
args: K2JVMCompilerArguments, args: K2JVMCompilerArguments,
environment: GradleCompilerEnvironment environment: GradleCompilerEnvironment
): ExitCode { ): ExitCode {
val buildFile = makeModuleFile( val buildFile = makeModuleFile(
args.moduleName!!, args.moduleName!!,
@@ -123,10 +123,10 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
} }
fun runJsCompiler( fun runJsCompiler(
kotlinSources: List<File>, kotlinSources: List<File>,
kotlinCommonSources: List<File>, kotlinCommonSources: List<File>,
args: K2JSCompilerArguments, args: K2JSCompilerArguments,
environment: GradleCompilerEnvironment environment: GradleCompilerEnvironment
): ExitCode { ): ExitCode {
args.freeArgs += kotlinSources.map { it.absolutePath } args.freeArgs += kotlinSources.map { it.absolutePath }
args.commonSources = kotlinCommonSources.map { it.absolutePath }.toTypedArray() args.commonSources = kotlinCommonSources.map { it.absolutePath }.toTypedArray()
@@ -134,26 +134,28 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
} }
fun runMetadataCompiler( fun runMetadataCompiler(
kotlinSources: List<File>, kotlinSources: List<File>,
args: K2MetadataCompilerArguments, args: K2MetadataCompilerArguments,
environment: GradleCompilerEnvironment environment: GradleCompilerEnvironment
): ExitCode { ): ExitCode {
args.freeArgs += kotlinSources.map { it.absolutePath } args.freeArgs += kotlinSources.map { it.absolutePath }
return runCompiler(K2METADATA_COMPILER, args, environment) return runCompiler(K2METADATA_COMPILER, args, environment)
} }
override fun compileWithDaemonOrFallback( override fun compileWithDaemonOrFallback(
compilerClassName: String, compilerClassName: String,
compilerArgs: CommonCompilerArguments, compilerArgs: CommonCompilerArguments,
environment: GradleCompilerEnvironment environment: GradleCompilerEnvironment
): ExitCode { ): ExitCode {
if (compilerArgs.version) { if (compilerArgs.version) {
project.logger.lifecycle("Kotlin version " + loadCompilerVersion(environment.compilerClasspath) + project.logger.lifecycle(
" (JRE " + System.getProperty("java.runtime.version") + ")") "Kotlin version " + loadCompilerVersion(environment.compilerClasspath) +
" (JRE " + System.getProperty("java.runtime.version") + ")"
)
compilerArgs.version = false compilerArgs.version = false
} }
val argsArray = ArgumentUtils.convertArgumentsToStringList(compilerArgs).toTypedArray() val argsArray = ArgumentUtils.convertArgumentsToStringList(compilerArgs).toTypedArray()
with (project.logger) { with(project.logger) {
kotlinDebug { "Kotlin compiler class: $compilerClassName" } kotlinDebug { "Kotlin compiler class: $compilerClassName" }
kotlinDebug { "Kotlin compiler classpath: ${environment.compilerFullClasspath.map { it.canonicalPath }.joinToString()}" } kotlinDebug { "Kotlin compiler classpath: ${environment.compilerFullClasspath.map { it.canonicalPath }.joinToString()}" }
kotlinDebug { "Kotlin compiler args: ${argsArray.joinToString(" ")}" } kotlinDebug { "Kotlin compiler args: ${argsArray.joinToString(" ")}" }
@@ -165,8 +167,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
if (daemonExitCode != null) { if (daemonExitCode != null) {
return daemonExitCode return daemonExitCode
} } else {
else {
log.warn("Could not connect to kotlin daemon. Using fallback strategy.") log.warn("Could not connect to kotlin daemon. Using fallback strategy.")
} }
} }
@@ -174,8 +175,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val isGradleDaemonUsed = System.getProperty("org.gradle.daemon")?.let(String::toBoolean) val isGradleDaemonUsed = System.getProperty("org.gradle.daemon")?.let(String::toBoolean)
return if (executionStrategy == IN_PROCESS_EXECUTION_STRATEGY || isGradleDaemonUsed == false) { return if (executionStrategy == IN_PROCESS_EXECUTION_STRATEGY || isGradleDaemonUsed == false) {
compileInProcess(argsArray, compilerClassName, environment) compileInProcess(argsArray, compilerClassName, environment)
} } else {
else {
compileOutOfProcess(argsArray, compilerClassName, environment) compileOutOfProcess(argsArray, compilerClassName, environment)
} }
} }
@@ -183,21 +183,23 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
private val kotlinCompilerExecutionStrategy: String private val kotlinCompilerExecutionStrategy: String
get() = System.getProperty(KOTLIN_COMPILER_EXECUTION_STRATEGY_PROPERTY) ?: DAEMON_EXECUTION_STRATEGY get() = System.getProperty(KOTLIN_COMPILER_EXECUTION_STRATEGY_PROPERTY) ?: DAEMON_EXECUTION_STRATEGY
override fun compileWithDaemon(compilerClassName: String, compilerArgs: CommonCompilerArguments, environment: GradleCompilerEnvironment): ExitCode? { override fun compileWithDaemon(
compilerClassName: String,
compilerArgs: CommonCompilerArguments,
environment: GradleCompilerEnvironment
): ExitCode? {
val connection = val connection =
try { try {
getDaemonConnection(environment) getDaemonConnection(environment)
} } catch (e: Throwable) {
catch (e: Throwable) { log.warn("Caught an exception trying to connect to Kotlin Daemon")
log.warn("Caught an exception trying to connect to Kotlin Daemon") e.printStackTrace()
e.printStackTrace() null
null }
}
if (connection == null) { if (connection == null) {
if (environment is GradleIncrementalCompilerEnvironment) { if (environment is GradleIncrementalCompilerEnvironment) {
log.warn("Could not perform incremental compilation: $COULD_NOT_CONNECT_TO_DAEMON_MESSAGE") log.warn("Could not perform incremental compilation: $COULD_NOT_CONNECT_TO_DAEMON_MESSAGE")
} } else {
else {
log.warn(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE) log.warn(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE)
} }
return null return null
@@ -217,8 +219,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
nonIncrementalCompilationWithDaemon(daemon, sessionId, targetPlatform, environment) nonIncrementalCompilationWithDaemon(daemon, sessionId, targetPlatform, environment)
} }
exitCodeFromProcessExitCode(res.get()) exitCodeFromProcessExitCode(res.get())
} } catch (e: Throwable) {
catch (e: Throwable) {
log.warn("Compilation with Kotlin compile daemon was not successful") log.warn("Compilation with Kotlin compile daemon was not successful")
e.printStackTrace() e.printStackTrace()
null null
@@ -228,8 +229,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
// TODO: implement a proper logic to avoid remote calls in such cases // TODO: implement a proper logic to avoid remote calls in such cases
try { try {
daemon.clearJarCache() daemon.clearJarCache()
} } catch (e: RemoteException) {
catch (e: RemoteException) {
log.warn("Unable to clear jar cache after compilation, maybe daemon is already down: $e") log.warn("Unable to clear jar cache after compilation, maybe daemon is already down: $e")
} }
logFinish(DAEMON_EXECUTION_STRATEGY) logFinish(DAEMON_EXECUTION_STRATEGY)
@@ -237,28 +237,29 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
} }
private fun nonIncrementalCompilationWithDaemon( private fun nonIncrementalCompilationWithDaemon(
daemon: CompileService, daemon: CompileService,
sessionId: Int, sessionId: Int,
targetPlatform: CompileService.TargetPlatform, targetPlatform: CompileService.TargetPlatform,
environment: GradleCompilerEnvironment environment: GradleCompilerEnvironment
): CompileService.CallResult<Int> { ): CompileService.CallResult<Int> {
val verbose = environment.compilerArgs.verbose val verbose = environment.compilerArgs.verbose
val compilationOptions = CompilationOptions( val compilationOptions = CompilationOptions(
compilerMode = CompilerMode.NON_INCREMENTAL_COMPILER, compilerMode = CompilerMode.NON_INCREMENTAL_COMPILER,
targetPlatform = targetPlatform, targetPlatform = targetPlatform,
reportCategories = reportCategories(verbose), reportCategories = reportCategories(verbose),
reportSeverity = reportSeverity(verbose), reportSeverity = reportSeverity(verbose),
requestedCompilationResults = emptyArray()) requestedCompilationResults = emptyArray()
)
val servicesFacade = GradleCompilerServicesFacadeImpl(project, environment.messageCollector) val servicesFacade = GradleCompilerServicesFacadeImpl(project, environment.messageCollector)
val argsArray = ArgumentUtils.convertArgumentsToStringList(environment.compilerArgs).toTypedArray() val argsArray = ArgumentUtils.convertArgumentsToStringList(environment.compilerArgs).toTypedArray()
return daemon.compile(sessionId, argsArray, compilationOptions, servicesFacade, compilationResults = null) return daemon.compile(sessionId, argsArray, compilationOptions, servicesFacade, compilationResults = null)
} }
private fun incrementalCompilationWithDaemon( private fun incrementalCompilationWithDaemon(
daemon: CompileService, daemon: CompileService,
sessionId: Int, sessionId: Int,
targetPlatform: CompileService.TargetPlatform, targetPlatform: CompileService.TargetPlatform,
environment: GradleIncrementalCompilerEnvironment environment: GradleIncrementalCompilerEnvironment
): CompileService.CallResult<Int> { ): CompileService.CallResult<Int> {
val knownChangedFiles = environment.changedFiles as? ChangedFiles.Known val knownChangedFiles = environment.changedFiles as? ChangedFiles.Known
@@ -286,33 +287,31 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
} }
private fun reportCategories(verbose: Boolean): Array<Int> = private fun reportCategories(verbose: Boolean): Array<Int> =
if (!verbose) { if (!verbose) {
arrayOf(ReportCategory.COMPILER_MESSAGE.code) arrayOf(ReportCategory.COMPILER_MESSAGE.code)
} } else {
else { ReportCategory.values().map { it.code }.toTypedArray()
ReportCategory.values().map { it.code }.toTypedArray() }
}
private fun reportSeverity(verbose: Boolean): Int = private fun reportSeverity(verbose: Boolean): Int =
if (!verbose) { if (!verbose) {
ReportSeverity.INFO.code ReportSeverity.INFO.code
} } else {
else { ReportSeverity.DEBUG.code
ReportSeverity.DEBUG.code }
}
private fun compileOutOfProcess( private fun compileOutOfProcess(
argsArray: Array<String>, argsArray: Array<String>,
compilerClassName: String, compilerClassName: String,
environment: GradleCompilerEnvironment environment: GradleCompilerEnvironment
): ExitCode { ): ExitCode {
return runToolInSeparateProcess(argsArray, compilerClassName, environment.compilerFullClasspath, log, loggingMessageCollector) return runToolInSeparateProcess(argsArray, compilerClassName, environment.compilerFullClasspath, log, loggingMessageCollector)
} }
private fun compileInProcess( private fun compileInProcess(
argsArray: Array<String>, argsArray: Array<String>,
compilerClassName: String, compilerClassName: String,
environment: GradleCompilerEnvironment environment: GradleCompilerEnvironment
): ExitCode { ): ExitCode {
val stream = ByteArrayOutputStream() val stream = ByteArrayOutputStream()
val out = PrintStream(stream) val out = PrintStream(stream)
@@ -323,10 +322,10 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val compiler = Class.forName(compilerClassName, true, classLoader) val compiler = Class.forName(compilerClassName, true, classLoader)
val exec = compiler.getMethod( val exec = compiler.getMethod(
"execAndOutputXml", "execAndOutputXml",
PrintStream::class.java, PrintStream::class.java,
servicesClass, servicesClass,
Array<String>::class.java Array<String>::class.java
) )
val res = exec.invoke(compiler.newInstance(), out, emptyServices, argsArray) val res = exec.invoke(compiler.newInstance(), out, emptyServices, argsArray)
@@ -417,10 +416,9 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val log = project.logger val log = project.logger
if (clientIsAliveFlagFile == null || !clientIsAliveFlagFile!!.exists()) { if (clientIsAliveFlagFile == null || !clientIsAliveFlagFile!!.exists()) {
val projectName = project.rootProject.name.normalizeForFlagFile() val projectName = project.rootProject.name.normalizeForFlagFile()
clientIsAliveFlagFile = newTmpFile(prefix = "kotlin-compiler-in-$projectName-", suffix = ".alive") clientIsAliveFlagFile = newTmpFile(prefix = "kotlin-compiler-in-$projectName-", suffix = ".alive")
log.kotlinDebug { CREATED_CLIENT_FILE_PREFIX + clientIsAliveFlagFile!!.canonicalPath } log.kotlinDebug { CREATED_CLIENT_FILE_PREFIX + clientIsAliveFlagFile!!.canonicalPath }
} } else {
else {
log.kotlinDebug { EXISTING_CLIENT_FILE_PREFIX + clientIsAliveFlagFile!!.canonicalPath } log.kotlinDebug { EXISTING_CLIENT_FILE_PREFIX + clientIsAliveFlagFile!!.canonicalPath }
} }
@@ -444,8 +442,7 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val sessionFilesDir = sessionsDir(project).apply { mkdirs() } val sessionFilesDir = sessionsDir(project).apply { mkdirs() }
sessionFlagFile = newTmpFile(prefix = "kotlin-compiler-", suffix = ".salive", directory = sessionFilesDir) sessionFlagFile = newTmpFile(prefix = "kotlin-compiler-", suffix = ".salive", directory = sessionFilesDir)
log.kotlinDebug { CREATED_SESSION_FILE_PREFIX + sessionFlagFile!!.relativeToRoot(project) } log.kotlinDebug { CREATED_SESSION_FILE_PREFIX + sessionFlagFile!!.relativeToRoot(project) }
} } else {
else {
log.kotlinDebug { EXISTING_SESSION_FILE_PREFIX + sessionFlagFile!!.relativeToRoot(project) } log.kotlinDebug { EXISTING_SESSION_FILE_PREFIX + sessionFlagFile!!.relativeToRoot(project) }
} }
@@ -453,6 +450,6 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
} }
internal fun sessionsDir(project: Project): File = internal fun sessionsDir(project: Project): File =
File(File(project.rootProject.buildDir, "kotlin"), "sessions") File(File(project.rootProject.buildDir, "kotlin"), "sessions")
} }
} }
@@ -28,9 +28,9 @@ import org.jetbrains.kotlin.konan.util.DependencyDirectories
/** Copied from Kotlin/Native repository. */ /** Copied from Kotlin/Native repository. */
internal enum class KotlinNativeProjectProperty(val propertyName: String) { internal enum class KotlinNativeProjectProperty(val propertyName: String) {
KONAN_HOME_OVERRIDE ("org.jetbrains.kotlin.native.home"), KONAN_HOME_OVERRIDE("org.jetbrains.kotlin.native.home"),
KONAN_JVM_ARGS ("org.jetbrains.kotlin.native.jvmArgs"), KONAN_JVM_ARGS("org.jetbrains.kotlin.native.jvmArgs"),
KONAN_VERSION ("org.jetbrains.kotlin.native.version"), KONAN_VERSION("org.jetbrains.kotlin.native.version"),
KONAN_USE_ENVIRONMENT_VARIABLES("org.jetbrains.kotlin.native.useEnvironmentVariables") KONAN_USE_ENVIRONMENT_VARIABLES("org.jetbrains.kotlin.native.useEnvironmentVariables")
} }
@@ -56,7 +56,7 @@ internal val Project.konanVersion: KonanVersion
KonanVersion.fromString(it.toString()) KonanVersion.fromString(it.toString())
} ?: NativeCompilerDownloader.DEFAULT_KONAN_VERSION } ?: NativeCompilerDownloader.DEFAULT_KONAN_VERSION
internal interface KonanToolRunner: Named { internal interface KonanToolRunner : Named {
val mainClass: String val mainClass: String
val classpath: FileCollection val classpath: FileCollection
val jvmArgs: List<String> val jvmArgs: List<String>
@@ -72,7 +72,7 @@ internal abstract class KonanCliRunner(
val fullName: String, val fullName: String,
val project: Project, val project: Project,
private val additionalJvmArgs: List<String> private val additionalJvmArgs: List<String>
): KonanToolRunner { ) : KonanToolRunner {
override val mainClass = "org.jetbrains.kotlin.cli.utilities.MainKt" override val mainClass = "org.jetbrains.kotlin.cli.utilities.MainKt"
override fun getName() = toolName override fun getName() = toolName
@@ -89,7 +89,7 @@ internal abstract class KonanCliRunner(
override val classpath: FileCollection = override val classpath: FileCollection =
project.fileTree("${project.konanHome}/konan/lib/") project.fileTree("${project.konanHome}/konan/lib/")
.apply { include("*.jar") } .apply { include("*.jar") }
override val jvmArgs = mutableListOf("-ea").apply { override val jvmArgs = mutableListOf("-ea").apply {
if (additionalJvmArgs.none { it.startsWith("-Xmx") } && if (additionalJvmArgs.none { it.startsWith("-Xmx") } &&
@@ -121,9 +121,11 @@ internal abstract class KonanCliRunner(
override fun run(args: List<String>) { override fun run(args: List<String>) {
project.logger.info("Run tool: $toolName with args: ${args.joinToString(separator = " ")}") project.logger.info("Run tool: $toolName with args: ${args.joinToString(separator = " ")}")
if (classpath.isEmpty) { if (classpath.isEmpty) {
throw IllegalStateException("Classpath of the tool is empty: $toolName\n" + throw IllegalStateException(
"Probably the '${KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE}' project property contains an incorrect path.\n" + "Classpath of the tool is empty: $toolName\n" +
"Please change it to the compiler root directory and rerun the build.") "Probably the '${KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE}' project property contains an incorrect path.\n" +
"Please change it to the compiler root directory and rerun the build."
)
} }
project.javaexec { spec -> project.javaexec { spec ->
@@ -145,15 +147,16 @@ internal abstract class KonanCliRunner(
} }
} }
internal class KonanInteropRunner(project: Project, additionalJvmArgs: List<String> = emptyList()) internal class KonanInteropRunner(project: Project, additionalJvmArgs: List<String> = emptyList()) :
: KonanCliRunner("cinterop", "Kotlin/Native cinterop tool", project, additionalJvmArgs) KonanCliRunner("cinterop", "Kotlin/Native cinterop tool", project, additionalJvmArgs) {
{
init { init {
if (HostManager.host == KonanTarget.MINGW_X64) { if (HostManager.host == KonanTarget.MINGW_X64) {
//TODO: Oh-ho-ho fix it in more convinient way. //TODO: Oh-ho-ho fix it in more convinient way.
environment.put("PATH", DependencyDirectories.defaultDependenciesRoot.absolutePath + environment.put(
"\\msys2-mingw-w64-x86_64-gcc-7.3.0-clang-llvm-lld-6.0.1" + "PATH", DependencyDirectories.defaultDependenciesRoot.absolutePath +
"\\bin;${environment.get("PATH")}") "\\msys2-mingw-w64-x86_64-gcc-7.3.0-clang-llvm-lld-6.0.1" +
"\\bin;${environment.get("PATH")}"
)
} }
} }
} }
@@ -162,8 +165,7 @@ internal class KonanCompilerRunner(
project: Project, project: Project,
additionalJvmArgs: List<String> = emptyList(), additionalJvmArgs: List<String> = emptyList(),
val useArgFile: Boolean = true val useArgFile: Boolean = true
) : KonanCliRunner("konanc", "Kotlin/Native compiler", project, additionalJvmArgs) ) : KonanCliRunner("konanc", "Kotlin/Native compiler", project, additionalJvmArgs) {
{
override fun transformArgs(args: List<String>): List<String> { override fun transformArgs(args: List<String>): List<String> {
if (!useArgFile) { if (!useArgFile) {
return args return args
@@ -182,5 +184,5 @@ internal class KonanCompilerRunner(
} }
} }
internal class KonanKlibRunner(project: Project, additionalJvmArgs: List<String> = emptyList()) internal class KonanKlibRunner(project: Project, additionalJvmArgs: List<String> = emptyList()) :
: KonanCliRunner("klib", "Klib management tool", project, additionalJvmArgs) KonanCliRunner("klib", "Klib management tool", project, additionalJvmArgs)
@@ -54,26 +54,25 @@ internal fun loadCompilerVersion(compilerClasspath: List<File>): String {
val bytes = jar.getInputStream(jar.getEntry(versionClassFileName)).use { it.readBytes() } val bytes = jar.getInputStream(jar.getEntry(versionClassFileName)).use { it.readBytes() }
checkVersion(bytes) checkVersion(bytes)
} }
} } else if (cpFile.isDirectory) {
else if (cpFile.isDirectory) {
File(cpFile, versionClassFileName).takeIf { it.isFile }?.let { File(cpFile, versionClassFileName).takeIf { it.isFile }?.let {
checkVersion(it.readBytes()) checkVersion(it.readBytes())
} }
} }
if (result != null) break if (result != null) break
} }
} catch (e: Throwable) {
} }
catch (e: Throwable) {}
return result ?: "<unknown>" return result ?: "<unknown>"
} }
internal fun runToolInSeparateProcess( internal fun runToolInSeparateProcess(
argsArray: Array<String>, compilerClassName: String, classpath: List<File>, argsArray: Array<String>, compilerClassName: String, classpath: List<File>,
logger: KotlinLogger, messageCollector: MessageCollector logger: KotlinLogger, messageCollector: MessageCollector
): ExitCode { ): ExitCode {
val javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java" val javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"
val classpathString = classpath.map {it.absolutePath}.joinToString(separator = File.pathSeparator) val classpathString = classpath.map { it.absolutePath }.joinToString(separator = File.pathSeparator)
val builder = ProcessBuilder(javaBin, "-cp", classpathString, compilerClassName, *argsArray) val builder = ProcessBuilder(javaBin, "-cp", classpathString, compilerClassName, *argsArray)
val process = launchProcessWithFallback(builder, DaemonReportingTargets(messageCollector = messageCollector)) val process = launchProcessWithFallback(builder, DaemonReportingTargets(messageCollector = messageCollector))
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.gradle.dsl
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Internal
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
interface KotlinCompile<T : KotlinCommonOptions> : Task { interface KotlinCompile<T : KotlinCommonOptions> : Task {
@get:Internal @get:Internal
@@ -7,27 +7,37 @@ internal abstract class KotlinJsDceOptionsBase : org.jetbrains.kotlin.gradle.dsl
private var allWarningsAsErrorsField: kotlin.Boolean? = null private var allWarningsAsErrorsField: kotlin.Boolean? = null
override var allWarningsAsErrors: kotlin.Boolean override var allWarningsAsErrors: kotlin.Boolean
get() = allWarningsAsErrorsField ?: false get() = allWarningsAsErrorsField ?: false
set(value) { allWarningsAsErrorsField = value } set(value) {
allWarningsAsErrorsField = value
}
private var suppressWarningsField: kotlin.Boolean? = null private var suppressWarningsField: kotlin.Boolean? = null
override var suppressWarnings: kotlin.Boolean override var suppressWarnings: kotlin.Boolean
get() = suppressWarningsField ?: false get() = suppressWarningsField ?: false
set(value) { suppressWarningsField = value } set(value) {
suppressWarningsField = value
}
private var verboseField: kotlin.Boolean? = null private var verboseField: kotlin.Boolean? = null
override var verbose: kotlin.Boolean override var verbose: kotlin.Boolean
get() = verboseField ?: false get() = verboseField ?: false
set(value) { verboseField = value } set(value) {
verboseField = value
}
private var devModeField: kotlin.Boolean? = null private var devModeField: kotlin.Boolean? = null
override var devMode: kotlin.Boolean override var devMode: kotlin.Boolean
get() = devModeField ?: false get() = devModeField ?: false
set(value) { devModeField = value } set(value) {
devModeField = value
}
private var outputDirectoryField: kotlin.String?? = null private var outputDirectoryField: kotlin.String?? = null
override var outputDirectory: kotlin.String? override var outputDirectory: kotlin.String?
get() = outputDirectoryField ?: null get() = outputDirectoryField ?: null
set(value) { outputDirectoryField = value } set(value) {
outputDirectoryField = value
}
internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JSDceArguments) { internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JSDceArguments) {
allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it } allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it }
@@ -7,82 +7,114 @@ internal abstract class KotlinJsOptionsBase : org.jetbrains.kotlin.gradle.dsl.Ko
private var allWarningsAsErrorsField: kotlin.Boolean? = null private var allWarningsAsErrorsField: kotlin.Boolean? = null
override var allWarningsAsErrors: kotlin.Boolean override var allWarningsAsErrors: kotlin.Boolean
get() = allWarningsAsErrorsField ?: false get() = allWarningsAsErrorsField ?: false
set(value) { allWarningsAsErrorsField = value } set(value) {
allWarningsAsErrorsField = value
}
private var suppressWarningsField: kotlin.Boolean? = null private var suppressWarningsField: kotlin.Boolean? = null
override var suppressWarnings: kotlin.Boolean override var suppressWarnings: kotlin.Boolean
get() = suppressWarningsField ?: false get() = suppressWarningsField ?: false
set(value) { suppressWarningsField = value } set(value) {
suppressWarningsField = value
}
private var verboseField: kotlin.Boolean? = null private var verboseField: kotlin.Boolean? = null
override var verbose: kotlin.Boolean override var verbose: kotlin.Boolean
get() = verboseField ?: false get() = verboseField ?: false
set(value) { verboseField = value } set(value) {
verboseField = value
}
private var apiVersionField: kotlin.String?? = null private var apiVersionField: kotlin.String?? = null
override var apiVersion: kotlin.String? override var apiVersion: kotlin.String?
get() = apiVersionField ?: null get() = apiVersionField ?: null
set(value) { apiVersionField = value } set(value) {
apiVersionField = value
}
private var languageVersionField: kotlin.String?? = null private var languageVersionField: kotlin.String?? = null
override var languageVersion: kotlin.String? override var languageVersion: kotlin.String?
get() = languageVersionField ?: null get() = languageVersionField ?: null
set(value) { languageVersionField = value } set(value) {
languageVersionField = value
}
private var friendModulesDisabledField: kotlin.Boolean? = null private var friendModulesDisabledField: kotlin.Boolean? = null
override var friendModulesDisabled: kotlin.Boolean override var friendModulesDisabled: kotlin.Boolean
get() = friendModulesDisabledField ?: false get() = friendModulesDisabledField ?: false
set(value) { friendModulesDisabledField = value } set(value) {
friendModulesDisabledField = value
}
private var mainField: kotlin.String? = null private var mainField: kotlin.String? = null
override var main: kotlin.String override var main: kotlin.String
get() = mainField ?: "call" get() = mainField ?: "call"
set(value) { mainField = value } set(value) {
mainField = value
}
private var metaInfoField: kotlin.Boolean? = null private var metaInfoField: kotlin.Boolean? = null
override var metaInfo: kotlin.Boolean override var metaInfo: kotlin.Boolean
get() = metaInfoField ?: true get() = metaInfoField ?: true
set(value) { metaInfoField = value } set(value) {
metaInfoField = value
}
private var moduleKindField: kotlin.String? = null private var moduleKindField: kotlin.String? = null
override var moduleKind: kotlin.String override var moduleKind: kotlin.String
get() = moduleKindField ?: "plain" get() = moduleKindField ?: "plain"
set(value) { moduleKindField = value } set(value) {
moduleKindField = value
}
private var noStdlibField: kotlin.Boolean? = null private var noStdlibField: kotlin.Boolean? = null
override var noStdlib: kotlin.Boolean override var noStdlib: kotlin.Boolean
get() = noStdlibField ?: true get() = noStdlibField ?: true
set(value) { noStdlibField = value } set(value) {
noStdlibField = value
}
private var outputFileField: kotlin.String?? = null private var outputFileField: kotlin.String?? = null
override var outputFile: kotlin.String? override var outputFile: kotlin.String?
get() = outputFileField ?: null get() = outputFileField ?: null
set(value) { outputFileField = value } set(value) {
outputFileField = value
}
private var sourceMapField: kotlin.Boolean? = null private var sourceMapField: kotlin.Boolean? = null
override var sourceMap: kotlin.Boolean override var sourceMap: kotlin.Boolean
get() = sourceMapField ?: false get() = sourceMapField ?: false
set(value) { sourceMapField = value } set(value) {
sourceMapField = value
}
private var sourceMapEmbedSourcesField: kotlin.String?? = null private var sourceMapEmbedSourcesField: kotlin.String?? = null
override var sourceMapEmbedSources: kotlin.String? override var sourceMapEmbedSources: kotlin.String?
get() = sourceMapEmbedSourcesField ?: null get() = sourceMapEmbedSourcesField ?: null
set(value) { sourceMapEmbedSourcesField = value } set(value) {
sourceMapEmbedSourcesField = value
}
private var sourceMapPrefixField: kotlin.String?? = null private var sourceMapPrefixField: kotlin.String?? = null
override var sourceMapPrefix: kotlin.String? override var sourceMapPrefix: kotlin.String?
get() = sourceMapPrefixField ?: null get() = sourceMapPrefixField ?: null
set(value) { sourceMapPrefixField = value } set(value) {
sourceMapPrefixField = value
}
private var targetField: kotlin.String? = null private var targetField: kotlin.String? = null
override var target: kotlin.String override var target: kotlin.String
get() = targetField ?: "v5" get() = targetField ?: "v5"
set(value) { targetField = value } set(value) {
targetField = value
}
private var typedArraysField: kotlin.Boolean? = null private var typedArraysField: kotlin.Boolean? = null
override var typedArrays: kotlin.Boolean override var typedArrays: kotlin.Boolean
get() = typedArraysField ?: true get() = typedArraysField ?: true
set(value) { typedArraysField = value } set(value) {
typedArraysField = value
}
internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments) { internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments) {
allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it } allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it }
@@ -7,62 +7,86 @@ internal abstract class KotlinJvmOptionsBase : org.jetbrains.kotlin.gradle.dsl.K
private var allWarningsAsErrorsField: kotlin.Boolean? = null private var allWarningsAsErrorsField: kotlin.Boolean? = null
override var allWarningsAsErrors: kotlin.Boolean override var allWarningsAsErrors: kotlin.Boolean
get() = allWarningsAsErrorsField ?: false get() = allWarningsAsErrorsField ?: false
set(value) { allWarningsAsErrorsField = value } set(value) {
allWarningsAsErrorsField = value
}
private var suppressWarningsField: kotlin.Boolean? = null private var suppressWarningsField: kotlin.Boolean? = null
override var suppressWarnings: kotlin.Boolean override var suppressWarnings: kotlin.Boolean
get() = suppressWarningsField ?: false get() = suppressWarningsField ?: false
set(value) { suppressWarningsField = value } set(value) {
suppressWarningsField = value
}
private var verboseField: kotlin.Boolean? = null private var verboseField: kotlin.Boolean? = null
override var verbose: kotlin.Boolean override var verbose: kotlin.Boolean
get() = verboseField ?: false get() = verboseField ?: false
set(value) { verboseField = value } set(value) {
verboseField = value
}
private var apiVersionField: kotlin.String?? = null private var apiVersionField: kotlin.String?? = null
override var apiVersion: kotlin.String? override var apiVersion: kotlin.String?
get() = apiVersionField ?: null get() = apiVersionField ?: null
set(value) { apiVersionField = value } set(value) {
apiVersionField = value
}
private var languageVersionField: kotlin.String?? = null private var languageVersionField: kotlin.String?? = null
override var languageVersion: kotlin.String? override var languageVersion: kotlin.String?
get() = languageVersionField ?: null get() = languageVersionField ?: null
set(value) { languageVersionField = value } set(value) {
languageVersionField = value
}
private var includeRuntimeField: kotlin.Boolean? = null private var includeRuntimeField: kotlin.Boolean? = null
override var includeRuntime: kotlin.Boolean override var includeRuntime: kotlin.Boolean
get() = includeRuntimeField ?: false get() = includeRuntimeField ?: false
set(value) { includeRuntimeField = value } set(value) {
includeRuntimeField = value
}
private var javaParametersField: kotlin.Boolean? = null private var javaParametersField: kotlin.Boolean? = null
override var javaParameters: kotlin.Boolean override var javaParameters: kotlin.Boolean
get() = javaParametersField ?: false get() = javaParametersField ?: false
set(value) { javaParametersField = value } set(value) {
javaParametersField = value
}
private var jdkHomeField: kotlin.String?? = null private var jdkHomeField: kotlin.String?? = null
override var jdkHome: kotlin.String? override var jdkHome: kotlin.String?
get() = jdkHomeField ?: null get() = jdkHomeField ?: null
set(value) { jdkHomeField = value } set(value) {
jdkHomeField = value
}
private var jvmTargetField: kotlin.String? = null private var jvmTargetField: kotlin.String? = null
override var jvmTarget: kotlin.String override var jvmTarget: kotlin.String
get() = jvmTargetField ?: "1.6" get() = jvmTargetField ?: "1.6"
set(value) { jvmTargetField = value } set(value) {
jvmTargetField = value
}
private var noJdkField: kotlin.Boolean? = null private var noJdkField: kotlin.Boolean? = null
override var noJdk: kotlin.Boolean override var noJdk: kotlin.Boolean
get() = noJdkField ?: false get() = noJdkField ?: false
set(value) { noJdkField = value } set(value) {
noJdkField = value
}
private var noReflectField: kotlin.Boolean? = null private var noReflectField: kotlin.Boolean? = null
override var noReflect: kotlin.Boolean override var noReflect: kotlin.Boolean
get() = noReflectField ?: true get() = noReflectField ?: true
set(value) { noReflectField = value } set(value) {
noReflectField = value
}
private var noStdlibField: kotlin.Boolean? = null private var noStdlibField: kotlin.Boolean? = null
override var noStdlib: kotlin.Boolean override var noStdlib: kotlin.Boolean
get() = noStdlibField ?: true get() = noStdlibField ?: true
set(value) { noStdlibField = value } set(value) {
noStdlibField = value
}
internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments) { internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments) {
allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it } allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it }
@@ -7,27 +7,37 @@ internal abstract class KotlinMultiplatformCommonOptionsBase : org.jetbrains.kot
private var allWarningsAsErrorsField: kotlin.Boolean? = null private var allWarningsAsErrorsField: kotlin.Boolean? = null
override var allWarningsAsErrors: kotlin.Boolean override var allWarningsAsErrors: kotlin.Boolean
get() = allWarningsAsErrorsField ?: false get() = allWarningsAsErrorsField ?: false
set(value) { allWarningsAsErrorsField = value } set(value) {
allWarningsAsErrorsField = value
}
private var suppressWarningsField: kotlin.Boolean? = null private var suppressWarningsField: kotlin.Boolean? = null
override var suppressWarnings: kotlin.Boolean override var suppressWarnings: kotlin.Boolean
get() = suppressWarningsField ?: false get() = suppressWarningsField ?: false
set(value) { suppressWarningsField = value } set(value) {
suppressWarningsField = value
}
private var verboseField: kotlin.Boolean? = null private var verboseField: kotlin.Boolean? = null
override var verbose: kotlin.Boolean override var verbose: kotlin.Boolean
get() = verboseField ?: false get() = verboseField ?: false
set(value) { verboseField = value } set(value) {
verboseField = value
}
private var apiVersionField: kotlin.String?? = null private var apiVersionField: kotlin.String?? = null
override var apiVersion: kotlin.String? override var apiVersion: kotlin.String?
get() = apiVersionField ?: null get() = apiVersionField ?: null
set(value) { apiVersionField = value } set(value) {
apiVersionField = value
}
private var languageVersionField: kotlin.String?? = null private var languageVersionField: kotlin.String?? = null
override var languageVersion: kotlin.String? override var languageVersion: kotlin.String?
get() = languageVersionField ?: null get() = languageVersionField ?: null
set(value) { languageVersionField = value } set(value) {
languageVersionField = value
}
internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments) { internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments) {
allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it } allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it }
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.gradle.dsl package org.jetbrains.kotlin.gradle.dsl
import org.gradle.api.InvalidUserCodeException
import org.gradle.api.NamedDomainObjectCollection import org.gradle.api.NamedDomainObjectCollection
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset
@@ -41,7 +41,9 @@ open class KotlinProjectExtension {
var sourceSets: NamedDomainObjectContainer<out KotlinSourceSet> var sourceSets: NamedDomainObjectContainer<out KotlinSourceSet>
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer<out KotlinSourceSet> get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer<out KotlinSourceSet>
internal set(value) { DslObject(this).extensions.add("sourceSets", value) } internal set(value) {
DslObject(this).extensions.add("sourceSets", value)
}
} }
open class KotlinSingleJavaTargetExtension : KotlinProjectExtension() { open class KotlinSingleJavaTargetExtension : KotlinProjectExtension() {
@@ -33,7 +33,7 @@ enum class AndroidExtensionsFeature(val featureName: String) {
internal companion object { internal companion object {
internal fun parseFeatures(features: Set<String>): SortedSet<AndroidExtensionsFeature> { internal fun parseFeatures(features: Set<String>): SortedSet<AndroidExtensionsFeature> {
fun find(name: String) = AndroidExtensionsFeature.values().firstOrNull { it.featureName == name } fun find(name: String) = AndroidExtensionsFeature.values().firstOrNull { it.featureName == name }
?: error("Can't find Android Extensions feature $name") ?: error("Can't find Android Extensions feature $name")
return features.mapTo(sortedSetOf()) { find(it) } return features.mapTo(sortedSetOf()) { find(it) }
} }
} }
@@ -38,7 +38,8 @@ import javax.inject.Inject
import javax.xml.parsers.DocumentBuilderFactory import javax.xml.parsers.DocumentBuilderFactory
// Use apply plugin: 'kotlin-android-extensions' to enable Android Extensions in an Android project. // Use apply plugin: 'kotlin-android-extensions' to enable Android Extensions in an Android project.
class AndroidExtensionsSubpluginIndicator @Inject internal constructor(private val registry: ToolingModelBuilderRegistry) : Plugin<Project> { class AndroidExtensionsSubpluginIndicator @Inject internal constructor(private val registry: ToolingModelBuilderRegistry) :
Plugin<Project> {
override fun apply(project: Project) { override fun apply(project: Project) {
val extension = project.extensions.create("androidExtensions", AndroidExtensionsExtension::class.java) val extension = project.extensions.create("androidExtensions", AndroidExtensionsExtension::class.java)
@@ -69,8 +70,11 @@ class AndroidExtensionsSubpluginIndicator @Inject internal constructor(private v
if (name != requiredConfigurationName) return@all if (name != requiredConfigurationName) return@all
configuration.dependencies.add(project.dependencies.create( configuration.dependencies.add(
"org.jetbrains.kotlin:kotlin-android-extensions-runtime:$kotlinPluginVersion")) project.dependencies.create(
"org.jetbrains.kotlin:kotlin-android-extensions-runtime:$kotlinPluginVersion"
)
)
} }
} }
} }
@@ -107,8 +111,10 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
val androidExtensionsExtension = project.extensions.getByType(AndroidExtensionsExtension::class.java) val androidExtensionsExtension = project.extensions.getByType(AndroidExtensionsExtension::class.java)
if (androidExtensionsExtension.isExperimental) { if (androidExtensionsExtension.isExperimental) {
return applyExperimental(kotlinCompile, androidExtension, androidExtensionsExtension, return applyExperimental(
project, variantData, androidProjectHandler) kotlinCompile, androidExtension, androidExtensionsExtension,
project, variantData, androidProjectHandler
)
} }
val sourceSets = androidExtension.sourceSets val sourceSets = androidExtension.sourceSets
@@ -120,19 +126,22 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
val manifestFile = mainSourceSet.manifest.srcFile val manifestFile = mainSourceSet.manifest.srcFile
val applicationPackage = getApplicationPackageFromManifest(manifestFile) ?: run { val applicationPackage = getApplicationPackageFromManifest(manifestFile) ?: run {
project.logger.warn( project.logger.warn(
"Application package name is not present in the manifest file (${manifestFile.absolutePath})") "Application package name is not present in the manifest file (${manifestFile.absolutePath})"
)
"" ""
} }
pluginOptions += SubpluginOption("package", applicationPackage) pluginOptions += SubpluginOption("package", applicationPackage)
fun addVariant(sourceSet: AndroidSourceSet) { fun addVariant(sourceSet: AndroidSourceSet) {
val optionValue = sourceSet.name + ';' + val optionValue = sourceSet.name + ';' +
sourceSet.res.srcDirs.joinToString(";") { it.absolutePath } sourceSet.res.srcDirs.joinToString(";") { it.absolutePath }
pluginOptions += CompositeSubpluginOption("variant", optionValue, listOf( pluginOptions += CompositeSubpluginOption(
"variant", optionValue, listOf(
SubpluginOption("sourceSetName", sourceSet.name), SubpluginOption("sourceSetName", sourceSet.name),
//use the INTERNAL option kind since the resources are tracked as sources (see below) //use the INTERNAL option kind since the resources are tracked as sources (see below)
FilesSubpluginOption("resDirs", sourceSet.res.srcDirs.toList()) FilesSubpluginOption("resDirs", sourceSet.res.srcDirs.toList())
)) )
)
kotlinCompile.source(project.files(getLayoutDirectories(sourceSet.res.srcDirs))) kotlinCompile.source(project.files(getLayoutDirectories(sourceSet.res.srcDirs)))
} }
@@ -157,23 +166,25 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
} }
private fun applyExperimental( private fun applyExperimental(
kotlinCompile: KotlinCompile, kotlinCompile: KotlinCompile,
androidExtension: BaseExtension, androidExtension: BaseExtension,
androidExtensionsExtension: AndroidExtensionsExtension, androidExtensionsExtension: AndroidExtensionsExtension,
project: Project, project: Project,
variantData: Any?, variantData: Any?,
androidProjectHandler: Any? androidProjectHandler: Any?
): List<SubpluginOption> { ): List<SubpluginOption> {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
androidProjectHandler as? AbstractAndroidProjectHandler<Any?> ?: return emptyList() androidProjectHandler as? AbstractAndroidProjectHandler<Any?> ?: return emptyList()
val pluginOptions = arrayListOf<SubpluginOption>() val pluginOptions = arrayListOf<SubpluginOption>()
pluginOptions += SubpluginOption("features", pluginOptions += SubpluginOption("features",
AndroidExtensionsFeature.parseFeatures(androidExtensionsExtension.features).joinToString(",") { it.featureName }) AndroidExtensionsFeature.parseFeatures(androidExtensionsExtension.features).joinToString(",") { it.featureName })
pluginOptions += SubpluginOption("experimental", "true") pluginOptions += SubpluginOption("experimental", "true")
pluginOptions += SubpluginOption("defaultCacheImplementation", pluginOptions += SubpluginOption(
androidExtensionsExtension.defaultCacheImplementation.optionName) "defaultCacheImplementation",
androidExtensionsExtension.defaultCacheImplementation.optionName
)
val mainSourceSet = androidExtension.sourceSets.getByName("main") val mainSourceSet = androidExtension.sourceSets.getByName("main")
pluginOptions += SubpluginOption("package", getApplicationPackage(project, mainSourceSet)) pluginOptions += SubpluginOption("package", getApplicationPackage(project, mainSourceSet))
@@ -184,10 +195,13 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
append(';') append(';')
resDirectories.joinTo(this, separator = ";") { it.canonicalPath } resDirectories.joinTo(this, separator = ";") { it.canonicalPath }
} }
pluginOptions += CompositeSubpluginOption("variant", optionValue, listOf( pluginOptions += CompositeSubpluginOption(
"variant", optionValue, listOf(
SubpluginOption("variantName", name), SubpluginOption("variantName", name),
// use INTERNAL option kind since the resources are tracked as sources (see below) // use INTERNAL option kind since the resources are tracked as sources (see below)
FilesSubpluginOption("resDirs", resDirectories))) FilesSubpluginOption("resDirs", resDirectories)
)
)
kotlinCompile.source(project.files(getLayoutDirectories(resDirectories))) kotlinCompile.source(project.files(getLayoutDirectories(resDirectories)))
} }
@@ -227,13 +241,15 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
} }
// Android25ProjectHandler.KaptVariant actually contains BaseVariant, not BaseVariantData // Android25ProjectHandler.KaptVariant actually contains BaseVariant, not BaseVariantData
private fun getVariantComponentNames(flavorData: Any?): VariantComponentNames? = when(flavorData) { private fun getVariantComponentNames(flavorData: Any?): VariantComponentNames? = when (flavorData) {
is KaptVariantData<*> -> getVariantComponentNames(flavorData.variantData) is KaptVariantData<*> -> getVariantComponentNames(flavorData.variantData)
is TestVariantData -> getVariantComponentNames(flavorData.testedVariantData) is TestVariantData -> getVariantComponentNames(flavorData.testedVariantData)
is TestVariant -> getVariantComponentNames(flavorData.testedVariant) is TestVariant -> getVariantComponentNames(flavorData.testedVariant)
is BaseVariant -> VariantComponentNames(flavorData.name, flavorData.flavorName, flavorData.buildType.name) is BaseVariant -> VariantComponentNames(flavorData.name, flavorData.flavorName, flavorData.buildType.name)
is BaseVariantData<*> -> VariantComponentNames(flavorData.name, flavorData.variantConfiguration.flavorName, is BaseVariantData<*> -> VariantComponentNames(
flavorData.variantConfiguration.buildType.name) flavorData.name, flavorData.variantConfiguration.flavorName,
flavorData.variantConfiguration.buildType.name
)
else -> null else -> null
} }
@@ -254,8 +270,10 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
val applicationPackage = getApplicationPackageFromManifest(manifestFile) val applicationPackage = getApplicationPackageFromManifest(manifestFile)
if (applicationPackage == null) { if (applicationPackage == null) {
project.logger.warn("Application package name is not present in the manifest file " + project.logger.warn(
"(${manifestFile.absolutePath})") "Application package name is not present in the manifest file " +
"(${manifestFile.absolutePath})"
)
return "" return ""
} else { } else {
@@ -266,8 +284,7 @@ class AndroidSubplugin : KotlinGradleSubplugin<KotlinCompile> {
private fun getApplicationPackageFromManifest(manifestFile: File): String? { private fun getApplicationPackageFromManifest(manifestFile: File): String? {
try { try {
return manifestFile.parseXml().documentElement.getAttribute("package") return manifestFile.parseXml().documentElement.getAttribute("package")
} } catch (e: Exception) {
catch (e: Exception) {
return null return null
} }
} }
@@ -27,8 +27,8 @@ interface CompilerArgumentAware<T : CommonToolArguments> {
val defaultSerializedCompilerArguments: List<String> val defaultSerializedCompilerArguments: List<String>
get() = createCompilerArgs() get() = createCompilerArgs()
.also { setupCompilerArgs(it, defaultsOnly = true) } .also { setupCompilerArgs(it, defaultsOnly = true) }
.let(ArgumentUtils::convertArgumentsToStringList) .let(ArgumentUtils::convertArgumentsToStringList)
val filteredArgumentsMap: Map<String, String> val filteredArgumentsMap: Map<String, String>
get() = CompilerArgumentsGradleInput.createInputsMap(prepareCompilerArguments()) get() = CompilerArgumentsGradleInput.createInputsMap(prepareCompilerArguments())
@@ -38,7 +38,7 @@ interface CompilerArgumentAware<T : CommonToolArguments> {
} }
internal fun <T : CommonToolArguments> CompilerArgumentAware<T>.prepareCompilerArguments() = internal fun <T : CommonToolArguments> CompilerArgumentAware<T>.prepareCompilerArguments() =
createCompilerArgs().also { setupCompilerArgs(it) } createCompilerArgs().also { setupCompilerArgs(it) }
interface CompilerArgumentAwareWithInput<T : CommonToolArguments> : CompilerArgumentAware<T> { interface CompilerArgumentAwareWithInput<T : CommonToolArguments> : CompilerArgumentAware<T> {
@get:Internal @get:Internal
@@ -19,16 +19,15 @@ package org.jetbrains.kotlin.gradle.internal
import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.cli.common.arguments.*
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1 import kotlin.reflect.KProperty1
import kotlin.reflect.full.memberProperties
internal object CompilerArgumentsGradleInput { internal object CompilerArgumentsGradleInput {
fun <T : CommonToolArguments> createInputsMap(args: T): Map<String, String> { fun <T : CommonToolArguments> createInputsMap(args: T): Map<String, String> {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val argumentProperties = val argumentProperties =
args::class.members.mapNotNull { member -> args::class.members.mapNotNull { member ->
(member as? KProperty1<T, *>)?.takeIf { it.annotations.any { ann -> ann is Argument } } (member as? KProperty1<T, *>)?.takeIf { it.annotations.any { ann -> ann is Argument } }
} + } +
(CommonToolArguments::freeArgs as KProperty1<T, *>) (CommonToolArguments::freeArgs as KProperty1<T, *>)
val filteredProperties = argumentProperties.filterNot { it in ignoredProperties } val filteredProperties = argumentProperties.filterNot { it in ignoredProperties }
@@ -47,28 +46,28 @@ internal object CompilerArgumentsGradleInput {
// We ignore some file properties e.g. to instead include their values into the Gradle file property checks, // We ignore some file properties e.g. to instead include their values into the Gradle file property checks,
// which, unlike String checks, run with specified path sensitivity; // which, unlike String checks, run with specified path sensitivity;
private val ignoredProperties = setOf<KProperty<*>>( private val ignoredProperties = setOf<KProperty<*>>(
CommonCompilerArguments::verbose, // debug should not lead to rebuild CommonCompilerArguments::verbose, // debug should not lead to rebuild
K2JVMCompilerArguments::destination, // handled by destinationDir K2JVMCompilerArguments::destination, // handled by destinationDir
K2JVMCompilerArguments::classpath, // handled by classpath of the Gradle tasks K2JVMCompilerArguments::classpath, // handled by classpath of the Gradle tasks
K2JVMCompilerArguments::friendPaths, // is part of the classpath K2JVMCompilerArguments::friendPaths, // is part of the classpath
K2JVMCompilerArguments::jdkHome, // JDK can be both placed differently and contain different files on user machines K2JVMCompilerArguments::jdkHome, // JDK can be both placed differently and contain different files on user machines
K2JVMCompilerArguments::buildFile, // in Gradle build, these XMLs are transient and provide no useful info K2JVMCompilerArguments::buildFile, // in Gradle build, these XMLs are transient and provide no useful info
K2JVMCompilerArguments::pluginOptions, // handled specially in the task K2JVMCompilerArguments::pluginOptions, // handled specially in the task
K2JVMCompilerArguments::pluginClasspaths, // handled in the task as classpath K2JVMCompilerArguments::pluginClasspaths, // handled in the task as classpath
K2JSCompilerArguments::outputFile, // already handled by Gradle task property K2JSCompilerArguments::outputFile, // already handled by Gradle task property
K2JSCompilerArguments::libraries, // defined by by classpath and friendDependency of the Gradle task K2JSCompilerArguments::libraries, // defined by by classpath and friendDependency of the Gradle task
K2JSCompilerArguments::sourceMapBaseDirs, // defined by sources K2JSCompilerArguments::sourceMapBaseDirs, // defined by sources
K2JSCompilerArguments::friendModules, // handled by Gradle task friendDependency property K2JSCompilerArguments::friendModules, // handled by Gradle task friendDependency property
K2JSCompilerArguments::pluginOptions, // handled specially in the task K2JSCompilerArguments::pluginOptions, // handled specially in the task
K2JSCompilerArguments::pluginClasspaths, // handled in the task as classpath K2JSCompilerArguments::pluginClasspaths, // handled in the task as classpath
K2MetadataCompilerArguments::classpath, // handled by classpath of the Gradle task K2MetadataCompilerArguments::classpath, // handled by classpath of the Gradle task
K2MetadataCompilerArguments::destination, // handled by destinationDir K2MetadataCompilerArguments::destination, // handled by destinationDir
K2MetadataCompilerArguments::pluginOptions, // handled specially in the task K2MetadataCompilerArguments::pluginOptions, // handled specially in the task
K2MetadataCompilerArguments::pluginClasspaths, // handled in the task as classpath K2MetadataCompilerArguments::pluginClasspaths, // handled in the task as classpath
K2JSDceArguments::outputDirectory // handled by destinationDir K2JSDceArguments::outputDirectory // handled by destinationDir
) )
} }
@@ -24,10 +24,10 @@ import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKa
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedSourcesDir import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedSourcesDir
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder
import org.jetbrains.kotlin.gradle.tasks.isWorkerAPISupported
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.isWorkerAPISupported
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
@@ -42,15 +42,15 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
@JvmStatic @JvmStatic
fun getKaptGeneratedClassesDir(project: Project, sourceSetName: String) = fun getKaptGeneratedClassesDir(project: Project, sourceSetName: String) =
File(project.project.buildDir, "tmp/kapt3/classes/$sourceSetName") File(project.project.buildDir, "tmp/kapt3/classes/$sourceSetName")
@JvmStatic @JvmStatic
fun getKaptGeneratedSourcesDir(project: Project, sourceSetName: String) = fun getKaptGeneratedSourcesDir(project: Project, sourceSetName: String) =
File(project.project.buildDir, "generated/source/kapt/$sourceSetName") File(project.project.buildDir, "generated/source/kapt/$sourceSetName")
@JvmStatic @JvmStatic
fun getKaptGeneratedKotlinSourcesDir(project: Project, sourceSetName: String) = fun getKaptGeneratedKotlinSourcesDir(project: Project, sourceSetName: String) =
File(project.project.buildDir, "generated/source/kaptKotlin/$sourceSetName") File(project.project.buildDir, "generated/source/kaptKotlin/$sourceSetName")
} }
override fun apply(project: Project) { override fun apply(project: Project) {
@@ -74,9 +74,10 @@ abstract class KaptVariantData<T>(val variantData: T) {
abstract fun addJavaSourceFoldersToModel(generatedFilesDir: File) abstract fun addJavaSourceFoldersToModel(generatedFilesDir: File)
abstract val annotationProcessorOptions: Map<String, String>? abstract val annotationProcessorOptions: Map<String, String>?
abstract fun registerGeneratedJavaSource( abstract fun registerGeneratedJavaSource(
project: Project, project: Project,
kaptTask: KaptTask, kaptTask: KaptTask,
javaTask: AbstractCompile) javaTask: AbstractCompile
)
open val annotationProcessorOptionProviders: List<*> open val annotationProcessorOptionProviders: List<*>
get() = emptyList<Any>() get() = emptyList<Any>()
@@ -135,7 +136,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
if (aptConfiguration.name != Kapt3KotlinGradleSubplugin.MAIN_KAPT_CONFIGURATION_NAME) { if (aptConfiguration.name != Kapt3KotlinGradleSubplugin.MAIN_KAPT_CONFIGURATION_NAME) {
// The main configuration can be created after the current one. We should handle this case // The main configuration can be created after the current one. We should handle this case
val mainConfiguration = findMainKaptConfiguration(project) val mainConfiguration = findMainKaptConfiguration(project)
?: createAptConfigurationIfNeeded(project, SourceSet.MAIN_SOURCE_SET_NAME) ?: createAptConfigurationIfNeeded(project, SourceSet.MAIN_SOURCE_SET_NAME)
aptConfiguration.extendsFrom(mainConfiguration) aptConfiguration.extendsFrom(mainConfiguration)
} }
@@ -201,8 +202,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
} }
kaptVariantData.name kaptVariantData.name
} } else {
else {
if (kotlinCompilation == null) error("In non-Android projects, Kotlin compilation should not be null") if (kotlinCompilation == null) error("In non-Android projects, Kotlin compilation should not be null")
handleSourceSet(kotlinCompilation.compilationName) handleSourceSet(kotlinCompilation.compilationName)
@@ -409,8 +409,9 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
private fun Kapt3SubpluginContext.createKaptGenerateStubsTask(): KaptGenerateStubsTask { private fun Kapt3SubpluginContext.createKaptGenerateStubsTask(): KaptGenerateStubsTask {
val kaptTask = project.tasks.create( val kaptTask = project.tasks.create(
getKaptTaskName("kaptGenerateStubs"), getKaptTaskName("kaptGenerateStubs"),
KaptGenerateStubsTask::class.java) KaptGenerateStubsTask::class.java
)
kaptTask.sourceSetName = sourceSetName kaptTask.sourceSetName = sourceSetName
kaptTask.kotlinCompileTask = kotlinCompile kaptTask.kotlinCompileTask = kotlinCompile
@@ -21,15 +21,15 @@ import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.incremental.ChangedFiles
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.FilteringSourceRootsContainer import org.jetbrains.kotlin.gradle.tasks.FilteringSourceRootsContainer
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.SourceRoots import org.jetbrains.kotlin.gradle.tasks.SourceRoots
import org.jetbrains.kotlin.gradle.incremental.ChangedFiles
import org.jetbrains.kotlin.gradle.utils.isParentOf import org.jetbrains.kotlin.gradle.utils.isParentOf
import org.jetbrains.kotlin.gradle.utils.pathsAsStringRelativeTo
import org.jetbrains.kotlin.incremental.classpathAsList import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile import org.jetbrains.kotlin.incremental.destinationAsFile
import org.jetbrains.kotlin.gradle.utils.pathsAsStringRelativeTo
import java.io.File import java.io.File
@CacheableTask @CacheableTask
@@ -45,27 +45,32 @@ open class KaptGenerateStubsTask : KotlinCompile() {
@get:Internal @get:Internal
lateinit var generatedSourcesDir: File lateinit var generatedSourcesDir: File
@get:Classpath @get:InputFiles @get:Classpath
@get:InputFiles
val kaptClasspath: FileCollection val kaptClasspath: FileCollection
get() = project.files(*kaptClasspathConfigurations.toTypedArray()) get() = project.files(*kaptClasspathConfigurations.toTypedArray())
@get:Internal @get:Internal
internal lateinit var kaptClasspathConfigurations: List<Configuration> internal lateinit var kaptClasspathConfigurations: List<Configuration>
@get:Classpath @get:InputFiles @Suppress("unused") @get:Classpath
internal val kotlinTaskPluginClasspath get() = kotlinCompileTask.pluginClasspath @get:InputFiles
@Suppress("unused")
internal val kotlinTaskPluginClasspath
get() = kotlinCompileTask.pluginClasspath
override fun source(vararg sources: Any?): SourceTask? { override fun source(vararg sources: Any?): SourceTask? {
return super.source(sourceRootsContainer.add(sources)) return super.source(sourceRootsContainer.add(sources))
} }
override fun setSource(sources: Any?) { override fun setSource(sources: Any?) {
super.setSource(sourceRootsContainer.set(sources)) super.setSource(sourceRootsContainer.set(sources))
} }
private fun isSourceRootAllowed(source: File): Boolean = private fun isSourceRootAllowed(source: File): Boolean =
!destinationDir.isParentOf(source) && !destinationDir.isParentOf(source) &&
!stubsDir.isParentOf(source) && !stubsDir.isParentOf(source) &&
!generatedSourcesDir.isParentOf(source) !generatedSourcesDir.isParentOf(source)
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) { override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) {
kotlinCompileTask.setupCompilerArgs(args) kotlinCompileTask.setupCompilerArgs(args)
@@ -5,10 +5,10 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.internal.ConventionTask import org.gradle.api.internal.ConventionTask
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.cacheOnlyIfEnabledForKotlin
import org.jetbrains.kotlin.gradle.tasks.isBuildCacheSupported
import org.jetbrains.kotlin.gradle.utils.isJavaFile import org.jetbrains.kotlin.gradle.utils.isJavaFile
import org.jetbrains.kotlin.gradle.utils.isParentOf
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
import java.io.File import java.io.File
@CacheableTask @CacheableTask
@@ -18,7 +18,7 @@ abstract class KaptTask : ConventionTask() {
if (isBuildCacheSupported()) { if (isBuildCacheSupported()) {
val reason = "Caching is disabled by default for kapt because of arbitrary behavior of external " + val reason = "Caching is disabled by default for kapt because of arbitrary behavior of external " +
"annotation processors. You can enable it by adding 'kapt.useBuildCache = true' to the build script." "annotation processors. You can enable it by adding 'kapt.useBuildCache = true' to the build script."
outputs.cacheIf(reason) { useBuildCache } outputs.cacheIf(reason) { useBuildCache }
} }
} }
@@ -29,12 +29,15 @@ abstract class KaptTask : ConventionTask() {
@get:Internal @get:Internal
internal lateinit var stubsDir: File internal lateinit var stubsDir: File
@get:Classpath @get:InputFiles @get:Classpath
@get:InputFiles
val kaptClasspath: FileCollection val kaptClasspath: FileCollection
get() = project.files(*kaptClasspathConfigurations.toTypedArray()) get() = project.files(*kaptClasspathConfigurations.toTypedArray())
@get:Classpath @get:InputFiles @get:Classpath
val compilerClasspath: List<File> get() = kotlinCompileTask.computedCompilerClasspath @get:InputFiles
val compilerClasspath: List<File>
get() = kotlinCompileTask.computedCompilerClasspath
@get:Internal @get:Internal
internal lateinit var kaptClasspathConfigurations: List<Configuration> internal lateinit var kaptClasspathConfigurations: List<Configuration>
@@ -51,14 +54,16 @@ abstract class KaptTask : ConventionTask() {
@get:Nested @get:Nested
internal val annotationProcessorOptionProviders: MutableList<Any> = mutableListOf() internal val annotationProcessorOptionProviders: MutableList<Any> = mutableListOf()
@get:Classpath @get:InputFiles @get:Classpath
@get:InputFiles
val classpath: FileCollection val classpath: FileCollection
get() = kotlinCompileTask.classpath get() = kotlinCompileTask.classpath
@get:Internal @get:Internal
var useBuildCache: Boolean = false var useBuildCache: Boolean = false
@get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE) @get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
val source: Collection<File> val source: Collection<File>
get() { get() {
val result = HashSet<File>() val result = HashSet<File>()
@@ -30,7 +30,8 @@ open class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<K2JV
@get:Classpath @get:Classpath
@get:InputFiles @get:InputFiles
@Suppress("unused") @Suppress("unused")
internal val kotlinTaskPluginClasspaths get() = kotlinCompileTask.pluginClasspath internal val kotlinTaskPluginClasspaths
get() = kotlinCompileTask.pluginClasspath
@get:Classpath @get:Classpath
@get:InputFiles @get:InputFiles
@@ -5,7 +5,10 @@
package org.jetbrains.kotlin.gradle.internal package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.tasks.* import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.TaskAction
import org.gradle.workers.IsolationMode import org.gradle.workers.IsolationMode
import org.gradle.workers.WorkerExecutor import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.gradle.internal package org.jetbrains.kotlin.gradle.internal
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
import org.jetbrains.kotlin.gradle.plugin.CompositeSubpluginOption import org.jetbrains.kotlin.gradle.plugin.CompositeSubpluginOption
import org.jetbrains.kotlin.gradle.plugin.FilesSubpluginOption import org.jetbrains.kotlin.gradle.plugin.FilesSubpluginOption
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
@@ -43,10 +43,10 @@ open class KaptExtension {
var useBuildCache: Boolean = false var useBuildCache: Boolean = false
private val apOptionsActions = private val apOptionsActions =
mutableListOf<(KaptAnnotationProcessorOptions) -> Unit>() mutableListOf<(KaptAnnotationProcessorOptions) -> Unit>()
private val javacOptionsActions = private val javacOptionsActions =
mutableListOf<(KaptJavacOptionsDelegate) -> Unit>() mutableListOf<(KaptJavacOptionsDelegate) -> Unit>()
private var apOptionsClosure: Closure<*>? = null private var apOptionsClosure: Closure<*>? = null
private var javacOptionsClosure: Closure<*>? = null private var javacOptionsClosure: Closure<*>? = null
@@ -105,9 +105,9 @@ open class KaptExtension {
* [project], [variant] and [android] properties are intended to be used inside the closure. * [project], [variant] and [android] properties are intended to be used inside the closure.
*/ */
open class KaptAnnotationProcessorOptions( open class KaptAnnotationProcessorOptions(
@Suppress("unused") open val project: Project, @Suppress("unused") open val project: Project,
@Suppress("unused") open val variant: Any?, @Suppress("unused") open val variant: Any?,
@Suppress("unused") open val android: Any? @Suppress("unused") open val android: Any?
) { ) {
internal val options = LinkedHashMap<String, String>() internal val options = LinkedHashMap<String, String>()
@@ -108,12 +108,13 @@ internal class KotlinGradleBuildServices private constructor(gradle: Gradle) : B
log.lifecycle(FORCE_SYSTEM_GC_MESSAGE) log.lifecycle(FORCE_SYSTEM_GC_MESSAGE)
val gcCountBefore = getGcCount() val gcCountBefore = getGcCount()
System.gc() System.gc()
while (getGcCount() == gcCountBefore) {} while (getGcCount() == gcCountBefore) {
}
val rt = Runtime.getRuntime() val rt = Runtime.getRuntime()
return (rt.totalMemory() - rt.freeMemory()) / 1024 return (rt.totalMemory() - rt.freeMemory()) / 1024
} }
private fun getGcCount(): Long = private fun getGcCount(): Long =
ManagementFactory.getGarbageCollectorMXBeans().sumByLong { Math.max(0, it.collectionCount) } ManagementFactory.getGarbageCollectorMXBeans().sumByLong { Math.max(0, it.collectionCount) }
} }
@@ -71,7 +71,7 @@ class KotlinJsDcePlugin : Plugin<Project> {
val configuration = project.configurations.getByName(kotlinCompilation.compileDependencyConfigurationName) val configuration = project.configurations.getByName(kotlinCompilation.compileDependencyConfigurationName)
with (dceTask) { with(dceTask) {
classpath = configuration classpath = configuration
destinationDir = dceTask.dceOptions.outputDirectory?.let { File(it) } ?: outputDir destinationDir = dceTask.dceOptions.outputDirectory?.let { File(it) } ?: outputDir
source(kotlinTask.outputFile) source(kotlinTask.outputFile)
@@ -45,7 +45,7 @@ const val EXPECTED_BY_CONFIG_NAME = "expectedBy"
const val IMPLEMENT_CONFIG_NAME = "implement" const val IMPLEMENT_CONFIG_NAME = "implement"
const val IMPLEMENT_DEPRECATION_WARNING = "The '$IMPLEMENT_CONFIG_NAME' configuration is deprecated and will be removed. " + const val IMPLEMENT_DEPRECATION_WARNING = "The '$IMPLEMENT_CONFIG_NAME' configuration is deprecated and will be removed. " +
"Use '$EXPECTED_BY_CONFIG_NAME' instead." "Use '$EXPECTED_BY_CONFIG_NAME' instead."
open class KotlinPlatformImplementationPluginBase(platformName: String) : KotlinPlatformPluginBase(platformName) { open class KotlinPlatformImplementationPluginBase(platformName: String) : KotlinPlatformPluginBase(platformName) {
private val commonProjects = arrayListOf<Project>() private val commonProjects = arrayListOf<Project>()
@@ -76,8 +76,7 @@ open class KotlinPlatformImplementationPluginBase(platformName: String) : Kotlin
configurationsForCommonModuleDependency(project).forEach { configuration -> configurationsForCommonModuleDependency(project).forEach { configuration ->
configuration.dependencies.add(dep) configuration.dependencies.add(dep)
} }
} } else {
else {
throw GradleException("$project '${config.name}' dependency is not a project: $dep") throw GradleException("$project '${config.name}' dependency is not a project: $dep")
} }
} }
@@ -102,9 +101,10 @@ open class KotlinPlatformImplementationPluginBase(platformName: String) : Kotlin
commonProject.whenEvaluated { commonProject.whenEvaluated {
if (!commonProject.pluginManager.hasPlugin("kotlin-platform-common")) { if (!commonProject.pluginManager.hasPlugin("kotlin-platform-common")) {
throw GradleException( throw GradleException(
"Platform project $platformProject has an " + "Platform project $platformProject has an " +
"'$EXPECTED_BY_CONFIG_NAME'${if (implementConfigurationIsUsed) "/'$IMPLEMENT_CONFIG_NAME'" else ""} " + "'$EXPECTED_BY_CONFIG_NAME'${if (implementConfigurationIsUsed) "/'$IMPLEMENT_CONFIG_NAME'" else ""} " +
"dependency to non-common project $commonProject") "dependency to non-common project $commonProject"
)
} }
// Since the two projects may add source sets in arbitrary order, and both may do that after the plugin is applied, // Since the two projects may add source sets in arbitrary order, and both may do that after the plugin is applied,
@@ -159,7 +159,8 @@ open class KotlinPlatformImplementationPluginBase(platformName: String) : Kotlin
project.kotlinExtension.sourceSets project.kotlinExtension.sourceSets
protected open fun addCommonSourceSetToPlatformSourceSet(commonSourceSet: Named, platformProject: Project) { protected open fun addCommonSourceSetToPlatformSourceSet(commonSourceSet: Named, platformProject: Project) {
platformProject.whenEvaluated { // At the point when the source set in the platform module is created, the task does not exist platformProject.whenEvaluated {
// At the point when the source set in the platform module is created, the task does not exist
val platformTask = platformProject.tasks val platformTask = platformProject.tasks
.withType(AbstractKotlinCompile::class.java) .withType(AbstractKotlinCompile::class.java)
.singleOrNull { it.sourceSetName == commonSourceSet.name } // TODO use strict check once this code is not run in K/N .singleOrNull { it.sourceSetName == commonSourceSet.name } // TODO use strict check once this code is not run in K/N
@@ -203,8 +204,7 @@ open class KotlinPlatformImplementationPluginBase(platformName: String) : Kotlin
internal fun <T> Project.whenEvaluated(fn: Project.() -> T) { internal fun <T> Project.whenEvaluated(fn: Project.() -> T) {
if (state.executed) { if (state.executed) {
fn() fn()
} } else {
else {
afterEvaluate { it.fn() } afterEvaluate { it.fn() }
} }
} }
@@ -217,7 +217,7 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
override fun configurationsForCommonModuleDependency(project: Project): List<Configuration> = override fun configurationsForCommonModuleDependency(project: Project): List<Configuration> =
(project.configurations.findByName("api"))?.let(::listOf) (project.configurations.findByName("api"))?.let(::listOf)
?: super.configurationsForCommonModuleDependency(project) // older Android plugins don't have api/implementation configs ?: super.configurationsForCommonModuleDependency(project) // older Android plugins don't have api/implementation configs
override fun namedSourceSetsContainer(project: Project): NamedDomainObjectContainer<*> = override fun namedSourceSetsContainer(project: Project): NamedDomainObjectContainer<*> =
(project.extensions.getByName("android") as BaseExtension).sourceSets (project.extensions.getByName("android") as BaseExtension).sourceSets
@@ -226,7 +226,7 @@ open class KotlinPlatformAndroidPlugin : KotlinPlatformImplementationPluginBase(
val androidExtension = platformProject.extensions.getByName("android") as BaseExtension val androidExtension = platformProject.extensions.getByName("android") as BaseExtension
val androidSourceSet = androidExtension.sourceSets.findByName(commonSourceSet.name) ?: return val androidSourceSet = androidExtension.sourceSets.findByName(commonSourceSet.name) ?: return
val kotlinSourceSet = androidSourceSet.getConvention(KOTLIN_DSL_NAME) as? KotlinSourceSet val kotlinSourceSet = androidSourceSet.getConvention(KOTLIN_DSL_NAME) as? KotlinSourceSet
?: return ?: return
kotlinSourceSet.kotlin.source(getKotlinSourceDirectorySetSafe(commonSourceSet)!!) kotlinSourceSet.kotlin.source(getKotlinSourceDirectorySetSafe(commonSourceSet)!!)
} }
} }
@@ -7,7 +7,6 @@ import groovy.lang.Closure
import org.gradle.api.* import org.gradle.api.*
import org.gradle.api.artifacts.ExternalDependency import org.gradle.api.artifacts.ExternalDependency
import org.gradle.api.attributes.Usage import org.gradle.api.attributes.Usage
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
@@ -18,7 +17,6 @@ import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.CompileClasspathNormalizer import org.gradle.api.tasks.CompileClasspathNormalizer
import org.gradle.api.tasks.Delete import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetOutput
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
@@ -159,7 +157,7 @@ internal class Kotlin2JvmSourceSetProcessor(
super.defaultKotlinDestinationDir super.defaultKotlinDestinationDir
override fun doCreateTask(project: Project, taskName: String): KotlinCompile = override fun doCreateTask(project: Project, taskName: String): KotlinCompile =
tasksProvider.createKotlinJVMTask(project, taskName, kotlinCompilation) tasksProvider.createKotlinJVMTask(project, taskName, kotlinCompilation)
override fun doTargetSpecificProcessing() { override fun doTargetSpecificProcessing() {
Kapt3KotlinGradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationName) Kapt3KotlinGradleSubplugin.createAptConfigurationIfNeeded(project, kotlinCompilation.compilationName)
@@ -200,35 +198,35 @@ internal class Kotlin2JvmSourceSetProcessor(
val configuration = project.configurations.getByName("apiElements") val configuration = project.configurations.getByName("apiElements")
checkedReflection({ checkedReflection({
val getOutgoing = configuration.javaClass.getMethod("getOutgoing") val getOutgoing = configuration.javaClass.getMethod("getOutgoing")
val outgoing = getOutgoing(configuration) val outgoing = getOutgoing(configuration)
val getVariants = outgoing.javaClass.getMethod("getVariants") val getVariants = outgoing.javaClass.getMethod("getVariants")
val variants = getVariants(outgoing) as NamedDomainObjectCollection<*> val variants = getVariants(outgoing) as NamedDomainObjectCollection<*>
val variant = variants.getByName("classes") val variant = variants.getByName("classes")
val artifactMethod = variant.javaClass.getMethod("artifact", Any::class.java) val artifactMethod = variant.javaClass.getMethod("artifact", Any::class.java)
val artifactMap = mapOf( val artifactMap = mapOf(
"file" to outputDir, "file" to outputDir,
"type" to "java-classes-directory", "type" to "java-classes-directory",
"builtBy" to taskDependency "builtBy" to taskDependency
) )
artifactMethod(variant, artifactMap) artifactMethod(variant, artifactMap)
return true return true
}, { reflectException -> }, { reflectException ->
logger.kotlinWarn("Could not register Kotlin output of source set $sourceSetName for java-library: $reflectException") logger.kotlinWarn("Could not register Kotlin output of source set $sourceSetName for java-library: $reflectException")
return false return false
}) })
} }
} }
internal fun KotlinCompilationOutput.tryAddClassesDir( internal fun KotlinCompilationOutput.tryAddClassesDir(
classesDirProvider: () -> FileCollection classesDirProvider: () -> FileCollection
): Boolean = ): Boolean =
if (isGradleVersionAtLeast(4, 0)) { if (isGradleVersionAtLeast(4, 0)) {
classesDirs.from(Callable { classesDirProvider() }) classesDirs.from(Callable { classesDirProvider() })
@@ -247,7 +245,7 @@ internal class Kotlin2JsSourceSetProcessor(
kotlinCompilation = kotlinCompilation kotlinCompilation = kotlinCompilation
) { ) {
override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile = override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile =
tasksProvider.createKotlinJSTask(project, taskName, kotlinCompilation) tasksProvider.createKotlinJSTask(project, taskName, kotlinCompilation)
override fun doTargetSpecificProcessing() { override fun doTargetSpecificProcessing() {
project.tasks.findByName(kotlinCompilation.compileAllTaskName)!!.dependsOn(kotlinTask) project.tasks.findByName(kotlinCompilation.compileAllTaskName)!!.dependsOn(kotlinTask)
@@ -265,14 +263,16 @@ internal class Kotlin2JsSourceSetProcessor(
val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion) val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project, kotlinPluginVersion)
val appliedPlugins = subpluginEnvironment.addSubpluginOptions( val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
project, kotlinTask, null, null, null, kotlinCompilation) project, kotlinTask, null, null, null, kotlinCompilation
)
if (outputDir.isParentOf(project.rootDir)) if (outputDir.isParentOf(project.rootDir))
throw InvalidUserDataException( throw InvalidUserDataException(
"The output directory '$outputDir' (defined by outputFile of $kotlinTask) contains or " + "The output directory '$outputDir' (defined by outputFile of $kotlinTask) contains or " +
"matches the project root directory '${project.rootDir}'.\n" + "matches the project root directory '${project.rootDir}'.\n" +
"Gradle will not be able to build the project because of the root directory lock.\n" + "Gradle will not be able to build the project because of the root directory lock.\n" +
"To fix this, consider using the default outputFile location instead of providing it explicitly.") "To fix this, consider using the default outputFile location instead of providing it explicitly."
)
kotlinTask.destinationDir = outputDir kotlinTask.destinationDir = outputDir
@@ -281,8 +281,8 @@ internal class Kotlin2JsSourceSetProcessor(
} }
appliedPlugins appliedPlugins
.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) } .flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
.forEach { task -> kotlinCompilation.allKotlinSourceSets.forEach { sourceSet -> task.source(sourceSet.kotlin) } } .forEach { task -> kotlinCompilation.allKotlinSourceSets.forEach { sourceSet -> task.source(sourceSet.kotlin) } }
} }
} }
@@ -325,16 +325,20 @@ internal class KotlinCommonSourceSetProcessor(
} }
override fun doCreateTask(project: Project, taskName: String): KotlinCompileCommon = override fun doCreateTask(project: Project, taskName: String): KotlinCompileCommon =
tasksProvider.createKotlinCommonTask(project, taskName, kotlinCompilation) tasksProvider.createKotlinCommonTask(project, taskName, kotlinCompilation)
} }
internal abstract class AbstractKotlinPlugin( internal abstract class AbstractKotlinPlugin(
val tasksProvider: KotlinTasksProvider, val tasksProvider: KotlinTasksProvider,
protected val kotlinPluginVersion: String, protected val kotlinPluginVersion: String,
val registry: ToolingModelBuilderRegistry val registry: ToolingModelBuilderRegistry
) : Plugin<Project> { ) : Plugin<Project> {
internal abstract fun buildSourceSetProcessor(project: Project, compilation: KotlinCompilation, kotlinPluginVersion: String): KotlinSourceSetProcessor<*> internal abstract fun buildSourceSetProcessor(
project: Project,
compilation: KotlinCompilation,
kotlinPluginVersion: String
): KotlinSourceSetProcessor<*>
override fun apply(project: Project) { override fun apply(project: Project) {
project.plugins.apply(JavaPlugin::class.java) project.plugins.apply(JavaPlugin::class.java)
@@ -355,7 +359,7 @@ internal abstract class AbstractKotlinPlugin(
fun configureProjectGlobalSettings(project: Project, kotlinPluginVersion: String) { fun configureProjectGlobalSettings(project: Project, kotlinPluginVersion: String) {
configureDefaultVersionsResolutionStrategy(project, kotlinPluginVersion) configureDefaultVersionsResolutionStrategy(project, kotlinPluginVersion)
configureClassInspectionForIC(project) configureClassInspectionForIC(project)
} }
fun configureTarget( fun configureTarget(
target: KotlinWithJavaTarget, target: KotlinWithJavaTarget,
@@ -399,7 +403,8 @@ internal abstract class AbstractKotlinPlugin(
val compilationsUnderConstruction = mutableMapOf<String, KotlinWithJavaCompilation>() val compilationsUnderConstruction = mutableMapOf<String, KotlinWithJavaCompilation>()
javaSourceSets.all { javaSourceSet -> javaSourceSets.all { javaSourceSet ->
val kotlinCompilation = compilationsUnderConstruction[javaSourceSet.name] ?: kotlinTarget.compilations.maybeCreate(javaSourceSet.name) val kotlinCompilation =
compilationsUnderConstruction[javaSourceSet.name] ?: kotlinTarget.compilations.maybeCreate(javaSourceSet.name)
kotlinCompilation.javaSourceSet = javaSourceSet kotlinCompilation.javaSourceSet = javaSourceSet
val kotlinSourceSet = project.kotlinExtension.sourceSets.maybeCreate(kotlinCompilation.name) val kotlinSourceSet = project.kotlinExtension.sourceSets.maybeCreate(kotlinCompilation.name)
javaSourceSet.addConvention(kotlinSourceSetDslName, kotlinSourceSet) javaSourceSet.addConvention(kotlinSourceSetDslName, kotlinSourceSet)
@@ -490,7 +495,7 @@ internal open class KotlinPlugin(
} }
override fun buildSourceSetProcessor(project: Project, compilation: KotlinCompilation, kotlinPluginVersion: String) = override fun buildSourceSetProcessor(project: Project, compilation: KotlinCompilation, kotlinPluginVersion: String) =
Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion) Kotlin2JvmSourceSetProcessor(project, tasksProvider, compilation, kotlinPluginVersion)
override fun apply(project: Project) { override fun apply(project: Project) {
val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, targetName).apply { val target = KotlinWithJavaTarget(project, KotlinPlatformType.jvm, targetName).apply {
@@ -668,14 +673,16 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
setUpDependencyResolution(variant, compilation) setUpDependencyResolution(variant, compilation)
} }
val androidPluginIds = listOf("android", "com.android.application", "android-library", "com.android.library", val androidPluginIds = listOf(
"com.android.test", "com.android.feature", "com.android.dynamic-feature", "com.android.instantapp") "android", "com.android.application", "android-library", "com.android.library",
"com.android.test", "com.android.feature", "com.android.dynamic-feature", "com.android.instantapp"
)
val plugin = androidPluginIds.asSequence() val plugin = androidPluginIds.asSequence()
.mapNotNull { project.plugins.findPlugin(it) as? BasePlugin } .mapNotNull { project.plugins.findPlugin(it) as? BasePlugin }
.firstOrNull() .firstOrNull()
?: throw InvalidPluginException("'kotlin-android' expects one of the Android Gradle " + ?: throw InvalidPluginException("'kotlin-android' expects one of the Android Gradle " +
"plugins to be applied to the project:\n\t" + "plugins to be applied to the project:\n\t" +
androidPluginIds.joinToString("\n\t") { "* $it" }) androidPluginIds.joinToString("\n\t") { "* $it" })
checkAndroidAnnotationProcessorDependencyUsage(project) checkAndroidAnnotationProcessorDependencyUsage(project)
@@ -751,10 +758,11 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
val javaTask = getJavaTask(variantData) val javaTask = getJavaTask(variantData)
val appliedPlugins = subpluginEnvironment.addSubpluginOptions( val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), this, null) project, kotlinTask, javaTask, wrapVariantDataForKapt(variantData), this, null
)
appliedPlugins.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) } appliedPlugins.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
.forEach { configureSources(it, variantData, null) } .forEach { configureSources(it, variantData, null) }
} }
private fun configureSources(compileTask: AbstractCompile, variantData: V, compilation: KotlinCompilation?) { private fun configureSources(compileTask: AbstractCompile, variantData: V, compilation: KotlinCompilation?) {
@@ -785,8 +793,7 @@ internal fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractComp
dir(kotlinTask.destinationDir) dir(kotlinTask.destinationDir)
.withNormalizer(CompileClasspathNormalizer::class.java) .withNormalizer(CompileClasspathNormalizer::class.java)
.withPropertyName("${kotlinTask.name}OutputClasses") .withPropertyName("${kotlinTask.name}OutputClasses")
} } else {
else {
dirCompatible(kotlinTask.destinationDir) dirCompatible(kotlinTask.destinationDir)
} }
} }
@@ -806,10 +813,10 @@ internal fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractComp
internal fun syncOutputTaskName(variantName: String) = "copy${variantName.capitalize()}KotlinClasses" internal fun syncOutputTaskName(variantName: String) = "copy${variantName.capitalize()}KotlinClasses"
internal fun createSyncOutputTask( internal fun createSyncOutputTask(
project: Project, project: Project,
kotlinCompile: KotlinCompile, kotlinCompile: KotlinCompile,
javaTask: AbstractCompile, javaTask: AbstractCompile,
variantName: String variantName: String
): SyncOutputTask { ): SyncOutputTask {
val kotlinDir = kotlinCompile.destinationDir val kotlinDir = kotlinCompile.destinationDir
val javaDir = javaTask.destinationDir val javaDir = javaTask.destinationDir
@@ -38,7 +38,7 @@ import kotlin.reflect.KClass
abstract class KotlinBasePluginWrapper( abstract class KotlinBasePluginWrapper(
protected val fileResolver: FileResolver protected val fileResolver: FileResolver
): Plugin<Project> { ) : Plugin<Project> {
private val log = Logging.getLogger(this.javaClass) private val log = Logging.getLogger(this.javaClass)
val kotlinPluginVersion = loadKotlinVersionFromResource(log) val kotlinPluginVersion = loadKotlinVersionFromResource(log)
@@ -92,9 +92,9 @@ abstract class KotlinBasePluginWrapper(
open class KotlinPluginWrapper @Inject constructor( open class KotlinPluginWrapper @Inject constructor(
fileResolver: FileResolver, fileResolver: FileResolver,
protected val registry: ToolingModelBuilderRegistry protected val registry: ToolingModelBuilderRegistry
): KotlinBasePluginWrapper(fileResolver) { ) : KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
KotlinPlugin(kotlinPluginVersion, registry) KotlinPlugin(kotlinPluginVersion, registry)
override val projectExtensionClass: KClass<out KotlinJvmProjectExtension> override val projectExtensionClass: KClass<out KotlinJvmProjectExtension>
get() = KotlinJvmProjectExtension::class get() = KotlinJvmProjectExtension::class
@@ -103,9 +103,9 @@ open class KotlinPluginWrapper @Inject constructor(
open class KotlinCommonPluginWrapper @Inject constructor( open class KotlinCommonPluginWrapper @Inject constructor(
fileResolver: FileResolver, fileResolver: FileResolver,
protected val registry: ToolingModelBuilderRegistry protected val registry: ToolingModelBuilderRegistry
): KotlinBasePluginWrapper(fileResolver) { ) : KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
KotlinCommonPlugin(kotlinPluginVersion, registry) KotlinCommonPlugin(kotlinPluginVersion, registry)
override val projectExtensionClass: KClass<out KotlinSingleJavaTargetExtension> override val projectExtensionClass: KClass<out KotlinSingleJavaTargetExtension>
get() = KotlinSingleJavaTargetExtension::class get() = KotlinSingleJavaTargetExtension::class
@@ -114,7 +114,7 @@ open class KotlinCommonPluginWrapper @Inject constructor(
open class KotlinAndroidPluginWrapper @Inject constructor( open class KotlinAndroidPluginWrapper @Inject constructor(
fileResolver: FileResolver, fileResolver: FileResolver,
protected val registry: ToolingModelBuilderRegistry protected val registry: ToolingModelBuilderRegistry
): KotlinBasePluginWrapper(fileResolver) { ) : KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
KotlinAndroidPlugin(kotlinPluginVersion) KotlinAndroidPlugin(kotlinPluginVersion)
} }
@@ -122,7 +122,7 @@ open class KotlinAndroidPluginWrapper @Inject constructor(
open class Kotlin2JsPluginWrapper @Inject constructor( open class Kotlin2JsPluginWrapper @Inject constructor(
fileResolver: FileResolver, fileResolver: FileResolver,
protected val registry: ToolingModelBuilderRegistry protected val registry: ToolingModelBuilderRegistry
): KotlinBasePluginWrapper(fileResolver) { ) : KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
Kotlin2JsPlugin(kotlinPluginVersion, registry) Kotlin2JsPlugin(kotlinPluginVersion, registry)
@@ -134,7 +134,7 @@ open class KotlinMultiplatformPluginWrapper @Inject constructor(
fileResolver: FileResolver, fileResolver: FileResolver,
private val instantiator: Instantiator, private val instantiator: Instantiator,
private val featurePreviews: FeaturePreviews private val featurePreviews: FeaturePreviews
): KotlinBasePluginWrapper(fileResolver) { ) : KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> = override fun getPlugin(project: Project, kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project> =
KotlinMultiplatformPlugin( KotlinMultiplatformPlugin(
fileResolver, fileResolver,
@@ -152,8 +152,8 @@ fun Plugin<*>.loadKotlinVersionFromResource(log: Logger): String {
log.kotlinDebug("Loading version information") log.kotlinDebug("Loading version information")
val props = Properties() val props = Properties()
val propFileName = "project.properties" val propFileName = "project.properties"
val inputStream = javaClass.classLoader!!.getResourceAsStream(propFileName) ?: val inputStream = javaClass.classLoader!!.getResourceAsStream(propFileName)
throw FileNotFoundException("property file '$propFileName' not found in the classpath") ?: throw FileNotFoundException("property file '$propFileName' not found in the classpath")
props.load(inputStream) props.load(inputStream)
@@ -72,13 +72,12 @@ internal class PropertiesProvider(private val project: Project) {
get() = booleanProperty("kotlin.useFallbackCompilerSearch") get() = booleanProperty("kotlin.useFallbackCompilerSearch")
private fun booleanProperty(propName: String): Boolean? = private fun booleanProperty(propName: String): Boolean? =
property(propName)?.toBoolean() property(propName)?.toBoolean()
private fun property(propName: String): String? = private fun property(propName: String): String? =
if (project.hasProperty(propName)) { if (project.hasProperty(propName)) {
project.property(propName) as? String project.property(propName) as? String
} } else {
else { localProperties.getProperty(propName)
localProperties.getProperty(propName) }
}
} }
@@ -121,7 +121,8 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
?: return // Otherwise, there is no runtime classpath ?: return // Otherwise, there is no runtime classpath
target.project.tasks.create(lowerCamelCaseName(target.targetName, testTaskNameSuffix), Test::class.java).apply { target.project.tasks.create(lowerCamelCaseName(target.targetName, testTaskNameSuffix), Test::class.java).apply {
project.afterEvaluate { // use afterEvaluate to override the JavaPlugin defaults for Test tasks project.afterEvaluate {
// use afterEvaluate to override the JavaPlugin defaults for Test tasks
conventionMapping.map("testClassesDirs") { testCompilation.output.classesDirs } conventionMapping.map("testClassesDirs") { testCompilation.output.classesDirs }
conventionMapping.map("classpath") { testCompilation.runtimeDependencyFiles } conventionMapping.map("classpath") { testCompilation.runtimeDependencyFiles }
description = "Runs the unit tests." description = "Runs the unit tests."
@@ -327,7 +328,7 @@ internal val KotlinCompilation.deprecatedCompileConfigurationName: String
internal val KotlinCompilationToRunnableFiles.deprecatedRuntimeConfigurationName: String internal val KotlinCompilationToRunnableFiles.deprecatedRuntimeConfigurationName: String
get() = disambiguateName("runtime") get() = disambiguateName("runtime")
open class KotlinTargetConfigurator<KotlinCompilationType: KotlinCompilation>( open class KotlinTargetConfigurator<KotlinCompilationType : KotlinCompilation>(
createDefaultSourceSets: Boolean, createDefaultSourceSets: Boolean,
createTestCompilation: Boolean createTestCompilation: Boolean
) : AbstractKotlinTargetConfigurator<KotlinOnlyTarget<KotlinCompilationType>>( ) : AbstractKotlinTargetConfigurator<KotlinOnlyTarget<KotlinCompilationType>>(
@@ -428,7 +429,7 @@ open class KotlinNativeTargetConfigurator(
return buildDir.resolve("bin/$targetSubDirectory${compilation.name}/$buildTypeSubDirectory/$kindSubDirectory") return buildDir.resolve("bin/$targetSubDirectory${compilation.name}/$buildTypeSubDirectory/$kindSubDirectory")
} }
private fun Project. klibOutputDirectory( private fun Project.klibOutputDirectory(
compilation: KotlinNativeCompilation compilation: KotlinNativeCompilation
): File { ): File {
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty() val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
@@ -653,7 +654,9 @@ open class KotlinNativeTargetConfigurator(
val compileOnlyDependencies = target.compilations.mapNotNull { val compileOnlyDependencies = target.compilations.mapNotNull {
val dependencies = configurations.getByName(it.compileOnlyConfigurationName).allDependencies val dependencies = configurations.getByName(it.compileOnlyConfigurationName).allDependencies
if (dependencies.isNotEmpty()) {it to dependencies} else null if (dependencies.isNotEmpty()) {
it to dependencies
} else null
} }
fun Dependency.stringCoordinates(): String = buildString { fun Dependency.stringCoordinates(): String = buildString {
@@ -666,13 +669,15 @@ open class KotlinNativeTargetConfigurator(
with(target.project.logger) { with(target.project.logger) {
warn("A compileOnly dependency is used in the Kotlin/Native target '${target.name}':") warn("A compileOnly dependency is used in the Kotlin/Native target '${target.name}':")
compileOnlyDependencies.forEach { compileOnlyDependencies.forEach {
warn(""" warn(
"""
Compilation: ${it.first.name} Compilation: ${it.first.name}
Dependencies: Dependencies:
${it.second.joinToString(separator = "\n") { it.stringCoordinates() }} ${it.second.joinToString(separator = "\n") { it.stringCoordinates() }}
""".trimIndent()) """.trimIndent()
)
} }
warn("Such dependencies are not applicable for Kotlin/Native, consider changing the dependency type to 'implementation' or 'api'.") warn("Such dependencies are not applicable for Kotlin/Native, consider changing the dependency type to 'implementation' or 'api'.")
} }
@@ -24,19 +24,19 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.utils.checkedReflection import org.jetbrains.kotlin.gradle.utils.checkedReflection
import java.io.File import java.io.File
internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools) internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools) :
: AbstractAndroidProjectHandler<BaseVariantData<out BaseVariantOutputData>>(kotlinConfigurationTools) { AbstractAndroidProjectHandler<BaseVariantData<out BaseVariantOutputData>>(kotlinConfigurationTools) {
override fun getSourceProviders(variantData: BaseVariantData<out BaseVariantOutputData>): Iterable<SourceProvider> = override fun getSourceProviders(variantData: BaseVariantData<out BaseVariantOutputData>): Iterable<SourceProvider> =
variantData.sourceProviders variantData.sourceProviders
override fun getAllJavaSources(variantData: BaseVariantData<out BaseVariantOutputData>): Iterable<File> = override fun getAllJavaSources(variantData: BaseVariantData<out BaseVariantOutputData>): Iterable<File> =
AndroidGradleWrapper.getJavaSources(variantData) AndroidGradleWrapper.getJavaSources(variantData)
override fun forEachVariant(project: Project, action: (BaseVariantData<out BaseVariantOutputData>) -> Unit) { override fun forEachVariant(project: Project, action: (BaseVariantData<out BaseVariantOutputData>) -> Unit) {
val plugin = (project.plugins.findPlugin("android") val plugin = (project.plugins.findPlugin("android")
?: project.plugins.findPlugin("android-library") ?: project.plugins.findPlugin("android-library")
?: project.plugins.findPlugin("com.android.test")) as BasePlugin ?: project.plugins.findPlugin("com.android.test")) as BasePlugin
val variantManager = AndroidGradleWrapper.getVariantDataManager(plugin) val variantManager = AndroidGradleWrapper.getVariantDataManager(plugin)
variantManager.variantDataList.forEach(action) variantManager.variantDataList.forEach(action)
} }
@@ -76,36 +76,39 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
get() = get() =
checkedReflection(f@{ checkedReflection(f@{
val output = variantConfiguration.javaClass.methods.firstOrNull { it.name == "getOutput" } val output = variantConfiguration.javaClass.methods.firstOrNull { it.name == "getOutput" }
?.invoke(variantConfiguration) ?.invoke(variantConfiguration)
?: return@f null ?: return@f null
output.javaClass.methods?.firstOrNull { it.name == "getJarFile" } output.javaClass.methods?.firstOrNull { it.name == "getJarFile" }
?.invoke(output) as? File ?.invoke(output) as? File
}, { e: Exception -> }, { e: Exception ->
logger.kotlinDebug("dependencyJarOrNull for lib variant $name failed due to $e") logger.kotlinDebug("dependencyJarOrNull for lib variant $name failed due to $e")
null null
}) })
override fun getVariantName(variant: BaseVariantData<out BaseVariantOutputData>): String = variant.name override fun getVariantName(variant: BaseVariantData<out BaseVariantOutputData>): String = variant.name
override fun checkVariantIsValid(variant: BaseVariantData<out BaseVariantOutputData>): Unit { override fun checkVariantIsValid(variant: BaseVariantData<out BaseVariantOutputData>): Unit {
if (AndroidGradleWrapper.isJackEnabled(variant)) { if (AndroidGradleWrapper.isJackEnabled(variant)) {
throw ProjectConfigurationException( throw ProjectConfigurationException(
"Kotlin Gradle plugin does not support the deprecated Jack toolchain.\n" + "Kotlin Gradle plugin does not support the deprecated Jack toolchain.\n" +
"Disable Jack or revert to Kotlin Gradle plugin version 1.1.1.", null) "Disable Jack or revert to Kotlin Gradle plugin version 1.1.1.", null
)
} }
} }
override fun getJavaTask(variantData: BaseVariantData<out BaseVariantOutputData>): AbstractCompile? = override fun getJavaTask(variantData: BaseVariantData<out BaseVariantOutputData>): AbstractCompile? =
AndroidGradleWrapper.getJavaTask(variantData) AndroidGradleWrapper.getJavaTask(variantData)
override fun addJavaSourceDirectoryToVariantModel(variantData: BaseVariantData<out BaseVariantOutputData>, override fun addJavaSourceDirectoryToVariantModel(
javaSourceDirectory: File) = variantData: BaseVariantData<out BaseVariantOutputData>,
variantData.addJavaSourceFoldersToModel(javaSourceDirectory) javaSourceDirectory: File
) =
variantData.addJavaSourceFoldersToModel(javaSourceDirectory)
override fun getTestedVariantData(variantData: BaseVariantData<*>): BaseVariantData<*>? = override fun getTestedVariantData(variantData: BaseVariantData<*>): BaseVariantData<*>? =
((variantData as? TestVariantData)?.testedVariantData as? BaseVariantData<*>) ((variantData as? TestVariantData)?.testedVariantData as? BaseVariantData<*>)
override fun getResDirectories(variantData: BaseVariantData<out BaseVariantOutputData>): List<File> { override fun getResDirectories(variantData: BaseVariantData<out BaseVariantOutputData>): List<File> {
return variantData.mergeResourcesTask?.rawInputFolders?.toList() ?: emptyList() return variantData.mergeResourcesTask?.rawInputFolders?.toList() ?: emptyList()
@@ -114,16 +117,16 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
private val BaseVariantData<*>.sourceProviders: List<SourceProvider> private val BaseVariantData<*>.sourceProviders: List<SourceProvider>
get() = variantConfiguration.sortedSourceProviders get() = variantConfiguration.sortedSourceProviders
private inner class KaptLegacyVariantData(variantData: BaseVariantData<out BaseVariantOutputData>) private inner class KaptLegacyVariantData(variantData: BaseVariantData<out BaseVariantOutputData>) :
: KaptVariantData<BaseVariantData<out BaseVariantOutputData>>(variantData) { KaptVariantData<BaseVariantData<out BaseVariantOutputData>>(variantData) {
override val name: String = variantData.name override val name: String = variantData.name
override val sourceProviders: Iterable<SourceProvider> = getSourceProviders(variantData) override val sourceProviders: Iterable<SourceProvider> = getSourceProviders(variantData)
override fun addJavaSourceFoldersToModel(generatedFilesDir: File) = override fun addJavaSourceFoldersToModel(generatedFilesDir: File) =
addJavaSourceDirectoryToVariantModel(variantData, generatedFilesDir) addJavaSourceDirectoryToVariantModel(variantData, generatedFilesDir)
override val annotationProcessorOptions: Map<String, String>? = override val annotationProcessorOptions: Map<String, String>? =
AndroidGradleWrapper.getAnnotationProcessorOptionsFromAndroidVariant(variantData) AndroidGradleWrapper.getAnnotationProcessorOptionsFromAndroidVariant(variantData)
override fun registerGeneratedJavaSource( override fun registerGeneratedJavaSource(
project: Project, project: Project,
@@ -136,5 +139,5 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
override fun wrapVariantDataForKapt(variantData: BaseVariantData<out BaseVariantOutputData>) override fun wrapVariantDataForKapt(variantData: BaseVariantData<out BaseVariantOutputData>)
: KaptVariantData<BaseVariantData<out BaseVariantOutputData>> = : KaptVariantData<BaseVariantData<out BaseVariantOutputData>> =
KaptLegacyVariantData(variantData) KaptLegacyVariantData(variantData)
} }
@@ -21,20 +21,20 @@ import org.jetbrains.annotations.TestOnly
internal abstract class TaskToFriendTaskMapper { internal abstract class TaskToFriendTaskMapper {
operator fun get(task: Task): String? = operator fun get(task: Task): String? =
getFriendByName(task.name) getFriendByName(task.name)
@TestOnly @TestOnly
operator fun get(name: String): String? = operator fun get(name: String): String? =
getFriendByName(name) getFriendByName(name)
protected abstract fun getFriendByName(name: String): String? protected abstract fun getFriendByName(name: String): String?
} }
sealed internal class RegexTaskToFriendTaskMapper( sealed internal class RegexTaskToFriendTaskMapper(
private val prefix: String, private val prefix: String,
suffix: String, suffix: String,
private val targetName: String, private val targetName: String,
private val postfixReplacement: String private val postfixReplacement: String
) : TaskToFriendTaskMapper() { ) : TaskToFriendTaskMapper() {
class Default(targetName: String) : RegexTaskToFriendTaskMapper("compile", "TestKotlin", targetName, "Kotlin") class Default(targetName: String) : RegexTaskToFriendTaskMapper("compile", "TestKotlin", targetName, "Kotlin")
class Android(targetName: String) : RegexTaskToFriendTaskMapper("compile", "(Unit|Android)TestKotlin", targetName, "Kotlin") class Android(targetName: String) : RegexTaskToFriendTaskMapper("compile", "(Unit|Android)TestKotlin", targetName, "Kotlin")
@@ -150,7 +150,7 @@ object AndroidGradleWrapper {
val compileDependencies = variantDependency("getCompileDependencies") ?: return null val compileDependencies = variantDependency("getCompileDependencies") ?: return null
val result = compileDependencies("getDirectAndroidDependencies") // android >= 2.3 val result = compileDependencies("getDirectAndroidDependencies") // android >= 2.3
?: compileDependencies("getAndroidDependencies") // android 2.2 ?: compileDependencies("getAndroidDependencies") // android 2.2
return result as? Iterable<*> return result as? Iterable<*>
} }
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileTree
import org.gradle.api.internal.HasConvention import org.gradle.api.internal.HasConvention
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.plugins.ExtensionAware import org.gradle.api.plugins.ExtensionAware
@@ -56,10 +55,10 @@ internal inline fun <reified T : Any> Any.addConvention(name: String, plugin: T)
} }
internal inline fun <reified T : Any> Any.addExtension(name: String, extension: T) = internal inline fun <reified T : Any> Any.addExtension(name: String, extension: T) =
(this as ExtensionAware).extensions.add(name, extension) (this as ExtensionAware).extensions.add(name, extension)
internal fun Any.getConvention(name: String): Any? = internal fun Any.getConvention(name: String): Any? =
(this as HasConvention).convention.plugins[name] (this as HasConvention).convention.plugins[name]
internal fun Logger.kotlinInfo(message: String) { internal fun Logger.kotlinInfo(message: String) {
this.info("[KOTLIN] $message") this.info("[KOTLIN] $message")
@@ -22,7 +22,7 @@ open class DefaultCInteropSettings @Inject constructor(
override val compilation: KotlinNativeCompilation override val compilation: KotlinNativeCompilation
) : CInteropSettings { ) : CInteropSettings {
inner class DefaultIncludeDirectories: CInteropSettings.IncludeDirectories { inner class DefaultIncludeDirectories : CInteropSettings.IncludeDirectories {
var allHeadersDirs: FileCollection = project.files() var allHeadersDirs: FileCollection = project.files()
var headerFilterDirs: FileCollection = project.files() var headerFilterDirs: FileCollection = project.files()
@@ -59,8 +59,8 @@ open class DefaultCInteropSettings @Inject constructor(
var packageName: String? = null var packageName: String? = null
val compilerOpts = mutableListOf<String>() val compilerOpts = mutableListOf<String>()
val linkerOpts = mutableListOf<String>() val linkerOpts = mutableListOf<String>()
val extraOpts = mutableListOf<String>() val extraOpts = mutableListOf<String>()
val includeDirs = DefaultIncludeDirectories() val includeDirs = DefaultIncludeDirectories()
var headers: FileCollection = project.files() var headers: FileCollection = project.files()
@@ -10,7 +10,7 @@ import org.gradle.api.NamedDomainObjectFactory
import org.gradle.api.Project import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
interface KotlinCompilationFactory<T: KotlinCompilation> : NamedDomainObjectFactory<T> { interface KotlinCompilationFactory<T : KotlinCompilation> : NamedDomainObjectFactory<T> {
val itemClass: Class<T> val itemClass: Class<T>
} }
@@ -68,7 +68,7 @@ class KotlinJsCompilationFactory(
get() = KotlinJsCompilation::class.java get() = KotlinJsCompilation::class.java
override fun create(name: String): KotlinJsCompilation = override fun create(name: String): KotlinJsCompilation =
KotlinJsCompilation(target, name) KotlinJsCompilation(target, name)
} }
class KotlinNativeCompilationFactory( class KotlinNativeCompilationFactory(
@@ -98,7 +98,8 @@ private fun rewriteMppDependenciesToTargetModuleDependencies(
} }
) )
val resolvedCompileDependencies by lazy { // don't resolve if no project dependencies on MPP projects are found val resolvedCompileDependencies by lazy {
// don't resolve if no project dependencies on MPP projects are found
targetCompileDependenciesConfiguration.resolvedConfiguration.lenientConfiguration.allModuleDependencies.associateBy { targetCompileDependenciesConfiguration.resolvedConfiguration.lenientConfiguration.allModuleDependencies.associateBy {
Triple(it.moduleGroup, it.moduleName, it.moduleVersion) Triple(it.moduleGroup, it.moduleName, it.moduleVersion)
} }
@@ -11,7 +11,7 @@ object KotlinNativeUsage {
const val FRAMEWORK = "kotlin-native-framework" const val FRAMEWORK = "kotlin-native-framework"
} }
enum class NativeBuildType(val optimized: Boolean, val debuggable: Boolean): Named { enum class NativeBuildType(val optimized: Boolean, val debuggable: Boolean) : Named {
RELEASE(true, false), RELEASE(true, false),
DEBUG(false, true); DEBUG(false, true);
@@ -33,7 +33,7 @@ class DefaultKotlinCompilationOutput(
class KotlinWithJavaCompilationOutput( class KotlinWithJavaCompilationOutput(
internal val compilation: KotlinWithJavaCompilation internal val compilation: KotlinWithJavaCompilation
): KotlinCompilationOutput, Callable<FileCollection> { ) : KotlinCompilationOutput, Callable<FileCollection> {
private val javaSourceSetOutput private val javaSourceSetOutput
get() = compilation.javaSourceSet.output get() = compilation.javaSourceSet.output
@@ -43,13 +43,15 @@ class KotlinWithJavaCompilationOutput(
override var resourcesDirProvider: Any override var resourcesDirProvider: Any
get() = javaSourceSetOutput.resourcesDir get() = javaSourceSetOutput.resourcesDir
set(value) { javaSourceSetOutput.setResourcesDir(value) } set(value) {
javaSourceSetOutput.setResourcesDir(value)
}
override val classesDirs: ConfigurableFileCollection = override val classesDirs: ConfigurableFileCollection =
if (isGradleVersionAtLeast(4, 0)) if (isGradleVersionAtLeast(4, 0))
javaSourceSetOutput.classesDirs as ConfigurableFileCollection javaSourceSetOutput.classesDirs as ConfigurableFileCollection
else else
// In Gradle < 4.0 `SourceSetOutput` does not have `classesDirs` // In Gradle < 4.0 `SourceSetOutput` does not have `classesDirs`
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
compilation.target.project.files(Callable { javaSourceSetOutput.classesDir }) compilation.target.project.files(Callable { javaSourceSetOutput.classesDir })
@@ -11,10 +11,8 @@ import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.attributes.AttributeContainer import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileTree
import org.gradle.api.file.SourceDirectorySet import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetOutput
import org.gradle.util.ConfigureUtil import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
@@ -26,7 +24,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import java.io.File import java.io.File
import java.lang.IllegalArgumentException
import java.util.* import java.util.*
import java.util.concurrent.Callable import java.util.concurrent.Callable
@@ -327,11 +324,13 @@ class KotlinNativeCompilation(
} }
var entryPoint: String? = null var entryPoint: String? = null
fun entryPoint(value: String) { entryPoint = value } fun entryPoint(value: String) {
entryPoint = value
}
// Interop DSL. // Interop DSL.
val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName ->
DefaultCInteropSettings(project, cinteropName,this) DefaultCInteropSettings(project, cinteropName, this)
} }
var linkerOpts = mutableListOf<String>() var linkerOpts = mutableListOf<String>()
@@ -350,8 +349,8 @@ class KotlinNativeCompilation(
fun findLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeCompile? = binaryTasks[kind to buildType] fun findLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeCompile? = binaryTasks[kind to buildType]
fun getLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeCompile = fun getLinkTask(kind: NativeOutputKind, buildType: NativeBuildType): KotlinNativeCompile =
findLinkTask(kind, buildType) ?: findLinkTask(kind, buildType)
throw IllegalArgumentException("Cannot find a link task for the binary kind '$kind' and the build type '$buildType'") ?: throw IllegalArgumentException("Cannot find a link task for the binary kind '$kind' and the build type '$buildType'")
fun findLinkTask(kind: String, buildType: String) = fun findLinkTask(kind: String, buildType: String) =
findLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase())) findLinkTask(NativeOutputKind.valueOf(kind.toUpperCase()), NativeBuildType.valueOf(buildType.toUpperCase()))
@@ -194,7 +194,7 @@ class KotlinAndroidTargetPreset(
class KotlinJvmWithJavaTargetPreset( class KotlinJvmWithJavaTargetPreset(
private val project: Project, private val project: Project,
private val kotlinPluginVersion: String private val kotlinPluginVersion: String
): KotlinTargetPreset<KotlinWithJavaTarget> { ) : KotlinTargetPreset<KotlinWithJavaTarget> {
override fun getName(): String = PRESET_NAME override fun getName(): String = PRESET_NAME
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
abstract class AbstractKotlinTarget ( abstract class AbstractKotlinTarget(
final override val project: Project final override val project: Project
) : KotlinTarget { ) : KotlinTarget {
private val attributeContainer = HierarchyAttributeContainer(parent = null) private val attributeContainer = HierarchyAttributeContainer(parent = null)
@@ -156,8 +156,9 @@ open class KotlinWithJavaTarget(
get() = JavaPlugin.JAR_TASK_NAME get() = JavaPlugin.JAR_TASK_NAME
override val compilations: NamedDomainObjectContainer<KotlinWithJavaCompilation> = override val compilations: NamedDomainObjectContainer<KotlinWithJavaCompilation> =
project.container(KotlinWithJavaCompilation::class.java, project.container(
KotlinWithJavaCompilationFactory(project, this) KotlinWithJavaCompilation::class.java,
KotlinWithJavaCompilationFactory(project, this)
) )
} }
@@ -34,18 +34,17 @@ open class KotlinVariant(
open class KotlinVariantWithCoordinates( open class KotlinVariantWithCoordinates(
target: KotlinTarget target: KotlinTarget
) : KotlinVariant(target), ) : KotlinVariant(target),
ComponentWithCoordinates /* Gradle 4.7+ API, don't use with older versions */ ComponentWithCoordinates /* Gradle 4.7+ API, don't use with older versions */ {
{
override fun getCoordinates() = object : ModuleVersionIdentifier { override fun getCoordinates() = object : ModuleVersionIdentifier {
private val project get() = target.project private val project get() = target.project
private val moduleName: String get() = private val moduleName: String
publicationDelegate?.artifactId ?: get() =
"${project.name}-${target.name.toLowerCase()}" publicationDelegate?.artifactId ?: "${project.name}-${target.name.toLowerCase()}"
private val moduleGroup: String get() = private val moduleGroup: String
publicationDelegate?.groupId ?: get() =
project.group.toString() publicationDelegate?.groupId ?: project.group.toString()
override fun getGroup() = moduleGroup override fun getGroup() = moduleGroup
override fun getName() = moduleName override fun getName() = moduleName
@@ -58,13 +57,13 @@ open class KotlinVariantWithCoordinates(
} }
} }
class KotlinVariantWithMetadataVariant(target: KotlinTarget, private val metadataTarget: KotlinTarget) class KotlinVariantWithMetadataVariant(target: KotlinTarget, private val metadataTarget: KotlinTarget) :
: KotlinVariantWithCoordinates(target), ComponentWithVariants { KotlinVariantWithCoordinates(target), ComponentWithVariants {
override fun getVariants() = setOf(metadataTarget.component) override fun getVariants() = setOf(metadataTarget.component)
} }
class KotlinVariantWithMetadataDependency(target: KotlinTarget, private val metadataTarget: KotlinTarget) class KotlinVariantWithMetadataDependency(target: KotlinTarget, private val metadataTarget: KotlinTarget) :
: KotlinVariantWithCoordinates(target) { KotlinVariantWithCoordinates(target) {
override fun getUsages(): Set<UsageContext> = target.createUsageContexts().mapTo(mutableSetOf()) { usageContext -> override fun getUsages(): Set<UsageContext> = target.createUsageContexts().mapTo(mutableSetOf()) { usageContext ->
UsageContextWithAdditionalDependencies(usageContext, setOf(metadataDependency())) UsageContextWithAdditionalDependencies(usageContext, setOf(metadataDependency()))
} }
@@ -63,7 +63,8 @@ class DefaultKotlinSourceSet(
override val resources: SourceDirectorySet = createDefaultSourceDirectorySet(displayName + " resources", fileResolver) override val resources: SourceDirectorySet = createDefaultSourceDirectorySet(displayName + " resources", fileResolver)
override fun kotlin(configureClosure: Closure<Any?>): SourceDirectorySet = kotlin.apply { ConfigureUtil.configure(configureClosure, this) } override fun kotlin(configureClosure: Closure<Any?>): SourceDirectorySet =
kotlin.apply { ConfigureUtil.configure(configureClosure, this) }
override fun languageSettings(configureClosure: Closure<Any?>): LanguageSettingsBuilder = languageSettings.apply { override fun languageSettings(configureClosure: Closure<Any?>): LanguageSettingsBuilder = languageSettings.apply {
ConfigureUtil.configure(configureClosure, this) ConfigureUtil.configure(configureClosure, this)
@@ -33,7 +33,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
override var apiVersion: String? override var apiVersion: String?
get() = apiVersionImpl?.versionString get() = apiVersionImpl?.versionString
set(value) { set(value) {
apiVersionImpl = value ?.let { versionString -> apiVersionImpl = value?.let { versionString ->
parseApiVersionSettings(versionString) ?: throw InvalidUserDataException( parseApiVersionSettings(versionString) ?: throw InvalidUserDataException(
"Incorrect API version. Expected one of: ${apiVersionValues.joinToString { "'${it.versionString}'" }}" "Incorrect API version. Expected one of: ${apiVersionValues.joinToString { "'${it.versionString}'" }}"
) )
@@ -36,7 +36,7 @@ internal abstract class KotlinSourceSetFactory<T : KotlinSourceSet> internal con
defineSourceSetConfigurations(project, sourceSet) defineSourceSetConfigurations(project, sourceSet)
} }
private fun defineSourceSetConfigurations(project: Project, sourceSet: KotlinSourceSet) = with (project.configurations) { private fun defineSourceSetConfigurations(project: Project, sourceSet: KotlinSourceSet) = with(project.configurations) {
sourceSet.relatedConfigurationNames.forEach { configurationName -> sourceSet.relatedConfigurationNames.forEach { configurationName ->
maybeCreate(configurationName) maybeCreate(configurationName)
} }
@@ -12,12 +12,12 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension
import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector import org.jetbrains.kotlin.gradle.tasks.GradleMessageCollector
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.script.KotlinScriptDefinition import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptDefinitionsFromClasspathDiscoverySource import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptDefinitionsFromClasspathDiscoverySource
import kotlin.properties.Delegates import kotlin.properties.Delegates
@@ -129,7 +129,7 @@ class ScriptingKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
if (!ScriptingGradleSubplugin.isEnabled(project)) return emptyList() if (!ScriptingGradleSubplugin.isEnabled(project)) return emptyList()
val scriptingExtension = project.extensions.findByType(ScriptingExtension::class.java) val scriptingExtension = project.extensions.findByType(ScriptingExtension::class.java)
?: project.extensions.create("kotlinScripting", ScriptingExtension::class.java) ?: project.extensions.create("kotlinScripting", ScriptingExtension::class.java)
val options = mutableListOf<SubpluginOption>() val options = mutableListOf<SubpluginOption>()
@@ -27,15 +27,14 @@ internal fun isWorkerAPISupported(): Boolean =
gradleVersion >= GradleVersion.version("4.3") gradleVersion >= GradleVersion.version("4.3")
internal fun isBuildCacheEnabledForKotlin(): Boolean = internal fun isBuildCacheEnabledForKotlin(): Boolean =
isBuildCacheSupported() && isBuildCacheSupported() &&
System.getProperty(KOTLIN_CACHING_ENABLED_PROPERTY)?.toBoolean() ?: true System.getProperty(KOTLIN_CACHING_ENABLED_PROPERTY)?.toBoolean() ?: true
internal fun <T : Task> T.cacheOnlyIfEnabledForKotlin() { internal fun <T : Task> T.cacheOnlyIfEnabledForKotlin() {
// The `cacheIf` method may be missing if the Gradle version is too low: // The `cacheIf` method may be missing if the Gradle version is too low:
try { try {
outputsCompatible.cacheIf { isBuildCacheEnabledForKotlin() } outputsCompatible.cacheIf { isBuildCacheEnabledForKotlin() }
} } catch (_: NoSuchMethodError) {
catch (_: NoSuchMethodError) {
} }
} }
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.gradle.tasks package org.jetbrains.kotlin.gradle.tasks
import org.jetbrains.kotlin.gradle.plugin.SubpluginOption import org.jetbrains.kotlin.gradle.plugin.SubpluginOption
import java.io.File
class CompilerPluginOptions { class CompilerPluginOptions {
private val mutableArguments = arrayListOf<String>() private val mutableArguments = arrayListOf<String>()
@@ -37,13 +37,13 @@ internal open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompil
get() = kotlinOptionsImpl get() = kotlinOptionsImpl
override fun createCompilerArgs(): K2MetadataCompilerArguments = override fun createCompilerArgs(): K2MetadataCompilerArguments =
K2MetadataCompilerArguments() K2MetadataCompilerArguments()
override fun getSourceRoots(): SourceRoots = override fun getSourceRoots(): SourceRoots =
SourceRoots.KotlinOnly.create(getSource(), sourceFilesExtensions) SourceRoots.KotlinOnly.create(getSource(), sourceFilesExtensions)
override fun findKotlinCompilerClasspath(project: Project): List<File> = override fun findKotlinCompilerClasspath(project: Project): List<File> =
findKotlinMetadataCompilerClasspath(project) findKotlinMetadataCompilerClasspath(project)
override fun setupCompilerArgs(args: K2MetadataCompilerArguments, defaultsOnly: Boolean) { override fun setupCompilerArgs(args: K2MetadataCompilerArguments, defaultsOnly: Boolean) {
args.apply { fillDefaultValues() } args.apply { fillDefaultValues() }
@@ -66,8 +66,8 @@ open class KotlinJsDce : AbstractKotlinCompileTool<K2JSDceArguments>(), KotlinJs
@TaskAction @TaskAction
fun performDce() { fun performDce() {
val inputFiles = (listOf(getSource()) + classpath.map { project.fileTree(it) }) val inputFiles = (listOf(getSource()) + classpath.map { project.fileTree(it) })
.reduce(FileTree::plus) .reduce(FileTree::plus)
.files.map { it.path } .files.map { it.path }
val outputDirArgs = arrayOf("-output-dir", destinationDir.path) val outputDirArgs = arrayOf("-output-dir", destinationDir.path)
@@ -75,8 +75,10 @@ open class KotlinJsDce : AbstractKotlinCompileTool<K2JSDceArguments>(), KotlinJs
val log = GradleKotlinLogger(project.logger) val log = GradleKotlinLogger(project.logger)
val allArgs = argsArray + outputDirArgs + inputFiles val allArgs = argsArray + outputDirArgs + inputFiles
val exitCode = runToolInSeparateProcess(allArgs, K2JSDce::class.java.name, computedCompilerClasspath, val exitCode = runToolInSeparateProcess(
log, createLoggingMessageCollector(log)) allArgs, K2JSDce::class.java.name, computedCompilerClasspath,
log, createLoggingMessageCollector(log)
)
throwGradleExceptionIfError(exitCode) throwGradleExceptionIfError(exitCode)
} }
} }
@@ -164,10 +164,13 @@ open class KotlinNativeCompile : AbstractCompile() {
// Delegate for compilations's extra options. // Delegate for compilations's extra options.
override var freeCompilerArgs: List<String> override var freeCompilerArgs: List<String>
get() = compilation.extraOpts get() = compilation.extraOpts
set(value) { compilation.extraOpts = value.toMutableList() } set(value) {
compilation.extraOpts = value.toMutableList()
}
} }
@Internal val kotlinOptions: KotlinCommonToolOptions = NativeCompilerOpts() @Internal
val kotlinOptions: KotlinCommonToolOptions = NativeCompilerOpts()
fun kotlinOptions(fn: KotlinCommonToolOptions.() -> Unit) { fun kotlinOptions(fn: KotlinCommonToolOptions.() -> Unit) {
kotlinOptions.fn() kotlinOptions.fn()
@@ -204,9 +207,10 @@ open class KotlinNativeCompile : AbstractCompile() {
val compilerPluginOptions = CompilerPluginOptions() val compilerPluginOptions = CompilerPluginOptions()
val compilerPluginCommandLine val compilerPluginCommandLine
@Input get()= compilerPluginOptions.arguments @Input get() = compilerPluginOptions.arguments
@Optional @InputFiles @Optional
@InputFiles
var compilerPluginClasspath: FileCollection? = null var compilerPluginClasspath: FileCollection? = null
val serializedCompilerArguments: List<String> val serializedCompilerArguments: List<String>
@@ -297,7 +301,7 @@ open class KotlinNativeCompile : AbstractCompile() {
} }
} }
open class CInteropProcess: DefaultTask() { open class CInteropProcess : DefaultTask() {
@Internal @Internal
lateinit var settings: DefaultCInteropSettings lateinit var settings: DefaultCInteropSettings
@@ -13,7 +13,7 @@ import java.util.*
internal sealed class SourceRoots(val kotlinSourceFiles: List<File>) { internal sealed class SourceRoots(val kotlinSourceFiles: List<File>) {
private companion object { private companion object {
fun dumpPaths(files: Iterable<File>): String = fun dumpPaths(files: Iterable<File>): String =
"[${files.map { it.canonicalPath }.sorted().joinToString(prefix = "\n\t", separator = ",\n\t")}]" "[${files.map { it.canonicalPath }.sorted().joinToString(prefix = "\n\t", separator = ",\n\t")}]"
} }
open fun log(taskName: String, logger: Logger) { open fun log(taskName: String, logger: Logger) {
@@ -25,7 +25,8 @@ internal sealed class SourceRoots(val kotlinSourceFiles: List<File>) {
fun create(taskSource: FileTree, sourceRoots: FilteringSourceRootsContainer, sourceFilesExtensions: List<String>): ForJvm { fun create(taskSource: FileTree, sourceRoots: FilteringSourceRootsContainer, sourceFilesExtensions: List<String>): ForJvm {
val kotlinSourceFiles = (taskSource as Iterable<File>).filter { it.isKotlinFile(sourceFilesExtensions) } val kotlinSourceFiles = (taskSource as Iterable<File>).filter { it.isKotlinFile(sourceFilesExtensions) }
val javaSourceRoots = findRootsForSources( val javaSourceRoots = findRootsForSources(
sourceRoots.sourceRoots, taskSource.filter(File::isJavaFile)) sourceRoots.sourceRoots, taskSource.filter(File::isJavaFile)
)
return ForJvm(kotlinSourceFiles, javaSourceRoots) return ForJvm(kotlinSourceFiles, javaSourceRoots)
} }
@@ -60,7 +60,7 @@ internal open class SyncOutputTask : DefaultTask() {
// Marked as input to make Gradle fall back to non-incremental build when it changes. // Marked as input to make Gradle fall back to non-incremental build when it changes.
@get:Input @get:Input
protected val classesDirs: List<File> protected val classesDirs: List<File>
get() = listOf(kotlinOutputDir, kaptClassesDir).filter(File::exists) get() = listOf(kotlinOutputDir, kaptClassesDir).filter(File::exists)
@get:OutputDirectory @get:OutputDirectory
var javaOutputDir: File by Delegates.notNull() var javaOutputDir: File by Delegates.notNull()
@@ -108,8 +108,7 @@ internal open class SyncOutputTask : DefaultTask() {
logger.kotlinDebug { "Incremental copying files from $sourceDirs to $javaOutputDir" } logger.kotlinDebug { "Incremental copying files from $sourceDirs to $javaOutputDir" }
inputs.outOfDate { processIncrementally(it) } inputs.outOfDate { processIncrementally(it) }
inputs.removed { processIncrementally(it) } inputs.removed { processIncrementally(it) }
} } else {
else {
logger.kotlinDebug { "Non-incremental copying files from $sourceDirs to $javaOutputDir" } logger.kotlinDebug { "Non-incremental copying files from $sourceDirs to $javaOutputDir" }
processNonIncrementally() processNonIncrementally()
} }
@@ -143,8 +142,7 @@ internal open class SyncOutputTask : DefaultTask() {
if (input.isRemoved) { if (input.isRemoved) {
// file was removed in kotlin dir, remove from java as well // file was removed in kotlin dir, remove from java as well
remove(fileInJavaDir) remove(fileInJavaDir)
} } else {
else {
// copy modified or added file from kotlin to java // copy modified or added file from kotlin to java
copy(fileInKotlinDir, fileInJavaDir) copy(fileInKotlinDir, fileInJavaDir)
} }
@@ -203,8 +201,7 @@ private fun saveTimestamps(snapshotFile: File, timestamps: Map<File, Long>, file
if (!snapshotFile.exists()) { if (!snapshotFile.exists()) {
snapshotFile.parentFile.mkdirs() snapshotFile.parentFile.mkdirs()
snapshotFile.createNewFile() snapshotFile.createNewFile()
} } else {
else {
snapshotFile.delete() snapshotFile.delete()
} }
@@ -81,27 +81,28 @@ abstract class AbstractKotlinCompileTool<T : CommonToolArguments>() : AbstractCo
@get:Input @get:Input
internal var useFallbackCompilerSearch: Boolean = false internal var useFallbackCompilerSearch: Boolean = false
@get:Classpath @get:InputFiles @get:Classpath
@get:InputFiles
internal val computedCompilerClasspath: List<File> internal val computedCompilerClasspath: List<File>
get() = compilerClasspath?.takeIf { it.isNotEmpty() } get() = compilerClasspath?.takeIf { it.isNotEmpty() }
?: compilerJarFile?.let { ?: compilerJarFile?.let {
// a hack to remove compiler jar from the cp, will be dropped when compilerJarFile will be removed // a hack to remove compiler jar from the cp, will be dropped when compilerJarFile will be removed
listOf(it) + findKotlinCompilerClasspath(project).filter { !it.name.startsWith("kotlin-compiler") } listOf(it) + findKotlinCompilerClasspath(project).filter { !it.name.startsWith("kotlin-compiler") }
}
?: if (!useFallbackCompilerSearch) {
try {
project.configurations.getByName(COMPILER_CLASSPATH_CONFIGURATION_NAME).resolve().toList()
} catch (e: Exception) {
project.logger.error(
"Could not resolve compiler classpath. " +
"Check if Kotlin Gradle plugin repository is configured in $project."
)
throw e
} }
?: if (!useFallbackCompilerSearch) { } else {
try { findKotlinCompilerClasspath(project)
project.configurations.getByName(COMPILER_CLASSPATH_CONFIGURATION_NAME).resolve().toList() }
} catch (e: Exception) { ?: throw IllegalStateException("Could not find Kotlin Compiler classpath")
project.logger.error(
"Could not resolve compiler classpath. " +
"Check if Kotlin Gradle plugin repository is configured in $project."
)
throw e
}
} else {
findKotlinCompilerClasspath(project)
}
?: throw IllegalStateException("Could not find Kotlin Compiler classpath")
protected abstract fun findKotlinCompilerClasspath(project: Project): List<File> protected abstract fun findKotlinCompilerClasspath(project: Project): List<File>
@@ -129,7 +130,8 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
} }
@get:Internal @get:Internal
internal val buildHistoryFile: File get() = File(taskBuildDirectory, "build-history.bin") internal val buildHistoryFile: File
get() = File(taskBuildDirectory, "build-history.bin")
@get:Input @get:Input
internal var useModuleDetection: Boolean = false internal var useModuleDetection: Boolean = false
@@ -146,13 +148,14 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
@get:Internal @get:Internal
internal val pluginOptions = CompilerPluginOptions() internal val pluginOptions = CompilerPluginOptions()
@get:Classpath @get:InputFiles @get:Classpath
@get:InputFiles
protected val additionalClasspath = arrayListOf<File>() protected val additionalClasspath = arrayListOf<File>()
@get:Internal // classpath already participates in the checks @get:Internal // classpath already participates in the checks
internal val compileClasspath: Iterable<File> internal val compileClasspath: Iterable<File>
get() = (classpath + additionalClasspath) get() = (classpath + additionalClasspath)
.filterTo(LinkedHashSet(), File::exists) .filterTo(LinkedHashSet(), File::exists)
private val sourceFilesExtensionsSources: MutableList<Iterable<String>> = mutableListOf() private val sourceFilesExtensionsSources: MutableList<Iterable<String>> = mutableListOf()
@@ -165,7 +168,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
} }
private val kotlinExt: KotlinProjectExtension private val kotlinExt: KotlinProjectExtension
get() = project.extensions.findByType(KotlinProjectExtension::class.java)!! get() = project.extensions.findByType(KotlinProjectExtension::class.java)!!
private lateinit var destinationDirProvider: Lazy<File> private lateinit var destinationDirProvider: Lazy<File>
@@ -186,12 +189,12 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
// Input is needed to force rebuild even if source files are not changed // Input is needed to force rebuild even if source files are not changed
@get:Input @get:Input
internal val coroutinesStr: String internal val coroutinesStr: String
get() = coroutines.name get() = coroutines.name
private val coroutines: Coroutines private val coroutines: Coroutines
get() = kotlinExt.experimental.coroutines get() = kotlinExt.experimental.coroutines
?: coroutinesFromGradleProperties ?: coroutinesFromGradleProperties
?: Coroutines.DEFAULT ?: Coroutines.DEFAULT
@get:Internal @get:Internal
internal var friendTaskName: String? = null internal var friendTaskName: String? = null
@@ -210,7 +213,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
internal val moduleName: String internal val moduleName: String
get() { get() {
val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName
?: project.name ?: project.name
val suffix = if (sourceSetName == "main") "" else "_$sourceSetName" val suffix = if (sourceSetName == "main") "" else "_$sourceSetName"
return filterModuleName("${baseName}$suffix") return filterModuleName("${baseName}$suffix")
} }
@@ -218,7 +221,7 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@get:Internal @get:Internal
internal val friendTask: AbstractKotlinCompile<T>? internal val friendTask: AbstractKotlinCompile<T>?
get() = friendTaskName?.let { project.tasks.findByName(it) } as? AbstractKotlinCompile<T> get() = friendTaskName?.let { project.tasks.findByName(it) } as? AbstractKotlinCompile<T>
/** Classes directories that are not produced by this task but should be consumed by /** Classes directories that are not produced by this task but should be consumed by
* other tasks that have this one as a [friendTask]. */ * other tasks that have this one as a [friendTask]. */
@@ -338,10 +341,10 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
} }
override fun findKotlinCompilerClasspath(project: Project): List<File> = override fun findKotlinCompilerClasspath(project: Project): List<File> =
findKotlinJvmCompilerClasspath(project) findKotlinJvmCompilerClasspath(project)
override fun createCompilerArgs(): K2JVMCompilerArguments = override fun createCompilerArgs(): K2JVMCompilerArguments =
K2JVMCompilerArguments() K2JVMCompilerArguments()
override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) { override fun setupCompilerArgs(args: K2JVMCompilerArguments, defaultsOnly: Boolean) {
args.apply { fillDefaultValues() } args.apply { fillDefaultValues() }
@@ -386,13 +389,13 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
else -> { else -> {
logger.info(USING_INCREMENTAL_COMPILATION_MESSAGE) logger.info(USING_INCREMENTAL_COMPILATION_MESSAGE)
GradleIncrementalCompilerEnvironment( GradleIncrementalCompilerEnvironment(
computedCompilerClasspath, computedCompilerClasspath,
if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(), if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(),
taskBuildDirectory, taskBuildDirectory,
messageCollector, outputItemCollector, args, messageCollector, outputItemCollector, args,
usePreciseJavaTracking = usePreciseJavaTracking, usePreciseJavaTracking = usePreciseJavaTracking,
localStateDirs = outputDirectories, localStateDirs = outputDirectories,
multiModuleICSettings = multiModuleICSettings multiModuleICSettings = multiModuleICSettings
) )
} }
} }
@@ -413,8 +416,7 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
disableMultiModuleICIfNeeded() disableMultiModuleICIfNeeded()
processCompilerExitCode(exitCode) processCompilerExitCode(exitCode)
} } catch (e: Throwable) {
catch (e: Throwable) {
cleanupOnError() cleanupOnError()
throw e throw e
} }
@@ -471,7 +473,7 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
private val kotlinOptionsImpl = KotlinJsOptionsImpl() private val kotlinOptionsImpl = KotlinJsOptionsImpl()
override val kotlinOptions: KotlinJsOptions override val kotlinOptions: KotlinJsOptions
get() = kotlinOptionsImpl get() = kotlinOptionsImpl
private val defaultOutputFile: File private val defaultOutputFile: File
get() = File(destinationDir, "$moduleName.js") get() = File(destinationDir, "$moduleName.js")
@@ -482,10 +484,10 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
get() = kotlinOptions.outputFile?.let(::File) ?: defaultOutputFile get() = kotlinOptions.outputFile?.let(::File) ?: defaultOutputFile
override fun findKotlinCompilerClasspath(project: Project): List<File> = override fun findKotlinCompilerClasspath(project: Project): List<File> =
findKotlinJsCompilerClasspath(project) findKotlinJsCompilerClasspath(project)
override fun createCompilerArgs(): K2JSCompilerArguments = override fun createCompilerArgs(): K2JSCompilerArguments =
K2JSCompilerArguments() K2JSCompilerArguments()
override fun setupCompilerArgs(args: K2JSCompilerArguments, defaultsOnly: Boolean) { override fun setupCompilerArgs(args: K2JSCompilerArguments, defaultsOnly: Boolean) {
args.apply { fillDefaultValues() } args.apply { fillDefaultValues() }
@@ -505,10 +507,10 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
@get:PathSensitive(PathSensitivity.RELATIVE) @get:PathSensitive(PathSensitivity.RELATIVE)
internal val friendDependency internal val friendDependency
get() = friendTaskName get() = friendTaskName
?.let { project.getTasksByName(it, false).singleOrNull() as? Kotlin2JsCompile } ?.let { project.getTasksByName(it, false).singleOrNull() as? Kotlin2JsCompile }
?.outputFile?.parentFile ?.outputFile?.parentFile
?.let { if (LibraryUtils.isKotlinJavascriptLibrary(it)) it else null } ?.let { if (LibraryUtils.isKotlinJavascriptLibrary(it)) it else null }
?.absolutePath ?.absolutePath
override fun callCompiler(args: K2JSCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) { override fun callCompiler(args: K2JSCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
sourceRoots as SourceRoots.KotlinOnly sourceRoots as SourceRoots.KotlinOnly
@@ -517,8 +519,8 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
destinationDir.mkdirs() destinationDir.mkdirs()
val dependencies = compileClasspath val dependencies = compileClasspath
.filter { LibraryUtils.isKotlinJavascriptLibrary(it) } .filter { LibraryUtils.isKotlinJavascriptLibrary(it) }
.map { it.canonicalPath } .map { it.canonicalPath }
args.libraries = (dependencies + listOfNotNull(friendDependency)).distinct().let { args.libraries = (dependencies + listOfNotNull(friendDependency)).distinct().let {
if (it.isNotEmpty()) if (it.isNotEmpty())
@@ -542,13 +544,13 @@ open class Kotlin2JsCompile() : AbstractKotlinCompile<K2JSCompilerArguments>(),
incremental -> { incremental -> {
logger.warn(USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE) logger.warn(USING_EXPERIMENTAL_JS_INCREMENTAL_COMPILATION_MESSAGE)
GradleIncrementalCompilerEnvironment( GradleIncrementalCompilerEnvironment(
computedCompilerClasspath, computedCompilerClasspath,
if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(), if (hasFilesInTaskBuildDirectory()) changedFiles else ChangedFiles.Unknown(),
taskBuildDirectory, taskBuildDirectory,
messageCollector, messageCollector,
outputItemCollector, outputItemCollector,
args, args,
multiModuleICSettings = multiModuleICSettings multiModuleICSettings = multiModuleICSettings
) )
} }
else -> { else -> {
@@ -601,7 +603,7 @@ internal class GradleMessageCollector(val logger: Logger) : MessageCollector {
when (severity) { when (severity) {
CompilerMessageSeverity.ERROR, CompilerMessageSeverity.ERROR,
CompilerMessageSeverity.EXCEPTION -> { CompilerMessageSeverity.EXCEPTION -> {
hasErrors = true hasErrors = true
logger.error(formatMsg("e")) logger.error(formatMsg("e"))
} }
@@ -48,34 +48,34 @@ private val KOTLIN_SCRIPT_JVM = "kotlin-scripting-jvm"
private val KOTLIN_REFLECT = "kotlin-reflect" private val KOTLIN_REFLECT = "kotlin-reflect"
internal fun findKotlinJvmCompilerClasspath(project: Project): List<File> = internal fun findKotlinJvmCompilerClasspath(project: Project): List<File> =
findKotlinModuleJar(project, K2JVM_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let { findKotlinModuleJar(project, K2JVM_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let {
if (it.isEmpty()) it if (it.isEmpty()) it
else it + findKotlinStdlibClasspath(project) + findKotlinScriptRuntimeClasspath(project) + findKotlinReflectClasspath(project) else it + findKotlinStdlibClasspath(project) + findKotlinScriptRuntimeClasspath(project) + findKotlinReflectClasspath(project)
} }
internal fun findKotlinJsCompilerClasspath(project: Project): List<File> = internal fun findKotlinJsCompilerClasspath(project: Project): List<File> =
findKotlinModuleJar(project, K2JS_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let { findKotlinModuleJar(project, K2JS_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let {
if (it.isEmpty()) it if (it.isEmpty()) it
else it + findKotlinStdlibClasspath(project) + findKotlinScriptRuntimeClasspath(project) + findKotlinReflectClasspath(project) else it + findKotlinStdlibClasspath(project) + findKotlinScriptRuntimeClasspath(project) + findKotlinReflectClasspath(project)
} }
internal fun findKotlinMetadataCompilerClasspath(project: Project): List<File> = internal fun findKotlinMetadataCompilerClasspath(project: Project): List<File> =
findKotlinModuleJar(project, K2METADATA_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let { findKotlinModuleJar(project, K2METADATA_COMPILER_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let {
if (it.isEmpty()) it if (it.isEmpty()) it
else it + findKotlinStdlibClasspath(project) + findKotlinScriptRuntimeClasspath(project) + findKotlinReflectClasspath(project) else it + findKotlinStdlibClasspath(project) + findKotlinScriptRuntimeClasspath(project) + findKotlinReflectClasspath(project)
} }
internal fun findKotlinJsDceClasspath(project: Project): List<File> = internal fun findKotlinJsDceClasspath(project: Project): List<File> =
findKotlinModuleJar(project, K2JS_DCE_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let { findKotlinModuleJar(project, K2JS_DCE_CLASS, KOTLIN_COMPILER_EMBEDDABLE).let {
if (it.isEmpty()) it if (it.isEmpty()) it
else it + findKotlinStdlibClasspath(project) + findKotlinScriptRuntimeClasspath(project) + findKotlinReflectClasspath(project) else it + findKotlinStdlibClasspath(project) + findKotlinScriptRuntimeClasspath(project) + findKotlinReflectClasspath(project)
} }
internal fun findKotlinStdlibClasspath(project: Project): List<File> = internal fun findKotlinStdlibClasspath(project: Project): List<File> =
findKotlinModuleJar(project, KOTLIN_STDLIB_EXPECTED_CLASS, KOTLIN_STDLIB) findKotlinModuleJar(project, KOTLIN_STDLIB_EXPECTED_CLASS, KOTLIN_STDLIB)
internal fun findKotlinScriptRuntimeClasspath(project: Project): List<File> = internal fun findKotlinScriptRuntimeClasspath(project: Project): List<File> =
findKotlinModuleJar(project, KOTLIN_SCRIPT_RUNTIME_EXPECTED_CLASS, KOTLIN_SCRIPT_RUNTIME) findKotlinModuleJar(project, KOTLIN_SCRIPT_RUNTIME_EXPECTED_CLASS, KOTLIN_SCRIPT_RUNTIME)
internal fun findKotlinScriptCommonClasspath(project: Project): List<File> = internal fun findKotlinScriptCommonClasspath(project: Project): List<File> =
findKotlinModuleJar(project, KOTLIN_SCRIPT_ANNOTATION_EXPECTED_CLASS, KOTLIN_SCRIPT_COMMON) findKotlinModuleJar(project, KOTLIN_SCRIPT_ANNOTATION_EXPECTED_CLASS, KOTLIN_SCRIPT_COMMON)
@@ -84,7 +84,7 @@ internal fun findKotlinScriptJvmClasspath(project: Project): List<File> =
findKotlinModuleJar(project, KOTLIN_JVM_SCRIPT_COMPILER_EXPECTED_CLASS, KOTLIN_SCRIPT_JVM) findKotlinModuleJar(project, KOTLIN_JVM_SCRIPT_COMPILER_EXPECTED_CLASS, KOTLIN_SCRIPT_JVM)
internal fun findKotlinReflectClasspath(project: Project): List<File> = internal fun findKotlinReflectClasspath(project: Project): List<File> =
findKotlinModuleJar(project, KOTLIN_REFLECT_EXPECTED_CLASS, KOTLIN_REFLECT) findKotlinModuleJar(project, KOTLIN_REFLECT_EXPECTED_CLASS, KOTLIN_REFLECT)
internal fun findToolsJar(): File? { internal fun findToolsJar(): File? {
val javacUtilContextClass = val javacUtilContextClass =
@@ -127,27 +127,27 @@ private fun findKotlinModuleJar(project: Project, expectedClassName: String, mod
val pluginVersion = pluginVersionFromAppliedPlugin(project) val pluginVersion = pluginVersionFromAppliedPlugin(project)
val filesToCheck = sequenceOf(pluginVersion?.let { version -> getModuleFromClassLoader(moduleId, version) }) + val filesToCheck = sequenceOf(pluginVersion?.let { version -> getModuleFromClassLoader(moduleId, version) }) +
Sequence { findPotentialModuleJars(project, moduleId).iterator() } //call the body only when queried Sequence { findPotentialModuleJars(project, moduleId).iterator() } //call the body only when queried
val entryToFind = expectedClassName.replace(".", "/") + ".class" val entryToFind = expectedClassName.replace(".", "/") + ".class"
return filesToCheck.filterNotNull().firstOrNull { it.hasEntry(entryToFind) }?.let { listOf(it) } ?: emptyList() return filesToCheck.filterNotNull().firstOrNull { it.hasEntry(entryToFind) }?.let { listOf(it) } ?: emptyList()
} }
private fun pluginVersionFromAppliedPlugin(project: Project): String? = private fun pluginVersionFromAppliedPlugin(project: Project): String? =
project.plugins.filterIsInstance<KotlinBasePluginWrapper>().firstOrNull()?.kotlinPluginVersion project.plugins.filterIsInstance<KotlinBasePluginWrapper>().firstOrNull()?.kotlinPluginVersion
private fun getModuleFromClassLoader(moduleId: String, moduleVersion: String): File? { private fun getModuleFromClassLoader(moduleId: String, moduleVersion: String): File? {
val urlClassLoader = KotlinPlugin::class.java.classLoader as? URLClassLoader ?: return null val urlClassLoader = KotlinPlugin::class.java.classLoader as? URLClassLoader ?: return null
return urlClassLoader.urLs return urlClassLoader.urLs
.firstOrNull { it.toString().endsWith("$moduleId-$moduleVersion.jar") } .firstOrNull { it.toString().endsWith("$moduleId-$moduleVersion.jar") }
?.let { File(it.toURI()) } ?.let { File(it.toURI()) }
?.takeIf(File::exists) ?.takeIf(File::exists)
} }
private fun findPotentialModuleJars(project: Project, moduleId: String): Iterable<File> { private fun findPotentialModuleJars(project: Project, moduleId: String): Iterable<File> {
val projects = generateSequence(project) { it.parent } val projects = generateSequence(project) { it.parent }
val classpathConfigurations = projects val classpathConfigurations = projects
.map { it.buildscript.configurations.findByName(ScriptHandler.CLASSPATH_CONFIGURATION) } .map { it.buildscript.configurations.findByName(ScriptHandler.CLASSPATH_CONFIGURATION) }
.filterNotNull() .filterNotNull()
val allFiles = HashSet<File>() val allFiles = HashSet<File>()
@@ -156,8 +156,7 @@ private fun findPotentialModuleJars(project: Project, moduleId: String): Iterabl
if (compilerEmbeddable != null) { if (compilerEmbeddable != null) {
return compilerEmbeddable.moduleArtifacts.map { it.file } return compilerEmbeddable.moduleArtifacts.map { it.file }
} } else {
else {
allFiles.addAll(configuration.files) allFiles.addAll(configuration.files)
} }
} }
@@ -167,7 +166,7 @@ private fun findPotentialModuleJars(project: Project, moduleId: String): Iterabl
private fun findKotlinModuleDependency(configuration: Configuration, moduleId: String): ResolvedDependency? { private fun findKotlinModuleDependency(configuration: Configuration, moduleId: String): ResolvedDependency? {
fun Iterable<ResolvedDependency>.findDependency(group: String, name: String): ResolvedDependency? = fun Iterable<ResolvedDependency>.findDependency(group: String, name: String): ResolvedDependency? =
find { it.moduleGroup == group && it.moduleName == name } find { it.moduleGroup == group && it.moduleName == name }
val firstLevelModuleDependencies = configuration.resolvedConfiguration.firstLevelModuleDependencies val firstLevelModuleDependencies = configuration.resolvedConfiguration.firstLevelModuleDependencies
val gradlePlugin = firstLevelModuleDependencies.findDependency(KOTLIN_MODULE_GROUP, KOTLIN_GRADLE_PLUGIN) val gradlePlugin = firstLevelModuleDependencies.findDependency(KOTLIN_MODULE_GROUP, KOTLIN_GRADLE_PLUGIN)
@@ -179,11 +178,9 @@ private fun File.hasEntry(entryToFind: String): Boolean {
try { try {
return zip.getEntry(entryToFind) != null return zip.getEntry(entryToFind) != null
} } catch (e: Exception) {
catch (e: Exception) {
return false return false
} } finally {
finally {
zip.close() zip.close()
} }
} }
@@ -2,21 +2,18 @@ package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.GradleException import org.gradle.api.GradleException
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.tasks.OutputDirectory
import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.utils.outputsCompatible import org.jetbrains.kotlin.gradle.utils.outputsCompatible
import java.io.File import java.io.File
import kotlin.reflect.KProperty1
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.memberProperties
fun throwGradleExceptionIfError(exitCode: ExitCode) { fun throwGradleExceptionIfError(exitCode: ExitCode) {
when (exitCode) { when (exitCode) {
ExitCode.COMPILATION_ERROR -> throw GradleException("Compilation error. See log for more details") ExitCode.COMPILATION_ERROR -> throw GradleException("Compilation error. See log for more details")
ExitCode.INTERNAL_ERROR -> throw GradleException("Internal compiler error. See log for more details") ExitCode.INTERNAL_ERROR -> throw GradleException("Internal compiler error. See log for more details")
ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException("Script execution error. See log for more details") ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException("Script execution error. See log for more details")
ExitCode.OK -> {} ExitCode.OK -> {
}
else -> throw IllegalStateException("Unexpected exit code: $exitCode") else -> throw IllegalStateException("Unexpected exit code: $exitCode")
} }
} }
@@ -10,7 +10,8 @@ import org.gradle.api.artifacts.repositories.ArtifactRepository
import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout import org.gradle.api.artifacts.repositories.IvyPatternRepositoryLayout
import org.gradle.api.file.FileTree import org.gradle.api.file.FileTree
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.jetbrains.kotlin.compilerRunner.* import org.jetbrains.kotlin.compilerRunner.KonanCompilerRunner
import org.jetbrains.kotlin.compilerRunner.konanVersion
import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.KonanVersionImpl import org.jetbrains.kotlin.konan.KonanVersionImpl
import org.jetbrains.kotlin.konan.MetaVersion import org.jetbrains.kotlin.konan.MetaVersion
@@ -28,21 +28,20 @@ internal data class ParsedGradleVersion(val major: Int, val minor: Int) : Compar
companion object { companion object {
private fun String.parseIntOrNull(): Int? = private fun String.parseIntOrNull(): Int? =
try { try {
toInt() toInt()
} } catch (e: NumberFormatException) {
catch (e: NumberFormatException) { null
null }
}
fun parse(version: String): ParsedGradleVersion? { fun parse(version: String): ParsedGradleVersion? {
val matches = "(\\d+)\\.(\\d+).*" val matches = "(\\d+)\\.(\\d+).*"
.toRegex() .toRegex()
.find(version) .find(version)
?.groups ?.groups
?.drop(1)?.take(2) ?.drop(1)?.take(2)
// checking if two subexpression groups are found and length of each is >0 and <4 // checking if two subexpression groups are found and length of each is >0 and <4
?.let { if (it.all { (it?.value?.length ?: 0).let { it > 0 && it < 4 }}) it else null } ?.let { if (it.all { (it?.value?.length ?: 0).let { it > 0 && it < 4 } }) it else null }
val versions = matches?.mapNotNull { it?.value?.parseIntOrNull() } ?: emptyList() val versions = matches?.mapNotNull { it?.value?.parseIntOrNull() } ?: emptyList()
if (versions.size == 2 && versions.all { it >= 0 }) { if (versions.size == 2 && versions.all { it >= 0 }) {
@@ -56,5 +55,5 @@ internal data class ParsedGradleVersion(val major: Int, val minor: Int) : Compar
} }
fun isGradleVersionAtLeast(major: Int, minor: Int) = fun isGradleVersionAtLeast(major: Int, minor: Int) =
ParsedGradleVersion.parse(GradleVersion.current().version) ParsedGradleVersion.parse(GradleVersion.current().version)
?.let { it >= ParsedGradleVersion(major, minor) } ?: false ?.let { it >= ParsedGradleVersion(major, minor) } ?: false
@@ -33,14 +33,11 @@ internal fun Class<*>.getDeclaredFieldInHierarchy(name: String): Field? {
internal inline fun <T> checkedReflection(block: () -> T, onReflectionException: (Exception) -> T): T { internal inline fun <T> checkedReflection(block: () -> T, onReflectionException: (Exception) -> T): T {
return try { return try {
block() block()
} } catch (e: InvocationTargetException) {
catch (e: InvocationTargetException) {
throw e.targetException throw e.targetException
} } catch (e: ReflectiveOperationException) {
catch (e: ReflectiveOperationException) {
onReflectionException(e) onReflectionException(e)
} } catch (e: IllegalArgumentException) {
catch (e: IllegalArgumentException) {
onReflectionException(e) onReflectionException(e)
} }
} }
@@ -20,4 +20,4 @@ import java.util.*
// Based on com.intellij.openapi.util.SystemInfoRt from Intellij platform // Based on com.intellij.openapi.util.SystemInfoRt from Intellij platform
internal val isWindows: Boolean = internal val isWindows: Boolean =
System.getProperty("os.name")?.toLowerCase(Locale.US)?.startsWith("windows") ?: false System.getProperty("os.name")?.toLowerCase(Locale.US)?.startsWith("windows") ?: false
@@ -9,11 +9,12 @@ class KotlinJvmOptionsTest {
fun testFreeArguments() { fun testFreeArguments() {
val options = KotlinJvmOptionsImpl() val options = KotlinJvmOptionsImpl()
options.freeCompilerArgs = listOf( options.freeCompilerArgs = listOf(
"-Xreport-perf", "-Xreport-perf",
"-Xallow-kotlin-package", "-Xallow-kotlin-package",
"-Xmultifile-parts-inherit", "-Xmultifile-parts-inherit",
"-Xdump-declarations-to", "declarationsPath", "-Xdump-declarations-to", "declarationsPath",
"-script-templates", "a,b,c") "-script-templates", "a,b,c"
)
val arguments = K2JVMCompilerArguments() val arguments = K2JVMCompilerArguments()
options.updateArguments(arguments) options.updateArguments(arguments)