All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.gradle.internal.CompilerArgumentsContributor.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.gradle.internal

import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileArgumentsProvider
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompilerArgumentsProvider
import org.jetbrains.kotlin.gradle.utils.toPathsArray
import org.jetbrains.kotlin.incremental.classpathAsList
import org.jetbrains.kotlin.incremental.destinationAsFile

internal interface CompilerArgumentsContributor {
    fun contributeArguments(
        args: T,
        flags: Collection
    )
}

internal interface CompilerArgumentsConfigurationFlag

internal object DefaultsOnly : CompilerArgumentsConfigurationFlag
internal object IgnoreClasspathResolutionErrors : CompilerArgumentsConfigurationFlag

internal fun compilerArgumentsConfigurationFlags(defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) =
    mutableSetOf().apply {
        if (defaultsOnly) add(DefaultsOnly)
        if (ignoreClasspathResolutionErrors) add(IgnoreClasspathResolutionErrors)
    }

/** The primary purpose of this class is to encapsulate compiler arguments setup done by the AbstractKotlinCompiler tasks,
 * but outside the tasks, so that this state & logic can be reused without referencing the task directly. */
internal open class AbstractKotlinCompileArgumentsContributor(
    // Don't save this reference into a property! That would be hostile to Gradle instant execution
    taskProvider: KotlinCompileArgumentsProvider>
) : CompilerArgumentsContributor {

    private val coroutines = taskProvider.coroutines
    protected val logger = taskProvider.logger
    private val isMultiplatform = taskProvider.isMultiplatform
    private val pluginClasspath = taskProvider.pluginClasspath
    private val pluginOptions = taskProvider.pluginOptions

    override fun contributeArguments(
        args: T,
        flags: Collection
    ) {
        if (logger.isDebugEnabled) {
            args.verbose = true
        }

        args.multiPlatform = isMultiplatform

        setupPlugins(args)
    }

    internal fun setupPlugins(compilerArgs: T) {
        compilerArgs.pluginClasspaths = pluginClasspath.toPathsArray()
        compilerArgs.pluginOptions = pluginOptions.arguments.toTypedArray()
    }
}

internal open class KotlinJvmCompilerArgumentsContributor(
    // Don't save this reference into a property! That would be hostile to Gradle instant execution. Only map it to the task properties.
    taskProvider: KotlinJvmCompilerArgumentsProvider
) : AbstractKotlinCompileArgumentsContributor(taskProvider) {

    private val moduleName = taskProvider.moduleName
    private val friendPaths = taskProvider.friendPaths
    private val compileClasspath = taskProvider.compileClasspath
    private val destinationDir = taskProvider.destinationDir
    private val kotlinOptions = taskProvider.kotlinOptions

    override fun contributeArguments(
        args: K2JVMCompilerArguments,
        flags: Collection
    ) {
        args.fillDefaultValues()

        super.contributeArguments(args, flags)

        args.moduleName = moduleName
        logger.kotlinDebug { "args.moduleName = ${args.moduleName}" }

        args.friendPaths = friendPaths.files.map { it.absolutePath }.toTypedArray()
        logger.kotlinDebug { "args.friendPaths = ${args.friendPaths?.joinToString() ?: "[]"}" }

        if (DefaultsOnly in flags) return

        args.allowNoSourceFiles = true
        args.classpathAsList = try {
            compileClasspath.toList().filter { it.exists() }
        } catch (e: Exception) {
            if (IgnoreClasspathResolutionErrors in flags) emptyList() else throw(e)
        }
        args.destinationAsFile = destinationDir

        warnJdkHomeNotUsed(kotlinOptions)

        kotlinOptions.forEach { it.updateArguments(args) }
    }

    private fun warnJdkHomeNotUsed(kotlinOptions: List) {
        kotlinOptions
            .firstOrNull {
                @Suppress("DEPRECATION")
                it.jdkHome != null
            }
            ?.run {
                logger.warn(
                    """
                    'kotlinOptions.jdkHome' is deprecated and will be ignored in Kotlin 1.7! 
                    
                    Consider using JavaToolchain on Gradle 6.7+:
                    kotlin {
                        jvmToolchain {
                            languageVersion.set(JavaLanguageVersion.of())
                        }
                    }
                    
                    Or on older versions of Gradle:
                    - Kotlin DSL:
                    project.tasks
                        .withType()
                        .configureEach {
                            it.kotlinJavaToolchain.jdk.use(
                                "/path/to/your/jdk",
                                JavaVersion.
                            )
                        }
                    - Groovy DSL
                    project.tasks
                        .withType(UsesKotlinJavaToolchain.class)
                        .configureEach {
                             it.kotlinJavaToolchain.jdk.use(
                                 '/path/to/your/jdk',
                                 JavaVersion.
                             )
                        }
                    """.trimIndent()
                )
            }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy