[FIR] Implement FIR version of parcelize plugin
This commit includes only generation of declarations and ir backend part, checkers are added in separate commit
This commit is contained in:
committed by
teamcityserver
parent
cb0705ec03
commit
eac9a9fc79
@@ -31,10 +31,7 @@ import org.jetbrains.kotlin.kapt3.test.AbstractIrKotlinKaptContextTest
|
||||
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptContextTest
|
||||
import org.jetbrains.kotlin.lombok.AbstractLombokCompileTest
|
||||
import org.jetbrains.kotlin.noarg.*
|
||||
import org.jetbrains.kotlin.parcelize.test.runners.AbstractParcelizeBoxTest
|
||||
import org.jetbrains.kotlin.parcelize.test.runners.AbstractParcelizeBytecodeListingTest
|
||||
import org.jetbrains.kotlin.parcelize.test.runners.AbstractParcelizeIrBoxTest
|
||||
import org.jetbrains.kotlin.parcelize.test.runners.AbstractParcelizeIrBytecodeListingTest
|
||||
import org.jetbrains.kotlin.parcelize.test.runners.*
|
||||
import org.jetbrains.kotlin.samWithReceiver.AbstractSamWithReceiverScriptTest
|
||||
import org.jetbrains.kotlin.samWithReceiver.AbstractSamWithReceiverTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
@@ -362,6 +359,10 @@ fun main(args: Array<String>) {
|
||||
model("box")
|
||||
}
|
||||
|
||||
testClass<AbstractParcelizeFirBoxTest> {
|
||||
model("box")
|
||||
}
|
||||
|
||||
testClass<AbstractParcelizeBytecodeListingTest> {
|
||||
model("codegen")
|
||||
}
|
||||
|
||||
@@ -24,6 +24,17 @@ dependencies {
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("asm-all", rootProject = rootProject) }
|
||||
|
||||
// FIR dependencies
|
||||
compileOnly(project(":compiler:fir:cones"))
|
||||
compileOnly(project(":compiler:fir:tree"))
|
||||
compileOnly(project(":compiler:fir:resolve"))
|
||||
compileOnly(project(":compiler:fir:checkers"))
|
||||
compileOnly(project(":compiler:fir:fir2ir"))
|
||||
compileOnly(project(":compiler:ir.backend.common"))
|
||||
compileOnly(project(":compiler:ir.tree.impl"))
|
||||
compileOnly(project(":compiler:fir:entrypoint"))
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
|
||||
testApiJUnit5()
|
||||
|
||||
testApi(project(":compiler:util"))
|
||||
@@ -39,6 +50,15 @@ dependencies {
|
||||
testApi(projectTests(":compiler:test-infrastructure"))
|
||||
testApi(projectTests(":compiler:test-infrastructure-utils"))
|
||||
|
||||
// FIR dependencies
|
||||
testApi(project(":compiler:fir:checkers"))
|
||||
testApi(project(":compiler:fir:checkers:checkers.jvm"))
|
||||
testRuntimeOnly(project(":compiler:fir:fir-serialization"))
|
||||
|
||||
testCompileOnly(project(":kotlin-reflect-api"))
|
||||
testRuntimeOnly(project(":kotlin-reflect"))
|
||||
testRuntimeOnly(project(":core:descriptors.runtime"))
|
||||
|
||||
testApi(commonDep("junit:junit"))
|
||||
|
||||
testRuntimeOnly(intellijPluginDep("junit"))
|
||||
|
||||
+8
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.parcelize.ir.AndroidSymbols
|
||||
import org.jetbrains.kotlin.parcelize.ir.ParcelizeFirIrTransformer
|
||||
import org.jetbrains.kotlin.parcelize.ir.ParcelizeIrTransformer
|
||||
|
||||
class ParcelizeIrGeneratorExtension : IrGenerationExtension {
|
||||
@@ -17,3 +18,10 @@ class ParcelizeIrGeneratorExtension : IrGenerationExtension {
|
||||
ParcelizeIrTransformer(pluginContext, androidSymbols).transform(moduleFragment)
|
||||
}
|
||||
}
|
||||
|
||||
class ParcelizeFirIrGeneratorExtension : IrGenerationExtension {
|
||||
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
|
||||
val androidSymbols = AndroidSymbols(pluginContext.irBuiltIns, moduleFragment)
|
||||
ParcelizeFirIrTransformer(pluginContext, androidSymbols).transform(moduleFragment)
|
||||
}
|
||||
}
|
||||
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fir
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPluginKey
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
|
||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||
import org.jetbrains.kotlin.fir.extensions.predicate.has
|
||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.isInt
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.parcelize.ParcelizeSyntheticComponent.ComponentKind
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
|
||||
class FirParcelizeDeclarationGenerator(session: FirSession) : FirDeclarationGenerationExtension(session) {
|
||||
companion object {
|
||||
private val PARCELIZE_ID = ClassId(FqName("kotlinx.parcelize"), Name.identifier("Parcelize"))
|
||||
private val OLD_PARCELIZE_ID = ClassId(FqName("kotlinx.android.parcel"), Name.identifier("Parcelize"))
|
||||
private val PREDICATE = has(PARCELIZE_ID.asSingleFqName(), OLD_PARCELIZE_ID.asSingleFqName())
|
||||
|
||||
private val DESCRIBE_CONTENTS_NAME = Name.identifier(ComponentKind.DESCRIBE_CONTENTS.methodName)
|
||||
private val WRITE_TO_PARCEL_NAME = Name.identifier(ComponentKind.WRITE_TO_PARCEL.methodName)
|
||||
private val DEST_NAME = Name.identifier("dest")
|
||||
|
||||
private val FLAGS_NAME = Name.identifier("flags")
|
||||
|
||||
private val PARCEL_ID = ClassId(FqName("android.os"), Name.identifier("Parcel"))
|
||||
private val parcelizeMethodsNames = setOf(DESCRIBE_CONTENTS_NAME, WRITE_TO_PARCEL_NAME)
|
||||
}
|
||||
|
||||
private val matchedClasses by lazy {
|
||||
session.predicateBasedProvider.getSymbolsByPredicate(PREDICATE)
|
||||
.filterIsInstance<FirRegularClassSymbol>()
|
||||
}
|
||||
|
||||
override fun generateFunctions(callableId: CallableId, owner: FirClassSymbol<*>?): List<FirNamedFunctionSymbol> {
|
||||
if (owner == null) return emptyList()
|
||||
require(owner is FirRegularClassSymbol)
|
||||
val functionSymbol = when (callableId.callableName) {
|
||||
DESCRIBE_CONTENTS_NAME -> {
|
||||
val hasDescribeContentImplementation = owner.hasDescribeContentsImplementation() ||
|
||||
lookupSuperTypes(owner, lookupInterfaces = false, deep = true, session).any {
|
||||
it.fullyExpandedType(session).toRegularClassSymbol(session)?.hasDescribeContentsImplementation() ?: false
|
||||
}
|
||||
runIf(!hasDescribeContentImplementation) {
|
||||
generateDescribeContents(owner, callableId)
|
||||
}
|
||||
}
|
||||
WRITE_TO_PARCEL_NAME -> {
|
||||
val declaredFunctions = owner.declarationSymbols.filterIsInstance<FirNamedFunctionSymbol>()
|
||||
runIf(declaredFunctions.none { it.isWriteToParcel() }) { generateWriteToParcel(owner, callableId) }
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
return listOfNotNull(functionSymbol)
|
||||
}
|
||||
|
||||
private fun FirRegularClassSymbol.hasDescribeContentsImplementation(): Boolean {
|
||||
return declarationSymbols.filterIsInstance<FirNamedFunctionSymbol>().any { it.isDescribeContentsImplementation() }
|
||||
}
|
||||
|
||||
private fun FirNamedFunctionSymbol.isDescribeContentsImplementation(): Boolean {
|
||||
if (name != DESCRIBE_CONTENTS_NAME) return false
|
||||
return valueParameterSymbols.isEmpty()
|
||||
}
|
||||
|
||||
private fun FirNamedFunctionSymbol.isWriteToParcel(): Boolean {
|
||||
if (name != WRITE_TO_PARCEL_NAME) return false
|
||||
val parameterSymbols = valueParameterSymbols
|
||||
if (parameterSymbols.size != 2) return false
|
||||
val (destSymbol, flagsSymbol) = parameterSymbols
|
||||
if (destSymbol.resolvedReturnTypeRef.coneType.classId != PARCEL_ID) return false
|
||||
if (!flagsSymbol.resolvedReturnTypeRef.type.isInt) return false
|
||||
return true
|
||||
}
|
||||
|
||||
private fun generateDescribeContents(owner: FirRegularClassSymbol, callableId: CallableId): FirNamedFunctionSymbol {
|
||||
return createFunction(owner, callableId) {
|
||||
returnTypeRef = session.builtinTypes.intType
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateWriteToParcel(owner: FirRegularClassSymbol, callableId: CallableId): FirNamedFunctionSymbol {
|
||||
return createFunction(owner, callableId) {
|
||||
returnTypeRef = session.builtinTypes.unitType
|
||||
|
||||
valueParameters += buildValueParameter {
|
||||
moduleData = session.moduleData
|
||||
origin = key.origin
|
||||
name = DEST_NAME
|
||||
returnTypeRef = buildResolvedTypeRef {
|
||||
type = ConeClassLikeTypeImpl(
|
||||
ConeClassLikeLookupTagImpl(PARCEL_ID),
|
||||
emptyArray(),
|
||||
isNullable = false
|
||||
)
|
||||
}
|
||||
symbol = FirValueParameterSymbol(name)
|
||||
isCrossinline = false
|
||||
isNoinline = false
|
||||
isVararg = false
|
||||
}
|
||||
|
||||
valueParameters += buildValueParameter {
|
||||
moduleData = session.moduleData
|
||||
origin = key.origin
|
||||
name = FLAGS_NAME
|
||||
returnTypeRef = session.builtinTypes.intType
|
||||
symbol = FirValueParameterSymbol(name)
|
||||
isCrossinline = false
|
||||
isNoinline = false
|
||||
isVararg = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun createFunction(
|
||||
owner: FirRegularClassSymbol,
|
||||
callableId: CallableId,
|
||||
init: FirSimpleFunctionBuilder.() -> Unit
|
||||
): FirNamedFunctionSymbol {
|
||||
val function = buildSimpleFunction {
|
||||
moduleData = session.moduleData
|
||||
origin = key.origin
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
Visibilities.Public,
|
||||
if (owner.modality == Modality.FINAL) Modality.FINAL else Modality.OPEN,
|
||||
EffectiveVisibility.Public
|
||||
).apply {
|
||||
isOverride = true
|
||||
}
|
||||
name = callableId.callableName
|
||||
symbol = FirNamedFunctionSymbol(callableId)
|
||||
dispatchReceiverType = owner.defaultType()
|
||||
init()
|
||||
}
|
||||
return function.symbol
|
||||
}
|
||||
|
||||
@OptIn(SymbolInternals::class)
|
||||
override fun getCallableNamesForClass(classSymbol: FirClassSymbol<*>): Set<Name> {
|
||||
return when {
|
||||
classSymbol.fir.modality == Modality.ABSTRACT -> emptySet()
|
||||
classSymbol in matchedClasses && classSymbol.fir.modality != Modality.SEALED -> parcelizeMethodsNames
|
||||
else -> {
|
||||
val hasAnnotatedSealedSuperType = classSymbol.resolvedSuperTypeRefs.any {
|
||||
val superSymbol = it.type.fullyExpandedType(session).toRegularClassSymbol(session) ?: return@any false
|
||||
superSymbol.fir.modality == Modality.SEALED && superSymbol in matchedClasses
|
||||
}
|
||||
if (hasAnnotatedSealedSuperType) {
|
||||
parcelizeMethodsNames
|
||||
} else {
|
||||
emptySet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val key: FirPluginKey
|
||||
get() = FirParcelizePluginKey
|
||||
|
||||
override fun FirDeclarationPredicateRegistrar.registerPredicates() {
|
||||
register(PREDICATE)
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||
|
||||
class FirParcelizeExtensionRegistrar : FirExtensionRegistrar() {
|
||||
override fun ExtensionRegistrarContext.configurePlugin() {
|
||||
+::FirParcelizeDeclarationGenerator
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPluginKey
|
||||
|
||||
object FirParcelizePluginKey : FirPluginKey() {
|
||||
override fun toString(): String {
|
||||
return "FirParcelize"
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.backend.IrPluginDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.util.companionObject
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.parcelize.PARCELER_FQNAME
|
||||
import org.jetbrains.kotlin.parcelize.ParcelizeSyntheticComponent
|
||||
import org.jetbrains.kotlin.parcelize.fir.FirParcelizePluginKey
|
||||
import org.jetbrains.kotlin.parcelize.serializers.ParcelizeExtensionBase
|
||||
|
||||
class ParcelizeFirIrTransformer(
|
||||
context: IrPluginContext,
|
||||
androidSymbols: AndroidSymbols
|
||||
) : ParcelizeIrTransformerBase(context, androidSymbols) {
|
||||
|
||||
fun transform(moduleFragment: IrModuleFragment) {
|
||||
moduleFragment.accept(this, null)
|
||||
deferredOperations.forEach { it() }
|
||||
}
|
||||
|
||||
override fun visitElement(element: IrElement) = element.acceptChildren(this, null)
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
declaration.acceptChildren(this, null)
|
||||
|
||||
// Sealed classes can be annotated with `@Parcelize`, but that only implies that we
|
||||
// should process their immediate subclasses.
|
||||
if (!declaration.isParcelize || declaration.modality == Modality.SEALED)
|
||||
return
|
||||
|
||||
val parcelableProperties = declaration.parcelableProperties
|
||||
|
||||
// If the companion extends Parceler, it can override parts of the generated implementation.
|
||||
val parcelerObject = declaration.companionObject()?.takeIf {
|
||||
it.isSubclassOfFqName(PARCELER_FQNAME.asString())
|
||||
}
|
||||
|
||||
for (function in declaration.functions) {
|
||||
val origin = function.origin
|
||||
if (origin !is IrPluginDeclarationOrigin || origin.pluginKey != FirParcelizePluginKey) continue
|
||||
when (function.name.identifier) {
|
||||
ParcelizeSyntheticComponent.ComponentKind.DESCRIBE_CONTENTS.methodName -> {
|
||||
function.generateDescribeContentsBody(parcelableProperties)
|
||||
}
|
||||
ParcelizeSyntheticComponent.ComponentKind.WRITE_TO_PARCEL.methodName -> {
|
||||
function.apply {
|
||||
val receiverParameter = dispatchReceiverParameter!!
|
||||
val (parcelParameter, flagsParameter) = function.valueParameters
|
||||
|
||||
// We need to defer the construction of the writer, since it may refer to the [writeToParcel] methods in other
|
||||
// @Parcelize classes in the current module, which might not be constructed yet at this point.
|
||||
defer {
|
||||
generateWriteToParcelBody(
|
||||
declaration,
|
||||
parcelerObject,
|
||||
parcelableProperties,
|
||||
receiverParameter,
|
||||
parcelParameter,
|
||||
flagsParameter
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> error("Generated declaration with unknown name: ${function.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
generateCreator(declaration, parcelerObject, parcelableProperties)
|
||||
}
|
||||
}
|
||||
+24
-168
@@ -6,54 +6,42 @@
|
||||
package org.jetbrains.kotlin.parcelize.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.util.companionObject
|
||||
import org.jetbrains.kotlin.ir.util.copyTypeAndValueArgumentsFrom
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.parcelize.ANDROID_PARCELABLE_CLASS_FQNAME
|
||||
import org.jetbrains.kotlin.parcelize.PARCELER_FQNAME
|
||||
import org.jetbrains.kotlin.parcelize.ParcelizeSyntheticComponent
|
||||
import org.jetbrains.kotlin.parcelize.serializers.ParcelizeExtensionBase
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
class ParcelizeIrTransformer(private val context: IrPluginContext, private val androidSymbols: AndroidSymbols) :
|
||||
ParcelizeExtensionBase, IrElementVisitorVoid {
|
||||
private val serializerFactory = IrParcelSerializerFactory(androidSymbols)
|
||||
|
||||
private val deferredOperations = mutableListOf<() -> Unit>()
|
||||
private fun defer(block: () -> Unit) = deferredOperations.add(block)
|
||||
|
||||
private fun IrPluginContext.createIrBuilder(symbol: IrSymbol) =
|
||||
DeclarationIrBuilder(this, symbol, symbol.owner.startOffset, symbol.owner.endOffset)
|
||||
|
||||
class ParcelizeIrTransformer(
|
||||
context: IrPluginContext,
|
||||
androidSymbols: AndroidSymbols
|
||||
) : ParcelizeIrTransformerBase(context, androidSymbols) {
|
||||
private val symbolMap = mutableMapOf<IrSimpleFunctionSymbol, IrSimpleFunctionSymbol>()
|
||||
|
||||
private val irFactory: IrFactory = IrFactoryImpl
|
||||
|
||||
fun transform(moduleFragment: IrModuleFragment) {
|
||||
moduleFragment.accept(this, null)
|
||||
deferredOperations.forEach { it() }
|
||||
@@ -142,10 +130,7 @@ class ParcelizeIrTransformer(private val context: IrPluginContext, private val a
|
||||
context.irBuiltIns.intType,
|
||||
modality = Modality.OPEN
|
||||
).apply {
|
||||
val flags = if (parcelableProperties.any { it.field.type.containsFileDescriptors }) 1 else 0
|
||||
body = context.createIrBuilder(symbol).run {
|
||||
irExprBody(irInt(flags))
|
||||
}
|
||||
generateDescribeContentsBody(parcelableProperties)
|
||||
|
||||
metadata = DescriptorMetadataSource.Function(
|
||||
declaration.descriptor.findFunction(ParcelizeSyntheticComponent.ComponentKind.DESCRIBE_CONTENTS)!!
|
||||
@@ -174,32 +159,14 @@ class ParcelizeIrTransformer(private val context: IrPluginContext, private val a
|
||||
// We need to defer the construction of the writer, since it may refer to the [writeToParcel] methods in other
|
||||
// @Parcelize classes in the current module, which might not be constructed yet at this point.
|
||||
defer {
|
||||
body = androidSymbols.createBuilder(symbol).run {
|
||||
irBlockBody {
|
||||
when {
|
||||
parcelerObject != null ->
|
||||
+parcelerWrite(parcelerObject, parcelParameter, flagsParameter, irGet(receiverParameter))
|
||||
|
||||
parcelableProperties.isNotEmpty() ->
|
||||
for (property in parcelableProperties) {
|
||||
+writeParcelWith(
|
||||
property.parceler,
|
||||
parcelParameter,
|
||||
flagsParameter,
|
||||
irGetField(irGet(receiverParameter), property.field)
|
||||
)
|
||||
}
|
||||
|
||||
else ->
|
||||
+writeParcelWith(
|
||||
declaration.classParceler,
|
||||
parcelParameter,
|
||||
flagsParameter,
|
||||
irGet(receiverParameter)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
generateWriteToParcelBody(
|
||||
declaration,
|
||||
parcelerObject,
|
||||
parcelableProperties,
|
||||
receiverParameter,
|
||||
parcelParameter,
|
||||
flagsParameter
|
||||
)
|
||||
}
|
||||
|
||||
metadata = DescriptorMetadataSource.Function(
|
||||
@@ -215,85 +182,8 @@ class ParcelizeIrTransformer(private val context: IrPluginContext, private val a
|
||||
}
|
||||
}
|
||||
|
||||
// Since the `CREATOR` object cannot refer to the type parameters of the parcelable class we use a star projected type
|
||||
val declarationType = declaration.symbol.starProjectedType
|
||||
val creatorType = androidSymbols.androidOsParcelableCreator.typeWith(declarationType)
|
||||
|
||||
if (!declaration.descriptor.hasCreatorField()) {
|
||||
declaration.addField {
|
||||
name = ParcelizeExtensionBase.CREATOR_NAME
|
||||
type = creatorType
|
||||
isStatic = true
|
||||
isFinal = true
|
||||
}.apply {
|
||||
val irField = this
|
||||
val creatorClass = irFactory.buildClass {
|
||||
name = Name.identifier("Creator")
|
||||
visibility = DescriptorVisibilities.LOCAL
|
||||
}.apply {
|
||||
parent = irField
|
||||
superTypes = listOf(creatorType)
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
|
||||
addConstructor {
|
||||
isPrimary = true
|
||||
}.apply {
|
||||
body = context.createIrBuilder(symbol).irBlockBody {
|
||||
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
|
||||
}
|
||||
}
|
||||
|
||||
val arrayType = context.irBuiltIns.arrayClass.typeWith(declarationType.makeNullable())
|
||||
addFunction("newArray", arrayType).apply {
|
||||
overriddenSymbols = listOf(androidSymbols.androidOsParcelableCreator.getSimpleFunction(name.asString())!!)
|
||||
val sizeParameter = addValueParameter("size", context.irBuiltIns.intType)
|
||||
body = context.createIrBuilder(symbol).run {
|
||||
irExprBody(
|
||||
parcelerNewArray(parcelerObject, sizeParameter)
|
||||
?: irCall(context.irBuiltIns.arrayOfNulls, arrayType).apply {
|
||||
putTypeArgument(0, arrayType)
|
||||
putValueArgument(0, irGet(sizeParameter))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
addFunction("createFromParcel", declarationType).apply {
|
||||
overriddenSymbols = listOf(androidSymbols.androidOsParcelableCreator.getSimpleFunction(name.asString())!!)
|
||||
val parcelParameter = addValueParameter("parcel", androidSymbols.androidOsParcel.defaultType)
|
||||
|
||||
// We need to defer the construction of the create method, since it may refer to the [Parcelable.Creator]
|
||||
// instances in other @Parcelize classes in the current module, which may not exist yet.
|
||||
defer {
|
||||
body = androidSymbols.createBuilder(symbol).run {
|
||||
irExprBody(
|
||||
when {
|
||||
parcelerObject != null ->
|
||||
parcelerCreate(parcelerObject, parcelParameter)
|
||||
|
||||
parcelableProperties.isNotEmpty() ->
|
||||
irCall(declaration.primaryConstructor!!).apply {
|
||||
for ((index, property) in parcelableProperties.withIndex()) {
|
||||
putValueArgument(index, readParcelWith(property.parceler, parcelParameter))
|
||||
}
|
||||
}
|
||||
|
||||
else ->
|
||||
readParcelWith(declaration.classParceler, parcelParameter)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initializer = context.createIrBuilder(symbol).run {
|
||||
irExprBody(irBlock {
|
||||
+creatorClass
|
||||
+irCall(creatorClass.primaryConstructor!!)
|
||||
})
|
||||
}
|
||||
}
|
||||
generateCreator(declaration, parcelerObject, parcelableProperties)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,38 +201,4 @@ class ParcelizeIrTransformer(private val context: IrPluginContext, private val a
|
||||
}.map { it.symbol }.toList()
|
||||
}
|
||||
}
|
||||
|
||||
private class ParcelableProperty(val field: IrField, parcelerThunk: () -> IrParcelSerializer) {
|
||||
val parceler by lazy(parcelerThunk)
|
||||
}
|
||||
|
||||
private val IrClass.classParceler: IrParcelSerializer
|
||||
get() = if (kind == ClassKind.CLASS) {
|
||||
IrNoParameterClassParcelSerializer(this)
|
||||
} else {
|
||||
serializerFactory.get(defaultType, parcelizeType = defaultType, strict = true, toplevel = true, scope = getParcelerScope())
|
||||
}
|
||||
|
||||
private val IrClass.parcelableProperties: List<ParcelableProperty>
|
||||
get() {
|
||||
if (kind != ClassKind.CLASS) return emptyList()
|
||||
|
||||
val constructor = primaryConstructor ?: return emptyList()
|
||||
val topLevelScope = getParcelerScope()
|
||||
|
||||
return constructor.valueParameters.map { parameter ->
|
||||
val property = properties.first { it.name == parameter.name }
|
||||
val localScope = property.getParcelerScope(topLevelScope)
|
||||
ParcelableProperty(property.backingField!!) {
|
||||
serializerFactory.get(parameter.type, parcelizeType = defaultType, scope = localScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *Heuristic* to determine if a Parcelable contains file descriptors.
|
||||
private val IrType.containsFileDescriptors: Boolean
|
||||
get() = erasedUpperBound.fqNameWhenAvailable == ParcelizeExtensionBase.FILE_DESCRIPTOR_FQNAME ||
|
||||
(this as? IrSimpleType)?.arguments?.any { argument ->
|
||||
argument.typeOrNull?.containsFileDescriptors == true
|
||||
} == true
|
||||
}
|
||||
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.parcelize.serializers.ParcelizeExtensionBase
|
||||
|
||||
abstract class ParcelizeIrTransformerBase(
|
||||
protected val context: IrPluginContext,
|
||||
protected val androidSymbols: AndroidSymbols
|
||||
) : ParcelizeExtensionBase, IrElementVisitorVoid {
|
||||
private val irFactory: IrFactory = IrFactoryImpl
|
||||
|
||||
protected val deferredOperations = mutableListOf<() -> Unit>()
|
||||
protected fun defer(block: () -> Unit) = deferredOperations.add(block)
|
||||
|
||||
protected fun IrSimpleFunction.generateDescribeContentsBody(parcelableProperties: List<ParcelableProperty>) {
|
||||
val flags = if (parcelableProperties.any { it.field.type.containsFileDescriptors }) 1 else 0
|
||||
body = context.createIrBuilder(symbol).run {
|
||||
irExprBody(irInt(flags))
|
||||
}
|
||||
}
|
||||
|
||||
protected fun IrSimpleFunction.generateWriteToParcelBody(
|
||||
irClass: IrClass,
|
||||
parcelerObject: IrClass?,
|
||||
parcelableProperties: List<ParcelableProperty>,
|
||||
receiverParameter: IrValueParameter,
|
||||
parcelParameter: IrValueParameter,
|
||||
flagsParameter: IrValueParameter
|
||||
) {
|
||||
body = androidSymbols.createBuilder(symbol).run {
|
||||
irBlockBody {
|
||||
when {
|
||||
parcelerObject != null ->
|
||||
+parcelerWrite(parcelerObject, parcelParameter, flagsParameter, irGet(receiverParameter))
|
||||
|
||||
parcelableProperties.isNotEmpty() ->
|
||||
for (property in parcelableProperties) {
|
||||
+writeParcelWith(
|
||||
property.parceler,
|
||||
parcelParameter,
|
||||
flagsParameter,
|
||||
irGetField(irGet(receiverParameter), property.field)
|
||||
)
|
||||
}
|
||||
|
||||
else ->
|
||||
+writeParcelWith(
|
||||
irClass.classParceler,
|
||||
parcelParameter,
|
||||
flagsParameter,
|
||||
irGet(receiverParameter)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected fun generateCreator(declaration: IrClass, parcelerObject: IrClass?, parcelableProperties: List<ParcelableProperty>) {
|
||||
// Since the `CREATOR` object cannot refer to the type parameters of the parcelable class we use a star projected type
|
||||
val declarationType = declaration.symbol.starProjectedType
|
||||
val creatorType = androidSymbols.androidOsParcelableCreator.typeWith(declarationType)
|
||||
|
||||
declaration.addField {
|
||||
name = ParcelizeExtensionBase.CREATOR_NAME
|
||||
type = creatorType
|
||||
isStatic = true
|
||||
isFinal = true
|
||||
}.apply {
|
||||
val irField = this
|
||||
val creatorClass = irFactory.buildClass {
|
||||
name = Name.identifier("Creator")
|
||||
visibility = DescriptorVisibilities.LOCAL
|
||||
}.apply {
|
||||
parent = irField
|
||||
superTypes = listOf(creatorType)
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
|
||||
addConstructor {
|
||||
isPrimary = true
|
||||
}.apply {
|
||||
body = context.createIrBuilder(symbol).irBlockBody {
|
||||
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
|
||||
}
|
||||
}
|
||||
|
||||
val arrayType = context.irBuiltIns.arrayClass.typeWith(declarationType.makeNullable())
|
||||
addFunction("newArray", arrayType).apply {
|
||||
overriddenSymbols = listOf(androidSymbols.androidOsParcelableCreator.getSimpleFunction(name.asString())!!)
|
||||
val sizeParameter = addValueParameter("size", context.irBuiltIns.intType)
|
||||
body = context.createIrBuilder(symbol).run {
|
||||
irExprBody(
|
||||
parcelerNewArray(parcelerObject, sizeParameter)
|
||||
?: irCall(context.irBuiltIns.arrayOfNulls, arrayType).apply {
|
||||
putTypeArgument(0, arrayType)
|
||||
putValueArgument(0, irGet(sizeParameter))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
addFunction("createFromParcel", declarationType).apply {
|
||||
overriddenSymbols = listOf(androidSymbols.androidOsParcelableCreator.getSimpleFunction(name.asString())!!)
|
||||
val parcelParameter = addValueParameter("parcel", androidSymbols.androidOsParcel.defaultType)
|
||||
|
||||
// We need to defer the construction of the create method, since it may refer to the [Parcelable.Creator]
|
||||
// instances in other @Parcelize classes in the current module, which may not exist yet.
|
||||
defer {
|
||||
body = androidSymbols.createBuilder(symbol).run {
|
||||
irExprBody(
|
||||
when {
|
||||
parcelerObject != null ->
|
||||
parcelerCreate(parcelerObject, parcelParameter)
|
||||
|
||||
parcelableProperties.isNotEmpty() ->
|
||||
irCall(declaration.primaryConstructor!!).apply {
|
||||
for ((index, property) in parcelableProperties.withIndex()) {
|
||||
putValueArgument(index, readParcelWith(property.parceler, parcelParameter))
|
||||
}
|
||||
}
|
||||
|
||||
else ->
|
||||
readParcelWith(declaration.classParceler, parcelParameter)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initializer = context.createIrBuilder(symbol).run {
|
||||
irExprBody(irBlock {
|
||||
+creatorClass
|
||||
+irCall(creatorClass.primaryConstructor!!)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val IrClass.classParceler: IrParcelSerializer
|
||||
get() = if (kind == ClassKind.CLASS) {
|
||||
IrNoParameterClassParcelSerializer(this)
|
||||
} else {
|
||||
serializerFactory.get(defaultType, parcelizeType = defaultType, strict = true, toplevel = true, scope = getParcelerScope())
|
||||
}
|
||||
|
||||
protected class ParcelableProperty(val field: IrField, parcelerThunk: () -> IrParcelSerializer) {
|
||||
val parceler by lazy(parcelerThunk)
|
||||
}
|
||||
|
||||
private val serializerFactory = IrParcelSerializerFactory(androidSymbols)
|
||||
|
||||
protected val IrClass.parcelableProperties: List<ParcelableProperty>
|
||||
get() {
|
||||
if (kind != ClassKind.CLASS) return emptyList()
|
||||
|
||||
val constructor = primaryConstructor ?: return emptyList()
|
||||
val topLevelScope = getParcelerScope()
|
||||
|
||||
return constructor.valueParameters.map { parameter ->
|
||||
val property = properties.first { it.name == parameter.name }
|
||||
val localScope = property.getParcelerScope(topLevelScope)
|
||||
ParcelableProperty(property.backingField!!) {
|
||||
serializerFactory.get(parameter.type, parcelizeType = defaultType, scope = localScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *Heuristic* to determine if a Parcelable contains file descriptors.
|
||||
private val IrType.containsFileDescriptors: Boolean
|
||||
get() = erasedUpperBound.fqNameWhenAvailable == ParcelizeExtensionBase.FILE_DESCRIPTOR_FQNAME ||
|
||||
(this as? IrSimpleType)?.arguments?.any { argument ->
|
||||
argument.typeOrNull?.containsFileDescriptors == true
|
||||
} == true
|
||||
|
||||
private fun IrPluginContext.createIrBuilder(symbol: IrSymbol): DeclarationIrBuilder {
|
||||
return DeclarationIrBuilder(this, symbol, symbol.owner.startOffset, symbol.owner.endOffset)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
// WITH_STDLIB
|
||||
// fir doesn't support annotations with type arguments
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
@file:JvmName("TestKt")
|
||||
package test
|
||||
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
// WITH_STDLIB
|
||||
// fir doesn't support annotations with type arguments
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
@file:JvmName("TestKt")
|
||||
package test
|
||||
@@ -53,4 +55,4 @@ fun box() = parcelTest { parcel ->
|
||||
with (test2) {
|
||||
assert(a == 5 && b == -5 && c == 3L && d == listOf(-1, -2, -3) && Arrays.equals(e, longArrayOf(3, 3, 3)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
// WITH_STDLIB
|
||||
// fir doesn't support annotations with type arguments
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
@file:JvmName("TestKt")
|
||||
package test
|
||||
@@ -46,4 +48,4 @@ fun box() = parcelTest { parcel ->
|
||||
|
||||
assert(test.a == "Abc" && test.b == "Abc" && test.c == "Abc" && test.d == "Abc")
|
||||
assert(test2.a == "3" && test2.b == "3" && test2.c == "Abc" && test2.d == "ABC")
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -2,6 +2,8 @@
|
||||
// See KT-38107
|
||||
// The JVM backend is missing support for custom parcelers in List<String>
|
||||
// WITH_STDLIB
|
||||
// fir doesn't support annotations with type arguments
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
@file:JvmName("TestKt")
|
||||
package test
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// WITH_STDLIB
|
||||
// fir doesn't support annotations with type arguments
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
@file:JvmName("TestKt")
|
||||
package test
|
||||
|
||||
+477
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.test.runners;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("plugins/parcelize/parcelize-compiler/testData/box")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class ParcelizeFirBoxTestGenerated extends AbstractParcelizeFirBoxTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInBox() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/parcelize/parcelize-compiler/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("allPrimitiveTypes.kt")
|
||||
public void testAllPrimitiveTypes() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/allPrimitiveTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("allUnsignedTypes.kt")
|
||||
public void testAllUnsignedTypes() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/allUnsignedTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arraySimple.kt")
|
||||
public void testArraySimple() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/arraySimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrays.kt")
|
||||
public void testArrays() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/arrays.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("binder.kt")
|
||||
public void testBinder() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/binder.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("boxedTypes.kt")
|
||||
public void testBoxedTypes() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/boxedTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("bundle.kt")
|
||||
public void testBundle() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/bundle.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("charSequence.kt")
|
||||
public void testCharSequence() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/charSequence.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("customNewArray.kt")
|
||||
public void testCustomNewArray() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/customNewArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("customParcelable.kt")
|
||||
public void testCustomParcelable() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/customParcelable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("customParcelerScoping.kt")
|
||||
public void testCustomParcelerScoping() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/customParcelerScoping.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("customSerializerBoxing.kt")
|
||||
public void testCustomSerializerBoxing() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/customSerializerBoxing.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("customSerializerSimple.kt")
|
||||
public void testCustomSerializerSimple() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/customSerializerSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("customSerializerWriteWith.kt")
|
||||
public void testCustomSerializerWriteWith() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/customSerializerWriteWith.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("customSimple.kt")
|
||||
public void testCustomSimple() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/customSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("enumObject.kt")
|
||||
public void testEnumObject() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/enumObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("enums.kt")
|
||||
public void testEnums() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/enums.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exceptions.kt")
|
||||
public void testExceptions() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/exceptions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("functions.kt")
|
||||
public void testFunctions() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/functions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("genericParcelable.kt")
|
||||
public void testGenericParcelable() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/genericParcelable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("generics.kt")
|
||||
public void testGenerics() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/generics.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("intArray.kt")
|
||||
public void testIntArray() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/intArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaInterop.kt")
|
||||
public void testJavaInterop() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/javaInterop.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt19747.kt")
|
||||
public void testKt19747() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt19747.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt19747Deprecated.kt")
|
||||
public void testKt19747Deprecated() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt19747Deprecated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt19747_2.kt")
|
||||
public void testKt19747_2() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt19747_2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt19749.kt")
|
||||
public void testKt19749() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt19749.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt19853.kt")
|
||||
public void testKt19853() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt19853.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt20002.kt")
|
||||
public void testKt20002() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt20002.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt20021.kt")
|
||||
public void testKt20021() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt20021.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt20717.kt")
|
||||
public void testKt20717() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt20717.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt25839.kt")
|
||||
public void testKt25839() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt25839.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt26221.kt")
|
||||
public void testKt26221() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt26221.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt36658.kt")
|
||||
public void testKt36658() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt36658.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt39981.kt")
|
||||
public void testKt39981() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt39981.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt41553.kt")
|
||||
public void testKt41553() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt41553.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt41553_2.kt")
|
||||
public void testKt41553_2() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt41553_2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46567.kt")
|
||||
public void testKt46567() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/kt46567.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("listKinds.kt")
|
||||
public void testListKinds() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/listKinds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("listSimple.kt")
|
||||
public void testListSimple() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/listSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lists.kt")
|
||||
public void testLists() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/lists.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mapKinds.kt")
|
||||
public void testMapKinds() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/mapKinds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mapSimple.kt")
|
||||
public void testMapSimple() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/mapSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("maps.kt")
|
||||
public void testMaps() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/maps.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedArrays.kt")
|
||||
public void testNestedArrays() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/nestedArrays.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedLists.kt")
|
||||
public void testNestedLists() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/nestedLists.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedMaps.kt")
|
||||
public void testNestedMaps() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/nestedMaps.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedParcelable.kt")
|
||||
public void testNestedParcelable() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/nestedParcelable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedSparseArrays.kt")
|
||||
public void testNestedSparseArrays() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/nestedSparseArrays.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedSparseArrays2.kt")
|
||||
public void testNestedSparseArrays2() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/nestedSparseArrays2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("newArray.kt")
|
||||
public void testNewArray() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/newArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("newArrayParceler.kt")
|
||||
public void testNewArrayParceler() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/newArrayParceler.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableTypes.kt")
|
||||
public void testNullableTypes() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/nullableTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableTypesSimple.kt")
|
||||
public void testNullableTypesSimple() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/nullableTypesSimple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objectWriteParcelable.kt")
|
||||
public void testObjectWriteParcelable() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/objectWriteParcelable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("objects.kt")
|
||||
public void testObjects() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/objects.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("openParcelize.kt")
|
||||
public void testOpenParcelize() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/openParcelize.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("parcelableValueClass.kt")
|
||||
public void testParcelableValueClass() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/parcelableValueClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("parcelizeCustomValueClass.kt")
|
||||
public void testParcelizeCustomValueClass() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/parcelizeCustomValueClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("persistableBundle.kt")
|
||||
public void testPersistableBundle() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/persistableBundle.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("primitiveTypes.kt")
|
||||
public void testPrimitiveTypes() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/primitiveTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("privateConstructor.kt")
|
||||
public void testPrivateConstructor() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/privateConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveGenerics.kt")
|
||||
public void testRecursiveGenerics() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/recursiveGenerics.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sealedClass.kt")
|
||||
public void testSealedClass() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/sealedClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sealedClass2.kt")
|
||||
public void testSealedClass2() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/sealedClass2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sealedInterface.kt")
|
||||
public void testSealedInterface() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/sealedInterface.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("shortArray.kt")
|
||||
public void testShortArray() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/shortArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleDeprecated.kt")
|
||||
public void testSimpleDeprecated() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/simpleDeprecated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sparseArrays.kt")
|
||||
public void testSparseArrays() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/sparseArrays.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("sparseBooleanArray.kt")
|
||||
public void testSparseBooleanArray() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/sparseBooleanArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typeParameters.kt")
|
||||
public void testTypeParameters() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/typeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unsignedArrays.kt")
|
||||
public void testUnsignedArrays() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/unsignedArrays.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassWrapper.kt")
|
||||
public void testValueClassWrapper() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/valueClassWrapper.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClasses.kt")
|
||||
public void testValueClasses() throws Exception {
|
||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/valueClasses.kt");
|
||||
}
|
||||
}
|
||||
+41
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.parcelize.test.runners
|
||||
|
||||
import org.jetbrains.kotlin.parcelize.fir.FirParcelizeExtensionRegistrar
|
||||
import org.jetbrains.kotlin.parcelize.test.services.ParcelizeEnvironmentConfigurator
|
||||
import org.jetbrains.kotlin.parcelize.test.services.ParcelizeMainClassProvider
|
||||
import org.jetbrains.kotlin.parcelize.test.services.ParcelizeRuntimeClasspathProvider
|
||||
@@ -14,19 +15,26 @@ import org.jetbrains.kotlin.test.TargetBackend
|
||||
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
||||
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
|
||||
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
|
||||
import org.jetbrains.kotlin.test.backend.handlers.IrTextDumpHandler
|
||||
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
|
||||
import org.jetbrains.kotlin.test.bind
|
||||
import org.jetbrains.kotlin.test.builders.*
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.builders.configureClassicFrontendHandlersStep
|
||||
import org.jetbrains.kotlin.test.builders.configureFirHandlersStep
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.REQUIRES_SEPARATE_PROCESS
|
||||
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.DIAGNOSTICS
|
||||
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.REPORT_ONLY_EXPLICITLY_DEFINED_DEBUG_INFO
|
||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives.ENABLE_PLUGIN_PHASES
|
||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
|
||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
|
||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
|
||||
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
||||
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
|
||||
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
|
||||
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
|
||||
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
||||
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirDiagnosticsHandler
|
||||
import org.jetbrains.kotlin.test.model.*
|
||||
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
||||
@@ -63,10 +71,16 @@ abstract class AbstractParcelizeBoxTestBase<R : ResultingArtifact.FrontendOutput
|
||||
)
|
||||
}
|
||||
|
||||
configureIrHandlersStep {
|
||||
useHandlers(::IrTextDumpHandler)
|
||||
}
|
||||
|
||||
configureCommonHandlersForBoxTest()
|
||||
|
||||
useCustomRuntimeClasspathProviders(::ParcelizeRuntimeClasspathProvider)
|
||||
useConfigurators(::ParcelizeEnvironmentConfigurator)
|
||||
|
||||
useConfigurators(::ParcelizeEnvironmentConfigurator.bind(targetFrontend == FrontendKinds.FIR))
|
||||
|
||||
useAdditionalSourceProviders(::ParcelizeUtilSourcesProvider)
|
||||
|
||||
useAdditionalServices(service<JvmBoxMainClassProvider>(::ParcelizeMainClassProvider))
|
||||
@@ -104,3 +118,29 @@ open class AbstractParcelizeIrBoxTest : AbstractParcelizeBoxTestBase<ClassicFron
|
||||
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
|
||||
get() = ::JvmIrBackendFacade
|
||||
}
|
||||
|
||||
open class AbstractParcelizeFirBoxTest : AbstractParcelizeBoxTestBase<FirOutputArtifact, IrBackendInput>(
|
||||
FrontendKinds.FIR,
|
||||
TargetBackend.JVM_IR
|
||||
) {
|
||||
override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>>
|
||||
get() = { testServices ->
|
||||
FirFrontendFacade(testServices) {
|
||||
it.registerExtensions(FirParcelizeExtensionRegistrar().configure())
|
||||
}
|
||||
}
|
||||
|
||||
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
|
||||
get() = ::Fir2IrResultsConverter
|
||||
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.Jvm>>
|
||||
get() = ::JvmIrBackendFacade
|
||||
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
with(builder) {
|
||||
defaultDirectives {
|
||||
+ENABLE_PLUGIN_PHASES
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.parcelize.test.runners
|
||||
|
||||
import org.jetbrains.kotlin.parcelize.test.services.ParcelizeEnvironmentConfigurator
|
||||
import org.jetbrains.kotlin.test.bind
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives.IR_DIFFERENCE
|
||||
import org.jetbrains.kotlin.test.runners.codegen.AbstractAsmLikeInstructionListingTest
|
||||
@@ -29,5 +30,5 @@ private fun TestConfigurationBuilder.configureParcelizeSpecific() {
|
||||
defaultDirectives {
|
||||
+IR_DIFFERENCE
|
||||
}
|
||||
useConfigurators(::ParcelizeEnvironmentConfigurator)
|
||||
useConfigurators(::ParcelizeEnvironmentConfigurator.bind(false))
|
||||
}
|
||||
|
||||
+11
-2
@@ -6,9 +6,11 @@
|
||||
package org.jetbrains.kotlin.parcelize.test.services
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.parcelize.ParcelizeComponentRegistrar
|
||||
import org.jetbrains.kotlin.parcelize.ParcelizeFirIrGeneratorExtension
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
@@ -16,7 +18,10 @@ import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
|
||||
class ParcelizeEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
|
||||
class ParcelizeEnvironmentConfigurator(
|
||||
testServices: TestServices,
|
||||
private val useFirExtension: Boolean
|
||||
) : EnvironmentConfigurator(testServices) {
|
||||
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
|
||||
val runtimeLibrary = File(PathUtil.kotlinPathsForCompiler.libPath, PathUtil.PARCELIZE_RUNTIME_PLUGIN_JAR_NAME)
|
||||
val androidExtensionsRuntimeLibrary = File(PathUtil.kotlinPathsForCompiler.libPath, PathUtil.ANDROID_EXTENSIONS_RUNTIME_PLUGIN_JAR_NAME)
|
||||
@@ -25,6 +30,10 @@ class ParcelizeEnvironmentConfigurator(testServices: TestServices) : Environment
|
||||
}
|
||||
|
||||
override fun registerCompilerExtensions(project: Project) {
|
||||
ParcelizeComponentRegistrar.registerParcelizeComponents(project)
|
||||
if (useFirExtension) {
|
||||
IrGenerationExtension.registerExtension(project, ParcelizeFirIrGeneratorExtension())
|
||||
} else {
|
||||
ParcelizeComponentRegistrar.registerParcelizeComponents(project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user