Migrate DescriptorsFactory.getFieldDescriptorForEnumEntry() API to symbols

This commit is contained in:
Mikhael Bogdanov
2018-05-08 11:24:12 +02:00
parent 9fad3f25f3
commit 2631d149b2
6 changed files with 55 additions and 35 deletions
@@ -9,9 +9,11 @@ import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
interface DescriptorsFactory {
fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor
fun getSymbolForEnumEntry(enumEntry: IrEnumEntrySymbol): IrFieldSymbol
fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor
fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): IrConstructorSymbol
fun getFieldDescriptorForObjectInstance(objectDescriptor: ClassDescriptor): PropertyDescriptor
@@ -24,7 +24,11 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -37,7 +41,7 @@ class JsDescriptorsFactory(
private val outerThisDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
private val innerClassConstructors = HashMap<ClassConstructorDescriptor, IrConstructorSymbol>()
override fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor = TODO()
override fun getSymbolForEnumEntry(enumEntry: IrEnumEntrySymbol): IrFieldSymbol = TODO()
override fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor =
if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor")
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
import org.jetbrains.kotlin.backend.jvm.lower.*
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -45,11 +46,16 @@ class JvmLower(val context: JvmBackendContext) {
SharedVariablesLowering(context).runOnFilePostfix(irFile)
InnerClassesLowering(context).runOnFilePostfix(irFile)
InnerClassConstructorCallsLowering(context).runOnFilePostfix(irFile)
LocalDeclarationsLowering(context,
object : LocalNameProvider {
override fun localName(descriptor: DeclarationDescriptor): String =
NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
}).runOnFilePostfix(irFile)
LocalDeclarationsLowering(
context,
object : LocalNameProvider {
override fun localName(descriptor: DeclarationDescriptor): String =
NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
}
).runOnFilePostfix(irFile)
irFile.acceptVoid(PatchDeclarationParentsVisitor())
EnumClassLowering(context).runOnFilePostfix(irFile)
//Should be before SyntheticAccessorLowering cause of synthetic accessor for companion constructor
ObjectClassLowering(context).lower(irFile)
@@ -27,7 +27,10 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
@@ -44,10 +47,13 @@ class JvmDescriptorsFactory(
private val outerThisDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
private val innerClassConstructors = HashMap<ClassConstructorDescriptor, IrConstructorSymbol>()
override fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor =
singletonFieldDescriptors.getOrPut(enumEntryDescriptor) {
override fun getSymbolForEnumEntry(enumEntry: IrEnumEntrySymbol): IrFieldSymbol {
val enumEntryDescriptor = enumEntry.descriptor
val fieldDescriptor = singletonFieldDescriptors.getOrPut(enumEntryDescriptor) {
createEnumEntryFieldDescriptor(enumEntryDescriptor)
}
return IrFieldSymbolImpl(fieldDescriptor)
}
fun createFileClassDescriptor(fileEntry: SourceManager.FileEntry, packageFragment: PackageFragmentDescriptor): FileClassDescriptor {
val ktFile = psiSourceManager.getKtFile(fileEntry as PsiSourceManager.PsiFileEntry)
@@ -33,10 +33,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
@@ -47,8 +44,7 @@ import java.util.*
class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
override fun lower(irClass: IrClass) {
val classDescriptor = irClass.descriptor
if (classDescriptor.kind != ClassKind.ENUM_CLASS) return
if (irClass.kind != ClassKind.ENUM_CLASS) return
EnumClassTransformer(irClass).run()
}
@@ -78,10 +74,11 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
}
private inner class EnumClassTransformer(val irClass: IrClass) {
private val enumEntryOrdinals = TObjectIntHashMap<ClassDescriptor>()
private val enumEntryOrdinals = TObjectIntHashMap<IrEnumEntry>()
private val enumEntryClassToEntry = HashMap<IrClass, IrEnumEntry>()
private val loweredEnumConstructors = HashMap<ClassConstructorDescriptor, IrConstructorImpl>()
private val loweredEnumConstructorParameters = HashMap<ValueParameterDescriptor, IrValueParameter>()
private val enumEntriesByField = HashMap<PropertyDescriptor, ClassDescriptor>()
private val enumEntriesByField = HashMap<IrField, IrEnumEntry>()
private val enumEntryFields = ArrayList<IrField>()
private lateinit var valuesField: IrField
@@ -100,7 +97,10 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
var ordinal = 0
irClass.declarations.forEach {
if (it is IrEnumEntry) {
enumEntryOrdinals.put(it.descriptor, ordinal)
enumEntryOrdinals.put(it, ordinal)
it.correspondingClass?.run {
enumEntryClassToEntry.put(this, it)
}
ordinal++
}
}
@@ -109,13 +109,16 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
private fun lowerEnumConstructors(irClass: IrClass) {
irClass.declarations.transform { declaration ->
if (declaration is IrConstructor)
transformEnumConstructor(declaration)
transformEnumConstructor(declaration, irClass)
else
declaration
}
}
private fun transformEnumConstructor(enumConstructor: IrConstructor): IrConstructor {
private fun transformEnumConstructor(
enumConstructor: IrConstructor,
enumClass: IrClass
): IrConstructor {
val constructorDescriptor = enumConstructor.descriptor
val loweredConstructorDescriptor = lowerEnumConstructor(constructorDescriptor)
return IrConstructorImpl(
@@ -123,6 +126,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
loweredConstructorDescriptor,
enumConstructor.body!! // will be transformed later
).apply {
parent = enumClass
createParameterDeclarations()
loweredEnumConstructors[constructorDescriptor] = this
constructorDescriptor.valueParameters.forEach {
@@ -185,16 +189,15 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
}
private fun createFieldForEnumEntry(enumEntry: IrEnumEntry): IrField {
val fieldPropertyDescriptor = context.descriptorsFactory.getFieldDescriptorForEnumEntry(enumEntry.descriptor)
enumEntriesByField[fieldPropertyDescriptor] = enumEntry.descriptor
val fieldSymbol = context.descriptorsFactory.getSymbolForEnumEntry(enumEntry.symbol)
return IrFieldImpl(
enumEntry.startOffset, enumEntry.endOffset, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_ENTRY,
fieldPropertyDescriptor,
IrExpressionBodyImpl(enumEntry.initializerExpression!!)
fieldSymbol
).also {
it.initializer = IrExpressionBodyImpl(enumEntry.initializerExpression!!)
enumEntryFields.add(it)
enumEntriesByField[it] = enumEntry
}
}
@@ -230,7 +233,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
private fun createSyntheticValuesFieldInitializerExpression(): IrExpression =
createArrayOfExpression(
irClass.descriptor.defaultType,
irClass.defaultType,
enumEntryFields.map { irField ->
IrGetFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irField.symbol)
})
@@ -312,7 +315,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
}
}
private abstract inner class InEnumEntry(private val enumEntry: ClassDescriptor) : EnumConstructorCallTransformer {
private abstract inner class InEnumEntry(private val enumEntry: IrEnumEntry) : EnumConstructorCallTransformer {
override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression {
val name = enumEntry.name.asString()
val ordinal = enumEntryOrdinals[enumEntry]
@@ -349,7 +352,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
): IrMemberAccessExpression
}
private inner class InEnumEntryClassConstructor(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) {
private inner class InEnumEntryClassConstructor(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) {
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructor) =
IrDelegatingConstructorCallImpl(
startOffset,
@@ -360,7 +363,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
)
}
private inner class InEnumEntryInitializer(enumEntry: ClassDescriptor) : InEnumEntry(enumEntry) {
private inner class InEnumEntryInitializer(enumEntry: IrEnumEntry) : InEnumEntry(enumEntry) {
override fun createConstructorCall(startOffset: Int, endOffset: Int, loweredConstructor: IrConstructor) =
IrCallImpl(
startOffset,
@@ -373,7 +376,7 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
private var enumConstructorCallTransformer: EnumConstructorCallTransformer? = null
override fun visitField(declaration: IrField): IrStatement {
val enumEntry = enumEntriesByField[declaration.descriptor]
val enumEntry = enumEntriesByField[declaration]
if (enumEntry == null) {
declaration.transformChildrenVoid(this)
return declaration
@@ -391,15 +394,14 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
}
override fun visitConstructor(declaration: IrConstructor): IrStatement {
val constructorDescriptor = declaration.descriptor
val containingClass = constructorDescriptor.containingDeclaration
val containingClass = declaration.parent as IrClass
// TODO local (non-enum) class in enum class constructor?
val previous = enumConstructorCallTransformer
if (containingClass.kind == ClassKind.ENUM_ENTRY) {
assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" }
enumConstructorCallTransformer = InEnumEntryClassConstructor(containingClass)
enumConstructorCallTransformer = InEnumEntryClassConstructor(enumEntryClassToEntry[containingClass]!!)
} else if (containingClass.kind == ClassKind.ENUM_CLASS) {
assert(enumConstructorCallTransformer == null) { "Nested enum entry initialization:\n${declaration.dump()}" }
enumConstructorCallTransformer = InEnumClassConstructor(declaration)
@@ -32,8 +32,8 @@ class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLowering
}
override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression {
val enumValueFieldDescriptor = context.descriptorsFactory.getFieldDescriptorForEnumEntry(expression.descriptor)
return IrGetFieldImpl(expression.startOffset, expression.endOffset, enumValueFieldDescriptor)
val entrySymbol = context.descriptorsFactory.getSymbolForEnumEntry(expression.symbol)
return IrGetFieldImpl(expression.startOffset, expression.endOffset, entrySymbol)
}
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {