Fix secondary constructor lowering

This commit is contained in:
Roman Artemev
2018-04-23 21:05:20 +03:00
parent 8721990a7f
commit 8bc80a9829
25 changed files with 129 additions and 236 deletions
@@ -8,10 +8,11 @@ package org.jetbrains.kotlin.backend.common.descriptors
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
interface DescriptorsFactory {
fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor
fun getOuterThisFieldDescriptor(classDescriptor: ClassDescriptor): PropertyDescriptor
fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): ClassConstructorDescriptor
fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): IrConstructorSymbol
fun getFieldDescriptorForObjectInstance(objectDescriptor: ClassDescriptor): PropertyDescriptor
}
@@ -5,8 +5,7 @@
package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrStatement
@@ -73,11 +72,11 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
val startOffset = irConstructor.startOffset
val endOffset = irConstructor.endOffset
val newDescriptor = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor)
val outerThisValueParameter = newDescriptor.valueParameters[0]
val newSymbol = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor)
val outerThisValueParameter = newSymbol.descriptor.valueParameters[0]
oldDescriptor.valueParameters.forEach { oldValueParameter ->
oldConstructorParameterToNew[oldValueParameter] = newDescriptor.valueParameters[oldValueParameter.index + 1]
oldConstructorParameterToNew[oldValueParameter] = newSymbol.descriptor.valueParameters[oldValueParameter.index + 1]
}
val blockBody = irConstructor.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${irConstructor.body}")
@@ -105,12 +104,12 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
}
return IrConstructorImpl(
startOffset, endOffset,
irConstructor.origin, // TODO special origin for lowered inner class constructors?
newDescriptor,
blockBody
startOffset, endOffset,
irConstructor.origin, // TODO special origin for lowered inner class constructors?
newSymbol,
blockBody
).apply {
newDescriptor.valueParameters.forEachIndexed { i, desc ->
newSymbol.descriptor.valueParameters.forEachIndexed { i, desc ->
val valueParameter = if (i == 0) {
IrValueParameterImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, FIELD_FOR_OUTER_THIS, desc, null)
} else {
@@ -159,7 +158,7 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
val outerThisField = context.descriptorsFactory.getOuterThisFieldDescriptor(innerClass)
irThis = IrGetFieldImpl(startOffset, endOffset, outerThisField, irThis, origin)
val outer = classDescriptor.containingDeclaration
val outer = innerClass.containingDeclaration
innerClass = outer as? ClassDescriptor ?:
throw AssertionError("Unexpected containing declaration for inner class $innerClass: $outer")
}
@@ -193,13 +192,13 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe
val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee)
val newCall = IrCallImpl(
expression.startOffset, expression.endOffset, newCallee,
expression.startOffset, expression.endOffset, newCallee, newCallee.descriptor,
null, // TODO type arguments map
expression.origin
)
newCall.putValueArgument(0, dispatchReceiver)
for (i in 1 .. newCallee.valueParameters.lastIndex) {
for (i in 1 .. newCallee.descriptor.valueParameters.lastIndex) {
newCall.putValueArgument(i, expression.getValueArgument(i - 1))
}
@@ -215,12 +214,12 @@ class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLowe
val newCallee = context.descriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee)
val newCall = IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset, newCallee,
expression.startOffset, expression.endOffset, newCallee, newCallee.descriptor,
null // TODO type arguments map
)
newCall.putValueArgument(0, dispatchReceiver)
for (i in 1 .. newCallee.valueParameters.lastIndex) {
for (i in 1 .. newCallee.descriptor.valueParameters.lastIndex) {
newCall.putValueArgument(i, expression.getValueArgument(i - 1))
}
@@ -235,6 +235,8 @@ val IrClass.defaultType: KotlinType
val IrSimpleFunction.isReal: Boolean get() = descriptor.kind.isReal
// This implementation is from kotlin-native
// TODO: use this implementation instead of any other
fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction? {
if (isReal) return this
@@ -264,7 +266,7 @@ fun IrSimpleFunction.resolveFakeOverride(): IrSimpleFunction? {
}
visited.clear()
realOverrides.asSequence().forEach { excludeRepeated(it) }
realOverrides.toList().forEach { excludeRepeated(it) }
return realOverrides.singleOrNull { it.modality != Modality.ABSTRACT }
}