From b99836edffc67c370825a05832b8a0ede8a3a544 Mon Sep 17 00:00:00 2001 From: ilmat192 Date: Tue, 15 May 2018 21:37:46 +0700 Subject: [PATCH] [gradle-plugin] Provide a simple tooling model for IDE (#1578) --- .../kotlin/konan/target/KonanTarget.kt | 3 +- .../gradle/plugin/KonanLibrariesSpec.kt | 13 ++++++ .../kotlin/gradle/plugin/KonanPlugin.kt | 8 +--- .../gradle/plugin/KonanToolingModelBuilder.kt | 45 ------------------- .../kotlin/gradle/plugin/model/KonanModel.kt | 21 +++++++-- .../gradle/plugin/model/KonanModelImpl.kt | 45 +++++++++++++++++++ .../gradle/plugin/tasks/KonanBuildingTask.kt | 2 + .../gradle/plugin/tasks/KonanCompileTask.kt | 34 +++++++++++--- .../plugin/tasks/KonanGenerateCMakeTask.kt | 2 +- .../gradle/plugin/tasks/KonanInteropTask.kt | 16 ++++++- 10 files changed, 124 insertions(+), 65 deletions(-) delete mode 100644 tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolingModelBuilder.kt create mode 100644 tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModelImpl.kt diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt index 1290c3f0092..efeaa706b09 100644 --- a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.konan.target import org.jetbrains.kotlin.konan.target.KonanTarget.* import org.jetbrains.kotlin.konan.util.Named +import java.io.Serializable enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSuffix: String, val staticPrefix: String, val staticSuffix: String) { @@ -39,7 +40,7 @@ enum class Architecture(val bitness: Int) { WASM32(32); } -sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture) : Named { +sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture) : Named, Serializable { object ANDROID_ARM32 : KonanTarget( "android_arm32", Family.ANDROID, Architecture.ARM32) object ANDROID_ARM64 : KonanTarget( "android_arm64", Family.ANDROID, Architecture.ARM64) object IOS_ARM64 : KonanTarget( "ios_arm64", Family.IOS, Architecture.ARM64) diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanLibrariesSpec.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanLibrariesSpec.kt index 5b36959383d..d55e86dd57a 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanLibrariesSpec.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanLibrariesSpec.kt @@ -24,6 +24,8 @@ import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Internal import org.jetbrains.kotlin.gradle.plugin.tasks.KonanArtifactWithLibrariesTask import org.jetbrains.kotlin.gradle.plugin.tasks.KonanBuildingTask +import org.jetbrains.kotlin.konan.library.defaultResolver +import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.visibleName import java.io.File @@ -129,4 +131,15 @@ open class KonanLibrariesSpec(val task: KonanArtifactWithLibrariesTask, val proj private fun Project.evaluationDependsOn(another: Project) { if (this != another) { evaluationDependsOn(another.path) } } + + fun asFiles(): List = mutableListOf().apply { + files.flatMapTo(this) { it.files } + addAll(artifactFiles) + val resolver = defaultResolver( + repos.map { it.absolutePath }, + task.konanTarget, + Distribution(konanHomeOverride = project.konanHome) + ) + namedKlibs.mapTo(this) { project.file(resolver.resolve(it).absolutePath) } + } } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt index 5576a5c9017..7fbbfa3f78e 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt @@ -17,8 +17,6 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.* -import org.gradle.api.artifacts.PublishArtifact -import org.gradle.api.attributes.Usage import org.gradle.api.component.ComponentWithVariants import org.gradle.api.component.SoftwareComponent import org.gradle.api.file.FileCollection @@ -26,16 +24,13 @@ import org.gradle.api.internal.FeaturePreviews import org.gradle.api.internal.component.SoftwareComponentInternal import org.gradle.api.internal.component.UsageContext import org.gradle.api.internal.project.ProjectInternal -import org.gradle.api.plugins.AppliedPlugin import org.gradle.api.plugins.BasePlugin import org.gradle.api.publish.PublishingExtension -import org.gradle.api.publish.internal.PublicationInternal import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal -import org.gradle.language.cpp.internal.NativeVariant -import org.gradle.language.nativeplatform.internal.Names import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.jetbrains.kotlin.gradle.plugin.KonanPlugin.Companion.COMPILE_ALL_TASK_NAME +import org.jetbrains.kotlin.gradle.plugin.model.KonanToolingModelBuilder import org.jetbrains.kotlin.gradle.plugin.tasks.* import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.target.HostManager @@ -43,7 +38,6 @@ import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.customerDistribution import org.jetbrains.kotlin.konan.util.* import java.io.File -import java.util.* import javax.inject.Inject /** diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolingModelBuilder.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolingModelBuilder.kt deleted file mode 100644 index 815327851eb..00000000000 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanToolingModelBuilder.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010-2017 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.Project -import org.gradle.tooling.provider.model.ToolingModelBuilder -import org.jetbrains.kotlin.gradle.plugin.model.KonanArtifact -import org.jetbrains.kotlin.gradle.plugin.model.KonanModel -import org.jetbrains.kotlin.konan.KonanVersion -import org.jetbrains.kotlin.konan.util.visibleName - -object KonanToolingModelBuilder : ToolingModelBuilder { - override fun canBuild(modelName: String): Boolean = KonanModel::class.java.name == modelName - - override fun buildAll(modelName: String, project: Project): KonanModel { - val artifacts = project.konanArtifactsContainer.flatten() - .toList() - .map { KonanArtifactImpl("${it.artifact.name}-${it.konanTarget.visibleName}", it.artifact.canonicalPath) } - return KonanModelImpl(artifacts) - } -} - -private class KonanModelImpl( - override val artifacts: List -) : KonanModel - - -private class KonanArtifactImpl( - override val name: String, - override val path: String -) : KonanArtifact diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt index b31a870cb3c..afb88fa1228 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt @@ -16,6 +16,9 @@ package org.jetbrains.kotlin.gradle.plugin.model +import org.jetbrains.kotlin.gradle.plugin.tasks.Produce +import org.jetbrains.kotlin.konan.target.KonanTarget +import java.io.File import java.io.Serializable /** @@ -23,10 +26,22 @@ import java.io.Serializable * This model is shared with the client processes such as an IDE. */ interface KonanModel : Serializable { - val artifacts: List + val konanHome: String + val konanVersion: String + + val artifacts: List } -interface KonanArtifact : Serializable { +/** + * A representation of a single binary produced by Kotlin/Native for a cetrain target. + */ +interface KonanModelArtifact : Serializable { val name: String - val path: String + val type: Produce + val targetPlatform: KonanTarget + val file: File + val buildTaskName: String + val srcDirs: List + val srcFiles: List + val libraries: List } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModelImpl.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModelImpl.kt new file mode 100644 index 00000000000..c4065b4dd2e --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModelImpl.kt @@ -0,0 +1,45 @@ +package org.jetbrains.kotlin.gradle.plugin.model + +import org.gradle.api.Project +import org.gradle.tooling.provider.model.ToolingModelBuilder +import org.jetbrains.kotlin.gradle.plugin.konanArtifactsContainer +import org.jetbrains.kotlin.gradle.plugin.konanExtension +import org.jetbrains.kotlin.gradle.plugin.konanHome +import org.jetbrains.kotlin.gradle.plugin.tasks.KonanBuildingTask +import org.jetbrains.kotlin.gradle.plugin.tasks.KonanCompileTask +import org.jetbrains.kotlin.gradle.plugin.tasks.Produce +import org.jetbrains.kotlin.konan.target.KonanTarget +import java.io.File + + +object KonanToolingModelBuilder : ToolingModelBuilder { + + override fun canBuild(modelName: String) = KonanModel::class.java.name == modelName + + override fun buildAll(modelName: String, project: Project): KonanModel { + val artifacts = project.konanArtifactsContainer.flatten().toList().map { it.toModelArtifact() } + return KonanModelImpl( + artifacts, + project.konanHome, + // TODO: Provide a better support for the default version + project.konanExtension.languageVersion ?: "1.2" + ) + } +} + +internal data class KonanModelImpl( + override val artifacts: List, + override val konanHome: String, + override val konanVersion: String +) : KonanModel + +internal data class KonanModelArtifactImpl( + override val name: String, + override val file: File, + override val type: Produce, + override val targetPlatform: KonanTarget, + override val buildTaskName: String, + override val srcDirs: List, + override val srcFiles: List, + override val libraries: List +) : KonanModelArtifact diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanBuildingTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanBuildingTask.kt index 784d5f98b47..f4098842b70 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanBuildingTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanBuildingTask.kt @@ -20,6 +20,7 @@ import org.gradle.api.tasks.Console import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifact import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File @@ -27,6 +28,7 @@ import java.io.File abstract class KonanBuildingTask: KonanArtifactWithLibrariesTask(), KonanBuildingSpec { internal abstract val toolRunner: KonanToolRunner + internal abstract fun toModelArtifact(): KonanModelArtifact override fun init(config: KonanBuildingConfig<*>, destinationDir: File, artifactName: String, target: KonanTarget) { dependsOn(project.konanCompilerDownloadTask) diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanCompileTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanCompileTask.kt index de6ad37397b..c2231bed372 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanCompileTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanCompileTask.kt @@ -16,12 +16,13 @@ package org.jetbrains.kotlin.gradle.plugin.tasks -import org.gradle.api.artifacts.FileCollectionDependency +import org.gradle.api.file.ConfigurableFileTree import org.gradle.api.file.FileCollection import org.gradle.api.tasks.* import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifact +import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifactImpl import org.jetbrains.kotlin.konan.target.CompilerOutputKind -import org.jetbrains.kotlin.konan.util.visibleName import java.io.File enum class Produce(val cliOption: String, val kind: CompilerOutputKind) { @@ -58,13 +59,21 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec { internal val commonSrcFiles_ = mutableSetOf() val commonSrcFiles: Collection - @InputFiles get() = if (enableMultiplatform) commonSrcFiles_ else emptyList() + @Internal get() = if (enableMultiplatform) commonSrcFiles_ else emptyList() // Other compilation parameters ------------------------------------------- protected val srcFiles_ = mutableSetOf() val srcFiles: Collection - @InputFiles get() = srcFiles_.takeIf { !it.isEmpty() } ?: listOf(project.konanDefaultSrcFiles) + @Internal get() = srcFiles_.takeIf { !it.isEmpty() } ?: listOf(project.konanDefaultSrcFiles) + + val allSources: Collection + @InputFiles get() = listOf(srcFiles, commonSrcFiles).flatten() + + private val allSourceFiles: List + @Internal get() = allSources + .flatMap { it.files } + .filter { it.name.endsWith(".kt") } @InputFiles val nativeLibraries = mutableSetOf() @@ -130,9 +139,7 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec { addAll(extraOpts) - listOf(srcFiles, commonSrcFiles).forEach { - it.flatMap { it.files }.filter { it.name.endsWith(".kt") }.mapTo(this) { it.canonicalPath } - } + allSourceFiles.mapTo(this) { it.canonicalPath } } // region DSL. @@ -213,6 +220,19 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec { measureTime = flag } // endregion + + // region IDE model + override fun toModelArtifact(): KonanModelArtifact = KonanModelArtifactImpl( + artifactName, + artifact, + produce, + konanTarget, + name, + allSources.filter { it is ConfigurableFileTree }.map { (it as ConfigurableFileTree).dir }, + allSourceFiles, + libraries.asFiles() + ) + // endregion } open class KonanCompileProgramTask: KonanCompileTask() { diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanGenerateCMakeTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanGenerateCMakeTask.kt index c4bda40972c..05e25c30fa4 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanGenerateCMakeTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanGenerateCMakeTask.kt @@ -113,7 +113,7 @@ open class KonanGenerateCMakeTask : DefaultTask() { .joinToString(" ") private val KonanCompileTask.cMakeSources: String - get() = srcFiles.flatMap { it.asCMakeSourceList }.joinToString(" ") + get() = allSources.flatMap { it.asCMakeSourceList }.joinToString(" ") private val KonanCompileTask.cMakeLibraries: String get() = mutableListOf().apply { diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt index 92a3e48a74e..6357e192444 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt @@ -23,8 +23,9 @@ import org.gradle.api.tasks.* import org.gradle.util.ConfigureUtil import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.KonanInteropSpec.IncludeDirectoriesSpec +import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifact +import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifactImpl import org.jetbrains.kotlin.konan.target.KonanTarget -import org.jetbrains.kotlin.konan.util.visibleName import java.io.File /** @@ -152,5 +153,18 @@ open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec { } // endregion + + // region IDE model + override fun toModelArtifact(): KonanModelArtifact = KonanModelArtifactImpl( + artifactName, + artifact, + Produce.LIBRARY, + konanTarget, + name, + listOfNotNull(defFile.parentFile), + listOf(defFile), + libraries.asFiles() + ) + // endregion }