Handle special case visibility rules in LocalDeclarationsLowering
This commit is contained in:
committed by
Alexander Udalov
parent
9a938b07ba
commit
626f4c94f6
-10
@@ -30,17 +30,7 @@ import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.util.isLocal
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import kotlin.collections.List
|
||||
import kotlin.collections.emptyList
|
||||
import kotlin.collections.filterTo
|
||||
import kotlin.collections.firstOrNull
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.getOrElse
|
||||
import kotlin.collections.mutableListOf
|
||||
import kotlin.collections.mutableMapOf
|
||||
import kotlin.collections.mutableSetOf
|
||||
import kotlin.collections.set
|
||||
import kotlin.collections.toList
|
||||
|
||||
class Closure(val capturedValues: List<IrValueSymbol> = emptyList())
|
||||
|
||||
|
||||
+30
-8
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.constructedClass
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -48,20 +49,32 @@ interface LocalNameProvider {
|
||||
}
|
||||
}
|
||||
|
||||
interface VisibilityPolicy {
|
||||
fun forClass(declaration: IrClass, inInlineFunctionScope: Boolean): Visibility =
|
||||
declaration.visibility
|
||||
|
||||
fun forConstructor(declaration: IrConstructor, inInlineFunctionScope: Boolean): Visibility =
|
||||
Visibilities.PRIVATE
|
||||
|
||||
companion object {
|
||||
val DEFAULT = object : VisibilityPolicy {}
|
||||
}
|
||||
}
|
||||
|
||||
val IrDeclaration.parentsWithSelf: Sequence<IrDeclarationParent>
|
||||
get() = generateSequence(this as? IrDeclarationParent) { (it as? IrDeclaration)?.parent }
|
||||
|
||||
val IrDeclaration.parents: Sequence<IrDeclarationParent>
|
||||
get() = parentsWithSelf.drop(1)
|
||||
|
||||
object BOUND_VALUE_PARAMETER: IrDeclarationOriginImpl("BOUND_VALUE_PARAMETER")
|
||||
object BOUND_VALUE_PARAMETER : IrDeclarationOriginImpl("BOUND_VALUE_PARAMETER")
|
||||
|
||||
object BOUND_RECEIVER_PARAMETER: IrDeclarationOriginImpl("BOUND_RECEIVER_PARAMETER")
|
||||
object BOUND_RECEIVER_PARAMETER : IrDeclarationOriginImpl("BOUND_RECEIVER_PARAMETER")
|
||||
|
||||
class LocalDeclarationsLowering(
|
||||
val context: BackendContext,
|
||||
val localNameProvider: LocalNameProvider = LocalNameProvider.DEFAULT,
|
||||
val loweredConstructorVisibility: Visibility = Visibilities.PRIVATE
|
||||
val visibilityPolicy: VisibilityPolicy = VisibilityPolicy.DEFAULT
|
||||
) :
|
||||
FileLoweringPass {
|
||||
|
||||
@@ -107,11 +120,12 @@ class LocalDeclarationsLowering(
|
||||
override lateinit var transformedDeclaration: IrSimpleFunction
|
||||
}
|
||||
|
||||
private class LocalClassConstructorContext(override val declaration: IrConstructor) : LocalContextWithClosureAsParameters() {
|
||||
private class LocalClassConstructorContext(override val declaration: IrConstructor, val inInlineFunctionScope: Boolean) :
|
||||
LocalContextWithClosureAsParameters() {
|
||||
override lateinit var transformedDeclaration: IrConstructor
|
||||
}
|
||||
|
||||
private class LocalClassContext(val declaration: IrClass) : LocalContext() {
|
||||
private class LocalClassContext(val declaration: IrClass, val inInlineFunctionScope: Boolean) : LocalContext() {
|
||||
lateinit var closure: Closure
|
||||
|
||||
// NOTE: This map is iterated over in `rewriteClassMembers` and we're relying on
|
||||
@@ -449,6 +463,8 @@ class LocalDeclarationsLowering(
|
||||
}
|
||||
|
||||
localClasses.values.forEach {
|
||||
val localClassVisibility = visibilityPolicy.forClass(it.declaration, it.inInlineFunctionScope)
|
||||
it.declaration.visibility = localClassVisibility
|
||||
createFieldsForCapturedValues(it)
|
||||
}
|
||||
|
||||
@@ -589,6 +605,9 @@ class LocalDeclarationsLowering(
|
||||
val newDescriptor = WrappedClassConstructorDescriptor(oldDeclaration.descriptor.annotations, oldDeclaration.descriptor.source)
|
||||
val newSymbol = IrConstructorSymbolImpl(newDescriptor)
|
||||
|
||||
val loweredConstructorVisibility =
|
||||
visibilityPolicy.forConstructor(oldDeclaration, constructorContext.inInlineFunctionScope)
|
||||
|
||||
val newDeclaration = IrConstructorImpl(
|
||||
oldDeclaration.startOffset, oldDeclaration.endOffset, oldDeclaration.origin,
|
||||
newSymbol, oldDeclaration.name, loweredConstructorVisibility, oldDeclaration.returnType, oldDeclaration.isInline,
|
||||
@@ -726,9 +745,9 @@ class LocalDeclarationsLowering(
|
||||
override fun visitConstructor(declaration: IrConstructor) {
|
||||
super.visitConstructor(declaration)
|
||||
|
||||
if (!(declaration.parent as IrClass).isLocalNotInner()) return
|
||||
if (!declaration.constructedClass.isLocalNotInner()) return
|
||||
|
||||
localClassConstructors[declaration] = LocalClassConstructorContext(declaration)
|
||||
localClassConstructors[declaration] = LocalClassConstructorContext(declaration, inInlineFunctionScope)
|
||||
}
|
||||
|
||||
override fun visitClassNew(declaration: IrClass) {
|
||||
@@ -736,9 +755,12 @@ class LocalDeclarationsLowering(
|
||||
|
||||
if (!declaration.isLocalNotInner()) return
|
||||
|
||||
val localClassContext = LocalClassContext(declaration)
|
||||
val localClassContext = LocalClassContext(declaration, inInlineFunctionScope)
|
||||
localClasses[declaration] = localClassContext
|
||||
}
|
||||
|
||||
private val inInlineFunctionScope: Boolean
|
||||
get() = allScopes.any { scope -> (scope.irElement as? IrFunction)?.isInline ?: false }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@ import org.jetbrains.kotlin.backend.jvm.lower.*
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
|
||||
@@ -90,10 +90,29 @@ private val propertiesPhase = makeIrFilePhase<JvmBackendContext>(
|
||||
|
||||
internal val localDeclarationsPhase = makeIrFilePhase<CommonBackendContext>(
|
||||
{ context ->
|
||||
LocalDeclarationsLowering(context, object : LocalNameProvider {
|
||||
override fun localName(declaration: IrDeclarationWithName): String =
|
||||
NameUtils.sanitizeAsJavaIdentifier(super.localName(declaration))
|
||||
}, Visibilities.PUBLIC)
|
||||
LocalDeclarationsLowering(
|
||||
context,
|
||||
object : LocalNameProvider {
|
||||
override fun localName(declaration: IrDeclarationWithName): String =
|
||||
NameUtils.sanitizeAsJavaIdentifier(super.localName(declaration))
|
||||
},
|
||||
object : VisibilityPolicy {
|
||||
override fun forClass(declaration: IrClass, inInlineFunctionScope: Boolean): Visibility =
|
||||
if (declaration.origin == JvmLoweredDeclarationOrigin.LAMBDA_IMPL ||
|
||||
declaration.origin == JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL ||
|
||||
declaration.origin == JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE) {
|
||||
scopedVisibility(inInlineFunctionScope)
|
||||
} else {
|
||||
declaration.visibility
|
||||
}
|
||||
|
||||
override fun forConstructor(declaration: IrConstructor, inInlineFunctionScope: Boolean): Visibility =
|
||||
scopedVisibility(inInlineFunctionScope)
|
||||
|
||||
private fun scopedVisibility(inInlineFunctionScope: Boolean): Visibility =
|
||||
if (inInlineFunctionScope) Visibilities.PUBLIC else JavaVisibilities.PACKAGE_VISIBILITY
|
||||
}
|
||||
)
|
||||
},
|
||||
name = "JvmLocalDeclarations",
|
||||
description = "Move local declarations to classes",
|
||||
|
||||
-4
@@ -172,7 +172,6 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
|
||||
functionReferenceClass.addConstructor {
|
||||
setSourceRange(irFunctionReference)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
visibility = if (inInlineFunctionScope) Visibilities.PUBLIC else JavaVisibilities.PACKAGE_VISIBILITY
|
||||
returnType = functionReferenceClass.defaultType
|
||||
isPrimary = true
|
||||
}.apply {
|
||||
@@ -381,9 +380,6 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
|
||||
private val currentDeclarationParent
|
||||
get() = allScopes.last { it.irElement is IrDeclarationParent }.irElement as IrDeclarationParent
|
||||
|
||||
private val inInlineFunctionScope: Boolean
|
||||
get() = allScopes.any { scope -> (scope.irElement as? IrFunction)?.isInline ?: false }
|
||||
|
||||
private fun IrClassSymbol.functionByName(name: String) = owner.functions.single { it.name.asString() == name }
|
||||
|
||||
private val functionReferenceReceiverField =
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.declarations
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
@@ -28,6 +29,8 @@ interface IrClass :
|
||||
|
||||
override val descriptor: ClassDescriptor
|
||||
|
||||
override var visibility: Visibility
|
||||
|
||||
val kind: ClassKind
|
||||
val modality: Modality
|
||||
val isCompanion: Boolean
|
||||
|
||||
@@ -37,7 +37,7 @@ class IrClassImpl(
|
||||
override val symbol: IrClassSymbol,
|
||||
override val name: Name,
|
||||
override val kind: ClassKind,
|
||||
override val visibility: Visibility,
|
||||
override var visibility: Visibility,
|
||||
override val modality: Modality,
|
||||
override val isCompanion: Boolean,
|
||||
override val isInner: Boolean,
|
||||
|
||||
@@ -27,7 +27,7 @@ class IrLazyClass(
|
||||
override val symbol: IrClassSymbol,
|
||||
override val name: Name,
|
||||
override val kind: ClassKind,
|
||||
override val visibility: Visibility,
|
||||
override var visibility: Visibility,
|
||||
override val modality: Modality,
|
||||
override val isCompanion: Boolean,
|
||||
override val isInner: Boolean,
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class A {
|
||||
fun foo() {}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class Foo {
|
||||
fun a() {
|
||||
val s = object { }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class Foo {
|
||||
fun foo() = { }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user