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

org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-RC
Show newest version
/*
 * Copyright 2010-2023 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.plugin

import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.ContributeCompilerArgumentsContext
import kotlin.reflect.KClass
import kotlin.reflect.cast

@InternalKotlinGradlePluginApi
interface KotlinCompilerArgumentsProducer {

    enum class ArgumentType {
        Primitive,
        PluginClasspath,
        DependencyClasspath,
        Sources;

        companion object {
            val all = values().toSet()
        }
    }

    interface CreateCompilerArgumentsContext {
        fun  create(type: KClass, action: ContributeCompilerArgumentsContext.() -> Unit): T

        companion object {
            val default: CreateCompilerArgumentsContext = CreateCompilerArgumentsContext()
            val lenient: CreateCompilerArgumentsContext = CreateCompilerArgumentsContext(isLenient = true)

            inline fun  CreateCompilerArgumentsContext.create(
                noinline action: ContributeCompilerArgumentsContext.() -> Unit
            ) = create(T::class, action)
        }
    }

    interface ContributeCompilerArgumentsContext {
        /**
         * This method shall be used for any [action] used to build arguments, that could potentially throw an exception
         * (like resolving dependencies). There are some scenarios (like IDE import), where we want to be lenient
         * and provide arguments on a 'best effort bases'.
         */
        fun  runSafe(action: () -> T): T?
        fun primitive(contribution: (args: T) -> Unit)
        fun pluginClasspath(contribution: (args: T) -> Unit)
        fun dependencyClasspath(contribution: (args: T) -> Unit)
        fun sources(contribution: (args: T) -> Unit)
    }

    fun createCompilerArguments(
        context: CreateCompilerArgumentsContext = CreateCompilerArgumentsContext.default
    ): CommonToolArguments
}

internal fun CreateCompilerArgumentsContext(
    includeArgumentTypes: Set = KotlinCompilerArgumentsProducer.ArgumentType.all,
    isLenient: Boolean = false
): KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext {
    return CreateCompilerArgumentsContextImpl(includeArgumentTypes, isLenient)
}

private class CreateCompilerArgumentsContextImpl(
    private val includeArgumentTypes: Set,
    private val isLenient: Boolean
) : KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext {

    override fun  create(
        type: KClass, action: ContributeCompilerArgumentsContext.() -> Unit
    ): T {
        val constructor = type.java.constructors.firstOrNull { it.parameters.isEmpty() }
            ?: throw IllegalArgumentException("'${type.qualifiedName}' does not have an empty constructor")
        val arguments = type.cast(constructor.newInstance())
        ContributeCompilerArgumentsContextImpl(arguments, includeArgumentTypes, isLenient).also(action)
        return arguments
    }

    private class ContributeCompilerArgumentsContextImpl(
        private val arguments: T,
        private val includedArgumentTypes: Set,
        private val isLenient: Boolean
    ) : ContributeCompilerArgumentsContext {

        private inline fun applyContribution(contribution: (args: T) -> Unit) {
            try {
                contribution(arguments)
            } catch (t: Throwable) {
                if (!isLenient) throw t
            }
        }

        override fun  runSafe(action: () -> T): T? {
            return try {
                action()
            } catch (t: Throwable) {
                if (isLenient) null else throw t
            }
        }

        override fun primitive(contribution: (args: T) -> Unit) {
            if (KotlinCompilerArgumentsProducer.ArgumentType.Primitive in includedArgumentTypes) {
                applyContribution(contribution)
            }
        }

        override fun pluginClasspath(contribution: (args: T) -> Unit) {
            if (KotlinCompilerArgumentsProducer.ArgumentType.PluginClasspath in includedArgumentTypes) {
                applyContribution(contribution)
            }
        }

        override fun dependencyClasspath(contribution: (args: T) -> Unit) {
            if (KotlinCompilerArgumentsProducer.ArgumentType.DependencyClasspath in includedArgumentTypes) {
                applyContribution(contribution)
            }
        }

        override fun sources(contribution: (args: T) -> Unit) {
            if (KotlinCompilerArgumentsProducer.ArgumentType.Sources in includedArgumentTypes) {
                applyContribution(contribution)
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy