From 96da6d35c5a44f1510a6ce6604bc56c15eeeaf5a Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 20 May 2020 14:16:34 +0300 Subject: [PATCH] [FIR] Add processor for transforming statuses with plugins --- .../resolve/transformers/ResolvePhaseUtils.kt | 6 + .../FirGlobalExtensionStatusProcessor.kt | 118 ++++++++++++++++++ .../fir/declarations/FirResolvePhase.kt | 2 + 3 files changed, 126 insertions(+) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalExtensionStatusProcessor.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ResolvePhaseUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ResolvePhaseUtils.kt index 1d78f12d151..454123f09ff 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ResolvePhaseUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ResolvePhaseUtils.kt @@ -12,7 +12,9 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveProcessor import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTypeBodyResolveProcessor import org.jetbrains.kotlin.fir.resolve.transformers.contracts.FirContractResolveProcessor +import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirGlobalExtensionStatusProcessor import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirPluginAnnotationsResolveProcessor +import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirTransformerBasedExtensionStatusProcessor fun FirResolvePhase.createProcessorByPhase( session: FirSession, @@ -27,6 +29,10 @@ fun FirResolvePhase.createProcessorByPhase( SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession) SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsProcessor(session, scopeSession) TYPES -> FirTypeResolveProcessor(session, scopeSession) + EXTENSION_STATUS_UPDATE -> when (compilerMode) { + CompilerMode.CLI -> FirGlobalExtensionStatusProcessor(session, scopeSession) + CompilerMode.IDE -> FirTransformerBasedExtensionStatusProcessor(session, scopeSession) + } STATUS -> FirStatusResolveProcessor(session, scopeSession) CONTRACTS -> FirContractResolveProcessor(session, scopeSession) IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveProcessor(session, scopeSession) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalExtensionStatusProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalExtensionStatusProcessor.kt new file mode 100644 index 00000000000..d7cd03df993 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalExtensionStatusProcessor.kt @@ -0,0 +1,118 @@ +/* + * 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.resolve.transformers.plugin + +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.extensions.extensionService +import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider +import org.jetbrains.kotlin.fir.extensions.statusTransformerExtensions +import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.transformers.FirGlobalResolveProcessor +import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveProcessor +import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult +import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer +import org.jetbrains.kotlin.fir.visitors.FirTransformer +import org.jetbrains.kotlin.fir.visitors.compose + +class FirGlobalExtensionStatusProcessor( + session: FirSession, + scopeSession: ScopeSession +) : FirGlobalResolveProcessor(session, scopeSession) { + override fun process() { + val extensions = session.extensionService.statusTransformerExtensions + if (extensions.isEmpty()) return + val provider = session.predicateBasedProvider + for (extension in extensions) { + val declarations = provider.getSymbolsByPredicate(extension.predicate) + for (declaration in declarations) { + // TODO: maybe replace with visitor? + if (declaration is FirMemberDeclaration) { + val newStatus = extension.transformStatus(declaration, declaration.status) + declaration.transformStatus(ReplaceStatus, newStatus) + } + } + } + } +} + +class FirTransformerBasedExtensionStatusProcessor( + session: FirSession, + scopeSession: ScopeSession +) : FirTransformerBasedResolveProcessor(session, scopeSession) { + override val transformer: FirTransformer = StatusUpdater() + + private inner class StatusUpdater : FirDefaultTransformer() { + private val extensions = session.extensionService.statusTransformerExtensions + + private fun FirMemberDeclaration.updateStatus() { + if (extensions.isEmpty()) return + var status = this.status + for (extension in extensions) { + status = extension.transformStatus(this, status) + } + transformStatus(ReplaceStatus, status) + } + + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { + return element.compose() + } + + override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): CompositeTransformResult { + typeAlias.updateStatus() + return typeAlias.compose() + } + + override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult { + regularClass.updateStatus() + regularClass.transformDeclarations(this, data) + return regularClass.compose() + } + + override fun transformConstructor(constructor: FirConstructor, data: Nothing?): CompositeTransformResult { + constructor.updateStatus() + return constructor.compose() + } + + override fun transformProperty(property: FirProperty, data: Nothing?): CompositeTransformResult { + property.updateStatus() + property.transformGetter(this, data) + property.transformSetter(this, data) + return property.compose() + } + + override fun transformField(field: FirField, data: Nothing?): CompositeTransformResult { + field.updateStatus() + return field.compose() + } + + override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Nothing?): CompositeTransformResult { + enumEntry.updateStatus() + return enumEntry.compose() + } + + override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?): CompositeTransformResult { + simpleFunction.updateStatus() + return simpleFunction.compose() + } + } +} + + +private object ReplaceStatus : FirTransformer() { + override fun transformElement(element: E, data: FirDeclarationStatus): CompositeTransformResult { + return element.compose() + } + + override fun transformDeclarationStatus( + declarationStatus: FirDeclarationStatus, + data: FirDeclarationStatus + ): CompositeTransformResult { + return data.compose() + } +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt index 2d8f32542e3..b02f96fabf1 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirResolvePhase.kt @@ -13,6 +13,7 @@ enum class FirResolvePhase { SUPER_TYPES, SEALED_CLASS_INHERITORS, TYPES, + EXTENSION_STATUS_UPDATE, STATUS, CONTRACTS, IMPLICIT_TYPES_BODY_RESOLVE, @@ -22,6 +23,7 @@ enum class FirResolvePhase { get() = when (this) { RAW_FIR -> RAW_FIR IMPORTS -> RAW_FIR + STATUS -> TYPES IMPLICIT_TYPES_BODY_RESOLVE, BODY_RESOLVE -> STATUS else -> values()[ordinal - 1] }