From 5fedb2f72d2e5bb0202ef34324552b5030173d2c Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Thu, 22 Dec 2022 14:47:05 +0200 Subject: [PATCH] [Parcelize] Use new DSL for generating declarations --- build.gradle.kts | 1 + .../parcelize-compiler/build.gradle.kts | 1 + .../parcelize.k2/build.gradle.kts | 1 + .../fir/FirParcelizeDeclarationGenerator.kt | 104 ++++-------------- 4 files changed, 26 insertions(+), 81 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9721874ffeb..2ace1ca832b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -363,6 +363,7 @@ val projectsWithEnabledContextReceivers by extra { ":compiler:fir:fir2ir", ":kotlin-lombok-compiler-plugin.k1", ":kotlinx-serialization-compiler-plugin.k2", + ":plugins:parcelize:parcelize-compiler:parcelize.k2", ":plugins:fir-plugin-prototype" ) } diff --git a/plugins/parcelize/parcelize-compiler/build.gradle.kts b/plugins/parcelize/parcelize-compiler/build.gradle.kts index 41df84f29fb..3e57a9a648b 100644 --- a/plugins/parcelize/parcelize-compiler/build.gradle.kts +++ b/plugins/parcelize/parcelize-compiler/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { testApi(projectTests(":compiler:test-infrastructure-utils")) // FIR dependencies + testApi(project(":compiler:fir:plugin-utils")) testApi(project(":compiler:fir:entrypoint")) testApi(project(":compiler:fir:checkers")) testApi(project(":compiler:fir:checkers:checkers.jvm")) diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/build.gradle.kts b/plugins/parcelize/parcelize-compiler/parcelize.k2/build.gradle.kts index add6f75aeb2..1649cd2116d 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.k2/build.gradle.kts +++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { compileOnly(project(":compiler:fir:cones")) compileOnly(project(":compiler:fir:tree")) compileOnly(project(":compiler:fir:resolve")) + compileOnly(project(":compiler:fir:plugin-utils")) compileOnly(project(":compiler:fir:checkers")) compileOnly(project(":compiler:fir:checkers:checkers.jvm")) compileOnly(project(":compiler:ir.backend.common")) diff --git a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/FirParcelizeDeclarationGenerator.kt b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/FirParcelizeDeclarationGenerator.kt index ce76a939f92..193f8d49b60 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/FirParcelizeDeclarationGenerator.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.k2/src/org/jetbrains/kotlin/parcelize/fir/FirParcelizeDeclarationGenerator.kt @@ -6,33 +6,23 @@ package org.jetbrains.kotlin.parcelize.fir import org.jetbrains.kotlin.GeneratedDeclarationKey -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.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.origin +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction 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.MemberGenerationContext import org.jetbrains.kotlin.fir.extensions.predicate.LookupPredicate 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.plugin.SimpleFunctionBuildingContext +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.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.fir.types.toRegularClassSymbol +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.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 { val owner = context?.owner ?: return emptyList() require(owner is FirRegularClassSymbol) - val functionSymbol = when (callableId.callableName) { + val function = 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) + createMemberFunctionForParcelize(owner, callableId.callableName, session.builtinTypes.intType.type) } } WRITE_TO_PARCEL_NAME -> { val declaredFunctions = owner.declarationSymbols.filterIsInstance() - 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 - } - return listOfNotNull(functionSymbol) + } ?: return emptyList() + return listOf(function.symbol) } private fun FirRegularClassSymbol.hasDescribeContentsImplementation(): Boolean { @@ -96,70 +91,17 @@ class FirParcelizeDeclarationGenerator(session: FirSession) : FirDeclarationGene 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) { - 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( + private inline fun createMemberFunctionForParcelize( 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() + name: Name, + returnType: ConeKotlinType, + crossinline init: SimpleFunctionBuildingContext.() -> Unit = {} + ): FirSimpleFunction { + return createMemberFunction(owner, key, name, returnType) { + modality = if (owner.modality == Modality.FINAL) Modality.FINAL else Modality.OPEN + status { isOverride = true } init() } - return function.symbol } @OptIn(SymbolInternals::class)