diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index b87455e007c..e4d0de5dafc 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.backend.jvm +import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager import org.jetbrains.kotlin.backend.jvm.descriptors.SpecialDescriptorsFactory import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns @@ -27,6 +28,6 @@ class JvmBackendContext( val irBuiltIns: IrBuiltIns ) { val builtIns = state.module.builtIns - val specialDescriptorsFactory = SpecialDescriptorsFactory(psiSourceManager) + val specialDescriptorsFactory = SpecialDescriptorsFactory(psiSourceManager, builtIns) + val sharedVariablesManager = JvmSharedVariablesManager(irBuiltIns) } - 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 c90afbdd58d..6e62e2afee9 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 @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.backend.jvm.lower.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -31,13 +32,14 @@ class JvmLower(val context: JvmBackendContext) { FileClassLowering(context).lower(irFile) ConstAndJvmFieldPropertiesLowering().lower(irFile) PropertiesLowering().lower(irFile) - InterfaceLowering(context.state).runOnFile(irFile) - InterfaceDelegationLowering(context.state).runOnFile(irFile) - LocalFunctionsLowering(context).runOnFile(irFile) - EnumClassLowering(context).runOnFile(irFile) - ObjectClassLowering(context).runOnFile(irFile) - InitializersLowering(context).runOnFile(irFile) - SingletonReferencesLowering(context).runOnFile(irFile) + InterfaceLowering(context.state).runOnFilePostfix(irFile) + InterfaceDelegationLowering(context.state).runOnFilePostfix(irFile) + SharedVariablesLowering(context).runOnFilePostfix(irFile) + LocalFunctionsLowering(context).runOnFilePostfix(irFile) + EnumClassLowering(context).runOnFilePostfix(irFile) + ObjectClassLowering(context).runOnFilePostfix(irFile) + InitializersLowering(context).runOnFilePostfix(irFile) + SingletonReferencesLowering(context).runOnFilePostfix(irFile) } } @@ -49,11 +51,15 @@ interface ClassLoweringPass { fun lower(irClass: IrClass) } +interface FunctionLoweringPass { + fun lower(irFunction: IrFunction) +} + interface BodyLoweringPass { fun lower(irBody: IrBody) } -fun ClassLoweringPass.runOnFile(irFile: IrFile) { +fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) { irFile.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) @@ -66,7 +72,7 @@ fun ClassLoweringPass.runOnFile(irFile: IrFile) { }) } -fun BodyLoweringPass.runOnFile(irFile: IrFile) { +fun BodyLoweringPass.runOnFilePostfix(irFile: IrFile) { irFile.acceptVoid(object : IrElementVisitorVoid { override fun visitElement(element: IrElement) { element.acceptChildrenVoid(this) @@ -77,4 +83,17 @@ fun BodyLoweringPass.runOnFile(irFile: IrFile) { lower(body) } }) +} + +fun FunctionLoweringPass.runOnFilePostfix(irFile: IrFile) { + irFile.acceptVoid(object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitFunction(declaration: IrFunction) { + declaration.acceptChildrenVoid(this) + lower(declaration) + } + }) } \ 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 2b87c96c627..298e4bd2da0 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 @@ -20,7 +20,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSpecialDescriptor -import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor +import org.jetbrains.kotlin.backend.jvm.descriptors.FileClassDescriptor import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor import org.jetbrains.kotlin.codegen.binding.CodegenBinding diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/FileClassDescriptor.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/FileClassDescriptor.kt new file mode 100644 index 00000000000..dccd7bd7fd5 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/FileClassDescriptor.kt @@ -0,0 +1,40 @@ +/* + * 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.descriptors + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.KotlinType + +interface FileClassDescriptor : ClassDescriptor + +class FileClassDescriptorImpl( + name: Name, + containingDeclaration: PackageFragmentDescriptor, + supertypes: List, + sourceElement: SourceElement, + annotations: Annotations +) : FileClassDescriptor, KnownClassDescriptor( + name, containingDeclaration, sourceElement, + ClassKind.CLASS, Modality.FINAL, Visibilities.PUBLIC, + annotations +) { + init { + initialize(emptyList(), supertypes) + } +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/KnownDescriptors.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/KnownDescriptors.kt new file mode 100644 index 00000000000..a8b2807105c --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/KnownDescriptors.kt @@ -0,0 +1,153 @@ +/* + * 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.descriptors + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.LazyClassReceiverParameterDescriptor +import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.* + +open class KnownPackageFragmentDescriptor(moduleDescriptor: ModuleDescriptor, fqName: FqName) : + PackageFragmentDescriptorImpl(moduleDescriptor, fqName) { + override fun getMemberScope(): MemberScope = MemberScope.Empty +} + +open class KnownClassDescriptor( + private val name: Name, + private val containingDeclaration: DeclarationDescriptor, + private val sourceElement: SourceElement, + private val kind: ClassKind, + private val modality: Modality, + private val visibility: Visibility, + override val annotations: Annotations +) : ClassDescriptor { + private lateinit var typeConstructor: TypeConstructor + private lateinit var supertypes: List + private lateinit var defaultType: SimpleType + private lateinit var declaredTypeParameters: List + + private val thisAsReceiverParameter = LazyClassReceiverParameterDescriptor(this) + + fun initialize(declaredTypeParameters: List, supertypes: List) { + this.declaredTypeParameters = declaredTypeParameters + this.supertypes = supertypes + this.typeConstructor = ClassTypeConstructorImpl(this, annotations, true, declaredTypeParameters, supertypes) + this.defaultType = TypeUtils.makeUnsubstitutedType(this, unsubstitutedMemberScope) + } + + companion object { + fun createClass( + name: Name, + containingDeclaration: DeclarationDescriptor, + supertypes: List, + modality: Modality = Modality.FINAL, + visibility: Visibility = Visibilities.PUBLIC, + annotations: Annotations = Annotations.EMPTY + ) = + KnownClassDescriptor( + name, containingDeclaration, + SourceElement.NO_SOURCE, ClassKind.CLASS, + modality, visibility, + annotations + ).apply { + initialize(emptyList(), supertypes) + } + + inline fun createClassWithTypeParameters( + name: Name, + containingDeclaration: DeclarationDescriptor, + supertypes: List, + modality: Modality = Modality.FINAL, + visibility: Visibility = Visibilities.PUBLIC, + annotations: Annotations = Annotations.EMPTY, + createTypeParameters: (ClassDescriptor) -> List + ) = + KnownClassDescriptor( + name, containingDeclaration, + SourceElement.NO_SOURCE, ClassKind.CLASS, + modality, visibility, + annotations + ).apply { + initialize(createTypeParameters(this), supertypes) + } + + fun createClassWithTypeParameters( + name: Name, + containingDeclaration: DeclarationDescriptor, + supertypes: List, + typeParameterNames: List, + modality: Modality = Modality.FINAL, + visibility: Visibility = Visibilities.PUBLIC, + annotations: Annotations = Annotations.EMPTY + ) = + createClassWithTypeParameters(name, containingDeclaration, supertypes, modality, visibility, annotations) { classDescriptor -> + typeParameterNames.mapIndexed { index, name -> + TypeParameterDescriptorImpl.createWithDefaultBound( + classDescriptor, Annotations.EMPTY, true, Variance.INVARIANT, name, index + ) + } + } + } + + override fun getCompanionObjectDescriptor(): ClassDescriptor? = null + override fun getConstructors(): Collection = emptyList() + override fun getContainingDeclaration(): DeclarationDescriptor = containingDeclaration + override fun getDeclaredTypeParameters(): List = declaredTypeParameters + override fun getKind(): ClassKind = kind + + override fun getMemberScope(typeArguments: MutableList): MemberScope = MemberScope.Empty + override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = MemberScope.Empty + override fun getStaticScope(): MemberScope = MemberScope.Empty + override fun getUnsubstitutedInnerClassesScope(): MemberScope = MemberScope.Empty + override fun getUnsubstitutedMemberScope(): MemberScope = MemberScope.Empty + + override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null + + override fun substitute(substitutor: TypeSubstitutor): ClassDescriptor = error("Class $this can't be substituted") + + override fun getThisAsReceiverParameter(): ReceiverParameterDescriptor = thisAsReceiverParameter + + override fun getModality(): Modality = modality + override fun getOriginal(): ClassDescriptor = this + override fun getName(): Name = name + override fun getVisibility(): Visibility = visibility + override fun getSource(): SourceElement = sourceElement + override fun getTypeConstructor(): TypeConstructor = typeConstructor + override fun getDefaultType(): SimpleType = defaultType + + override fun isCompanionObject(): Boolean = false + override fun isData(): Boolean = false + override fun isInner(): Boolean = false + + override fun accept(visitor: DeclarationDescriptorVisitor, data: D): R { + return visitor.visitClassDescriptor(this, data) + } + + override fun acceptVoid(visitor: DeclarationDescriptorVisitor) { + visitor.visitClassDescriptor(this, null) + } + + override fun toString(): String = + "KnownClassDescriptor($fqNameUnsafe)" +} + diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt new file mode 100644 index 00000000000..2ed199dfad0 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SharedVariablesManager.kt @@ -0,0 +1,209 @@ +/* + * 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.descriptors + +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.builtins.PrimitiveType +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.LocalVariableDescriptor +import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl +import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.declarations.IrVariable +import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl +import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrGetValue +import org.jetbrains.kotlin.ir.expressions.IrSetVariable +import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.types.* + +interface SharedVariablesManager { + fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor + fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement + fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression + fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression +} + +class JvmSharedVariablesManager(val irBuiltIns: IrBuiltIns) : SharedVariablesManager { + private val builtIns = irBuiltIns.builtIns + private val fromAny = listOf(builtIns.anyType) + + private val kotlinJvmInternalPackage = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.jvm.internal")) + private val refNamespaceClass = KnownClassDescriptor.createClass(Name.identifier("Ref"), kotlinJvmInternalPackage, fromAny) + + private class PrimitiveRefDescriptorsProvider(type: KotlinType, refClass: ClassDescriptor) { + val refType: KotlinType = refClass.defaultType + + val refConstructor: ClassConstructorDescriptor = + ClassConstructorDescriptorImpl.create(refClass, Annotations.EMPTY, true, SourceElement.NO_SOURCE).apply { + initialize(emptyList(), Visibilities.PUBLIC, emptyList()) + returnType = refType + } + + + val elementField: PropertyDescriptor = + PropertyDescriptorImpl.create( + refClass, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, true, + Name.identifier("element"), CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE, + false, false + ).initialize(type, dispatchReceiverParameter = refClass.thisAsReceiverParameter) + } + + private val primitiveRefDescriptorProviders = + PrimitiveType.values().associate { + val type = builtIns.getPrimitiveKotlinType(it) + + val refClassName = Name.identifier(it.typeName.asString() + "Ref") + val refClass = KnownClassDescriptor.createClass(refClassName, refNamespaceClass, fromAny) + + it to PrimitiveRefDescriptorsProvider(type, refClass) + } + + private inner class ObjectRefDescriptorsProvider { + val genericRefClass: ClassDescriptor = + KnownClassDescriptor.createClassWithTypeParameters( + Name.identifier("ObjectRef"), refNamespaceClass, fromAny, listOf(Name.identifier("T")) + ) + + val genericRefConstructor: ClassConstructorDescriptor = + ClassConstructorDescriptorImpl.create(genericRefClass, Annotations.EMPTY, true, SourceElement.NO_SOURCE).apply { + initialize(emptyList(), Visibilities.PUBLIC) + val typeParameter = typeParameters[0] + val typeParameterType = KotlinTypeFactory.simpleType(Annotations.EMPTY, typeParameter.typeConstructor, listOf(), false, MemberScope.Empty) + returnType = KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, genericRefClass, listOf(TypeProjectionImpl(Variance.INVARIANT, typeParameterType))) + } + + + val constructorTypeParameter: TypeParameterDescriptor = + genericRefConstructor.typeParameters[0] + + fun getSubstitutedRefConstructor(valueType: KotlinType): ClassConstructorDescriptor = + genericRefConstructor.substitute(TypeSubstitutor.create( + mapOf(constructorTypeParameter.typeConstructor to TypeProjectionImpl(Variance.INVARIANT, valueType)) + )) + + val genericElementField: PropertyDescriptor = + PropertyDescriptorImpl.create( + genericRefClass, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, true, + Name.identifier("element"), CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE, + false, false + ).initialize( + type = builtIns.anyType, + dispatchReceiverParameter = genericRefClass.thisAsReceiverParameter + ) + + fun getRefType(valueType: KotlinType) = + KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, genericRefClass, listOf(TypeProjectionImpl(Variance.INVARIANT, valueType))) + } + + private val objectRefDescriptorsProvider = ObjectRefDescriptorsProvider() + + override fun createSharedVariableDescriptor(variableDescriptor: VariableDescriptor): VariableDescriptor = + LocalVariableDescriptor( + variableDescriptor.containingDeclaration, variableDescriptor.annotations, variableDescriptor.name, + getSharedVariableType(variableDescriptor.type), + false, false, variableDescriptor.source + ) + + override fun defineSharedValue(sharedVariableDescriptor: VariableDescriptor, originalDeclaration: IrVariable): IrStatement { + val valueType = originalDeclaration.descriptor.type + val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)] + + val refConstructor = + primitiveRefDescriptorsProvider?.refConstructor ?: + objectRefDescriptorsProvider.getSubstitutedRefConstructor(valueType) + + val refConstructorTypeArguments = + if (primitiveRefDescriptorsProvider != null) null + else mapOf(objectRefDescriptorsProvider.constructorTypeParameter to valueType) + + val elementPropertyDescriptor = + primitiveRefDescriptorsProvider?.elementField ?: + objectRefDescriptorsProvider.genericElementField + + val refConstructorCall = IrCallImpl( + originalDeclaration.startOffset, originalDeclaration.endOffset, + refConstructor, refConstructorTypeArguments + ) + val sharedVariableDeclaration = IrVariableImpl( + originalDeclaration.startOffset, originalDeclaration.endOffset, originalDeclaration.origin, + sharedVariableDescriptor, refConstructorCall + ) + + val initializer = originalDeclaration.initializer ?: + return sharedVariableDeclaration + + val sharedVariableInitialization = IrSetFieldImpl( + initializer.startOffset, initializer.endOffset, + elementPropertyDescriptor, + IrGetValueImpl(initializer.startOffset, initializer.endOffset, sharedVariableDescriptor), + initializer + ) + + return IrCompositeImpl( + originalDeclaration.startOffset, originalDeclaration.endOffset, builtIns.unitType, null, + listOf(sharedVariableDeclaration, sharedVariableInitialization) + ) + } + + private fun getElementFieldDescriptor(valueType: KotlinType): PropertyDescriptor { + val primitiveRefDescriptorsProvider = primitiveRefDescriptorProviders[getPrimitiveType(valueType)] + + return primitiveRefDescriptorsProvider?.elementField ?: + objectRefDescriptorsProvider.genericElementField + } + + override fun getSharedValue(sharedVariableDescriptor: VariableDescriptor, originalGet: IrGetValue): IrExpression = + IrGetFieldImpl( + originalGet.startOffset, originalGet.endOffset, + getElementFieldDescriptor(originalGet.descriptor.type), + IrGetValueImpl(originalGet.startOffset, originalGet.endOffset, sharedVariableDescriptor), + originalGet.origin + ) + + override fun setSharedValue(sharedVariableDescriptor: VariableDescriptor, originalSet: IrSetVariable): IrExpression = + IrSetFieldImpl( + originalSet.startOffset, originalSet.endOffset, + getElementFieldDescriptor(originalSet.descriptor.type), + IrGetValueImpl(originalSet.startOffset, originalSet.endOffset, sharedVariableDescriptor), + originalSet.value, + originalSet.origin + ) + + private fun getSharedVariableType(valueType: KotlinType): KotlinType = + primitiveRefDescriptorProviders[getPrimitiveType(valueType)]?.refType ?: + objectRefDescriptorsProvider.getRefType(valueType) + + private fun getPrimitiveType(type: KotlinType): PrimitiveType? = + when { + KotlinBuiltIns.isBoolean(type) -> PrimitiveType.BOOLEAN + KotlinBuiltIns.isChar(type) -> PrimitiveType.CHAR + KotlinBuiltIns.isByte(type) -> PrimitiveType.BYTE + KotlinBuiltIns.isShort(type) -> PrimitiveType.SHORT + KotlinBuiltIns.isInt(type) -> PrimitiveType.INT + KotlinBuiltIns.isLong(type) -> PrimitiveType.LONG + KotlinBuiltIns.isFloat(type) -> PrimitiveType.FLOAT + KotlinBuiltIns.isDouble(type) -> PrimitiveType.DOUBLE + else -> null + } + +} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt index e0d51758aa2..9cf0e4ad1a8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/SpecialDescriptorsFactory.kt @@ -16,8 +16,7 @@ package org.jetbrains.kotlin.backend.jvm.descriptors -import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor -import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptorImpl +import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl @@ -29,7 +28,10 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.org.objectweb.asm.Opcodes import java.util.* -class SpecialDescriptorsFactory(val psiSourceManager: PsiSourceManager) { +class SpecialDescriptorsFactory( + val psiSourceManager: PsiSourceManager, + val builtIns: KotlinBuiltIns +) { private val singletonFieldDescriptors = HashMap() fun getFieldDescriptorForEnumEntry(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor = @@ -42,7 +44,12 @@ class SpecialDescriptorsFactory(val psiSourceManager: PsiSourceManager) { ?: throw AssertionError("Unexpected file entry: $fileEntry") val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(ktFile) val sourceElement = KotlinSourceElement(ktFile) - return FileClassDescriptorImpl(fileClassInfo.fileClassFqName.shortName(), packageFragment, sourceElement) + return FileClassDescriptorImpl( + fileClassInfo.fileClassFqName.shortName(), packageFragment, + listOf(builtIns.anyType), + sourceElement, + Annotations.EMPTY // TODO file annotations + ) } private fun createEnumEntryFieldDescriptor(enumEntryDescriptor: ClassDescriptor): PropertyDescriptor { @@ -76,8 +83,7 @@ class SpecialDescriptorsFactory(val psiSourceManager: PsiSourceManager) { Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false, Name.identifier("INSTANCE"), CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, false, false - ) - instanceFieldDescriptor.setType(objectDescriptor.defaultType, listOf(), null as ReceiverParameterDescriptor?, null as ReceiverParameterDescriptor?) + ).initialize(objectDescriptor.defaultType) return instanceFieldDescriptor } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/Util.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/Util.kt new file mode 100644 index 00000000000..c1b7a7491e0 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/Util.kt @@ -0,0 +1,37 @@ +/* + * 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.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.types.KotlinType + +fun PropertyDescriptorImpl.initialize( + type: KotlinType, + typeParameters: List = emptyList(), + dispatchReceiverParameter: ReceiverParameterDescriptor? = null, + extensionReceiverParameter: ReceiverParameterDescriptor? = null, + getter: PropertyGetterDescriptorImpl? = null, + setter: PropertySetterDescriptorImpl? = null +): PropertyDescriptorImpl { + setType(type, typeParameters, dispatchReceiverParameter, extensionReceiverParameter) + initialize(getter, setter) + return this +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Concat.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Concat.kt index 7ab5d3f3f89..a09b80ce24d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Concat.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/Concat.kt @@ -83,6 +83,7 @@ class Concat : IntrinsicMethod() { override fun genArg(expression: IrExpression, codegen: org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen, index: Int, data: BlockInfo) { super.genArg(expression, codegen, index, data) if (index == 0) { + codegen.mv.checkcast(AsmTypes.JAVA_STRING_TYPE) codegen.mv.invokespecial("java/lang/StringBuilder", "", "(Ljava/lang/String;)V", false) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassDescriptor.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassDescriptor.kt deleted file mode 100644 index 8cc2ee5034b..00000000000 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassDescriptor.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.types.* - -interface FileClassDescriptor : ClassDescriptor - -class FileClassDescriptorImpl( - private val nameImpl: Name, - private val containingDeclarationImpl: PackageFragmentDescriptor, - private val sourceElement: SourceElement -) : FileClassDescriptor { - override fun getCompanionObjectDescriptor(): ClassDescriptor? = null - override fun getConstructors(): Collection = emptyList() - override fun getContainingDeclaration(): DeclarationDescriptor = containingDeclarationImpl - override fun getDeclaredTypeParameters(): List = emptyList() - override fun getKind(): ClassKind = ClassKind.CLASS - - override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = error("File class has no member scope") - override fun getModality(): Modality = Modality.FINAL - override fun getOriginal(): ClassDescriptor = this - override fun getName(): Name = nameImpl - override fun getStaticScope(): MemberScope = error("File class has no static scope") - override fun getThisAsReceiverParameter(): ReceiverParameterDescriptor = error("File class has no instances") - override fun getUnsubstitutedInnerClassesScope(): MemberScope = error("File class has no inner classes scope") - override fun getUnsubstitutedMemberScope(): MemberScope = error("File class has no member scope") - override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null - override fun getVisibility(): Visibility = Visibilities.PUBLIC - override fun isCompanionObject(): Boolean = false - override fun isData(): Boolean = false - override fun substitute(substitutor: TypeSubstitutor): ClassDescriptor = error("File class can't be substituted") - override fun getSource(): SourceElement = sourceElement - override fun isInner(): Boolean = false - - override val annotations = Annotations.EMPTY // TODO file annotations - - private val typeConstructor = ClassTypeConstructorImpl(this, annotations, true, emptyList(), listOf(builtIns.anyType)) - private val defaultType = KotlinTypeFactory.simpleNotNullType(annotations, this, emptyList()) - - override fun getTypeConstructor(): TypeConstructor = typeConstructor - - override fun getDefaultType(): SimpleType = defaultType - - override fun getMemberScope(typeArguments: MutableList): MemberScope = - MemberScope.Empty // TODO do we need a more useful MemberScope here? - - override fun accept(visitor: DeclarationDescriptorVisitor, data: D): R { - return visitor.visitClassDescriptor(this, data) - } - - override fun acceptVoid(visitor: DeclarationDescriptorVisitor) { - visitor.visitClassDescriptor(this, null) - } - - override fun toString(): String = - "IrFileClassDescriptor($fqNameUnsafe)" -} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SharedVariablesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SharedVariablesLowering.kt new file mode 100644 index 00000000000..2893a852e2f --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SharedVariablesLowering.kt @@ -0,0 +1,124 @@ +/* + * 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.FunctionLoweringPass +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.descriptors.ValueDescriptor +import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrVariable +import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrGetValue +import org.jetbrains.kotlin.ir.expressions.IrSetVariable +import org.jetbrains.kotlin.ir.expressions.IrValueAccessExpression +import org.jetbrains.kotlin.ir.visitors.* +import java.util.* + +class SharedVariablesLowering(val context: JvmBackendContext) : FunctionLoweringPass { + override fun lower(irFunction: IrFunction) { + SharedVariablesTransformer(irFunction).lowerSharedVariables() + } + + private inner class SharedVariablesTransformer(val irFunction: IrFunction) { + val sharedVariables = HashSet() + + fun lowerSharedVariables() { + collectSharedVariables() + if (sharedVariables.isEmpty()) return + rewriteSharedVariables() + } + + private fun collectSharedVariables() { + irFunction.acceptVoid(object : IrElementVisitorVoid { + val declarationsStack = ArrayDeque() + val declaredVariables = HashSet() + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitFunction(declaration: IrFunction) { + declarationsStack.push(declaration) + declaration.acceptChildrenVoid(this) + declarationsStack.pop() + } + + override fun visitVariable(declaration: IrVariable) { + declaredVariables.add(declaration.descriptor) + } + + override fun visitVariableAccess(expression: IrValueAccessExpression) { + expression.acceptChildrenVoid(this) + + val descriptor = expression.descriptor + if (descriptor in declaredVariables && descriptor.containingDeclaration != declarationsStack.peek()) { + sharedVariables.add(descriptor) + } + } + }) + } + + private fun rewriteSharedVariables() { + val transformedDescriptors = HashMap() + + irFunction.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitVariable(declaration: IrVariable): IrStatement { + declaration.transformChildrenVoid(this) + + val oldDescriptor = declaration.descriptor + if (oldDescriptor !in sharedVariables) return declaration + + val newDescriptor = context.sharedVariablesManager.createSharedVariableDescriptor(oldDescriptor) + transformedDescriptors[oldDescriptor] = newDescriptor + + return context.sharedVariablesManager.defineSharedValue(newDescriptor, declaration) + } + }) + + irFunction.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitGetValue(expression: IrGetValue): IrExpression { + expression.transformChildrenVoid(this) + + val newDescriptor = getTransformedDescriptor(expression.descriptor) ?: return expression + + return context.sharedVariablesManager.getSharedValue(newDescriptor, expression) + } + + override fun visitSetVariable(expression: IrSetVariable): IrExpression { + expression.transformChildrenVoid(this) + + val newDescriptor = getTransformedDescriptor(expression.descriptor) ?: return expression + + return context.sharedVariablesManager.setSharedValue(newDescriptor, expression) + } + + private fun getTransformedDescriptor(oldDescriptor: ValueDescriptor): VariableDescriptor? = + transformedDescriptors.getOrElse(oldDescriptor) { + assert(oldDescriptor !in sharedVariables) { + "Shared variable is not transformed: $oldDescriptor" + } + null + } + }) + } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt index 369fbff858b..59e010b0536 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltIns.kt @@ -22,12 +22,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl -import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinTypeFactory -import org.jetbrains.kotlin.types.TypeSubstitution import org.jetbrains.kotlin.types.Variance class BuiltinsOperatorsBuilder(val packageFragment: PackageFragmentDescriptor, val builtIns: KotlinBuiltIns) { @@ -36,6 +34,7 @@ class BuiltinsOperatorsBuilder(val packageFragment: PackageFragmentDescriptor, v val anyN = builtIns.nullableAnyType val int = builtIns.intType val nothing = builtIns.nothingType + val unit = builtIns.unitType fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List): IrBuiltinOperatorDescriptor { val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType) @@ -60,13 +59,15 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) { val throwNpe: FunctionDescriptor = builder.run { defineOperator("THROW_NPE", nothing, listOf()) } val booleanNot: FunctionDescriptor = builder.run { defineOperator("NOT", bool, listOf(bool)) } + val noWhenBranchMatchedException: FunctionDescriptor = builder.run { defineOperator("noWhenBranchMatchedException", unit, listOf()) } + val enumValueOf: FunctionDescriptor = SimpleFunctionDescriptorImpl.create( packageFragment, Annotations.EMPTY, Name.identifier("enumValueOf"), CallableMemberDescriptor.Kind.SYNTHESIZED, - org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE + SourceElement.NO_SOURCE ).apply { val typeParameterT = TypeParameterDescriptorImpl.createWithDefaultBound( this, Annotations.EMPTY, true, Variance.INVARIANT, Name.identifier("T"), 0 @@ -82,19 +83,6 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) { initialize(null, null, listOf(typeParameterT), listOf(valueParameterName), returnType, Modality.FINAL, Visibilities.PUBLIC) } - val noWhenBranchMatchedException: FunctionDescriptor = - SimpleFunctionDescriptorImpl.create( - packageFragment, - Annotations.EMPTY, - Name.identifier("noWhenBranchMatchedException"), - CallableMemberDescriptor.Kind.SYNTHESIZED, - org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE - ).apply { - val returnType = KotlinTypeFactory.simpleType(Annotations.EMPTY, builtIns.unit.typeConstructor, listOf(), false) - - initialize(null, null, listOf(), listOf(), returnType, Modality.FINAL, Visibilities.PUBLIC) - } - companion object { val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir") } diff --git a/compiler/testData/ir/box/closureConversion1.kt b/compiler/testData/ir/box/closureConversion/closureConversion1.kt similarity index 100% rename from compiler/testData/ir/box/closureConversion1.kt rename to compiler/testData/ir/box/closureConversion/closureConversion1.kt diff --git a/compiler/testData/ir/box/closureConversion2.kt b/compiler/testData/ir/box/closureConversion/closureConversion2.kt similarity index 100% rename from compiler/testData/ir/box/closureConversion2.kt rename to compiler/testData/ir/box/closureConversion/closureConversion2.kt diff --git a/compiler/testData/ir/box/closureConversion3.kt b/compiler/testData/ir/box/closureConversion/closureConversion3.kt similarity index 100% rename from compiler/testData/ir/box/closureConversion3.kt rename to compiler/testData/ir/box/closureConversion/closureConversion3.kt diff --git a/compiler/testData/ir/box/closureConversion4.kt b/compiler/testData/ir/box/closureConversion/closureConversion4.kt similarity index 100% rename from compiler/testData/ir/box/closureConversion4.kt rename to compiler/testData/ir/box/closureConversion/closureConversion4.kt diff --git a/compiler/testData/ir/box/closureConversion/mutable1.kt b/compiler/testData/ir/box/closureConversion/mutable1.kt new file mode 100644 index 00000000000..6eb6bb71ff7 --- /dev/null +++ b/compiler/testData/ir/box/closureConversion/mutable1.kt @@ -0,0 +1,9 @@ +fun box(): String { + var result = "" + fun add(s: String) { + result += s + } + add("O") + add("K") + return result +} \ No newline at end of file diff --git a/compiler/testData/ir/box/closureConversion/mutablePrimitives.kt b/compiler/testData/ir/box/closureConversion/mutablePrimitives.kt new file mode 100644 index 00000000000..314ff34dd37 --- /dev/null +++ b/compiler/testData/ir/box/closureConversion/mutablePrimitives.kt @@ -0,0 +1,85 @@ +fun testBoolean(v: Boolean): Boolean { + var value = false + fun setValue(v: Boolean) { + value = v + } + setValue(v) + return value +} + +fun testChar(v: Char): Char { + var value = 0.toChar() + fun setValue(v: Char) { + value = v + } + setValue(v) + return value +} + +fun testByte(v: Byte): Byte { + var value = 0.toByte() + fun setValue(v: Byte) { + value = v + } + setValue(v) + return value +} + +fun testShort(v: Short): Short { + var value = 0.toShort() + fun setValue(v: Short) { + value = v + } + setValue(v) + return value +} + +fun testInt(v: Int): Int { + var value = 0.toInt() + fun setValue(v: Int) { + value = v + } + setValue(v) + return value +} + +fun testLong(v: Long): Long { + var value = 0.toLong() + fun setValue(v: Long) { + value = v + } + setValue(v) + return value +} + +fun testFloat(v: Float): Float { + var value = 0.toFloat() + fun setValue(v: Float) { + value = v + } + setValue(v) + return value +} + +fun testDouble(v: Double): Double { + var value = 0.toDouble() + fun setValue(v: Double) { + value = v + } + setValue(v) + return value +} + +fun box(): String { + return when { + testBoolean(true) != true -> "testBoolean" + testChar('a') != 'a' -> "testChar" + testByte(1) != 1.toByte() -> "testByte" + testShort(1) != 1.toShort() -> "testShort" + testInt(1) != 1 -> "testInt" + testLong(1) != 1L -> "testLong" + testFloat(1.0F) != 1.0F -> "testFloat" + testDouble(1.0) != 1.0 -> "testDouble" + else -> "OK" + } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrOnlyBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrOnlyBoxCodegenTestGenerated.java index c64af4bce04..97c46aaa92f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrOnlyBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrOnlyBoxCodegenTestGenerated.java @@ -41,30 +41,6 @@ public class IrOnlyBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTest doTest(fileName); } - @TestMetadata("closureConversion1.kt") - public void testClosureConversion1() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion1.kt"); - doTest(fileName); - } - - @TestMetadata("closureConversion2.kt") - public void testClosureConversion2() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion2.kt"); - doTest(fileName); - } - - @TestMetadata("closureConversion3.kt") - public void testClosureConversion3() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion3.kt"); - doTest(fileName); - } - - @TestMetadata("closureConversion4.kt") - public void testClosureConversion4() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion4.kt"); - doTest(fileName); - } - @TestMetadata("enumClass.kt") public void testEnumClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/enumClass.kt"); @@ -100,4 +76,49 @@ public class IrOnlyBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTest String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/simple.kt"); doTest(fileName); } + + @TestMetadata("compiler/testData/ir/box/closureConversion") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ClosureConversion extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInClosureConversion() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/box/closureConversion"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("closureConversion1.kt") + public void testClosureConversion1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion/closureConversion1.kt"); + doTest(fileName); + } + + @TestMetadata("closureConversion2.kt") + public void testClosureConversion2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion/closureConversion2.kt"); + doTest(fileName); + } + + @TestMetadata("closureConversion3.kt") + public void testClosureConversion3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion/closureConversion3.kt"); + doTest(fileName); + } + + @TestMetadata("closureConversion4.kt") + public void testClosureConversion4() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion/closureConversion4.kt"); + doTest(fileName); + } + + @TestMetadata("mutable1.kt") + public void testMutable1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion/mutable1.kt"); + doTest(fileName); + } + + @TestMetadata("mutablePrimitives.kt") + public void testMutablePrimitives() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/box/closureConversion/mutablePrimitives.kt"); + doTest(fileName); + } + } }