Shared variables lowering.
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
+1
-1
@@ -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
|
||||
|
||||
+40
@@ -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<KotlinType>,
|
||||
sourceElement: SourceElement,
|
||||
annotations: Annotations
|
||||
) : FileClassDescriptor, KnownClassDescriptor(
|
||||
name, containingDeclaration, sourceElement,
|
||||
ClassKind.CLASS, Modality.FINAL, Visibilities.PUBLIC,
|
||||
annotations
|
||||
) {
|
||||
init {
|
||||
initialize(emptyList(), supertypes)
|
||||
}
|
||||
}
|
||||
+153
@@ -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<KotlinType>
|
||||
private lateinit var defaultType: SimpleType
|
||||
private lateinit var declaredTypeParameters: List<TypeParameterDescriptor>
|
||||
|
||||
private val thisAsReceiverParameter = LazyClassReceiverParameterDescriptor(this)
|
||||
|
||||
fun initialize(declaredTypeParameters: List<TypeParameterDescriptor>, supertypes: List<KotlinType>) {
|
||||
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<KotlinType>,
|
||||
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<KotlinType>,
|
||||
modality: Modality = Modality.FINAL,
|
||||
visibility: Visibility = Visibilities.PUBLIC,
|
||||
annotations: Annotations = Annotations.EMPTY,
|
||||
createTypeParameters: (ClassDescriptor) -> List<TypeParameterDescriptor>
|
||||
) =
|
||||
KnownClassDescriptor(
|
||||
name, containingDeclaration,
|
||||
SourceElement.NO_SOURCE, ClassKind.CLASS,
|
||||
modality, visibility,
|
||||
annotations
|
||||
).apply {
|
||||
initialize(createTypeParameters(this), supertypes)
|
||||
}
|
||||
|
||||
fun createClassWithTypeParameters(
|
||||
name: Name,
|
||||
containingDeclaration: DeclarationDescriptor,
|
||||
supertypes: List<KotlinType>,
|
||||
typeParameterNames: List<Name>,
|
||||
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<ClassConstructorDescriptor> = emptyList()
|
||||
override fun getContainingDeclaration(): DeclarationDescriptor = containingDeclaration
|
||||
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> = declaredTypeParameters
|
||||
override fun getKind(): ClassKind = kind
|
||||
|
||||
override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): 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 <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
|
||||
return visitor.visitClassDescriptor(this, data)
|
||||
}
|
||||
|
||||
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>) {
|
||||
visitor.visitClassDescriptor(this, null)
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
"KnownClassDescriptor($fqNameUnsafe)"
|
||||
}
|
||||
|
||||
+209
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
+12
-6
@@ -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<ClassDescriptor, PropertyDescriptor>()
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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<TypeParameterDescriptor> = emptyList(),
|
||||
dispatchReceiverParameter: ReceiverParameterDescriptor? = null,
|
||||
extensionReceiverParameter: ReceiverParameterDescriptor? = null,
|
||||
getter: PropertyGetterDescriptorImpl? = null,
|
||||
setter: PropertySetterDescriptorImpl? = null
|
||||
): PropertyDescriptorImpl {
|
||||
setType(type, typeParameters, dispatchReceiverParameter, extensionReceiverParameter)
|
||||
initialize(getter, setter)
|
||||
return this
|
||||
}
|
||||
@@ -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", "<init>", "(Ljava/lang/String;)V", false)
|
||||
}
|
||||
}
|
||||
|
||||
-78
@@ -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<ClassConstructorDescriptor> = emptyList()
|
||||
override fun getContainingDeclaration(): DeclarationDescriptor = containingDeclarationImpl
|
||||
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> = 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<out TypeProjection>): MemberScope =
|
||||
MemberScope.Empty // TODO do we need a more useful MemberScope here?
|
||||
|
||||
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
|
||||
return visitor.visitClassDescriptor(this, data)
|
||||
}
|
||||
|
||||
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>) {
|
||||
visitor.visitClassDescriptor(this, null)
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
"IrFileClassDescriptor($fqNameUnsafe)"
|
||||
}
|
||||
+124
@@ -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<ValueDescriptor>()
|
||||
|
||||
fun lowerSharedVariables() {
|
||||
collectSharedVariables()
|
||||
if (sharedVariables.isEmpty()) return
|
||||
rewriteSharedVariables()
|
||||
}
|
||||
|
||||
private fun collectSharedVariables() {
|
||||
irFunction.acceptVoid(object : IrElementVisitorVoid {
|
||||
val declarationsStack = ArrayDeque<IrDeclaration>()
|
||||
val declaredVariables = HashSet<VariableDescriptor>()
|
||||
|
||||
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<ValueDescriptor, VariableDescriptor>()
|
||||
|
||||
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
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<KotlinType>): 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")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
fun add(s: String) {
|
||||
result += s
|
||||
}
|
||||
add("O")
|
||||
add("K")
|
||||
return result
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user