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