From c31f91c28a8d1f563290018827125249ef1dc641 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Wed, 14 Dec 2016 17:34:03 +0300 Subject: [PATCH] Introduce Gradle multiplatform plugin --- .../kotlin/gradle/KotlinGradlePluginIT.kt | 22 ++++ .../multiplatformProject/build.gradle | 16 +++ .../multiplatformProject/lib/build.gradle | 1 + .../lib/src/main/kotlin/PlatformClass.kt | 5 + .../lib/src/test/kotlin/PlatformTest.kt | 5 + .../multiplatformProject/libJs/build.gradle | 5 + .../libJs/src/main/kotlin/PlatformClass.kt | 5 + .../libJs/src/test/kotlin/PlatformTest.kt | 5 + .../multiplatformProject/libJvm/build.gradle | 6 + .../libJvm/src/main/kotlin/PlatformClass.kt | 5 + .../libJvm/src/main/kotlin/javaLibUse.kt | 7 ++ .../libJvm/src/test/kotlin/PlatformTest.kt | 5 + .../multiplatformProject/settings.gradle | 1 + .../plugin/KotlinMultiplatformPlugin.kt | 113 ++++++++++++++++++ .../kotlin/gradle/plugin/KotlinPlugin.kt | 37 ++++++ .../gradle/plugin/KotlinPluginWrapper.kt | 5 + .../gradle/plugin/TaskToFriendTaskMapper.kt | 1 + .../gradle/tasks/KotlinCompileCommon.kt | 50 ++++++++ .../kotlin/gradle/tasks/TasksProvider.kt | 11 ++ .../kotlin-platform-common.properties | 1 + .../kotlin-platform-js.properties | 1 + .../kotlin-platform-jvm.properties | 1 + 22 files changed, 308 insertions(+) create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/src/main/kotlin/PlatformClass.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/src/test/kotlin/PlatformTest.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/src/main/kotlin/PlatformClass.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/src/test/kotlin/PlatformTest.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/main/kotlin/PlatformClass.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/main/kotlin/javaLibUse.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/test/kotlin/PlatformTest.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/settings.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformPlugin.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-common.properties create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-js.properties create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-jvm.properties diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt index dd568189aa0..d2de8b9546c 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt @@ -291,4 +291,26 @@ class KotlinGradleIT: BaseGradleIT() { assertSuccessful() } } + + + @Test + fun testMultiplatformCompile() { + val project = Project("multiplatformProject", GRADLE_VERSION) + + project.build("build") { + assertSuccessful() + assertContains(":lib:compileKotlinCommon", + ":lib:compileTestKotlinCommon", + ":libJvm:compileKotlin", + ":libJvm:compileTestKotlin", + ":libJs:compileKotlin2Js", + ":libJs:compileTestKotlin2Js") + assertFileExists("lib/build/classes/main/foo/PlatformClass.kotlin_metadata") + assertFileExists("lib/build/classes/test/foo/PlatformTest.kotlin_metadata") + assertFileExists("libJvm/build/classes/main/foo/PlatformClass.class") + assertFileExists("libJvm/build/classes/test/foo/PlatformTest.class") + assertFileExists("libJs/build/classes/main/libJs_main.js") + assertFileExists("libJs/build/classes/test/libJs_test.js") + } + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/build.gradle new file mode 100644 index 00000000000..478f50872b3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/build.gradle @@ -0,0 +1,16 @@ +buildscript { + repositories { + mavenLocal() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + mavenLocal() + jcenter() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/build.gradle new file mode 100644 index 00000000000..48e89733657 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/build.gradle @@ -0,0 +1 @@ +apply plugin: 'kotlin-platform-common' diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/src/main/kotlin/PlatformClass.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/src/main/kotlin/PlatformClass.kt new file mode 100644 index 00000000000..8c90b64b3b4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/src/main/kotlin/PlatformClass.kt @@ -0,0 +1,5 @@ +package foo + +header class PlatformClass { + val value: String +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/src/test/kotlin/PlatformTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/src/test/kotlin/PlatformTest.kt new file mode 100644 index 00000000000..198abbd3a89 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/lib/src/test/kotlin/PlatformTest.kt @@ -0,0 +1,5 @@ +package foo + +header class PlatformTest { + //val value: PlatformClass +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/build.gradle new file mode 100644 index 00000000000..39d39f6489e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/build.gradle @@ -0,0 +1,5 @@ +apply plugin: 'kotlin-platform-js' + +dependencies { + implement project(":lib") +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/src/main/kotlin/PlatformClass.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/src/main/kotlin/PlatformClass.kt new file mode 100644 index 00000000000..c4c8fd17a8f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/src/main/kotlin/PlatformClass.kt @@ -0,0 +1,5 @@ +package foo + +impl class PlatformClass { + impl val value: String = "JS" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/src/test/kotlin/PlatformTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/src/test/kotlin/PlatformTest.kt new file mode 100644 index 00000000000..0bffae06946 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJs/src/test/kotlin/PlatformTest.kt @@ -0,0 +1,5 @@ +package foo + +impl class PlatformTest { + //impl val value: PlatformClass = PlatformClass() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/build.gradle new file mode 100644 index 00000000000..55e087896da --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/build.gradle @@ -0,0 +1,6 @@ +apply plugin: 'kotlin-platform-jvm' + +dependencies { + implement project(":lib") + compile 'com.google.guava:guava:20.0' +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/main/kotlin/PlatformClass.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/main/kotlin/PlatformClass.kt new file mode 100644 index 00000000000..c615b4ecd12 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/main/kotlin/PlatformClass.kt @@ -0,0 +1,5 @@ +package foo + +impl class PlatformClass { + impl val value: String = "JVM" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/main/kotlin/javaLibUse.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/main/kotlin/javaLibUse.kt new file mode 100644 index 00000000000..c48348ed34e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/main/kotlin/javaLibUse.kt @@ -0,0 +1,7 @@ +package foo + +import com.google.common.collect.ImmutableSet + +fun main(args: Array) { + val colors = ImmutableSet.of("red", "orange", "yellow") +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/test/kotlin/PlatformTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/test/kotlin/PlatformTest.kt new file mode 100644 index 00000000000..0bffae06946 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/libJvm/src/test/kotlin/PlatformTest.kt @@ -0,0 +1,5 @@ +package foo + +impl class PlatformTest { + //impl val value: PlatformClass = PlatformClass() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/settings.gradle new file mode 100644 index 00000000000..daa61d91f69 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/multiplatformProject/settings.gradle @@ -0,0 +1 @@ +include ':lib', ':libJvm', ':libJs' \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformPlugin.kt new file mode 100644 index 00000000000..5439a9cfc8c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinMultiplatformPlugin.kt @@ -0,0 +1,113 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.GradleException +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.ProjectDependency +import org.gradle.api.file.SourceDirectorySet +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.SourceSetContainer +import org.jetbrains.kotlin.gradle.dsl.KotlinCompile +import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile + +abstract class KotlinPlatformPluginBase(protected val platformName: String) : Plugin + +open class KotlinPlatformCommonPlugin : KotlinPlatformPluginBase("common") { + override fun apply(project: Project) { + project.applyPlugin() + } +} + +open class KotlinPlatformImplementationPluginBase(platformName: String) : KotlinPlatformPluginBase(platformName) { + private val commonProjects = arrayListOf() + private val platformSourceSets = hashMapOf() + + override fun apply(project: Project) { + project.tasks.withType(AbstractKotlinCompile::class.java).all { + (it as KotlinCompile<*>).kotlinOptions.freeCompilerArgs += listOf("-Xmulti-platform") + } + + project.sourceSets.associateByTo(platformSourceSets, SourceSet::getName) + + val implementConfig = project.configurations.create("implement") + implementConfig.isTransitive = false + implementConfig.dependencies.whenObjectAdded { dep -> + if (dep is ProjectDependency) { + addCommonProject(dep.dependencyProject, project) + } + else { + throw GradleException("$project `implement` dependency is not a project: $dep") + } + } + } + + private fun addCommonProject(commonProject: Project, platformProject: Project) { + commonProjects.add(commonProject) + if (commonProjects.size > 1) { + throw GradleException("Platform project $platformProject implements more than one common project: ${commonProjects.joinToString()}") + } + + commonProject.whenEvaluated { + if ((!commonProject.plugins.hasPlugin(KotlinPlatformCommonPlugin::class.java))) { + throw GradleException("Platform project $platformProject implements non-common project $commonProject (`apply plugin 'kotlin-platform-kotlin'`)") + } + + commonProject.sourceSets.all { commonSourceSet -> + // todo: warn if not found + val platformSourceSet = platformSourceSets[commonSourceSet.name] + val platformKotlinSourceDirectorySet = platformSourceSet?.kotlin + commonSourceSet.kotlin?.srcDirs?.forEach { platformKotlinSourceDirectorySet?.srcDir(it) } + } + } + } + + private val SourceSet.kotlin: SourceDirectorySet? + get() = ((getConvention("kotlin") ?: getConvention("kotlin2js")) as? KotlinSourceSet)?.kotlin +} + +open class KotlinPlatformJvmPlugin : KotlinPlatformImplementationPluginBase("jvm") { + override fun apply(project: Project) { + project.applyPlugin() + super.apply(project) + } +} + +open class KotlinPlatformJsPlugin : KotlinPlatformImplementationPluginBase("js") { + override fun apply(project: Project) { + project.applyPlugin() + super.apply(project) + } +} + +private val Project.sourceSets: SourceSetContainer + get() = convention.getPlugin(JavaPluginConvention::class.java).sourceSets + +private fun Project.whenEvaluated(fn: Project.()->T) { + if (state.executed) { + fn() + } + else { + afterEvaluate { it.fn() } + } +} + +private inline fun > Project.applyPlugin() { + pluginManager.apply(T::class.java) +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index f93616072f8..058cfcfc28e 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -209,6 +209,35 @@ internal class Kotlin2JsSourceSetProcessor( } } +internal class KotlinCommonSourceSetProcessor( + project: Project, + javaBasePlugin: JavaBasePlugin, + sourceSet: SourceSet, + tasksProvider: KotlinTasksProvider, + kotlinSourceSetProvider: KotlinSourceSetProvider +) : KotlinSourceSetProcessor( + project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider, + dslExtensionName = KOTLIN_DSL_NAME, + taskDescription = "Compiles the kotlin sources in $sourceSet to Metadata.", + compileTaskNameSuffix = "kotlinCommon" +) { + override fun doTargetSpecificProcessing() { + project.afterEvaluate { project -> + kotlinTask.source(kotlinSourceSet.kotlin) + project.tasks.findByName(sourceSet.classesTaskName).dependsOn(kotlinTask) + // can be missing (e.g. in case of tests) + project.tasks.findByName(sourceSet.jarTaskName)?.dependsOn(kotlinTask) + val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName) + project.tasks.remove(javaTask) + } + } + + override val defaultKotlinDestinationDir: File + get() = sourceSet.output.classesDir + + override fun doCreateTask(project: Project, taskName: String): KotlinCompileCommon = + tasksProvider.createKotlinCommonTask(project, taskName, sourceSet.name) +} internal abstract class AbstractKotlinPlugin( val tasksProvider: KotlinTasksProvider, @@ -252,6 +281,14 @@ internal open class KotlinPlugin( } } +internal open class KotlinCommonPlugin( + tasksProvider: KotlinTasksProvider, + kotlinSourceSetProvider: KotlinSourceSetProvider, + kotlinPluginVersion: String +) : AbstractKotlinPlugin(tasksProvider, kotlinSourceSetProvider, kotlinPluginVersion) { + override fun buildSourceSetProcessor(project: Project, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet, kotlinPluginVersion: String) = + KotlinCommonSourceSetProcessor(project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider) +} internal open class Kotlin2JsPlugin( tasksProvider: KotlinTasksProvider, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index 2db2768531b..bace148f722 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -48,6 +48,11 @@ open class KotlinPluginWrapper @Inject constructor(fileResolver: FileResolver): KotlinPlugin(KotlinTasksProvider(), KotlinSourceSetProviderImpl(fileResolver), kotlinPluginVersion, kotlinGradleBuildServices) } +open class KotlinCommonPluginWrapper @Inject constructor(fileResolver: FileResolver): KotlinBasePluginWrapper(fileResolver) { + override fun getPlugin(kotlinGradleBuildServices: KotlinGradleBuildServices) = + KotlinCommonPlugin(KotlinCommonTasksProvider(), KotlinSourceSetProviderImpl(fileResolver), kotlinPluginVersion) +} + open class KotlinAndroidPluginWrapper @Inject constructor(fileResolver: FileResolver): KotlinBasePluginWrapper(fileResolver) { override fun getPlugin(kotlinGradleBuildServices: KotlinGradleBuildServices) = KotlinAndroidPlugin(AndroidTasksProvider(), KotlinSourceSetProviderImpl(fileResolver), kotlinPluginVersion, kotlinGradleBuildServices) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/TaskToFriendTaskMapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/TaskToFriendTaskMapper.kt index f7eb31e1db2..66b52e07b3b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/TaskToFriendTaskMapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/TaskToFriendTaskMapper.kt @@ -37,6 +37,7 @@ sealed internal class RegexTaskToFriendTaskMapper( ) : TaskToFriendTaskMapper() { class Default : RegexTaskToFriendTaskMapper("compile", "TestKotlin", "Kotlin") class JavaScript : RegexTaskToFriendTaskMapper("compile", "TestKotlin2Js", "Kotlin2Js") + class Common : RegexTaskToFriendTaskMapper("compile", "TestKotlinCommon", "KotlinCommon") class Android : RegexTaskToFriendTaskMapper("compile", "(Unit|Android)TestKotlin", "Kotlin") private val regex = "$prefix(.*)$suffix".toRegex() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt new file mode 100644 index 00000000000..1bd6e1536a6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle.tasks + +import org.gradle.api.tasks.compile.AbstractCompile +import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments +import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler +import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.incremental.ChangedFiles +import java.io.File + +internal open class KotlinCompileCommon : AbstractKotlinCompile() { + override val compiler = K2MetadataCompiler() + + override fun populateCompilerArguments(): K2MetadataCompilerArguments = + K2MetadataCompilerArguments() + + override fun getSourceRoots(): SourceRoots = + SourceRoots.KotlinOnly.create(getSource()) + + override fun callCompiler(args: K2MetadataCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) { + val classpathList = classpath.files.toMutableList() + val friendTask = friendTaskName?.let { project.tasks.findByName(it) } as? AbstractCompile + friendTask?.let { classpathList.add(it.destinationDir) } + + with(args) { + classpath = classpathList.joinToString(File.pathSeparator) + destination = destinationDir.canonicalPath + freeArgs = sourceRoots.kotlinSourceFiles.map { it.canonicalPath } + } + + val messageCollector = GradleMessageCollector(project.logger) + val exitCode = compiler.exec(messageCollector, Services.EMPTY, args) + throwGradleExceptionIfError(exitCode) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt index 1bf5f658205..a3115d75bcf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt @@ -37,10 +37,21 @@ internal open class KotlinTasksProvider { friendTaskName = taskToFriendTaskMapper[this] } + fun createKotlinCommonTask(project: Project, name: String, sourceSetName: String): KotlinCompileCommon = + project.tasks.create(name, KotlinCompileCommon::class.java).apply { + this.sourceSetName = sourceSetName + friendTaskName = taskToFriendTaskMapper[this] + } + protected open val taskToFriendTaskMapper: TaskToFriendTaskMapper = RegexTaskToFriendTaskMapper.Default() } +internal class KotlinCommonTasksProvider : KotlinTasksProvider() { + override val taskToFriendTaskMapper: TaskToFriendTaskMapper = + RegexTaskToFriendTaskMapper.Common() +} + internal class Kotlin2JsTasksProvider : KotlinTasksProvider() { override val taskToFriendTaskMapper: TaskToFriendTaskMapper = RegexTaskToFriendTaskMapper.JavaScript() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-common.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-common.properties new file mode 100644 index 00000000000..d1134b3181e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-common.properties @@ -0,0 +1 @@ +implementation-class=org.jetbrains.kotlin.gradle.plugin.KotlinPlatformCommonPlugin \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-js.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-js.properties new file mode 100644 index 00000000000..a8b3400c856 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-js.properties @@ -0,0 +1 @@ +implementation-class=org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJsPlugin \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-jvm.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-jvm.properties new file mode 100644 index 00000000000..8107ccd3f55 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-platform-jvm.properties @@ -0,0 +1 @@ +implementation-class=org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin \ No newline at end of file