Handle special case visibility rules in LocalDeclarationsLowering

This commit is contained in:
Steven Schäfer
2019-09-02 15:54:23 +02:00
committed by Alexander Udalov
parent 9a938b07ba
commit 626f4c94f6
10 changed files with 61 additions and 34 deletions
@@ -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())
@@ -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",
@@ -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,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
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
class Foo {
fun foo() = { }
}