initial compose-gradle-plugin
diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 7f80f69..b55442c 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml
@@ -40,5 +40,6 @@ </component> <component name="VcsDirectoryMappings"> <mapping directory="" vcs="Git" /> + <mapping directory="$PROJECT_DIR$/plugins/compose/compose-compiler-plugin" vcs="Git" /> </component> </project> \ No newline at end of file
diff --git a/.space/CODEOWNERS b/.space/CODEOWNERS index aec6192..cdd568f 100644 --- a/.space/CODEOWNERS +++ b/.space/CODEOWNERS
@@ -300,6 +300,7 @@ /libraries/tools/kotlin-annotations-jvm/ "Kotlin Libraries" /libraries/tools/kotlin-assignment/ "Kotlin Build Tools" /libraries/tools/kotlin-bom/ "Kotlin Build Infrastructure" +/libraries/tools/kotlin-compose-compiler/ "Kotlin Build Tools" /libraries/tools/kotlin-dist-for-jps-meta/ "Kotlin Build Tools" /libraries/tools/kotlin-gradle-build-metrics/ "Kotlin Build Tools" /libraries/tools/kotlin-gradle-compiler-types/ "Kotlin Build Tools"
diff --git a/build.gradle.kts b/build.gradle.kts index 7bf8f70..ffa30ee 100644 --- a/build.gradle.kts +++ b/build.gradle.kts
@@ -526,6 +526,7 @@ ":kotlin-gradle-plugin-idea-proto", ":kotlin-gradle-plugin-model", ":kotlin-gradle-plugin-tcs-android", + ":compose-compiler-gradle-plugin", ":kotlin-allopen", ":kotlin-noarg", ":kotlin-power-assert",
diff --git a/libraries/tools/kotlin-compose-compiler/build.gradle.kts b/libraries/tools/kotlin-compose-compiler/build.gradle.kts new file mode 100644 index 0000000..a7845b7 --- /dev/null +++ b/libraries/tools/kotlin-compose-compiler/build.gradle.kts
@@ -0,0 +1,21 @@ +plugins { + id("gradle-plugin-common-configuration") +} + +dependencies { + commonApi(platform(project(":kotlin-gradle-plugins-bom"))) + commonApi(project(":kotlin-gradle-plugin-model")) + + commonCompileOnly(project(":kotlin-compiler-embeddable")) +} + +gradlePlugin { + plugins { + create("kotlinComposeCompilerPlugin") { + id = "org.jetbrains.kotlin.plugin.compose-compiler-gradle-plugin" + displayName = "Kotlin Compose Compiler plugin" + description = displayName + implementationClass = "org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradleSubplugin" + } + } +}
diff --git a/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/ComposeCompilerGradlePluginExtension.kt b/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/ComposeCompilerGradlePluginExtension.kt new file mode 100644 index 0000000..2600131 --- /dev/null +++ b/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/ComposeCompilerGradlePluginExtension.kt
@@ -0,0 +1,65 @@ +/* + * 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.compose.compiler.gradle + +open class ComposeCompilerGradlePluginExtension { + internal val myPresets = mutableListOf<String>() + + open fun preset(name: String) { + myPresets.add(name) + } + + + /** Enable Live Literals code generation */ + var liveLiterals: Boolean = false + + /** Enable Live Literals code generation (with per-file enabled flags) */ + var liveLiteralsEnabled: Boolean = false + + /** Generate function key meta classes with annotations indicating the functions and their group keys. Generally used for tooling. */ + var generateFunctionKeyMetaClasses: Boolean = false + + /** Include source information in generated code */ + var sourceInformation: Boolean = false + + /** Save compose build metrics to this folder */ + var metricsDestination: String? = null + + /** Save compose build reports to this folder */ + var reportsDestination: String? = null + + /** Include source information in generated code */ + var intrinsicRemember: Boolean = false + + /** Remove groups around non-skipping composable functions */ + var nonSkippingGroupOptimization: Boolean = false + + /** Suppress Kotlin version compatibility check */ + var suppressKotlinVersionCompatibilityCheck: String? = null + + /** Generate decoy methods in IR transform */ + var generateDecoys: Boolean = false + + /** Enable experimental strong skipping mode */ + var experimentalStrongSkipping: Boolean = false + + /** Path to stability configuration file */ + var stabilityConfigurationPath: String = "" + + /** Include composition trace markers in generate code */ + var traceMarkersEnabled: Boolean = false +}
diff --git a/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/ComposeCompilerSubplugin.kt b/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/ComposeCompilerSubplugin.kt new file mode 100644 index 0000000..6db8225 --- /dev/null +++ b/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/ComposeCompilerSubplugin.kt
@@ -0,0 +1,88 @@ +/* + * Copyright 2010-2024 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.compose.compiler.gradle + +import org.gradle.api.Project +import org.gradle.api.artifacts.UnknownConfigurationException +import org.gradle.api.provider.Provider +import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry +import org.jetbrains.kotlin.compose.compiler.gradle.model.builder.ComposeCompilerModelBuilder +import org.jetbrains.kotlin.config.KotlinCompilerVersion +import org.jetbrains.kotlin.gradle.plugin.* +import javax.inject.Inject + +class ComposeCompilerGradleSubplugin +@Inject internal constructor( + private val registry: ToolingModelBuilderRegistry +) : KotlinCompilerPluginSupportPlugin { + + companion object { + fun getComposeCompilerGradlePluginExtension(project: Project): ComposeCompilerGradlePluginExtension { + return project.extensions.getByType(ComposeCompilerGradlePluginExtension::class.java) + } + + private const val COMPOSE_COMPILER_ARTIFACT_NAME = "compiler" + } + + override fun apply(target: Project) { + target.extensions.create("compose_compiler", ComposeCompilerGradlePluginExtension::class.java) + registry.register(ComposeCompilerModelBuilder()) + } + + override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean = true + + override fun applyToCompilation( + kotlinCompilation: KotlinCompilation<*> + ): Provider<List<SubpluginOption>> { + val project = kotlinCompilation.target.project + + val composeCompilerExtension = project.extensions.getByType(ComposeCompilerGradlePluginExtension::class.java) + + val kotlinExtensionConfiguration = try { + project.configurations.getByName("kotlin-extension") + } catch (e: UnknownConfigurationException) { + null + } + if (kotlinExtensionConfiguration != null) println(kotlinExtensionConfiguration::class) + + kotlinExtensionConfiguration?.incoming?.beforeResolve { + kotlinExtensionConfiguration.resolutionStrategy.dependencySubstitution { + // entry.key is in the form of "group:module" (without a version), and + // Gradle accepts that form. + it.substitute(it.module("androidx.compose.compiler:compiler")) + .using(it.module("org.jetbrains.kotlin.compose:compiler:${KotlinCompilerVersion.getVersion()}")) + .withoutArtifactSelectors() // https://github.com/gradle/gradle/issues/5174#issuecomment-828558594 + .because("Compose Compiler is now shipped as part of Kotlin distribution") + } + } + + return project.provider { + val options = mutableListOf<SubpluginOption>() + + options += SubpluginOption("liveLiterals", composeCompilerExtension.liveLiterals.toString()) + options += SubpluginOption("liveLiteralsEnabled", composeCompilerExtension.liveLiteralsEnabled.toString()) + options += SubpluginOption("generateFunctionKeyMetaClasses", composeCompilerExtension.generateFunctionKeyMetaClasses.toString()) + if(kotlinExtensionConfiguration == null) // TODO: Is there a better way to check if AGP already set the option? + options += SubpluginOption("sourceInformation", composeCompilerExtension.sourceInformation.toString()) + if(composeCompilerExtension.metricsDestination != null) options += SubpluginOption("metricsDestination", composeCompilerExtension.metricsDestination!!.toString()) + if(composeCompilerExtension.reportsDestination != null) options += SubpluginOption("reportsDestination", composeCompilerExtension.reportsDestination!!.toString()) + options += SubpluginOption("intrinsicRemember", composeCompilerExtension.intrinsicRemember.toString()) + options += SubpluginOption("nonSkippingGroupOptimization", composeCompilerExtension.nonSkippingGroupOptimization.toString()) + options += SubpluginOption("suppressKotlinVersionCompatibilityCheck", composeCompilerExtension.suppressKotlinVersionCompatibilityCheck.toString()) + options += SubpluginOption("generateDecoys", composeCompilerExtension.generateDecoys.toString()) + options += SubpluginOption("experimentalStrongSkipping", composeCompilerExtension.experimentalStrongSkipping.toString()) + options += SubpluginOption("stabilityConfigurationPath", composeCompilerExtension.stabilityConfigurationPath) + options += SubpluginOption("traceMarkersEnabled", composeCompilerExtension.traceMarkersEnabled.toString()) + + options + } + } + + /** Get ID of the Kotlin Compiler plugin */ + override fun getCompilerPluginId() = "androidx.compose.compiler.plugins.kotlin" + override fun getPluginArtifact(): SubpluginArtifact = + SubpluginArtifact(groupId = "org.jetbrains.kotlin.compose", artifactId = COMPOSE_COMPILER_ARTIFACT_NAME) +}
diff --git a/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/model/builder/ComposeCompilerModelBuilder.kt b/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/model/builder/ComposeCompilerModelBuilder.kt new file mode 100644 index 0000000..b05e1b8 --- /dev/null +++ b/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/model/builder/ComposeCompilerModelBuilder.kt
@@ -0,0 +1,29 @@ +/* + * Copyright 2010-2024 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.compose.compiler.gradle.model.builder + +import org.gradle.api.Project +import org.gradle.tooling.provider.model.ToolingModelBuilder +import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension +import org.jetbrains.kotlin.compose.compiler.gradle.model.impl.ComposeCompilerImpl +import org.jetbrains.kotlin.gradle.model.ComposeCompiler + +/** + * [ToolingModelBuilder] for [ComposeCompiler] models. + * This model builder is registered for Kotlin All Open sub-plugin. + */ +class ComposeCompilerModelBuilder : ToolingModelBuilder { + + override fun canBuild(modelName: String): Boolean { + return modelName == ComposeCompiler::class.java.name + } + + override fun buildAll(modelName: String, project: Project): Any { + require(canBuild(modelName)) { "buildAll(\"$modelName\") has been called while canBeBuild is false" } + val extension = project.extensions.getByType(ComposeCompilerGradlePluginExtension::class.java) + return ComposeCompilerImpl(project.name, /*extension.myAnnotations, */extension.myPresets) + } +}
diff --git a/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/model/impl/ComposeCompilerImpl.kt b/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/model/impl/ComposeCompilerImpl.kt new file mode 100644 index 0000000..9ece2af --- /dev/null +++ b/libraries/tools/kotlin-compose-compiler/src/common/kotlin/org/jetbrains/kotlin/compose/compiler/gradle/model/impl/ComposeCompilerImpl.kt
@@ -0,0 +1,25 @@ +/* + * Copyright 2010-2024 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.compose.compiler.gradle.model.impl + +import org.jetbrains.kotlin.gradle.model.ComposeCompiler +import java.io.Serializable + +/** + * Implementation of the [ComposeCompiler] interface. + */ +data class ComposeCompilerImpl( + override val name: String, + // override val annotations: List<String>, + override val presets: List<String> +) : ComposeCompiler, Serializable { + + override val modelVersion = serialVersionUID + + companion object { + private const val serialVersionUID = 1L + } +} \ No newline at end of file
diff --git a/libraries/tools/kotlin-compose-compiler/src/common/resources/META-INF/gradle-plugins/kotlin-composecompiler.properties b/libraries/tools/kotlin-compose-compiler/src/common/resources/META-INF/gradle-plugins/kotlin-composecompiler.properties new file mode 100644 index 0000000..f10fafa --- /dev/null +++ b/libraries/tools/kotlin-compose-compiler/src/common/resources/META-INF/gradle-plugins/kotlin-composecompiler.properties
@@ -0,0 +1 @@ +implementation-class=org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradleSubplugin \ No newline at end of file
diff --git a/libraries/tools/kotlin-compose-compiler/src/common/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin b/libraries/tools/kotlin-compose-compiler/src/common/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin new file mode 100644 index 0000000..3cdaffb --- /dev/null +++ b/libraries/tools/kotlin-compose-compiler/src/common/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
@@ -0,0 +1 @@ +org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradleSubplugin \ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin-model/src/common/kotlin/org/jetbrains/kotlin/gradle/model/ComposeCompiler.kt b/libraries/tools/kotlin-gradle-plugin-model/src/common/kotlin/org/jetbrains/kotlin/gradle/model/ComposeCompiler.kt new file mode 100644 index 0000000..d4b216d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-model/src/common/kotlin/org/jetbrains/kotlin/gradle/model/ComposeCompiler.kt
@@ -0,0 +1,35 @@ +/* + * Copyright 2010-2018 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.model + +/** + * Entry point for Kotlin All Open models. + * Represents the description of annotations interpreted by 'kotlin-allopen' plugin. + */ +interface ComposeCompiler { + + /** + * Return a number representing the version of this API. + * Always increasing if changed. + * + * @return the version of this model. + */ + val modelVersion: Long + + /** + * Returns the module (Gradle project) name. + * + * @return the module name. + */ + val name: String + + /** + * Return the list of presets. + * + * @return the list of presets. + */ + val presets: List<String> +} \ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugins-bom/build.gradle.kts b/libraries/tools/kotlin-gradle-plugins-bom/build.gradle.kts index ea65b4c..f04820f 100644 --- a/libraries/tools/kotlin-gradle-plugins-bom/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugins-bom/build.gradle.kts
@@ -17,6 +17,7 @@ // plugins api(project(":kotlin-gradle-plugin")) api(project(":atomicfu")) + api(project(":compose-compiler-gradle-plugin")) api(project(":kotlin-allopen")) api(project(":kotlin-lombok")) api(project(":kotlin-noarg"))
diff --git a/plugins/compose-compiler-plugin b/plugins/compose-compiler-plugin new file mode 160000 index 0000000..8102984 --- /dev/null +++ b/plugins/compose-compiler-plugin
@@ -0,0 +1 @@ +Subproject commit 81029848464870e6cee7225c7186df9fe3e26677
diff --git a/plugins/compose/compose-compiler-plugin b/plugins/compose/compose-compiler-plugin new file mode 160000 index 0000000..8102984 --- /dev/null +++ b/plugins/compose/compose-compiler-plugin
@@ -0,0 +1 @@ +Subproject commit 81029848464870e6cee7225c7186df9fe3e26677
diff --git a/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/tasks.kt b/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/tasks.kt index c9cbc93..fe3809f 100644 --- a/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/tasks.kt +++ b/repo/gradle-build-conventions/buildsrc-compat/src/main/kotlin/tasks.kt
@@ -33,6 +33,7 @@ val kotlinGradlePluginAndItsRequired = arrayOf( ":kotlin-assignment", + ":compose-compiler-gradle-plugin", ":kotlin-allopen", ":kotlin-noarg", ":kotlin-power-assert",
diff --git a/settings.gradle b/settings.gradle index fbf9806..60ab9a6 100644 --- a/settings.gradle +++ b/settings.gradle
@@ -231,6 +231,7 @@ ":libraries:tools:gradle:fus-statistics-gradle-plugin", ":kotlin-tooling-metadata", ":kotlin-tooling-core", + ":compose-compiler-gradle-plugin", ":kotlin-allopen", ":kotlin-noarg", ":kotlin-power-assert", @@ -796,6 +797,7 @@ project(":gradle:regression-benchmarks").projectDir = "$rootDir/libraries/tools/gradle/regression-benchmarks" as File project(':kotlin-tooling-metadata').projectDir = "$rootDir/libraries/tools/kotlin-tooling-metadata" as File project(':kotlin-tooling-core').projectDir = "$rootDir/libraries/tools/kotlin-tooling-core" as File +project(':compose-compiler-gradle-plugin').projectDir = "$rootDir/libraries/tools/kotlin-compose-compiler" as File project(':kotlin-allopen').projectDir = "$rootDir/libraries/tools/kotlin-allopen" as File project(':kotlin-noarg').projectDir = "$rootDir/libraries/tools/kotlin-noarg" as File project(':kotlin-power-assert').projectDir = "$rootDir/libraries/tools/kotlin-power-assert" as File