[gradle-plugin] Provide a simple tooling model for IDE (#1578)

This commit is contained in:
ilmat192
2018-05-15 21:37:46 +07:00
committed by Nikolay Igotti
parent dff4ce98e9
commit b99836edff
10 changed files with 124 additions and 65 deletions
@@ -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)
@@ -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<File> = mutableListOf<File>().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) }
}
}
@@ -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
/**
@@ -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<KonanArtifact>
) : KonanModel
private class KonanArtifactImpl(
override val name: String,
override val path: String
) : KonanArtifact
@@ -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<KonanArtifact>
val konanHome: String
val konanVersion: String
val artifacts: List<KonanModelArtifact>
}
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<File>
val srcFiles: List<File>
val libraries: List<File>
}
@@ -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<KonanModelArtifact>,
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<File>,
override val srcFiles: List<File>,
override val libraries: List<File>
) : KonanModelArtifact
@@ -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)
@@ -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<FileCollection>()
val commonSrcFiles: Collection<FileCollection>
@InputFiles get() = if (enableMultiplatform) commonSrcFiles_ else emptyList()
@Internal get() = if (enableMultiplatform) commonSrcFiles_ else emptyList()
// Other compilation parameters -------------------------------------------
protected val srcFiles_ = mutableSetOf<FileCollection>()
val srcFiles: Collection<FileCollection>
@InputFiles get() = srcFiles_.takeIf { !it.isEmpty() } ?: listOf(project.konanDefaultSrcFiles)
@Internal get() = srcFiles_.takeIf { !it.isEmpty() } ?: listOf(project.konanDefaultSrcFiles)
val allSources: Collection<FileCollection>
@InputFiles get() = listOf(srcFiles, commonSrcFiles).flatten()
private val allSourceFiles: List<File>
@Internal get() = allSources
.flatMap { it.files }
.filter { it.name.endsWith(".kt") }
@InputFiles val nativeLibraries = mutableSetOf<FileCollection>()
@@ -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() {
@@ -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<String>().apply {
@@ -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
}