[FIR] Add status transformer extension

This commit is contained in:
Dmitriy Novozhilov
2020-04-24 17:36:55 +03:00
parent 7f8a8ca099
commit 9b43c66f80
3 changed files with 96 additions and 10 deletions
@@ -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<FirExtensionRegistrarExtension>(
@@ -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<FirStatusTransformerExtension.Factory> = mutableListOf()
class RegisteredExtensions(
val statusTransformerExtensions: List<FirStatusTransformerExtension.Factory>
)
}
fun FirExtensionPointService.registerExtensions(extensions: FirExtensionRegistrarExtension.RegisteredExtensions) {}
fun FirExtensionPointService.registerExtensions(extensions: FirExtensionRegistrarExtension.RegisteredExtensions) {
registerExtensions(FirStatusTransformerExtension::class, extensions.statusTransformerExtensions)
}
@@ -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<FirStatusTransformerExtension>
}
val FirExtensionPointService.statusTransformerExtensions: List<FirStatusTransformerExtension> 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)
}
@@ -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<FirDeclaration> {
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<FirStatement> {
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<FirStatement> {
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<FirStatement>
}
@@ -122,7 +128,8 @@ private class FirStatusResolveTransformer(
constructor: FirConstructor,
data: FirDeclarationStatus?
): CompositeTransformResult<FirDeclaration> {
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<FirDeclaration> {
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<FirDeclaration> {
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<FirStatement> {
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 <F : FirClass<F>> FirClass<F>.effectiveVisibility: FirEffectiveVisibility