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

org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTargetConfigurator.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * Copyright 2010-2021 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.targets.js.ir

import org.gradle.api.InvalidUserDataException
import org.gradle.api.attributes.Usage
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Zip
import org.jetbrains.kotlin.gradle.dsl.KotlinJsOptions
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
import org.jetbrains.kotlin.gradle.testing.testTaskName
import org.jetbrains.kotlin.gradle.utils.isParentOf
import org.jetbrains.kotlin.gradle.utils.klibModuleName
import java.io.File

open class KotlinJsIrTargetConfigurator() :
    KotlinOnlyTargetConfigurator(true, true),
    KotlinTargetWithTestsConfigurator {

    override val testRunClass: Class get() = KotlinJsReportAggregatingTestRun::class.java

    override val archiveType: String
        get() = KLIB_TYPE

    override fun createTestRun(
        name: String,
        target: KotlinJsIrTarget
    ): KotlinJsReportAggregatingTestRun {
        val result = KotlinJsReportAggregatingTestRun(name, target)

        val testTask = target.project.kotlinTestRegistry.getOrCreateAggregatedTestTask(
            name = result.testTaskName,
            description = "Run JS tests for all platforms"
        )

        // workaround to avoid the infinite recursion in item factories of the target and the subtargets:
        target.testRuns.matching { it.name == name }.whenObjectAdded {
            it.configureAllExecutions {
                // do not do anything with the aggregated test run, but ensure that they are created
            }
        }

        result.executionTask = testTask

        return result
    }

    override fun buildCompilationProcessor(compilation: KotlinJsIrCompilation): KotlinSourceSetProcessor<*> {
        val tasksProvider = KotlinTasksProvider()
        return KotlinJsIrSourceSetProcessor(tasksProvider, compilation)
    }

    override fun createArchiveTasks(target: KotlinJsIrTarget): TaskProvider {
        return super.createArchiveTasks(target).apply {
            configure { it.archiveExtension.set(KLIB_TYPE) }
        }
    }

    override fun configureCompilations(target: KotlinJsIrTarget) {
        super.configureCompilations(target)

        target.compilations.all { compilation ->
            compilation.kotlinOptions {
                configureOptions()

                var produceUnzippedKlib = isProduceUnzippedKlib()
                val produceZippedKlib = isProduceZippedKlib()

                freeCompilerArgs = freeCompilerArgs + DISABLE_PRE_IR

                val isMainCompilation = compilation.isMain()

                if (!produceUnzippedKlib && !produceZippedKlib) {
                    freeCompilerArgs = freeCompilerArgs + PRODUCE_UNZIPPED_KLIB
                    produceUnzippedKlib = true
                }

                // Configure FQ module name to avoid cyclic dependencies in klib manifests (see KT-36721).
                val baseName = if (isMainCompilation) {
                    target.project.name
                } else {
                    "${target.project.name}_${compilation.name}"
                }

                compilation.compileKotlinTaskProvider.configure { task ->
                    val outputFilePath = outputFile ?: if (produceUnzippedKlib) {
                        task.destinationDir.absoluteFile.normalize().absolutePath
                    } else {
                        File(task.destinationDir, "$baseName.$KLIB_TYPE").absoluteFile.normalize().absolutePath
                    }
                    outputFile = outputFilePath

                    val taskOutputDir = if (produceUnzippedKlib) File(outputFilePath) else File(outputFilePath).parentFile
                    if (taskOutputDir.isParentOf(task.project.rootDir))
                        throw InvalidUserDataException(
                            "The output directory '$taskOutputDir' (defined by outputFile of $task) contains or " +
                                    "matches the project root directory '${task.project.rootDir}'.\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."
                        )

                    task.destinationDir = taskOutputDir
                }

                val klibModuleName = target.project.klibModuleName(baseName)
                freeCompilerArgs = freeCompilerArgs + "$MODULE_NAME=$klibModuleName"
            }

            compilation.binaries
                .withType(JsIrBinary::class.java)
                .all { binary ->
                    binary.linkTask.configure { linkTask ->
                        linkTask.kotlinOptions.configureOptions()

                        val rootDir = binary.project.rootDir
                        linkTask.kotlinOptions.freeCompilerArgs += listOf(
                            "-source-map-base-dirs",
                            rootDir.absolutePath
                        )

                        linkTask.kotlinOptions.freeCompilerArgs += listOf(
                            "-source-map-prefix",
                            rootDir.toRelativeString(binary.compilation.npmProject.dist) + File.separator
                        )
                    }
                }
        }
    }

    private fun KotlinJsOptions.configureOptions() {
        moduleKind = "umd"
        sourceMap = true
        sourceMapEmbedSources = "never"
    }

    override fun defineConfigurationsForTarget(target: KotlinJsIrTarget) {
        super.defineConfigurationsForTarget(target)
        implementationToApiElements(target)

        if (target.isMpp!!) return

        target.project.configurations.maybeCreate(
            target.commonFakeApiElementsConfigurationName
        ).apply {
            description = "Common Fake API elements for main."
            isVisible = false
            isCanBeResolved = false
            isCanBeConsumed = true
            attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
            attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy