diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaFacade.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaFacade.kt index 3b8c8a1e633..b2298896427 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaFacade.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaFacade.kt @@ -20,9 +20,13 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildConstructedClassTypePa import org.jetbrains.kotlin.fir.declarations.builder.buildEnumEntry import org.jetbrains.kotlin.fir.declarations.builder.buildOuterClassTypeParameterRef import org.jetbrains.kotlin.fir.declarations.builder.buildTypeParameter +import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility import org.jetbrains.kotlin.fir.declarations.utils.modality +import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension +import org.jetbrains.kotlin.fir.extensions.extensionService +import org.jetbrains.kotlin.fir.extensions.statusTransformerExtensions import org.jetbrains.kotlin.fir.java.declarations.* import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement import org.jetbrains.kotlin.fir.resolve.defaultType @@ -31,6 +35,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl +import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.load.java.JavaClassFinder import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.structure.* @@ -71,6 +76,7 @@ abstract class FirJavaFacade( private val parentClassTypeParameterStackCache = mutableMapOf() private val parentClassEffectiveVisibilityCache = mutableMapOf() + private val statusExtensions = session.extensionService.statusTransformerExtensions fun findClass(classId: ClassId, knownContent: ByteArray? = null): JavaClass? = classFinder.findClass(JavaClassFinder.Request(classId, knownContent)) @@ -179,9 +185,45 @@ abstract class FirJavaFacade( enhancement.enhanceTypeParameterBoundsAfterFirstRound(firJavaClass.typeParameters, initialBounds) + updateStatuses(firJavaClass, parentClassSymbol) + return firJavaClass } + private fun updateStatuses(firJavaClass: FirJavaClass, parentClassSymbol: FirRegularClassSymbol?) { + if (statusExtensions.isEmpty()) return + val classSymbol = firJavaClass.symbol + val visitor = object : FirVisitorVoid() { + override fun visitElement(element: FirElement) {} + + override fun visitRegularClass(regularClass: FirRegularClass) { + regularClass.applyExtensionTransformers { + transformStatus(it, regularClass, parentClassSymbol, isLocal = false) + } + regularClass.acceptChildren(this) + } + + override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) { + simpleFunction.applyExtensionTransformers { + transformStatus(it, simpleFunction, classSymbol, isLocal = false) + } + } + + override fun visitField(field: FirField) { + field.applyExtensionTransformers { + transformStatus(it, field, classSymbol, isLocal = false) + } + } + + override fun visitConstructor(constructor: FirConstructor) { + constructor.applyExtensionTransformers { + transformStatus(it, constructor, classSymbol, isLocal = false) + } + } + } + firJavaClass.accept(visitor) + } + private fun createFirJavaClass( javaClass: JavaClass, classSymbol: FirRegularClassSymbol, @@ -672,4 +714,25 @@ abstract class FirJavaFacade( private fun List.toRefs(): List { return this.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } } } + + private inline fun FirMemberDeclaration.applyExtensionTransformers( + operation: FirStatusTransformerExtension.(FirDeclarationStatus) -> FirDeclarationStatus + ) { + val declaration = this + val oldStatus = declaration.status as FirResolvedDeclarationStatusImpl + val newStatus = statusExtensions.fold(status) { acc, it -> + if (it.needTransformStatus(declaration)) { + it.operation(acc) + } else { + acc + } + } as FirDeclarationStatusImpl + if (newStatus === oldStatus) return + val resolvedStatus = newStatus.resolved( + newStatus.visibility, + newStatus.modality ?: oldStatus.modality, + oldStatus.effectiveVisibility + ) + replaceStatus(resolvedStatus) + } } diff --git a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/k2/FirLombokRegistrar.kt b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/k2/FirLombokRegistrar.kt index 378d89b83e6..e4856dfe538 100644 --- a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/k2/FirLombokRegistrar.kt +++ b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/k2/FirLombokRegistrar.kt @@ -18,5 +18,6 @@ class FirLombokRegistrar(private val lombokConfigFile: File?) : FirExtensionRegi +::WithGenerator +::LombokConstructorsGenerator +::BuilderGenerator + +::ValueFieldVisibilityTransformer } } diff --git a/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/k2/generators/ValueFieldVisibilityTransformer.kt b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/k2/generators/ValueFieldVisibilityTransformer.kt new file mode 100644 index 00000000000..bbe8e3f000d --- /dev/null +++ b/plugins/lombok/lombok.k2/src/org/jetbrains/kotlin/lombok/k2/generators/ValueFieldVisibilityTransformer.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2023 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.lombok.k2.generators + +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.java.JavaVisibilities +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.copy +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus +import org.jetbrains.kotlin.fir.declarations.FirField +import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension +import org.jetbrains.kotlin.fir.java.declarations.FirJavaField +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.lombok.k2.config.lombokService + +class ValueFieldVisibilityTransformer(session: FirSession) : FirStatusTransformerExtension(session) { + override fun needTransformStatus(declaration: FirDeclaration): Boolean { + return declaration is FirJavaField + } + + override fun transformStatus( + status: FirDeclarationStatus, + field: FirField, + containingClass: FirClassLikeSymbol<*>?, + isLocal: Boolean + ): FirDeclarationStatus { + if (containingClass == null) return status + if (status.visibility != JavaVisibilities.PackageVisibility) return status + if (session.lombokService.getValue(containingClass) == null) return status + return status.copy(visibility = Visibilities.Private) + } +} diff --git a/plugins/lombok/testData/box/valueFieldAccess.kt b/plugins/lombok/testData/box/valueFieldAccess.kt index 2961946a017..2b8e3352a9d 100644 --- a/plugins/lombok/testData/box/valueFieldAccess.kt +++ b/plugins/lombok/testData/box/valueFieldAccess.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_K2: JVM_IR // ISSUE: KT-51092 // FILE: MyValue.java import lombok.Value;