From 9b43c66f8016dc21355f5d59423e7642bdf95d33 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 24 Apr 2020 17:36:55 +0300 Subject: [PATCH] [FIR] Add status transformer extension --- .../FirExtensionRegistrarExtension.kt | 21 +++++-- .../FirStatusTransfomerExtension.kt | 56 +++++++++++++++++++ .../FirStatusResolveTransformer.kt | 29 ++++++++-- 3 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirStatusTransfomerExtension.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionRegistrarExtension.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionRegistrarExtension.kt index b4e93afbf35..a4a77b8bcf4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionRegistrarExtension.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirExtensionRegistrarExtension.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.extensions import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor +import org.jetbrains.kotlin.fir.FirSession abstract class FirExtensionRegistrarExtension { companion object : ProjectExtensionDescriptor( @@ -13,16 +14,28 @@ abstract class FirExtensionRegistrarExtension { FirExtensionRegistrarExtension::class.java ) - protected inner class ExtensionRegistrarContext + protected inner class ExtensionRegistrarContext { + operator fun ((FirSession) -> FirStatusTransformerExtension).unaryPlus() { + statusTransformerExtensions += FirStatusTransformerExtension.Factory { this.invoke(it) } + } + } protected abstract fun ExtensionRegistrarContext.configurePlugin() fun configure(): RegisteredExtensions { ExtensionRegistrarContext().configurePlugin() - return RegisteredExtensions() + return RegisteredExtensions( + statusTransformerExtensions + ) } - class RegisteredExtensions + private val statusTransformerExtensions: MutableList = mutableListOf() + + class RegisteredExtensions( + val statusTransformerExtensions: List + ) } -fun FirExtensionPointService.registerExtensions(extensions: FirExtensionRegistrarExtension.RegisteredExtensions) {} \ No newline at end of file +fun FirExtensionPointService.registerExtensions(extensions: FirExtensionRegistrarExtension.RegisteredExtensions) { + registerExtensions(FirStatusTransformerExtension::class, extensions.statusTransformerExtensions) +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirStatusTransfomerExtension.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirStatusTransfomerExtension.kt new file mode 100644 index 00000000000..231c384a460 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirStatusTransfomerExtension.kt @@ -0,0 +1,56 @@ +/* + * 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.fir.extensions + +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus +import org.jetbrains.kotlin.fir.declarations.FirResolvedDeclarationStatus +import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl + +abstract class FirStatusTransformerExtension(session: FirSession) : FirExtensionPoint(session) { + companion object { + val NAME = FirExtensionPointName("StatusTransformer") + } + + final override val name: FirExtensionPointName + get() = NAME + + abstract fun transformStatus(declaration: FirDeclaration, status: FirDeclarationStatus): FirDeclarationStatus + + fun interface Factory : FirExtensionPoint.Factory +} + +val FirExtensionPointService.statusTransformerExtensions: List by FirExtensionPointService.registeredExtensions() + +inline fun FirDeclarationStatus.transform( + visibility: Visibility = this.visibility, + modality: Modality? = this.modality, + init: FirDeclarationStatusImpl.() -> Unit = {} +): FirDeclarationStatus { + return FirDeclarationStatusImpl(visibility, modality).apply { + isExpect = this@transform.isExpect + isActual = this@transform.isActual + isOverride = this@transform.isOverride + isOperator = this@transform.isOperator + isInfix = this@transform.isInfix + isInline = this@transform.isInline + isTailRec = this@transform.isTailRec + isExternal = this@transform.isExternal + isConst = this@transform.isConst + isLateInit = this@transform.isLateInit + isInner = this@transform.isInner + isCompanion = this@transform.isCompanion + isData = this@transform.isData + isSuspend = this@transform.isSuspend + isStatic = this@transform.isStatic + isFromSealedClass = this@transform.isFromSealedClass + isFromEnumClass = this@transform.isFromEnumClass + }.apply(init) +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt index 740c6907d54..2e8d3549143 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt @@ -14,6 +14,9 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.extensions.extensionPointService +import org.jetbrains.kotlin.fir.extensions.statusTransformerExtensions +import org.jetbrains.kotlin.fir.firEffectiveVisibility import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.compose @@ -89,12 +92,14 @@ private class FirStatusResolveTransformer( override fun transformTypeAlias(typeAlias: FirTypeAlias, data: FirDeclarationStatus?): CompositeTransformResult { typeAlias.typeParameters.forEach { transformDeclaration(it, data) } - typeAlias.transformStatus(this, typeAlias.resolveStatus(typeAlias.status, containingClass, isLocal = false)) + val status = prepareStatus(typeAlias, typeAlias.status) + typeAlias.transformStatus(this, typeAlias.resolveStatus(status, containingClass, isLocal = false)) return transformDeclaration(typeAlias, data) } override fun transformRegularClass(regularClass: FirRegularClass, data: FirDeclarationStatus?): CompositeTransformResult { - regularClass.transformStatus(this, regularClass.resolveStatus(regularClass.status, containingClass, isLocal = false)) + val status = prepareStatus(regularClass, regularClass.status) + regularClass.transformStatus(this, regularClass.resolveStatus(status, containingClass, isLocal = false)) return storeClass(regularClass) { regularClass.typeParameters.forEach { it.transformSingle(this, data) } transformDeclaration(regularClass, data) @@ -114,7 +119,8 @@ private class FirStatusResolveTransformer( propertyAccessor: FirPropertyAccessor, data: FirDeclarationStatus? ): CompositeTransformResult { - propertyAccessor.transformStatus(this, propertyAccessor.resolveStatus(propertyAccessor.status, containingClass, isLocal = false)) + val status = prepareStatus(propertyAccessor, propertyAccessor.status) + propertyAccessor.transformStatus(this, propertyAccessor.resolveStatus(status, containingClass, isLocal = false)) return transformDeclaration(propertyAccessor, data) as CompositeTransformResult } @@ -122,7 +128,8 @@ private class FirStatusResolveTransformer( constructor: FirConstructor, data: FirDeclarationStatus? ): CompositeTransformResult { - constructor.transformStatus(this, constructor.resolveStatus(constructor.status, containingClass, isLocal = false)) + val status = prepareStatus(constructor, constructor.status) + constructor.transformStatus(this, constructor.resolveStatus(status, containingClass, isLocal = false)) return transformDeclaration(constructor, data) } @@ -130,7 +137,8 @@ private class FirStatusResolveTransformer( simpleFunction: FirSimpleFunction, data: FirDeclarationStatus? ): CompositeTransformResult { - simpleFunction.transformStatus(this, simpleFunction.resolveStatus(simpleFunction.status, containingClass, isLocal = false)) + val status = prepareStatus(simpleFunction, simpleFunction.status) + simpleFunction.transformStatus(this, simpleFunction.resolveStatus(status, containingClass, isLocal = false)) return transformDeclaration(simpleFunction, data) } @@ -138,7 +146,8 @@ private class FirStatusResolveTransformer( property: FirProperty, data: FirDeclarationStatus? ): CompositeTransformResult { - property.transformStatus(this, property.resolveStatus(property.status, containingClass, isLocal = false)) + val status = prepareStatus(property, property.status) + property.transformStatus(this, property.resolveStatus(status, containingClass, isLocal = false)) return transformDeclaration(property, data) } @@ -163,6 +172,14 @@ private class FirStatusResolveTransformer( override fun transformBlock(block: FirBlock, data: FirDeclarationStatus?): CompositeTransformResult { return block.compose() } + + private fun prepareStatus(declaration: FirDeclaration, status: FirDeclarationStatus): FirDeclarationStatus { + var result = status + session.extensionPointService.statusTransformerExtensions.forEach { + result = it.transformStatus(declaration, status) + } + return result + } } private val > FirClass.effectiveVisibility: FirEffectiveVisibility