Inner classes lowering.

This commit is contained in:
Dmitry Petrov
2016-10-18 15:59:33 +03:00
parent f933cf5395
commit 7dce1f438f
16 changed files with 380 additions and 31 deletions
@@ -1261,10 +1261,13 @@ public class KotlinTypeMapper {
}
private void writeAdditionalConstructorParameters(@NotNull ClassConstructorDescriptor descriptor, @NotNull JvmSignatureWriter sw) {
boolean isSynthesized = descriptor.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED;
//if (isSynthesized) return;
MutableClosure closure = bindingContext.get(CodegenBinding.CLOSURE, descriptor.getContainingDeclaration());
ClassDescriptor captureThis = getDispatchReceiverParameterForConstructorCall(descriptor, closure);
if (captureThis != null) {
if (!isSynthesized && captureThis != null) {
writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType(), descriptor);
}
@@ -1274,12 +1277,16 @@ public class KotlinTypeMapper {
}
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (descriptor.getKind() != CallableMemberDescriptor.Kind.SYNTHESIZED &&
(containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY)) {
writeParameter(
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType(), descriptor);
writeParameter(
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getIntType(), descriptor);
if (!isSynthesized) {
if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) {
writeParameter(
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType(),
descriptor);
writeParameter(
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getIntType(),
descriptor);
}
}
if (closure == null) return;
@@ -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")
}
@@ -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)
@@ -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)
}
}
@@ -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
)
@@ -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
@@ -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")
@@ -0,0 +1,8 @@
class Outer {
val x = "O"
inner class Inner {
val y = x + "K"
}
}
fun box() = Outer().Inner().y
@@ -0,0 +1,5 @@
class Outer {
inner class Inner(val x: Int) {
constructor() : this(0)
}
}
@@ -0,0 +1,25 @@
FILE /innerClassWithDelegatingConstructor.kt
CLASS CLASS Outer
CONSTRUCTOR public constructor Outer()
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
INSTANCE_INITIALIZER_CALL classDescriptor='Outer'
CLASS CLASS Inner
CONSTRUCTOR public constructor Inner(x: kotlin.Int)
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
INSTANCE_INITIALIZER_CALL classDescriptor='Inner'
PROPERTY public final val x: kotlin.Int
FIELD PROPERTY_BACKING_FIELD public final val x: kotlin.Int
EXPRESSION_BODY
GET_VAR 'value-parameter x: Int' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER
FUN DEFAULT_PROPERTY_ACCESSOR public final fun <get-x>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-x>(): Int'
GET_FIELD 'x: Int' type=kotlin.Int origin=null
receiver: GET_VAR '<receiver: Inner>' type=Outer.Inner origin=null
CONSTRUCTOR public constructor Inner()
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Inner(Int)'
$this: GET_VAR '<receiver: Outer>' type=Outer origin=null
x: CONST Int type=kotlin.Int value='0'
@@ -109,6 +109,12 @@ public class IrOnlyBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTest
doTest(fileName);
}
@TestMetadata("innerClass1.kt")
public void testInnerClass1() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion/innerClass1.kt");
doTest(fileName);
}
@TestMetadata("mutable1.kt")
public void testMutable1() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion/mutable1.kt");
@@ -127,6 +127,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
doTest(fileName);
}
@TestMetadata("innerClassWithDelegatingConstructor.kt")
public void testInnerClassWithDelegatingConstructor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/innerClassWithDelegatingConstructor.kt");
doTest(fileName);
}
@TestMetadata("localClasses.kt")
public void testLocalClasses() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/localClasses.kt");