diff --git a/compiler/ir/backend.jvm/backend.jvm.iml b/compiler/ir/backend.jvm/backend.jvm.iml index 3f84a98cbb2..fe10d927fa6 100644 --- a/compiler/ir/backend.jvm/backend.jvm.iml +++ b/compiler/ir/backend.jvm/backend.jvm.iml @@ -10,6 +10,7 @@ + diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt new file mode 100644 index 00000000000..cb10e4c9218 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt @@ -0,0 +1,23 @@ +/* + * 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 + +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl + +object JvmDeclarationOrigins { + object CLASS_STATIC_INITIALIZER : IrDeclarationOriginImpl("CLASS_STATIC_INITIALIZER") +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 4424aac1b8e..68a4af5e6f1 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -17,12 +17,38 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.backend.jvm.lower.FileClassLowering +import org.jetbrains.kotlin.backend.jvm.lower.InitializersLowering import org.jetbrains.kotlin.backend.jvm.lower.PropertiesLowering +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer import org.jetbrains.kotlin.ir.declarations.IrFile class JvmLower(val context: JvmBackendContext) { fun lower(irFile: IrFile) { FileClassLowering(context.jvmFileClassProvider).lower(irFile) PropertiesLowering().lower(irFile) + InitializersLowering().runOnNormalizedFile(irFile) } } + +interface FileLoweringPass { + fun lower(irFile: IrFile + ) +} + +interface ClassLoweringPass { + fun lower(irClass: IrClass) +} + +fun ClassLoweringPass.runOnNormalizedFile(irFile: IrFile) { + fun runPostfix(irDeclarationContainer: IrDeclarationContainer) { + irDeclarationContainer.declarations.forEach { + if (it is IrClass) { + runPostfix(it) + lower(it) + } + } + } + + runPostfix(irFile) +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 535c0c5d63e..7537acc6d5d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -46,7 +46,7 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac val type: Type = typeMapper.mapType(descriptor) - val psiElement = irClass.descriptor.psiElement + val psiElement = irClass.descriptor.psiElement!! val visitor: ClassBuilder = state.factory.newVisitor(OtherOrigin(psiElement, descriptor), type, psiElement.containingFile) @@ -91,22 +91,14 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac fun generateDeclaration(declaration: IrDeclaration) { when (declaration) { - is IrProperty -> { - declaration.backingField?.let { - generateField(it) - } - - declaration.getter?.let { - generateMethod(it) - } - - declaration.setter?.let { - generateMethod(it) - } - } + is IrField -> + generateField(declaration) is IrFunction -> { generateMethod(declaration) } + is IrAnonymousInitializer -> { + // skip + } else -> throw RuntimeException("Unsupported declaration $declaration") } } @@ -161,11 +153,17 @@ fun MemberDescriptor.calculateCommonFlags(): Int { else -> throw RuntimeException("Unsupported modality $modality for descriptor $this") } + if (this is CallableMemberDescriptor) { + if (this !is ConstructorDescriptor && dispatchReceiverParameter == null) { + flags = flags or Opcodes.ACC_STATIC + } + } + return flags } -val DeclarationDescriptorWithSource.psiElement: PsiElement - get() = (source as PsiSourceElement).psi!! +val DeclarationDescriptorWithSource.psiElement: PsiElement? + get() = (source as? PsiSourceElement)?.psi val IrField.OtherOrigin: JvmDeclarationOrigin get() = OtherOrigin(descriptor.psiElement, this.descriptor) @@ -173,7 +171,12 @@ val IrField.OtherOrigin: JvmDeclarationOrigin val IrFunction.OtherOrigin: JvmDeclarationOrigin get() = OtherOrigin(descriptor.psiElement, this.descriptor) -fun ClassDescriptor.getMemberOwnerKind(): OwnerKind = when (this) { - is FileClassDescriptor -> OwnerKind.PACKAGE - else -> OwnerKind.IMPLEMENTATION +fun DeclarationDescriptor.getMemberOwnerKind(): OwnerKind = when (this) { + is FileClassDescriptor -> + OwnerKind.PACKAGE + is PackageFragmentDescriptor, + is ClassDescriptor -> + OwnerKind.IMPLEMENTATION + else -> + throw AssertionError("Unexpected declaration container: $this") } \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 307f42c30c1..57dd619b8e6 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -238,6 +238,26 @@ class ExpressionCodegen( return generateLocal(expression.descriptor, expression.asmType) } + private fun generateFieldValue(expression: IrFieldAccessExpression, data: BlockInfo): StackValue { + val receiverValue = expression.receiver?.accept(this, data) ?: StackValue.none() + val propertyDescriptor = expression.descriptor + val fieldType = typeMapper.mapType(propertyDescriptor.type) + val ownerType = typeMapper.mapImplementationOwner(propertyDescriptor) + val fieldName = propertyDescriptor.name.asString() + val isStatic = expression.receiver == null // TODO + return StackValue.field(fieldType, ownerType, fieldName, isStatic, receiverValue, propertyDescriptor) + } + + override fun visitGetField(expression: IrGetField, data: BlockInfo): StackValue { + return generateFieldValue(expression, data) + } + + override fun visitSetField(expression: IrSetField, data: BlockInfo): StackValue { + val fieldValue = generateFieldValue(expression, data) + fieldValue.store(expression.value.accept(this, data), mv) + return expression.onStack + } + private fun generateLocal(descriptor: CallableDescriptor, type: Type): StackValue { StackValue.local(frame.getIndex(descriptor), type).put(type, mv) return onStack(type) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index bb58a7dc28c..955fc686bd4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -24,7 +24,6 @@ import org.jetbrains.org.objectweb.asm.Opcodes.ACC_STATIC import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter class FunctionCodegen(val irFunction: IrFunction, val classCodegen: ClassCodegen) { - fun generate() { val signature = classCodegen.typeMapper.mapSignatureWithGeneric(irFunction.descriptor, OwnerKind.IMPLEMENTATION) val isStatic = isStaticMethod(classCodegen.descriptor.getMemberOwnerKind(), irFunction.descriptor) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt index a0e64bc16fd..f7ba3817273 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.backend.jvm.lower +import org.jetbrains.kotlin.backend.jvm.FileLoweringPass import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin @@ -23,8 +24,8 @@ import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import java.util.* -class FileClassLowering(val jvmFileClassProvider: JvmFileClassProvider) { - fun lower(irFile: IrFile) { +class FileClassLowering(val jvmFileClassProvider: JvmFileClassProvider) : FileLoweringPass { + override fun lower(irFile: IrFile) { val classes = ArrayList() val fileClassMembers = ArrayList() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InitializersLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InitializersLowering.kt index ef54a104274..6bde59603db 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InitializersLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InitializersLowering.kt @@ -16,20 +16,131 @@ package org.jetbrains.kotlin.backend.jvm.lower +import org.jetbrains.kotlin.backend.jvm.ClassLoweringPass +import org.jetbrains.kotlin.backend.jvm.JvmDeclarationOrigins import org.jetbrains.kotlin.backend.jvm.codegen.getMemberOwnerKind -import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.codegen.AsmUtil +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.expressions.IrBlockBody +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrInstanceInitializerCall import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrThisReferenceImpl +import org.jetbrains.kotlin.ir.util.DeepCopyIrTree +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import java.util.* -class InitializersLowering { - fun lower(irClass: IrClass) { +class InitializersLowering : ClassLoweringPass { + override fun lower(irClass: IrClass) { + val classInitializersBuilder = ClassInitializersBuilder(irClass) + irClass.acceptChildrenVoid(classInitializersBuilder) + + classInitializersBuilder.transformInstanceInitializerCallsInConstructors(irClass) + + classInitializersBuilder.createStaticInitializationMethod(irClass) + } + + private class ClassInitializersBuilder(val irClass: IrClass) : IrElementVisitorVoid { val classMemberOwnerKind = irClass.descriptor.getMemberOwnerKind() - val staticInitializerBody = IrBlockBodyImpl(irClass.startOffset, irClass.endOffset) - val instanceInitializerBlock = IrBlockImpl(irClass.startOffset, irClass.endOffset, irClass.descriptor.builtIns.unitType, null) + val staticInitializerStatements = ArrayList() - // TODO + val instanceInitializerStatements = ArrayList() + + override fun visitElement(element: IrElement) { + // skip everything else + } + + override fun visitField(declaration: IrField) { + val irFieldInitializer = declaration.initializer?.let { it.expression } ?: return + + val receiver = + if (declaration.descriptor.dispatchReceiverParameter != null) // TODO isStaticField + IrThisReferenceImpl(irFieldInitializer.startOffset, irFieldInitializer.endOffset, + irClass.descriptor.defaultType, irClass.descriptor) + else null + val irSetField = IrSetFieldImpl( + irFieldInitializer.startOffset, irFieldInitializer.endOffset, + declaration.descriptor, + receiver, + irFieldInitializer, + null, null + ) + + if (declaration.descriptor.isStatic()) { + staticInitializerStatements.add(irSetField) + } + else { + instanceInitializerStatements.add(irSetField) + } + } + + override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) { + instanceInitializerStatements.addAll(declaration.body.statements) + } + + private fun CallableMemberDescriptor.isStatic() = + AsmUtil.isStaticMethod(classMemberOwnerKind, this) // TODO what about properties? + + + fun transformInstanceInitializerCallsInConstructors(irClass: IrClass) { + for (irDeclaration in irClass.declarations) { + if (irDeclaration !is IrConstructor) continue + val irBody = irDeclaration.body as IrBlockBody + if (irBody.statements.any { it is IrInstanceInitializerCall }) { + val newStatements = irBody.statements.map { irStatement -> + if (irStatement is IrInstanceInitializerCall) { + IrBlockImpl(irClass.startOffset, irClass.endOffset, irDeclaration.descriptor.builtIns.unitType, null, + instanceInitializerStatements.map { it.copy() }) + } + else { + irStatement + } + } + irBody.statements.clear() + irBody.statements.addAll(newStatements) + } + } + } + + fun createStaticInitializationMethod(irClass: IrClass) { + val staticInitializerDescriptor = SimpleFunctionDescriptorImpl.create( + irClass.descriptor, Annotations.EMPTY, clinitName, + CallableMemberDescriptor.Kind.SYNTHESIZED, + SourceElement.NO_SOURCE + ) + staticInitializerDescriptor.initialize( + null, null, emptyList(), emptyList(), + irClass.descriptor.builtIns.unitType, + Modality.FINAL, Visibilities.PUBLIC + ) + irClass.declarations.add( + IrFunctionImpl(irClass.startOffset, irClass.endOffset, JvmDeclarationOrigins.CLASS_STATIC_INITIALIZER, + staticInitializerDescriptor, + IrBlockBodyImpl(irClass.startOffset, irClass.endOffset, + staticInitializerStatements.map { it.copy() })) + ) + } + } + + companion object { + val clinitName = Name.special("") + + val deepCopyVisitor = DeepCopyIrTree() + + fun IrStatement.copy() = transform(deepCopyVisitor, null) + fun IrExpression.copy() = transform(deepCopyVisitor, null) } } \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertiesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertiesLowering.kt index 1dd2d74ebf0..65d0c5cc288 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertiesLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertiesLowering.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.backend.jvm.lower +import org.jetbrains.kotlin.backend.jvm.FileLoweringPass import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration @@ -26,8 +27,8 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* -class PropertiesLowering : IrElementTransformerVoid() { - fun lower(irFile: IrFile) { +class PropertiesLowering : IrElementTransformerVoid(), FileLoweringPass { + override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(this) } @@ -44,18 +45,18 @@ class PropertiesLowering : IrElementTransformerVoid() { } private fun transformDeclarations(declarations: MutableList) { - val properties = linkedSetOf() - - declarations.filterIsInstanceTo(properties) - - declarations.removeAll(properties) - - properties.flatMapTo(declarations) { irProperty -> - val result = ArrayList(3) - result.addIfNotNull(irProperty.backingField) - result.addIfNotNull(irProperty.getter) - result.addIfNotNull(irProperty.setter) - result + val newDeclarations = ArrayList() + for (declaration in declarations) { + if (declaration is IrProperty) { + newDeclarations.addIfNotNull(declaration.backingField) + newDeclarations.addIfNotNull(declaration.getter) + newDeclarations.addIfNotNull(declaration.setter) + } + else { + newDeclarations.add(declaration) + } } + declarations.clear() + declarations.addAll(newDeclarations) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt index f61e81bf593..52f27bd7779 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrAnonymousInitializer.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.ir.declarations import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.IrBody interface IrAnonymousInitializer : IrDeclaration { @@ -25,6 +26,6 @@ interface IrAnonymousInitializer : IrDeclaration { override val declarationKind: IrDeclarationKind get() = IrDeclarationKind.ANONYMOUS_INITIALIZER - var body: IrBody + var body: IrBlockBody } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt index 0ccfa9ed778..5bbc06dafe2 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationOrigin.kt @@ -23,7 +23,6 @@ interface IrDeclarationOrigin { object DELEGATE : IrDeclarationOriginImpl("DELEGATE") object DELEGATED_PROPERTY_ACCESSOR : IrDeclarationOriginImpl("DELEGATED_PROPERTY_ACCESSOR") object DELEGATED_MEMBER : IrDeclarationOriginImpl("DELEGATED_MEMBER") - object CLASS_FOR_ENUM_ENTRY : IrDeclarationOriginImpl("CLASS_FOR_ENUM_ENTRY") object ENUM_CLASS_SPECIAL_MEMBER : IrDeclarationOriginImpl("ENUM_CLASS_SPECIAL_MEMBER") object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER") object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA") diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt index 6b08f08b8c2..76b23aea27f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt @@ -37,5 +37,5 @@ interface IrField : IrDeclaration { override val declarationKind: IrDeclarationKind get() = IrDeclarationKind.FIELD - var initializer: IrBody? + var initializer: IrExpressionBody? } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrAnonymousInitializerImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrAnonymousInitializerImpl.kt index d87ef1bf1f9..a486a762196 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrAnonymousInitializerImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrAnonymousInitializerImpl.kt @@ -34,12 +34,12 @@ class IrAnonymousInitializerImpl( ) : IrDeclarationBase(startOffset, endOffset, origin), IrAnonymousInitializer { constructor( startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor, - body: IrBody + body: IrBlockBody ) : this(startOffset, endOffset, origin, descriptor) { this.body = body } - override lateinit var body: IrBody + override lateinit var body: IrBlockBody override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitAnonymousInitializer(this, data) @@ -50,6 +50,6 @@ class IrAnonymousInitializerImpl( } override fun transformChildren(transformer: IrElementTransformer, data: D) { - body = body.transform(transformer, data) + body = body.transform(transformer, data) as IrBlockBody } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFieldImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFieldImpl.kt index dc77fec7ebf..5c7b99133ce 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFieldImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrFieldImpl.kt @@ -32,12 +32,12 @@ class IrFieldImpl( override val descriptor: PropertyDescriptor ): IrDeclarationBase(startOffset, endOffset, origin), IrField { constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor, - initializer: IrBody? + initializer: IrExpressionBody? ) : this(startOffset, endOffset, origin, descriptor) { this.initializer = initializer } - override var initializer: IrBody? = null + override var initializer: IrExpressionBody? = null override fun accept(visitor: IrElementVisitor, data: D): R { return visitor.visitField(this, data) @@ -48,6 +48,6 @@ class IrFieldImpl( } override fun transformChildren(transformer: IrElementTransformer, data: D) { - initializer = initializer?.transform(transformer, data) + initializer = initializer?.transform(transformer, data) as? IrExpressionBody } } \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt index b671e22aac2..395a0472d26 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt @@ -137,7 +137,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() { declaration.startOffset, declaration.endOffset, mapDeclarationOrigin(declaration.origin), mapPropertyDeclaration(declaration.descriptor), - declaration.initializer?.transform(this, null) + declaration.initializer?.transform(this, null) as? IrExpressionBody ) override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrLocalDelegatedProperty = @@ -164,7 +164,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() { declaration.startOffset, declaration.endOffset, mapDeclarationOrigin(declaration.origin), mapClassDeclaration(declaration.descriptor), - declaration.body.transform(this, null) + declaration.body.transform(this, null) as IrBlockBody ) override fun visitVariable(declaration: IrVariable): IrVariable = diff --git a/compiler/testData/ir/box/classInitializers.kt b/compiler/testData/ir/box/classInitializers.kt new file mode 100644 index 00000000000..8db45da6166 --- /dev/null +++ b/compiler/testData/ir/box/classInitializers.kt @@ -0,0 +1,22 @@ +fun assertEquals(actual: T, expected: T) { + if (actual != expected) { + throw java.lang.AssertionError("Assertion failed: $actual != $expected") + } +} + +class Test(val x: Int) { + val y = x + 1 + val z: Int + init { + z = y + 1 + } +} + +fun box(): String { + val test = Test(1) + assertEquals(test.x, 1) + assertEquals(test.y, 2) + assertEquals(test.z, 3) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/ir/box/fileClassInitializers.kt b/compiler/testData/ir/box/fileClassInitializers.kt new file mode 100644 index 00000000000..40b521bc0bc --- /dev/null +++ b/compiler/testData/ir/box/fileClassInitializers.kt @@ -0,0 +1,15 @@ +fun assertEquals(actual: T, expected: T) { + if (actual != expected) { + throw java.lang.AssertionError("Assertion failed: $actual != $expected") + } +} + +val x = 1 +val y = x + 1 + +fun box(): String { + assertEquals(x, 1) + assertEquals(y, 2) + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index d5835123688..00271589230 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5657,6 +5657,51 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class DestructuringDeclInLambdaParam extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInDestructuringDeclInLambdaParam() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/destructuringDeclInLambdaParam"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("extensionComponents.kt") + public void testExtensionComponents() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/extensionComponents.kt"); + doTest(fileName); + } + + @TestMetadata("generic.kt") + public void testGeneric() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/generic.kt"); + doTest(fileName); + } + + @TestMetadata("inline.kt") + public void testInline() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/inline.kt"); + doTest(fileName); + } + + @TestMetadata("otherParameters.kt") + public void testOtherParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/otherParameters.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/simple.kt"); + doTest(fileName); + } + + @TestMetadata("stdlibUsages.kt") + public void testStdlibUsages() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/stdlibUsages.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/diagnostics") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -12066,6 +12111,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/constructors"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("annotationClass.kt") + public void testAnnotationClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/constructors/annotationClass.kt"); + doTest(fileName); + } + @TestMetadata("classesWithoutConstructors.kt") public void testClassesWithoutConstructors() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/constructors/classesWithoutConstructors.kt"); @@ -12091,6 +12142,87 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/reflection/createAnnotation") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class CreateAnnotation extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInCreateAnnotation() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/createAnnotation"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("annotationType.kt") + public void testAnnotationType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/annotationType.kt"); + doTest(fileName); + } + + @TestMetadata("arrayOfKClasses.kt") + public void testArrayOfKClasses() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/arrayOfKClasses.kt"); + doTest(fileName); + } + + @TestMetadata("callByJava.kt") + public void testCallByJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/callByJava.kt"); + doTest(fileName); + } + + @TestMetadata("callByKotlin.kt") + public void testCallByKotlin() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/callByKotlin.kt"); + doTest(fileName); + } + + @TestMetadata("callJava.kt") + public void testCallJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/callJava.kt"); + doTest(fileName); + } + + @TestMetadata("callKotlin.kt") + public void testCallKotlin() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/callKotlin.kt"); + doTest(fileName); + } + + @TestMetadata("createJdkAnnotationInstance.kt") + public void testCreateJdkAnnotationInstance() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/createJdkAnnotationInstance.kt"); + doTest(fileName); + } + + @TestMetadata("enumKClassAnnotation.kt") + public void testEnumKClassAnnotation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/enumKClassAnnotation.kt"); + doTest(fileName); + } + + @TestMetadata("equalsHashCodeToString.kt") + public void testEqualsHashCodeToString() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/equalsHashCodeToString.kt"); + doTest(fileName); + } + + @TestMetadata("floatingPointParameters.kt") + public void testFloatingPointParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/floatingPointParameters.kt"); + doTest(fileName); + } + + @TestMetadata("parameterNamedEquals.kt") + public void testParameterNamedEquals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/parameterNamedEquals.kt"); + doTest(fileName); + } + + @TestMetadata("primitivesAndArrays.kt") + public void testPrimitivesAndArrays() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/createAnnotation/primitivesAndArrays.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/reflection/enclosing") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -12569,6 +12701,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/mapping/types"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("annotationConstructorParameters.kt") + public void testAnnotationConstructorParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/mapping/types/annotationConstructorParameters.kt"); + doTest(fileName); + } + @TestMetadata("array.kt") public void testArray() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/mapping/types/array.kt"); @@ -12960,6 +13098,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("javaAnnotationConstructor.kt") + public void testJavaAnnotationConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/parameters/javaAnnotationConstructor.kt"); + doTest(fileName); + } + @TestMetadata("javaParametersHaveNoNames.kt") public void testJavaParametersHaveNoNames() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/parameters/javaParametersHaveNoNames.kt"); @@ -15603,6 +15747,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasObject.kt"); doTest(fileName); } + + @TestMetadata("typeAliasObjectCallable.kt") + public void testTypeAliasObjectCallable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasObjectCallable.kt"); + doTest(fileName); + } + + @TestMetadata("typeAliasSecondaryConstructor.kt") + public void testTypeAliasSecondaryConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasSecondaryConstructor.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/unaryOp") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrOnlyBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrOnlyBoxCodegenTestGenerated.java new file mode 100644 index 00000000000..be0bc5346fe --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrOnlyBoxCodegenTestGenerated.java @@ -0,0 +1,49 @@ +/* + * 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.codegen.ir; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/ir/box") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class IrOnlyBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInBox() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/box"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("classInitializers.kt") + public void testClassInitializers() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/classInitializers.kt"); + doTest(fileName); + } + + @TestMetadata("fileClassInitializers.kt") + public void testFileClassInitializers() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/fileClassInitializers.kt"); + doTest(fileName); + } +} diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 2c28f9e42cd..5d1ab55933c 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -225,6 +225,10 @@ fun main(args: Array) { model("codegen/box", targetBackend = TargetBackend.JVM) } + testClass("IrOnlyBoxCodegenTestGenerated") { + model("ir/box", targetBackend = TargetBackend.JVM) + } + testClass("BlackBoxInlineCodegenTestGenerated") { model("codegen/boxInline") }