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