[Parcelize] Use new DSL for generating declarations

This commit is contained in:
Dmitriy Novozhilov
2022-12-22 14:47:05 +02:00
committed by Space Team
parent 3744878b6d
commit 5fedb2f72d
4 changed files with 26 additions and 81 deletions
+1
View File
@@ -363,6 +363,7 @@ val projectsWithEnabledContextReceivers by extra {
":compiler:fir:fir2ir", ":compiler:fir:fir2ir",
":kotlin-lombok-compiler-plugin.k1", ":kotlin-lombok-compiler-plugin.k1",
":kotlinx-serialization-compiler-plugin.k2", ":kotlinx-serialization-compiler-plugin.k2",
":plugins:parcelize:parcelize-compiler:parcelize.k2",
":plugins:fir-plugin-prototype" ":plugins:fir-plugin-prototype"
) )
} }
@@ -37,6 +37,7 @@ dependencies {
testApi(projectTests(":compiler:test-infrastructure-utils")) testApi(projectTests(":compiler:test-infrastructure-utils"))
// FIR dependencies // FIR dependencies
testApi(project(":compiler:fir:plugin-utils"))
testApi(project(":compiler:fir:entrypoint")) testApi(project(":compiler:fir:entrypoint"))
testApi(project(":compiler:fir:checkers")) testApi(project(":compiler:fir:checkers"))
testApi(project(":compiler:fir:checkers:checkers.jvm")) testApi(project(":compiler:fir:checkers:checkers.jvm"))
@@ -12,6 +12,7 @@ dependencies {
compileOnly(project(":compiler:fir:cones")) compileOnly(project(":compiler:fir:cones"))
compileOnly(project(":compiler:fir:tree")) compileOnly(project(":compiler:fir:tree"))
compileOnly(project(":compiler:fir:resolve")) compileOnly(project(":compiler:fir:resolve"))
compileOnly(project(":compiler:fir:plugin-utils"))
compileOnly(project(":compiler:fir:checkers")) compileOnly(project(":compiler:fir:checkers"))
compileOnly(project(":compiler:fir:checkers:checkers.jvm")) compileOnly(project(":compiler:fir:checkers:checkers.jvm"))
compileOnly(project(":compiler:ir.backend.common")) compileOnly(project(":compiler:ir.backend.common"))
@@ -6,33 +6,23 @@
package org.jetbrains.kotlin.parcelize.fir package org.jetbrains.kotlin.parcelize.fir
import org.jetbrains.kotlin.GeneratedDeclarationKey import org.jetbrains.kotlin.GeneratedDeclarationKey
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
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.origin
import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.moduleData import org.jetbrains.kotlin.fir.plugin.SimpleFunctionBuildingContext
import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.plugin.createConeType
import org.jetbrains.kotlin.fir.plugin.createMemberFunction
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.*
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.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.parcelize.ParcelizeNames.DESCRIBE_CONTENTS_NAME import org.jetbrains.kotlin.parcelize.ParcelizeNames.DESCRIBE_CONTENTS_NAME
@@ -58,23 +48,28 @@ class FirParcelizeDeclarationGenerator(session: FirSession) : FirDeclarationGene
override fun generateFunctions(callableId: CallableId, context: MemberGenerationContext?): List<FirNamedFunctionSymbol> { override fun generateFunctions(callableId: CallableId, context: MemberGenerationContext?): List<FirNamedFunctionSymbol> {
val owner = context?.owner ?: return emptyList() val owner = context?.owner ?: return emptyList()
require(owner is FirRegularClassSymbol) require(owner is FirRegularClassSymbol)
val functionSymbol = when (callableId.callableName) { val function = when (callableId.callableName) {
DESCRIBE_CONTENTS_NAME -> { DESCRIBE_CONTENTS_NAME -> {
val hasDescribeContentImplementation = owner.hasDescribeContentsImplementation() || val hasDescribeContentImplementation = owner.hasDescribeContentsImplementation() ||
lookupSuperTypes(owner, lookupInterfaces = false, deep = true, session).any { lookupSuperTypes(owner, lookupInterfaces = false, deep = true, session).any {
it.fullyExpandedType(session).toRegularClassSymbol(session)?.hasDescribeContentsImplementation() ?: false it.fullyExpandedType(session).toRegularClassSymbol(session)?.hasDescribeContentsImplementation() ?: false
} }
runIf(!hasDescribeContentImplementation) { runIf(!hasDescribeContentImplementation) {
generateDescribeContents(owner, callableId) createMemberFunctionForParcelize(owner, callableId.callableName, session.builtinTypes.intType.type)
} }
} }
WRITE_TO_PARCEL_NAME -> { WRITE_TO_PARCEL_NAME -> {
val declaredFunctions = owner.declarationSymbols.filterIsInstance<FirNamedFunctionSymbol>() val declaredFunctions = owner.declarationSymbols.filterIsInstance<FirNamedFunctionSymbol>()
runIf(declaredFunctions.none { it.isWriteToParcel() }) { generateWriteToParcel(owner, callableId) } runIf(declaredFunctions.none { it.isWriteToParcel() }) {
createMemberFunctionForParcelize(owner, callableId.callableName, session.builtinTypes.unitType.type) {
valueParameter(DEST_NAME, PARCEL_ID.createConeType(session))
valueParameter(FLAGS_NAME, session.builtinTypes.intType.type)
}
}
} }
else -> null else -> null
} } ?: return emptyList()
return listOfNotNull(functionSymbol) return listOf(function.symbol)
} }
private fun FirRegularClassSymbol.hasDescribeContentsImplementation(): Boolean { private fun FirRegularClassSymbol.hasDescribeContentsImplementation(): Boolean {
@@ -96,70 +91,17 @@ class FirParcelizeDeclarationGenerator(session: FirSession) : FirDeclarationGene
return true return true
} }
private fun generateDescribeContents(owner: FirRegularClassSymbol, callableId: CallableId): FirNamedFunctionSymbol { private inline fun createMemberFunctionForParcelize(
return createFunction(owner, callableId) {
returnTypeRef = session.builtinTypes.intType
}
}
private fun generateWriteToParcel(owner: FirRegularClassSymbol, callableId: CallableId): FirNamedFunctionSymbol {
return createFunction(owner, callableId) {
val functionSymbol = this.symbol
returnTypeRef = session.builtinTypes.unitType
valueParameters += buildValueParameter {
moduleData = session.moduleData
origin = key.origin
name = DEST_NAME
containingFunctionSymbol = functionSymbol
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
containingFunctionSymbol = functionSymbol
returnTypeRef = session.builtinTypes.intType
symbol = FirValueParameterSymbol(name)
isCrossinline = false
isNoinline = false
isVararg = false
}
}
}
private inline fun createFunction(
owner: FirRegularClassSymbol, owner: FirRegularClassSymbol,
callableId: CallableId, name: Name,
init: FirSimpleFunctionBuilder.() -> Unit returnType: ConeKotlinType,
): FirNamedFunctionSymbol { crossinline init: SimpleFunctionBuildingContext.() -> Unit = {}
val function = buildSimpleFunction { ): FirSimpleFunction {
moduleData = session.moduleData return createMemberFunction(owner, key, name, returnType) {
origin = key.origin modality = if (owner.modality == Modality.FINAL) Modality.FINAL else Modality.OPEN
status = FirResolvedDeclarationStatusImpl( status { isOverride = true }
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() init()
} }
return function.symbol
} }
@OptIn(SymbolInternals::class) @OptIn(SymbolInternals::class)