[Parcelize] Allow parcelize to work on common code in multiplatform.
Since parcelize is Android specific, it should only be enabled for Android compilation. In order to allow parcelize to generate code for declarations in common code, we make checkers platform checkers and we allow the registration of an additional annotations to trigger parcelize processing. That way, code such as: ``` package my.package annotation class Parcelize expect interface MyParcelable @Parcelize data class User(name: String): MyParcelable ``` Will work with an Android platform actual of the form: ``` actual typealias MyParcelable = android.os.Parcelable ``` And telling the plugin to trigger parcelize processing with the additional annotation `my.package.Parcelize`. Fixes https://issuetracker.google.com/315775835.
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.parcelize.ParcelizeCommandLineProcessor
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.parcelize
|
||||
|
||||
import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOption
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
|
||||
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
|
||||
class ParcelizeCommandLineProcessor : CommandLineProcessor {
|
||||
companion object {
|
||||
const val COMPILER_PLUGIN_ID: String = "org.jetbrains.kotlin.parcelize"
|
||||
|
||||
val ADDITIONAL_ANNOTATION_OPTION: CliOption =
|
||||
CliOption(
|
||||
"additionalAnnotation",
|
||||
"<fully qualified name>",
|
||||
"Additional annotation to trigger parcelize processing.",
|
||||
required = false,
|
||||
allowMultipleOccurrences = true
|
||||
)
|
||||
}
|
||||
|
||||
override val pluginId: String
|
||||
get() = COMPILER_PLUGIN_ID
|
||||
|
||||
override val pluginOptions: Collection<AbstractCliOption>
|
||||
get() = listOf(ADDITIONAL_ANNOTATION_OPTION)
|
||||
|
||||
override fun processOption(option: AbstractCliOption, value: String, configuration: CompilerConfiguration) {
|
||||
when (option) {
|
||||
ADDITIONAL_ANNOTATION_OPTION -> configuration.appendList(ParcelizeConfigurationKeys.ADDITIONAL_ANNOTATION, value)
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.optionName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
-10
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.container.useInstance
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.parcelize.fir.FirParcelizeExtensionRegistrar
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
@@ -21,35 +22,44 @@ import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
|
||||
|
||||
class ParcelizeComponentRegistrar : CompilerPluginRegistrar() {
|
||||
companion object {
|
||||
fun registerParcelizeComponents(extensionStorage: ExtensionStorage, useFir: Boolean) = with(extensionStorage) {
|
||||
fun registerParcelizeComponents(
|
||||
extensionStorage: ExtensionStorage,
|
||||
additionalAnnotation: List<String>,
|
||||
useFir: Boolean
|
||||
) = with(extensionStorage) {
|
||||
val parcelizeAnnotations = ParcelizeNames.PARCELIZE_CLASS_FQ_NAMES.toMutableList()
|
||||
additionalAnnotation.mapTo(parcelizeAnnotations) { FqName(it) }
|
||||
if (useFir) {
|
||||
IrGenerationExtension.registerExtension(ParcelizeFirIrGeneratorExtension())
|
||||
IrGenerationExtension.registerExtension(ParcelizeFirIrGeneratorExtension(parcelizeAnnotations))
|
||||
} else {
|
||||
IrGenerationExtension.registerExtension(ParcelizeIrGeneratorExtension())
|
||||
IrGenerationExtension.registerExtension(ParcelizeIrGeneratorExtension(parcelizeAnnotations))
|
||||
}
|
||||
SyntheticResolveExtension.registerExtension(ParcelizeResolveExtension())
|
||||
StorageComponentContainerContributor.registerExtension(ParcelizeDeclarationCheckerComponentContainerContributor())
|
||||
FirExtensionRegistrarAdapter.registerExtension(FirParcelizeExtensionRegistrar())
|
||||
SyntheticResolveExtension.registerExtension(ParcelizeResolveExtension(parcelizeAnnotations))
|
||||
StorageComponentContainerContributor.registerExtension(ParcelizeDeclarationCheckerComponentContainerContributor(parcelizeAnnotations))
|
||||
FirExtensionRegistrarAdapter.registerExtension(FirParcelizeExtensionRegistrar(parcelizeAnnotations))
|
||||
}
|
||||
}
|
||||
|
||||
override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
|
||||
registerParcelizeComponents(this, configuration.getBoolean(CommonConfigurationKeys.USE_FIR))
|
||||
val additionalAnnotation = configuration.get(ParcelizeConfigurationKeys.ADDITIONAL_ANNOTATION) ?: emptyList()
|
||||
registerParcelizeComponents(this, additionalAnnotation, configuration.getBoolean(CommonConfigurationKeys.USE_FIR))
|
||||
}
|
||||
|
||||
override val supportsK2: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
class ParcelizeDeclarationCheckerComponentContainerContributor : StorageComponentContainerContributor {
|
||||
class ParcelizeDeclarationCheckerComponentContainerContributor(
|
||||
private val parcelizeAnnotations: List<FqName>
|
||||
) : StorageComponentContainerContributor {
|
||||
override fun registerModuleComponents(
|
||||
container: StorageComponentContainer,
|
||||
platform: TargetPlatform,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
) {
|
||||
if (platform.isJvm()) {
|
||||
container.useInstance(ParcelizeDeclarationChecker())
|
||||
container.useInstance(ParcelizeAnnotationChecker())
|
||||
container.useInstance(ParcelizeDeclarationChecker(parcelizeAnnotations))
|
||||
container.useInstance(ParcelizeAnnotationChecker(parcelizeAnnotations))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* 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.parcelize
|
||||
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
|
||||
object ParcelizeConfigurationKeys {
|
||||
val ADDITIONAL_ANNOTATION: CompilerConfigurationKey<List<String>> =
|
||||
CompilerConfigurationKey.create(ParcelizeCommandLineProcessor.ADDITIONAL_ANNOTATION_OPTION.description)
|
||||
}
|
||||
Reference in New Issue
Block a user