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

org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * Copyright 2010-2018 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.dsl

import org.gradle.api.*
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterFinaliseDsl
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.targetHierarchy.KotlinTargetHierarchyDslImpl
import javax.inject.Inject

abstract class KotlinMultiplatformExtension(project: Project) :
    KotlinProjectExtension(project),
    KotlinTargetContainerWithPresetFunctions,
    KotlinTargetContainerWithJsPresetFunctions,
    KotlinTargetContainerWithWasmPresetFunctions,
    KotlinTargetContainerWithNativeShortcuts {
    override val presets: NamedDomainObjectCollection> = project.container(KotlinTargetPreset::class.java)

    final override val targets: NamedDomainObjectCollection = project.container(KotlinTarget::class.java)

    internal suspend fun awaitTargets(): NamedDomainObjectCollection {
        AfterFinaliseDsl.await()
        return targets
    }

    override val compilerTypeFromProperties: KotlinJsCompilerType? = project.kotlinPropertiesProvider.jsCompiler

    private val presetExtension = project.objects.newInstance(
        DefaultTargetsFromPresetExtension::class.java,
        { this },
        targets
    )

    fun targets(configure: Action) {
        configure.execute(presetExtension)
    }

    fun targets(configure: TargetsFromPresetExtension.() -> Unit) {
        configure(presetExtension)
    }

    internal val internalKotlinTargetHierarchy by lazy {
        KotlinTargetHierarchyDslImpl(targets, sourceSets)
    }

    @ExperimentalKotlinGradlePluginApi
    val targetHierarchy: KotlinTargetHierarchyDsl get() = internalKotlinTargetHierarchy

    @Suppress("unused") // DSL
    val testableTargets: NamedDomainObjectCollection>
        get() = targets.withType(KotlinTargetWithTests::class.java)

    fun metadata(configure: KotlinOnlyTarget>.() -> Unit = { }): KotlinOnlyTarget> =
        @Suppress("UNCHECKED_CAST")
        (targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) as KotlinOnlyTarget>).also(configure)

    fun metadata(configure: Action>>) = metadata { configure.execute(this) }

    fun withSourcesJar(publish: Boolean = true) {
        targets.all { it.withSourcesJar(publish) }
    }

    fun  targetFromPreset(
        preset: KotlinTargetPreset,
        name: String = preset.name,
        configure: T.() -> Unit = { },
    ): T = configureOrCreate(name, preset, configure)

    fun  targetFromPreset(
        preset: KotlinTargetPreset,
        name: String,
        configure: Action,
    ) = targetFromPreset(preset, name) { configure.execute(this) }

    fun  targetFromPreset(preset: KotlinTargetPreset) = targetFromPreset(preset, preset.name) { }
    fun  targetFromPreset(preset: KotlinTargetPreset, name: String) = targetFromPreset(preset, name) { }
    fun  targetFromPreset(preset: KotlinTargetPreset, configure: Action) =
        targetFromPreset(preset, preset.name, configure)

    internal val rootSoftwareComponent: KotlinSoftwareComponent by lazy {
        KotlinSoftwareComponentWithCoordinatesAndPublication(project, "kotlin", targets)
    }
}

interface TargetsFromPresetExtension : NamedDomainObjectCollection {

    fun  fromPreset(
        preset: KotlinTargetPreset,
        name: String,
        configureAction: T.() -> Unit = {},
    ): T

    fun  fromPreset(
        preset: KotlinTargetPreset,
        name: String,
    ): T = fromPreset(preset, name, {})

    fun  fromPreset(
        preset: KotlinTargetPreset,
        name: String,
        configureAction: Action,
    ): T
}

internal abstract class DefaultTargetsFromPresetExtension @Inject constructor(
    private val targetsContainer: () -> KotlinTargetsContainerWithPresets,
    val targets: NamedDomainObjectCollection,
) : TargetsFromPresetExtension,
    NamedDomainObjectCollection by targets {

    override fun  fromPreset(
        preset: KotlinTargetPreset,
        name: String,
        configureAction: T.() -> Unit,
    ): T = targetsContainer().configureOrCreate(name, preset, configureAction)

    override fun  fromPreset(
        preset: KotlinTargetPreset,
        name: String,
        configureAction: Action,
    ) = fromPreset(preset, name) {
        configureAction.execute(this)
    }
}

internal fun KotlinTarget.isProducedFromPreset(kotlinTargetPreset: KotlinTargetPreset<*>): Boolean =
    preset == kotlinTargetPreset

internal fun  KotlinTargetsContainerWithPresets.configureOrCreate(
    targetName: String,
    targetPreset: KotlinTargetPreset,
    configure: T.() -> Unit,
): T {
    val existingTarget = targets.findByName(targetName)
    when {
        existingTarget?.isProducedFromPreset(targetPreset) ?: false -> {
            @Suppress("UNCHECKED_CAST")
            configure(existingTarget as T)
            return existingTarget
        }

        existingTarget == null -> {
            val newTarget = targetPreset.createTarget(targetName)
            targets.add(newTarget)
            configure(newTarget)
            return newTarget
        }

        else -> {
            throw InvalidUserCodeException(
                "The target '$targetName' already exists, but it was not created with the '${targetPreset.name}' preset. " +
                        "To configure it, access it by name in `kotlin.targets`" +
                        (" or use the preset function '${existingTarget.preset?.name}'."
                            .takeIf { existingTarget.preset != null } ?: ".")
            )
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy