From e91785ba393111bddaf297c36168853ad8eef43b Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Fri, 11 Feb 2022 15:54:26 +0100 Subject: [PATCH] [KPM] Implement initial IdeaKotlinProjectModelBuilder - Introduce `kotlin-gradle-plugin-idea` module that allows to share models between the IDE and KGP - Add `kotlin-gradle-plugin-idea` to the RuntimePublicAPITest to ensure binary compatibility ^KT-51262 --- .idea/kotlinScripting.xml | 6 ++++ build.gradle.kts | 1 + buildSrc/src/main/kotlin/tasks.kt | 1 + .../binary-compatibility-validator/ReadMe.md | 2 +- .../build.gradle | 1 + .../RuntimePublicAPITest.kt | 4 +++ .../dsl/kotlinTopLevelExtensionConfig.kt | 2 +- .../plugin/mpp/pm20/KotlinGradleFragment.kt | 2 ++ .../tools/kotlin-gradle-plugin-idea/ReadMe.md | 13 +++++++ .../build.gradle.kts | 9 +++++ .../gradle/kpm/idea/IdeaKotlinFragment.kt | 28 +++++++++++++++ .../kpm/idea/IdeaKotlinFragmentDependency.kt | 8 +++++ .../kpm/idea/IdeaKotlinLanguageSettings.kt | 30 ++++++++++++++++ .../gradle/kpm/idea/IdeaKotlinModule.kt | 18 ++++++++++ .../kpm/idea/IdeaKotlinModuleIdentifier.kt | 34 +++++++++++++++++++ .../gradle/kpm/idea/IdeaKotlinProjectModel.kt | 23 +++++++++++++ .../kpm/idea/IdeaKotlinResourceDirectory.kt | 17 ++++++++++ .../kpm/idea/IdeaKotlinSourceDirectory.kt | 17 ++++++++++ .../gradle/kpm/idea/KotlinGradlePluginApi.kt | 12 +++++++ .../kotlin-gradle-plugin/build.gradle.kts | 2 ++ .../kpm/idea/IdeaKotlinFragmentBuilder.kt | 27 +++++++++++++++ .../idea/IdeaKotlinLanguageSettingsBuilder.kt | 22 ++++++++++++ .../kpm/idea/IdeaKotlinModuleBuilder.kt | 17 ++++++++++ .../idea/IdeaKotlinModuleIdentifierBuilder.kt | 21 ++++++++++++ .../kpm/idea/IdeaKotlinProjectModelBuilder.kt | 24 +++++++++++++ .../gradle/plugin/mpp/pm20/GradlePlugin.kt | 10 +++++- .../plugin/mpp/pm20/LegacyMappedVariant.kt | 4 +-- .../src/main/kotlin/KotlinModule.kt | 3 +- settings.gradle | 2 ++ 29 files changed, 353 insertions(+), 7 deletions(-) create mode 100644 .idea/kotlinScripting.xml create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/ReadMe.md create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/build.gradle.kts create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragment.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentDependency.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModule.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModel.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/KotlinGradlePluginApi.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentBuilder.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettingsBuilder.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleBuilder.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifierBuilder.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModelBuilder.kt diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml new file mode 100644 index 00000000000..bc444dead97 --- /dev/null +++ b/.idea/kotlinScripting.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b6f8dfe2058..f0a7770bd6e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -362,6 +362,7 @@ val projectsWithDisabledFirBootstrap = coreLibProjects + listOf( val gradlePluginProjects = listOf( ":kotlin-gradle-plugin", ":kotlin-gradle-plugin-api", + ":kotlin-gradle-plugin-idea", ":kotlin-gradle-plugin-kpm-android", ":kotlin-allopen", ":kotlin-annotation-processing-gradle", diff --git a/buildSrc/src/main/kotlin/tasks.kt b/buildSrc/src/main/kotlin/tasks.kt index 47325dc20d9..ebb93b5ae5e 100644 --- a/buildSrc/src/main/kotlin/tasks.kt +++ b/buildSrc/src/main/kotlin/tasks.kt @@ -40,6 +40,7 @@ val kotlinGradlePluginAndItsRequired = arrayOf( ":kotlin-daemon-client", ":kotlin-project-model", ":kotlin-gradle-plugin-api", + ":kotlin-gradle-plugin-idea", ":kotlin-gradle-plugin", ":kotlin-gradle-plugin-model", ":kotlin-tooling-metadata", diff --git a/libraries/tools/binary-compatibility-validator/ReadMe.md b/libraries/tools/binary-compatibility-validator/ReadMe.md index 458df4eb7ba..6f0112d9de7 100644 --- a/libraries/tools/binary-compatibility-validator/ReadMe.md +++ b/libraries/tools/binary-compatibility-validator/ReadMe.md @@ -7,7 +7,7 @@ and ensure that the public binary API wasn't changed in a way that make this cha Compile and run tests. `CasesPublicAPITest` verifies the tool itself, and `RuntimePublicAPITest` dumps the public API of `kotlin-stdlib`, -`kotlin-stdlib-jdk7/8`, and `kotlin-reflect` jars, +`kotlin-stdlib-jdk7/8`, `kotlin-reflect` and `kotlin-gradle-plugin-idea` jars, which must be built beforehand with gradle. Use `clean assemble` tasks, since the incremental compilation currently doesn't produce all the required output. diff --git a/libraries/tools/binary-compatibility-validator/build.gradle b/libraries/tools/binary-compatibility-validator/build.gradle index d94c621b02f..efc148c4488 100644 --- a/libraries/tools/binary-compatibility-validator/build.gradle +++ b/libraries/tools/binary-compatibility-validator/build.gradle @@ -14,6 +14,7 @@ dependencies { testArtifacts project(':kotlin-stdlib-jdk7') testArtifacts project(':kotlin-stdlib-jdk8') testArtifacts project(':kotlin-reflect') + testArtifacts project(':kotlin-gradle-plugin-idea') } pill { diff --git a/libraries/tools/binary-compatibility-validator/src/test/kotlin/org.jetbrains.kotlin.tools.tests/RuntimePublicAPITest.kt b/libraries/tools/binary-compatibility-validator/src/test/kotlin/org.jetbrains.kotlin.tools.tests/RuntimePublicAPITest.kt index 16a433cf292..da0b308ded4 100644 --- a/libraries/tools/binary-compatibility-validator/src/test/kotlin/org.jetbrains.kotlin.tools.tests/RuntimePublicAPITest.kt +++ b/libraries/tools/binary-compatibility-validator/src/test/kotlin/org.jetbrains.kotlin.tools.tests/RuntimePublicAPITest.kt @@ -33,6 +33,10 @@ class RuntimePublicAPITest { snapshotAPIAndCompare("../../reflect/api/build/libs", "kotlin-reflect-api(?!-[-a-z]+)", nonPublicPackages = listOf("kotlin.reflect.jvm.internal")) } + @Test fun kotlinGradlePluginIdea() { + snapshotAPIAndCompare("../kotlin-gradle-plugin-idea/build/libs", "kotlin-gradle-plugin-idea(?!-[-a-z]+)") + } + private fun snapshotAPIAndCompare( basePath: String, jarPattern: String, diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/kotlinTopLevelExtensionConfig.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/kotlinTopLevelExtensionConfig.kt index 14b067ba40c..efe2ce5fbb9 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/kotlinTopLevelExtensionConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/kotlinTopLevelExtensionConfig.kt @@ -40,7 +40,7 @@ interface ExperimentalExtensionConfig { /** * Different modes that can be used to set the level of issue reporting for [KotlinTopLevelExtensionConfig.explicitApi] option. */ -enum class ExplicitApiMode(private val cliOption: String) { +enum class ExplicitApiMode(val cliOption: String) { /** Report issues as errors. */ Strict("strict"), diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt index b49518eb138..f82a8ab327f 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinGradleFragment.kt @@ -31,6 +31,8 @@ interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, Ko fun refines(other: NamedDomainObjectProvider) + override val directRefinesDependencies: Iterable + override fun dependencies(configureClosure: Closure) = dependencies f@{ project.configure(this@f, configureClosure) } diff --git a/libraries/tools/kotlin-gradle-plugin-idea/ReadMe.md b/libraries/tools/kotlin-gradle-plugin-idea/ReadMe.md new file mode 100644 index 00000000000..d0a4dfb9a3d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/ReadMe.md @@ -0,0 +1,13 @@ +# Kotlin Gradle Plugin Models shared between IDEA import and KGP +The classes defined in this module will be available inside the Kotlin Gradle Plugin (KGP) +as well as in the IDE import (GradleProject). + +## Binary Compatibility: +Binary compatibility can be tested by +`./gradlew :tools:binary-compatibility-validator:clean :tools:binary-compatibility-validator:test` + +Binary incompatible changes have to go through a proper deprecation cycle after releases + +### Unstable APIs / KotlinGradlePluginApi +Some APIs are marked with 'KotlinGradlePluginApi' which means, that those are not kept binary compatible and are considered 'unstable' +from the IDEA perspective. Typically constructors for models are marked like this diff --git a/libraries/tools/kotlin-gradle-plugin-idea/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-idea/build.gradle.kts new file mode 100644 index 00000000000..5197182bdea --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + kotlin("jvm") +} + +dependencies { + implementation(project(":kotlin-stdlib")) +} + +publish() diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragment.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragment.kt new file mode 100644 index 00000000000..d50c267b47d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragment.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import java.io.Serializable + +interface IdeaKotlinFragment : Serializable { + val name: String + val languageSettings: IdeaKotlinLanguageSettings? + val dependencies: Collection + val directRefinesDependencies: Collection + val sourceDirectories: Collection + val resourceDirectories: Collection +} + +class IdeaKotlinFragmentImpl @KotlinGradlePluginApi constructor( + override val name: String, + override val languageSettings: IdeaKotlinLanguageSettings?, + override val dependencies: Collection, + override val directRefinesDependencies: Collection, + override val sourceDirectories: Collection, + override val resourceDirectories: Collection +) : IdeaKotlinFragment + + diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentDependency.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentDependency.kt new file mode 100644 index 00000000000..781f1aa8ffe --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentDependency.kt @@ -0,0 +1,8 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +interface IdeaKotlinFragmentDependency diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings.kt new file mode 100644 index 00000000000..13565ce47bd --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettings.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import java.io.File + +interface IdeaKotlinLanguageSettings { + val languageVersion: String? + val apiVersion: String? + val isProgressiveMode: Boolean + val enabledLanguageFeatures: Collection + val optInAnnotationsInUse: Collection + val compilerPluginArguments: Collection + val compilerPluginClasspath: Collection + val freeCompilerArgs: Collection +} + +class IdeaKotlinLanguageSettingsImpl @KotlinGradlePluginApi constructor( + override val languageVersion: String?, + override val apiVersion: String?, + override val isProgressiveMode: Boolean, + override val enabledLanguageFeatures: Collection, + override val optInAnnotationsInUse: Collection, + override val compilerPluginArguments: Collection, + override val compilerPluginClasspath: Collection, + override val freeCompilerArgs: Collection +) : IdeaKotlinLanguageSettings diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModule.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModule.kt new file mode 100644 index 00000000000..12e50601a99 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModule.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import java.io.Serializable + +interface IdeaKotlinModule : Serializable { + val moduleIdentifier: IdeaKotlinModuleIdentifier + val fragments: Collection +} + +class IdeaKotlinModuleImpl @KotlinGradlePluginApi constructor( + override val moduleIdentifier: IdeaKotlinModuleIdentifier, + override val fragments: Collection +) : IdeaKotlinModule diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier.kt new file mode 100644 index 00000000000..3d6c41f1422 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifier.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import java.io.Serializable + +sealed interface IdeaKotlinModuleIdentifier : Serializable { + val moduleClassifier: String? +} + +interface IdeaKotlinLocalModuleIdentifier : IdeaKotlinModuleIdentifier { + val buildId: String + val projectId: String +} + +interface IdeaKotlinMavenModuleIdentifier : IdeaKotlinModuleIdentifier { + val group: String + val name: String +} + +class IdeaKotlinLocalModuleIdentifierImpl @KotlinGradlePluginApi constructor( + override val moduleClassifier: String?, + override val buildId: String, + override val projectId: String +) : IdeaKotlinLocalModuleIdentifier + +class IdeaKotlinMavenModuleIdentifierImpl @KotlinGradlePluginApi constructor( + override val moduleClassifier: String?, + override val group: String, + override val name: String +) : IdeaKotlinMavenModuleIdentifier diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModel.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModel.kt new file mode 100644 index 00000000000..e55786f90f3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModel.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import java.io.File +import java.io.Serializable + +interface IdeaKotlinProjectModel : Serializable { + val coreLibrariesVersion: String + val explicitApiModeCliOption: String? + val kotlinNativeHome: File + val modules: List +} + +class IdeaKotlinProjectModelImpl @KotlinGradlePluginApi constructor( + override val coreLibrariesVersion: String, + override val explicitApiModeCliOption: String?, + override val kotlinNativeHome: File, + override val modules: List +) : IdeaKotlinProjectModel diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectory.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectory.kt new file mode 100644 index 00000000000..612650321df --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinResourceDirectory.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import java.io.File +import java.io.Serializable + +interface IdeaKotlinResourceDirectory : Serializable { + val file: File +} + +class IdeaKotlinResourceDirectoryImpl @KotlinGradlePluginApi constructor( + override val file: File +) : IdeaKotlinResourceDirectory diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectory.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectory.kt new file mode 100644 index 00000000000..c68a1617de1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinSourceDirectory.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import java.io.File +import java.io.Serializable + +interface IdeaKotlinSourceDirectory : Serializable { + val file: File +} + +class IdeaKotlinSourceDirectoryImpl @KotlinGradlePluginApi constructor( + override val file: File, +) : IdeaKotlinSourceDirectory diff --git a/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/KotlinGradlePluginApi.kt b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/KotlinGradlePluginApi.kt new file mode 100644 index 00000000000..b58047f960c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-idea/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/KotlinGradlePluginApi.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +@RequiresOptIn( + level = RequiresOptIn.Level.ERROR, + message = "This API can only be used by the Kotlin Gradle Plugin and is not kept stable for access inside the IDE process" +) +annotation class KotlinGradlePluginApi diff --git a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts index f582da670c5..2677ef30cb6 100644 --- a/libraries/tools/kotlin-gradle-plugin/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin/build.gradle.kts @@ -30,6 +30,7 @@ kotlin.sourceSets.all { languageSettings.optIn("kotlin.RequiresOptIn") languageSettings.optIn("org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalVariantApi") languageSettings.optIn("org.jetbrains.kotlin.gradle.plugin.mpp.external.AdvancedExternalVariantApi") + languageSettings.optIn("org.jetbrains.kotlin.gradle.kpm.idea.KotlinGradlePluginApi") } dependencies { @@ -56,6 +57,7 @@ dependencies { embedded(project(":kotlin-gradle-statistics")) compileOnly(project(":kotlin-gradle-build-metrics")) embedded(project(":kotlin-gradle-build-metrics")) + implementation(project(":kotlin-gradle-plugin-idea")) implementation(commonDependency("com.google.code.gson:gson")) implementation(commonDependency("com.google.guava:guava")) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentBuilder.kt new file mode 100644 index 00000000000..120d9d30a98 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinFragmentBuilder.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleFragment + +internal fun KotlinGradleFragment.toIdeaKotlinFragment( + cache: MutableMap = mutableMapOf() +): IdeaKotlinFragment { + return cache.getOrPut(this) { + IdeaKotlinFragmentImpl( + name = name, + languageSettings = languageSettings.toIdeaKotlinLanguageSettings(), + dependencies = emptyList(), + directRefinesDependencies = directRefinesDependencies.map { refinesFragment -> + refinesFragment.toIdeaKotlinFragment(cache) + }, + sourceDirectories = kotlinSourceRoots.sourceDirectories.files.toList().map { file -> + IdeaKotlinSourceDirectoryImpl(file) + }, + resourceDirectories = emptyList() + ) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettingsBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettingsBuilder.kt new file mode 100644 index 00000000000..e0447c825b5 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinLanguageSettingsBuilder.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder +import org.jetbrains.kotlin.project.model.LanguageSettings + +internal fun LanguageSettings.toIdeaKotlinLanguageSettings(): IdeaKotlinLanguageSettings { + return IdeaKotlinLanguageSettingsImpl( + languageVersion = languageVersion, + apiVersion = apiVersion, + isProgressiveMode = progressiveMode, + enabledLanguageFeatures = enabledLanguageFeatures.toSet(), + optInAnnotationsInUse = optInAnnotationsInUse.toSet(), + compilerPluginArguments = (this as? DefaultLanguageSettingsBuilder)?.compilerPluginArguments?.toList().orEmpty(), + compilerPluginClasspath = (this as? DefaultLanguageSettingsBuilder)?.compilerPluginClasspath?.toList().orEmpty(), + freeCompilerArgs = (this as? DefaultLanguageSettingsBuilder)?.freeCompilerArgs?.toList().orEmpty() + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleBuilder.kt new file mode 100644 index 00000000000..8453f9f9d71 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleBuilder.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleFragment +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule + +internal fun KotlinGradleModule.toIdeaKotlinModule(): IdeaKotlinModule { + val fragmentsCache = mutableMapOf() + return IdeaKotlinModuleImpl( + moduleIdentifier = moduleIdentifier.toIdeaKotlinModuleIdentifier(), + fragments = fragments.toList().map { fragment -> fragment.toIdeaKotlinFragment(fragmentsCache) } + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifierBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifierBuilder.kt new file mode 100644 index 00000000000..5f5121b2f5f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinModuleIdentifierBuilder.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2022 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.kpm.idea + +import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier +import org.jetbrains.kotlin.project.model.LocalModuleIdentifier +import org.jetbrains.kotlin.project.model.MavenModuleIdentifier + +internal fun KotlinModuleIdentifier.toIdeaKotlinModuleIdentifier(): IdeaKotlinModuleIdentifier { + return when (this) { + is LocalModuleIdentifier -> IdeaKotlinLocalModuleIdentifierImpl( + moduleClassifier, buildId = buildId, projectId = projectId + ) + is MavenModuleIdentifier -> IdeaKotlinMavenModuleIdentifierImpl( + moduleClassifier, group = group, name = name + ) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModelBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModelBuilder.kt new file mode 100644 index 00000000000..b97b317120f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/kpm/idea/IdeaKotlinProjectModelBuilder.kt @@ -0,0 +1,24 @@ +package org.jetbrains.kotlin.gradle.kpm.idea + +import org.gradle.api.Project +import org.gradle.tooling.provider.model.ToolingModelBuilder +import org.jetbrains.kotlin.compilerRunner.konanHome +import org.jetbrains.kotlin.gradle.dsl.pm20Extension +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension +import java.io.File + +class IdeaKotlinProjectModelBuilder : ToolingModelBuilder { + override fun canBuild(modelName: String): Boolean = modelName == IdeaKotlinProjectModel::class.java.name + override fun buildAll(modelName: String, project: Project): IdeaKotlinProjectModel { + return project.pm20Extension.toIdeaKotlinProjectModel() + } +} + +internal fun KotlinPm20ProjectExtension.toIdeaKotlinProjectModel(): IdeaKotlinProjectModel { + return IdeaKotlinProjectModelImpl( + coreLibrariesVersion = coreLibrariesVersion, + explicitApiModeCliOption = explicitApi?.cliOption, + kotlinNativeHome = File(project.konanHome).absoluteFile, + modules = modules.map { module -> module.toIdeaKotlinModule() } + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt index affc3d78ecf..31aec3e5f12 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt @@ -13,18 +13,21 @@ import org.gradle.api.component.SoftwareComponentFactory import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication +import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension import org.jetbrains.kotlin.gradle.dsl.pm20Extension import org.jetbrains.kotlin.gradle.dsl.topLevelExtensionOrNull import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies +import org.jetbrains.kotlin.gradle.kpm.idea.IdeaKotlinProjectModelBuilder import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier import javax.inject.Inject abstract class KotlinPm20GradlePlugin @Inject constructor( - @Inject private val softwareComponentFactory: SoftwareComponentFactory + @Inject private val softwareComponentFactory: SoftwareComponentFactory, + @Inject private val toolingModelBuilderRegistry: ToolingModelBuilderRegistry ) : Plugin { override fun apply(project: Project) { checkGradleCompatibility("the Kotlin Multiplatform plugin", GradleVersion.version("6.1")) @@ -37,6 +40,7 @@ abstract class KotlinPm20GradlePlugin @Inject constructor( registerDefaultVariantFactories(project) setupFragmentsMetadataForKpmModules(project) setupKpmModulesPublication(project) + setupToolingModelBuilder() } private fun createDefaultModules(project: Project) { @@ -77,6 +81,10 @@ abstract class KotlinPm20GradlePlugin @Inject constructor( } } } + + private fun setupToolingModelBuilder() { + toolingModelBuilderRegistry.register(IdeaKotlinProjectModelBuilder()) + } } fun rootPublicationComponentName(module: KotlinGradleModule) = diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/LegacyMappedVariant.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/LegacyMappedVariant.kt index 3dca4a14fce..afa52640970 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/LegacyMappedVariant.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/LegacyMappedVariant.kt @@ -102,7 +102,7 @@ internal open class LegacyMappedVariant( override val fragmentName: String get() = fragmentForDefaultSourceSet.fragmentName + "Variant" - override val directRefinesDependencies: Iterable + override val directRefinesDependencies: Iterable get() = fragmentForDefaultSourceSet.directRefinesDependencies override val declaredModuleDependencies: Iterable @@ -239,4 +239,4 @@ internal fun mapTargetCompilationsToKpmVariants(target: AbstractKotlinTarget, pu VariantPublishingConfigurator.get(target.project).configurePublishing(request) } } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModule.kt b/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModule.kt index 373d689c9d6..a9deacdd482 100644 --- a/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModule.kt +++ b/libraries/tools/kotlin-project-model/src/main/kotlin/KotlinModule.kt @@ -7,8 +7,7 @@ package org.jetbrains.kotlin.project.model import java.io.Serializable -// TODO sealed with an abstract subclass? this will make exhaustive checks work -open class KotlinModuleIdentifier(open val moduleClassifier: String?): Serializable +sealed class KotlinModuleIdentifier(open val moduleClassifier: String?): Serializable // TODO consider id: Any, to allow IDs with custom equality? data class LocalModuleIdentifier( diff --git a/settings.gradle b/settings.gradle index bfbd77be5ea..9f68639373e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -227,6 +227,7 @@ include ":benchmarks", ":tools:kotlinp", ":kotlin-project-model", ":kotlin-gradle-plugin-api", + ":kotlin-gradle-plugin-idea", ":kotlin-gradle-plugin-dsl-codegen", ":kotlin-gradle-plugin-npm-versions-codegen", ":kotlin-gradle-statistics", @@ -631,6 +632,7 @@ project(':kotlin-sam-with-receiver-compiler-plugin').projectDir = "$rootDir/plug project(':tools:kotlinp').projectDir = "$rootDir/libraries/tools/kotlinp" as File project(':kotlin-project-model').projectDir = "$rootDir/libraries/tools/kotlin-project-model" as File project(':kotlin-gradle-plugin-api').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-api" as File +project(':kotlin-gradle-plugin-idea').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-idea" as File project(':kotlin-gradle-plugin-dsl-codegen').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-dsl-codegen" as File project(':kotlin-gradle-plugin-npm-versions-codegen').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-npm-versions-codegen" as File project(':kotlin-gradle-statistics').projectDir = "$rootDir/libraries/tools/kotlin-gradle-statistics" as File