Inner classes lowering.
This commit is contained in:
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.jvm
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
|
||||
|
||||
interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER")
|
||||
@@ -26,10 +27,10 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object FIELD_FOR_ENUM_ENTRY : IrDeclarationOriginImpl("FIELD_FOR_ENUM_ENTRY")
|
||||
object FIELD_FOR_ENUM_VALUES : IrDeclarationOriginImpl("FIELD_FOR_ENUM_VALUES")
|
||||
object FIELD_FOR_OBJECT_INSTANCE : IrDeclarationOriginImpl("FIELD_FOR_OBJECT_INSTANCE")
|
||||
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
|
||||
object SYNTHETIC_ACCESSOR : IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR")
|
||||
}
|
||||
|
||||
interface JvmLoweredStatementOrigin : IrStatementOrigin {
|
||||
object DEFAULT_IMPLS_DELEGATION : IrStatementOrigin.IrStatementOriginImpl("DEFAULT_IMPL_DELEGATION")
|
||||
|
||||
object DEFAULT_IMPLS_DELEGATION : IrStatementOriginImpl("DEFAULT_IMPL_DELEGATION")
|
||||
}
|
||||
@@ -35,6 +35,8 @@ class JvmLower(val context: JvmBackendContext) {
|
||||
InterfaceLowering(context.state).runOnFilePostfix(irFile)
|
||||
InterfaceDelegationLowering(context.state).runOnFilePostfix(irFile)
|
||||
SharedVariablesLowering(context).runOnFilePostfix(irFile)
|
||||
InnerClassesLowering(context).runOnFilePostfix(irFile)
|
||||
InnerClassConstructorCallsLowering(context).runOnFilePostfix(irFile)
|
||||
LocalFunctionsLowering(context).runOnFilePostfix(irFile)
|
||||
EnumClassLowering(context).runOnFilePostfix(irFile)
|
||||
ObjectClassLowering(context).runOnFilePostfix(irFile)
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -201,6 +202,9 @@ fun MemberDescriptor.calculateCommonFlags(): Int {
|
||||
else if (visibility == Visibilities.PROTECTED) {
|
||||
flags = flags.or(Opcodes.ACC_PROTECTED)
|
||||
}
|
||||
else if (visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||
// default visibility
|
||||
}
|
||||
else {
|
||||
throw RuntimeException("Unsupported visibility $visibility for descriptor $this")
|
||||
}
|
||||
|
||||
+10
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
@@ -41,6 +42,15 @@ class FunctionCodegen(val irFunction: IrFunction, val classCodegen: ClassCodegen
|
||||
val descriptor = irFunction.descriptor
|
||||
|
||||
fun generate() {
|
||||
try {
|
||||
doGenerate()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throw RuntimeException("${e.message} + while generating code for:\n${irFunction.dump()}", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doGenerate() {
|
||||
val signature = classCodegen.typeMapper.mapSignatureWithGeneric(descriptor, OwnerKind.IMPLEMENTATION)
|
||||
val isStatic = isStaticMethod(classCodegen.descriptor.getMemberOwnerKind(), descriptor) || DescriptorUtils.isStaticDeclaration(descriptor)
|
||||
val frameMap = createFrameMapWithReceivers(classCodegen.state, descriptor, signature, isStatic)
|
||||
|
||||
+14
@@ -70,5 +70,19 @@ class JvmPropertyDescriptorImpl(
|
||||
containingDeclaration, null, annotations, modality, visibility, extraFlags, false, name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED, source, false, false
|
||||
).initialize(type)
|
||||
|
||||
fun createFinalField(
|
||||
name: Name,
|
||||
type: KotlinType,
|
||||
classDescriptor: ClassDescriptor,
|
||||
annotations: Annotations,
|
||||
visibility: Visibility,
|
||||
extraFlags: Int,
|
||||
source: SourceElement
|
||||
): PropertyDescriptorImpl =
|
||||
JvmPropertyDescriptorImpl(
|
||||
classDescriptor, null, annotations, Modality.FINAL, visibility, extraFlags, false, name,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED, source, false, false
|
||||
).initialize(type, dispatchReceiverParameter = classDescriptor.thisAsReceiverParameter)
|
||||
}
|
||||
}
|
||||
+46
@@ -19,11 +19,14 @@ package org.jetbrains.kotlin.backend.jvm.descriptors
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
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.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.ir.SourceManager
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import java.util.*
|
||||
@@ -33,6 +36,8 @@ class SpecialDescriptorsFactory(
|
||||
val builtIns: KotlinBuiltIns
|
||||
) {
|
||||
private val singletonFieldDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
|
||||
private val outerThisDescriptors = HashMap<ClassDescriptor, PropertyDescriptor>()
|
||||
private val innerClassConstructors = HashMap<ClassConstructorDescriptor, ClassConstructorDescriptor>()
|
||||
|
||||
fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor =
|
||||
singletonFieldDescriptors.getOrPut(enumEntryDescriptor) {
|
||||
@@ -52,6 +57,47 @@ class SpecialDescriptorsFactory(
|
||||
)
|
||||
}
|
||||
|
||||
fun getOuterThisFieldDescriptor(innerClassDescriptor: ClassDescriptor): PropertyDescriptor =
|
||||
if (!innerClassDescriptor.isInner) throw AssertionError("Class is not inner: $innerClassDescriptor")
|
||||
else outerThisDescriptors.getOrPut(innerClassDescriptor) {
|
||||
val outerClassDescriptor = DescriptorUtils.getContainingClass(innerClassDescriptor) ?:
|
||||
throw AssertionError("No containing class for inner class $innerClassDescriptor")
|
||||
|
||||
JvmPropertyDescriptorImpl.createFinalField(
|
||||
Name.identifier("this$0"), outerClassDescriptor.defaultType, innerClassDescriptor,
|
||||
Annotations.EMPTY, JavaVisibilities.PACKAGE_VISIBILITY, Opcodes.ACC_SYNTHETIC, SourceElement.NO_SOURCE
|
||||
)
|
||||
}
|
||||
|
||||
fun getInnerClassConstructorWithOuterThisParameter(innerClassConstructor: ClassConstructorDescriptor): ClassConstructorDescriptor {
|
||||
val innerClass = innerClassConstructor.containingDeclaration
|
||||
assert(innerClass.isInner) { "Class is not inner: $innerClass" }
|
||||
|
||||
return innerClassConstructors.getOrPut(innerClassConstructor) {
|
||||
createInnerClassConstructorWithOuterThisParameter(innerClassConstructor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createInnerClassConstructorWithOuterThisParameter(oldDescriptor: ClassConstructorDescriptor): ClassConstructorDescriptor {
|
||||
val classDescriptor = oldDescriptor.containingDeclaration
|
||||
val outerThisType = (classDescriptor.containingDeclaration as ClassDescriptor).defaultType
|
||||
|
||||
val newDescriptor = ClassConstructorDescriptorImpl.createSynthesized(
|
||||
classDescriptor, oldDescriptor.annotations, oldDescriptor.isPrimary, oldDescriptor.source
|
||||
)
|
||||
|
||||
val outerThisValueParameter = newDescriptor.createValueParameter(0, "\$outer", outerThisType)
|
||||
|
||||
val newValueParameters =
|
||||
listOf(outerThisValueParameter) +
|
||||
oldDescriptor.valueParameters.map { it.copy(newDescriptor, it.name, it.index + 1) }
|
||||
newDescriptor.initialize(newValueParameters, oldDescriptor.visibility)
|
||||
newDescriptor.returnType = oldDescriptor.returnType
|
||||
return newDescriptor
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun createEnumEntryFieldDescriptor(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor {
|
||||
assert(enumEntryDescriptor.kind == ClassKind.ENUM_ENTRY) { "Should be enum entry: $enumEntryDescriptor" }
|
||||
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
fun PropertyDescriptorImpl.initialize(
|
||||
type: KotlinType,
|
||||
@@ -34,4 +35,14 @@ fun PropertyDescriptorImpl.initialize(
|
||||
setType(type, typeParameters, dispatchReceiverParameter, extensionReceiverParameter)
|
||||
initialize(getter, setter)
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
fun CallableMemberDescriptor.createValueParameter(index: Int, name: String, type: KotlinType): ValueParameterDescriptor =
|
||||
ValueParameterDescriptorImpl(
|
||||
this, null,
|
||||
index,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier(name),
|
||||
type,
|
||||
false, false, false, false, null, SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
+3
-12
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.backend.jvm.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.createValueParameter
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
@@ -137,8 +138,8 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
val valueParameters =
|
||||
listOf(
|
||||
loweredConstructorDescriptor.createSpecialParameter(0, "name", context.builtIns.stringType),
|
||||
loweredConstructorDescriptor.createSpecialParameter(1, "ordinal", context.builtIns.intType)
|
||||
loweredConstructorDescriptor.createValueParameter(0, "name", context.builtIns.stringType),
|
||||
loweredConstructorDescriptor.createValueParameter(1, "ordinal", context.builtIns.intType)
|
||||
) +
|
||||
constructorDescriptor.valueParameters.map {
|
||||
lowerConstructorValueParameter(loweredConstructorDescriptor, it)
|
||||
@@ -152,16 +153,6 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
return loweredConstructorDescriptor
|
||||
}
|
||||
|
||||
private fun ClassConstructorDescriptor.createSpecialParameter(index: Int, name: String, type: KotlinType): ValueParameterDescriptor =
|
||||
ValueParameterDescriptorImpl(
|
||||
this, null,
|
||||
index,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier(name),
|
||||
type,
|
||||
false, false, false, false, null, SourceElement.NO_SOURCE
|
||||
)
|
||||
|
||||
private fun lowerConstructorValueParameter(
|
||||
loweredConstructorDescriptor: ClassConstructorDescriptor,
|
||||
valueParameterDescriptor: ValueParameterDescriptor
|
||||
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.jvm.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
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.dump
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||
|
||||
class InnerClassesLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
InnerClassTransformer(irClass).lowerInnerClass()
|
||||
}
|
||||
|
||||
private inner class InnerClassTransformer(val irClass: IrClass) {
|
||||
val classDescriptor = irClass.descriptor
|
||||
|
||||
private lateinit var outerThisFieldDescriptor: PropertyDescriptor
|
||||
|
||||
fun lowerInnerClass() {
|
||||
if (!irClass.descriptor.isInner) return
|
||||
|
||||
createOuterThisField()
|
||||
lowerConstructors()
|
||||
lowerOuterThisReferences()
|
||||
}
|
||||
|
||||
private fun createOuterThisField() {
|
||||
outerThisFieldDescriptor = context.specialDescriptorsFactory.getOuterThisFieldDescriptor(irClass.descriptor)
|
||||
|
||||
irClass.declarations.add(IrFieldImpl(
|
||||
irClass.startOffset, irClass.endOffset,
|
||||
JvmLoweredDeclarationOrigin.FIELD_FOR_OUTER_THIS,
|
||||
outerThisFieldDescriptor
|
||||
))
|
||||
}
|
||||
|
||||
private fun lowerConstructors() {
|
||||
irClass.declarations.transformFlat { irMember ->
|
||||
if (irMember is IrConstructor)
|
||||
lowerConstructor(irMember).singletonList()
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun lowerConstructor(irConstructor: IrConstructor): IrConstructor {
|
||||
val oldDescriptor = irConstructor.descriptor
|
||||
val startOffset = irConstructor.startOffset
|
||||
val endOffset = irConstructor.endOffset
|
||||
|
||||
val newDescriptor = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(oldDescriptor)
|
||||
val outerThisValueParameter = newDescriptor.valueParameters[0]
|
||||
|
||||
val blockBody = irConstructor.body as? IrBlockBody ?: throw AssertionError("Unexpected constructor body: ${irConstructor.body}")
|
||||
|
||||
val instanceInitializerIndex = blockBody.statements.indexOfFirst { it is IrInstanceInitializerCall }
|
||||
if (instanceInitializerIndex >= 0) {
|
||||
// Initializing constructor: initialize 'this.this$0' with '$outer'
|
||||
blockBody.statements.add(
|
||||
instanceInitializerIndex,
|
||||
IrSetFieldImpl(
|
||||
startOffset, endOffset, outerThisFieldDescriptor,
|
||||
IrGetValueImpl(startOffset, endOffset, classDescriptor.thisAsReceiverParameter),
|
||||
IrGetValueImpl(startOffset, endOffset, outerThisValueParameter)
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
// Delegating constructor: invoke old constructor with dispatch receiver '$outer'
|
||||
val delegatingConstructorCall = (blockBody.statements.find { it is IrDelegatingConstructorCall } ?:
|
||||
throw AssertionError("Delegating constructor call expected: ${irConstructor.dump()}")
|
||||
) as IrDelegatingConstructorCall
|
||||
delegatingConstructorCall.dispatchReceiver = IrGetValueImpl(
|
||||
delegatingConstructorCall.startOffset, delegatingConstructorCall.endOffset, outerThisValueParameter
|
||||
)
|
||||
}
|
||||
|
||||
return IrConstructorImpl(
|
||||
startOffset, endOffset,
|
||||
irConstructor.origin, // TODO special origin for lowered inner class constructors?
|
||||
newDescriptor,
|
||||
blockBody
|
||||
)
|
||||
}
|
||||
|
||||
private fun lowerOuterThisReferences() {
|
||||
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val implicitThisClass = expression.descriptor.getClassDescriptorForImplicitThis() ?:
|
||||
return expression
|
||||
|
||||
if (implicitThisClass == classDescriptor) return expression
|
||||
|
||||
val startOffset = expression.startOffset
|
||||
val endOffset = expression.endOffset
|
||||
val origin = expression.origin
|
||||
|
||||
var irThis: IrExpression = IrGetValueImpl(startOffset, endOffset, classDescriptor.thisAsReceiverParameter, origin)
|
||||
var innerClass = classDescriptor
|
||||
|
||||
while (innerClass != implicitThisClass) {
|
||||
if (!innerClass.isInner) {
|
||||
// Captured 'this' unrelated to inner classes nesting hierarchy, leave it as is -
|
||||
// should be transformed by closures conversion.
|
||||
return expression
|
||||
}
|
||||
|
||||
val outerThisField = context.specialDescriptorsFactory.getOuterThisFieldDescriptor(innerClass)
|
||||
irThis = IrGetFieldImpl(startOffset, endOffset, outerThisField, irThis, origin)
|
||||
|
||||
val outer = classDescriptor.containingDeclaration
|
||||
innerClass = outer as? ClassDescriptor ?:
|
||||
throw AssertionError("Unexpected containing declaration for inner class $innerClass: $outer")
|
||||
}
|
||||
|
||||
return irThis
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun ValueDescriptor.getClassDescriptorForImplicitThis(): ClassDescriptor? {
|
||||
if (this is ReceiverParameterDescriptor) {
|
||||
val receiverValue = value
|
||||
if (receiverValue is ImplicitClassReceiver) {
|
||||
return receiverValue.classDescriptor
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class InnerClassConstructorCallsLowering(val context: JvmBackendContext) : BodyLoweringPass {
|
||||
override fun lower(irBody: IrBody) {
|
||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val dispatchReceiver = expression.dispatchReceiver ?: return expression
|
||||
val callee = expression.descriptor as? ClassConstructorDescriptor ?: return expression
|
||||
if (!callee.constructedClass.isInner) return expression
|
||||
|
||||
val newCallee = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee)
|
||||
val newCall = IrCallImpl(
|
||||
expression.startOffset, expression.endOffset, newCallee,
|
||||
null, // TODO type arguments map
|
||||
expression.origin
|
||||
)
|
||||
|
||||
newCall.putValueArgument(0, dispatchReceiver)
|
||||
for (i in 1 .. newCallee.valueParameters.lastIndex) {
|
||||
newCall.putValueArgument(i, expression.getValueArgument(i))
|
||||
}
|
||||
|
||||
return newCall
|
||||
}
|
||||
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val dispatchReceiver = expression.dispatchReceiver ?: return expression
|
||||
val callee = expression.descriptor
|
||||
if (!callee.constructedClass.isInner) return expression
|
||||
|
||||
val newCallee = context.specialDescriptorsFactory.getInnerClassConstructorWithOuterThisParameter(callee)
|
||||
val newCall = IrDelegatingConstructorCallImpl(
|
||||
expression.startOffset, expression.endOffset, newCallee,
|
||||
null // TODO type arguments map
|
||||
)
|
||||
|
||||
newCall.putValueArgument(0, dispatchReceiver)
|
||||
for (i in 1 .. newCallee.valueParameters.lastIndex) {
|
||||
newCall.putValueArgument(i, expression.getValueArgument(i))
|
||||
}
|
||||
|
||||
return newCall
|
||||
}
|
||||
|
||||
// TODO callable references?
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
interface IrStatementOrigin {
|
||||
abstract class IrStatementOriginImpl(val debugName: String): IrStatementOrigin {
|
||||
override fun toString(): String = debugName
|
||||
}
|
||||
abstract class IrStatementOriginImpl(val debugName: String): IrStatementOrigin {
|
||||
override fun toString(): String = debugName
|
||||
}
|
||||
|
||||
interface IrStatementOrigin {
|
||||
object SAFE_CALL : IrStatementOriginImpl("SAFE_CALL")
|
||||
|
||||
object UMINUS : IrStatementOriginImpl("UMINUS")
|
||||
|
||||
Reference in New Issue
Block a user