Add symbols to references

TODO: fix some more tests
This commit is contained in:
Dmitry Petrov
2017-03-23 16:04:40 +03:00
parent 0595e93952
commit c9777fd79f
189 changed files with 2723 additions and 1048 deletions
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
@@ -154,14 +153,14 @@ class LocalFunctionsLowering(val context: BackendContext): DeclarationContainerL
return this
}
override fun visitCallableReference(expression: IrCallableReference): IrExpression {
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
expression.transformChildrenVoid(this)
val oldCallee = expression.descriptor.original
val localFunctionData = localFunctions[oldCallee] ?: return expression
val newCallee = localFunctionData.transformedDescriptor
val newCallableReference = IrCallableReferenceImpl(
val newCallableReference = IrFunctionReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type, // TODO functional type for transformed descriptor
newCallee,
@@ -179,7 +178,9 @@ class LocalFunctionsLowering(val context: BackendContext): DeclarationContainerL
val localFunctionData = localFunctions[oldReturnTarget] ?: return expression
val newReturnTarget = localFunctionData.transformedDescriptor
return IrReturnImpl(expression.startOffset, expression.endOffset, newReturnTarget, expression.value)
return IrReturnImpl(expression.startOffset, expression.endOffset,
newReturnTarget,
expression.value)
}
}
@@ -196,15 +197,17 @@ class LocalFunctionsLowering(val context: BackendContext): DeclarationContainerL
}
private fun createNewCall(oldCall: IrCall, newCallee: FunctionDescriptor) =
if (oldCall is IrCallWithShallowCopy)
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifier)
else
IrCallImpl(
oldCall.startOffset, oldCall.endOffset,
newCallee,
remapTypeArguments(oldCall, newCallee),
oldCall.origin, oldCall.superQualifier
)
when (oldCall) {
is IrCallWithShallowCopy ->
oldCall.shallowCopy(oldCall.origin, newCallee, oldCall.superQualifier)
else ->
IrCallImpl(
oldCall.startOffset, oldCall.endOffset,
newCallee,
remapTypeArguments(oldCall, newCallee),
oldCall.origin, oldCall.superQualifier
)
}
private fun remapTypeArguments(oldExpression: IrMemberAccessExpression, newCallee: FunctionDescriptor): Map<TypeParameterDescriptor, KotlinType>? {
val oldCallee = oldExpression.descriptor
@@ -193,12 +193,14 @@ class BridgeLowering(val state: GenerationState) : ClassLoweringPass {
//TODO: rewrite
//here some 'isSpecialBridge' magic (see type special descriptor processing in KotlinTypeMapper)
val implementation = if (isSpecialBridge) delegateTo.descriptor.copyAsDeclaration() else delegateTo.descriptor
val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, implementation.returnType!!, implementation, null, JvmLoweredStatementOrigin.BRIDGE_DELEGATION, null)
val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
implementation,
null, JvmLoweredStatementOrigin.BRIDGE_DELEGATION, null)
call.dispatchReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, containingClass.thisAsReceiverParameter, JvmLoweredStatementOrigin.BRIDGE_DELEGATION)
newDescriptor.valueParameters.mapIndexed { i, valueParameterDescriptor ->
call.putValueArgument(i, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueParameterDescriptor, JvmLoweredStatementOrigin.BRIDGE_DELEGATION))
}
irBody.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, newDescriptor.returnType!!, newDescriptor, call))
irBody.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, newDescriptor, call))
return irFunction
}
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
import org.jetbrains.kotlin.ir.util.deepCopy
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -127,9 +127,7 @@ class InitializersLowering(val context: JvmBackendContext) : ClassLoweringPass {
companion object {
val clinitName = Name.special("<clinit>")
val deepCopyVisitor = DeepCopyIrTree()
fun IrStatement.copy() = transform(deepCopyVisitor, null)
fun IrExpression.copy() = transform(deepCopyVisitor, null)
fun IrStatement.copy() = deepCopy()
fun IrExpression.copy() = deepCopy()
}
}
@@ -18,11 +18,9 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptor
import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptorImpl
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.isDefinitelyNotDefaultImplsMethod
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.ClassDescriptor
@@ -31,7 +29,10 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -76,8 +77,8 @@ class InterfaceDelegationLowering(val state: GenerationState) : IrElementTransfo
val defaultImpls = InterfaceLowering.createDefaultImplsClassDescriptor(interfaceDescriptor)
val defaultImplFun = InterfaceLowering.createDefaultImplFunDescriptor(defaultImpls, interfaceFun.original, interfaceDescriptor, state.typeMapper)
val returnType = inheritedFun.returnType!!
val irCallImpl = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, returnType, defaultImplFun, null, JvmLoweredStatementOrigin.DEFAULT_IMPLS_DELEGATION)
irBody.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, returnType, inheritedFun, irCallImpl))
val irCallImpl = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, defaultImplFun, null, JvmLoweredStatementOrigin.DEFAULT_IMPLS_DELEGATION)
irBody.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, inheritedFun, irCallImpl))
var shift = 0
if (inheritedFun.dispatchReceiverParameter != null) {
@@ -140,7 +140,7 @@ class SyntheticAccessorLowering(val state: GenerationState) : FileLoweringPass,
accessorDescriptor, body
)
val calleeDescriptor = accessor.calleeDescriptor
val returnExpr = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, calleeDescriptor.returnType!!, calleeDescriptor, emptyMap())
val returnExpr = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, calleeDescriptor)
copyAllArgsToValueParams(returnExpr, accessorDescriptor)
body.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, accessor, returnExpr))
data.irClass.declarations.add(syntheticFunction)
@@ -158,8 +158,7 @@ class SyntheticAccessorLowering(val state: GenerationState) : FileLoweringPass,
if (accessor is AccessorForCallableDescriptor<*> && descriptor !is AccessorForCallableDescriptor<*>) {
val accessorOwner = accessor.containingDeclaration as ClassOrPackageFragmentDescriptor
val staticAccessor = descriptor.toStatic(accessorOwner, Name.identifier(state.typeMapper.mapAsmMethod(accessor as FunctionDescriptor).name)) //TODO change call
val call = IrCallImpl(expression.startOffset, expression.endOffset, expression.descriptor.returnType!!, staticAccessor, emptyMap(),
expression.origin/*TODO super*/)
val call = IrCallImpl(expression.startOffset, expression.endOffset, staticAccessor, emptyMap(), expression.origin/*TODO super*/)
//copyAllArgsToValueParams(call, expression)
expression.receiverAndArgs().forEachIndexed { i, irExpression ->
call.putValueArgument(i, irExpression)
@@ -21,5 +21,5 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
fun IrVariable.defaultLoad(): IrExpression =
IrGetValueImpl(startOffset, endOffset, descriptor)
IrGetValueImpl(startOffset, endOffset, symbol)
@@ -56,7 +56,8 @@ fun StatementGenerator.generateReceiver(startOffset: Int, endOffset: Int, receiv
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
generateSingletonReference(receiverClassDescriptor, startOffset, endOffset, receiver.type)
else
IrGetValueImpl(startOffset, endOffset, receiverClassDescriptor.thisAsReceiverParameter)
IrGetValueImpl(startOffset, endOffset,
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter))
}
is ThisClassReceiver ->
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
@@ -66,9 +67,10 @@ fun StatementGenerator.generateReceiver(startOffset: Int, endOffset: Int, receiv
generateExpression(receiver.expression)
is ClassValueReceiver ->
IrGetObjectValueImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
receiver.classQualifier.descriptor as ClassDescriptor)
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor))
is ExtensionReceiver ->
IrGetValueImpl(startOffset, startOffset, receiver.declarationDescriptor.extensionReceiverParameter!!)
IrGetValueImpl(startOffset, startOffset,
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!))
else ->
TODO("Receiver: ${receiver::class.java.simpleName}")
}
@@ -79,16 +81,19 @@ fun StatementGenerator.generateReceiver(startOffset: Int, endOffset: Int, receiv
OnceExpressionValue(receiverExpression)
}
fun generateSingletonReference(descriptor: ClassDescriptor, startOffset: Int, endOffset: Int, type: KotlinType): IrDeclarationReference =
fun StatementGenerator.generateSingletonReference(descriptor: ClassDescriptor, startOffset: Int, endOffset: Int, type: KotlinType): IrDeclarationReference =
when {
DescriptorUtils.isObject(descriptor) ->
IrGetObjectValueImpl(startOffset, endOffset, type, descriptor)
IrGetObjectValueImpl(startOffset, endOffset, type,
context.symbolTable.referenceClass(descriptor))
DescriptorUtils.isEnumEntry(descriptor) ->
IrGetEnumValueImpl(startOffset, endOffset, type, descriptor)
IrGetEnumValueImpl(startOffset, endOffset, type,
context.symbolTable.referenceEnumEntry(descriptor))
else -> {
val companionObjectDescriptor = descriptor.companionObjectDescriptor
?: throw java.lang.AssertionError("Class value without companion object: $descriptor")
IrGetObjectValueImpl(startOffset, endOffset, type, companionObjectDescriptor)
IrGetObjectValueImpl(startOffset, endOffset, type,
context.symbolTable.referenceClass(companionObjectDescriptor))
}
}
@@ -98,11 +103,12 @@ private fun StatementGenerator.shouldGenerateReceiverAsSingletonReference(receiv
this.scopeOwner.containingDeclaration != receiverClassDescriptor
}
private fun generateThisOrSuperReceiver(receiver: ReceiverValue, classDescriptor: ClassDescriptor): IrExpression {
private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverValue, classDescriptor: ClassDescriptor): IrExpression {
val expressionReceiver = receiver as? ExpressionReceiver ?:
throw AssertionError("'this' or 'super' receiver should be an expression receiver")
val ktReceiver = expressionReceiver.expression
return IrGetValueImpl(ktReceiver.startOffset, ktReceiver.endOffset, classDescriptor.thisAsReceiverParameter)
return IrGetValueImpl(ktReceiver.startOffset, ktReceiver.endOffset,
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter))
}
fun StatementGenerator.generateBackingFieldReceiver(
@@ -158,7 +164,7 @@ fun StatementGenerator.generateCallReceiver(
}
}
private fun generateReceiverForCalleeImportedFromObject(
private fun StatementGenerator.generateReceiverForCalleeImportedFromObject(
startOffset: Int,
endOffset: Int,
calleeDescriptor: ImportedFromObjectCallableDescriptor<*>
@@ -166,7 +172,8 @@ private fun generateReceiverForCalleeImportedFromObject(
val objectDescriptor = calleeDescriptor.containingObject
val objectType = objectDescriptor.defaultType
return generateExpressionValue(objectType) {
IrGetObjectValueImpl(startOffset, endOffset, objectType, objectDescriptor)
IrGetObjectValueImpl(startOffset, endOffset, objectType,
context.symbolTable.referenceClass(objectDescriptor))
}
}
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
import org.jetbrains.kotlin.ir.builders.defineTemporary
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irTemporary
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
import org.jetbrains.kotlin.types.KotlinType
class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateAssignment(expression: KtBinaryExpression): IrExpression {
@@ -88,12 +89,12 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
return irAssignmentReceiver.assign { irLValue ->
irBlock(expression, origin, irLValue.type) {
val temporary = defineTemporary(irLValue.load())
val temporary = irTemporary(irLValue.load())
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
opCall.setExplicitReceiverValue(VariableLValue(startOffset, endOffset, temporary))
opCall.setExplicitReceiverValue(VariableLValue(startOffset, endOffset, temporary.symbol))
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin)
+irLValue.store(irOpCall)
+irGet(temporary)
+irGet(temporary.symbol)
}
}
}
@@ -109,23 +110,50 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
return when (descriptor) {
is SyntheticFieldDescriptor -> {
val receiverValue = statementGenerator.generateBackingFieldReceiver(ktLeft.startOffset, ktLeft.endOffset, resolvedCall, descriptor)
BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor.propertyDescriptor, receiverValue, origin)
createBackingFieldLValue(ktLeft, descriptor.propertyDescriptor, receiverValue, origin)
}
is LocalVariableDescriptor ->
@Suppress("DEPRECATION")
if (descriptor.isDelegated)
DelegatedLocalPropertyLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, origin)
DelegatedLocalPropertyLValue(
ktLeft.startOffset, ktLeft.endOffset,
descriptor.type,
descriptor.getter?.let { context.symbolTable.referenceDeclaredFunction(it) },
descriptor.setter?.let { context.symbolTable.referenceDeclaredFunction(it) },
origin
)
else
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, origin)
VariableLValue(
ktLeft.startOffset, ktLeft.endOffset,
context.symbolTable.referenceVariable(descriptor),
origin
)
is PropertyDescriptor ->
generateAssignmentReceiverForProperty(descriptor, origin, ktLeft, resolvedCall)
is VariableDescriptor ->
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, origin)
is ValueDescriptor ->
VariableLValue(
ktLeft.startOffset, ktLeft.endOffset,
context.symbolTable.referenceValue(descriptor),
origin
)
else ->
OnceExpressionValue(statementGenerator.generateExpression(ktLeft))
}
}
private fun createBackingFieldLValue(
ktExpression: KtExpression,
descriptor: PropertyDescriptor,
receiverValue: IntermediateValue?,
origin: IrStatementOrigin?
): BackingFieldLValue =
BackingFieldLValue(
ktExpression.startOffset, ktExpression.endOffset,
descriptor.type,
context.symbolTable.referenceField(descriptor),
receiverValue, origin
)
private fun generateAssignmentReceiverForProperty(
descriptor: PropertyDescriptor,
origin: IrStatementOrigin,
@@ -134,10 +162,11 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
): AssignmentReceiver =
if (isValInitializationInConstructor(descriptor, resolvedCall)) {
val thisClass = getThisClass()
val irThis = IrGetValueImpl(ktLeft.startOffset, ktLeft.endOffset, thisClass.thisAsReceiverParameter)
BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor,
RematerializableValue(irThis), null)
val irThis = IrGetValueImpl(
ktLeft.startOffset, ktLeft.endOffset,
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
)
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
}
else {
val propertyReceiver = statementGenerator.generateCallReceiver(
@@ -147,10 +176,43 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
val superQualifier = getSuperQualifier(resolvedCall)
SimplePropertyLValue(context, scope, ktLeft.startOffset, ktLeft.endOffset, origin, descriptor,
getTypeArguments(resolvedCall), propertyReceiver, superQualifier)
createPropertyLValue(ktLeft, descriptor, propertyReceiver, getTypeArguments(resolvedCall), origin, superQualifier)
}
private fun createPropertyLValue(
ktExpression: KtExpression,
descriptor: PropertyDescriptor,
propertyReceiver: CallReceiver,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin?,
superQualifier: ClassDescriptor?
): PropertyLValueBase {
val superQualifierSymbol = superQualifier?.let { context.symbolTable.referenceClass(it) }
val getterSymbol = descriptor.getter?.let { context.symbolTable.referenceFunction(it) }
val setterSymbol = descriptor.setter?.let { context.symbolTable.referenceFunction(it) }
return if (getterSymbol != null || setterSymbol != null) {
AccessorPropertyLValue(
scope,
ktExpression.startOffset, ktExpression.endOffset, origin,
descriptor.type,
getterSymbol,
setterSymbol,
typeArguments,
propertyReceiver,
superQualifierSymbol
)
}
else
FieldPropertyLValue(
scope,
ktExpression.startOffset, ktExpression.endOffset, origin,
context.symbolTable.referenceField(descriptor),
propertyReceiver,
superQualifierSymbol
)
}
private fun isValInitializationInConstructor(descriptor: PropertyDescriptor, resolvedCall: ResolvedCall<*>): Boolean =
!descriptor.isVar &&
descriptor.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -28,11 +29,17 @@ import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import java.lang.AssertionError
import java.util.*
class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context: GeneratorContext) : GeneratorWithScope {
override val scope = Scope(scopeOwner)
class BodyGenerator(
val scopeOwnerSymbol: IrSymbol,
override val context: GeneratorContext
) : GeneratorWithScope {
val scopeOwner: DeclarationDescriptor get() = scopeOwnerSymbol.descriptor
override val scope = Scope(scopeOwnerSymbol)
private val loopTable = HashMap<KtLoopExpression, IrLoop>()
fun generateFunctionBody(ktBody: KtExpression): IrBody {
@@ -62,7 +69,8 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
val ktDestructuringDeclaration = ktParameter.destructuringDeclaration ?: continue
val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
val parameterValue = VariableLValue(ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset,
valueParameter, IrStatementOrigin.DESTRUCTURING_DECLARATION)
context.symbolTable.referenceValue(valueParameter),
IrStatementOrigin.DESTRUCTURING_DECLARATION)
statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue)
}
@@ -78,7 +86,8 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
else {
irBlockBody.statements.add(generateReturnExpression(
ktBody.startOffset, ktBody.endOffset,
IrGetObjectValueImpl(ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType, context.builtIns.unit)))
IrGetObjectValueImpl(ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType,
context.symbolTable.referenceClass(context.builtIns.unit))))
}
}
@@ -111,7 +120,9 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
private fun generateReturnExpression(startOffset: Int, endOffset: Int, returnValue: IrExpression): IrReturnImpl {
val returnTarget = (scopeOwner as? CallableDescriptor) ?:
throw AssertionError("'return' in a non-callable: $scopeOwner")
return IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, returnTarget, returnValue)
return IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType,
context.symbolTable.referenceFunction(returnTarget),
returnValue)
}
@@ -166,7 +177,8 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
generateSuperConstructorCall(irBlockBody, ktClassOrObject)
val classDescriptor = (scopeOwner as ClassConstructorDescriptor).containingDeclaration
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, classDescriptor))
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset,
context.symbolTable.referenceClass(classDescriptor)))
return irBlockBody
}
@@ -177,7 +189,8 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
generateDelegatingConstructorCall(irBlockBody, ktConstructor)
val classDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor).containingDeclaration as ClassDescriptor
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktConstructor.startOffset, ktConstructor.endOffset, classDescriptor))
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktConstructor.startOffset, ktConstructor.endOffset,
context.symbolTable.referenceClass(classDescriptor)))
ktConstructor.bodyExpression?.let { ktBody ->
createStatementGenerator().generateBlockBodyStatements(irBlockBody, ktBody)
@@ -222,12 +235,23 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
private fun generateAnySuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) {
val anyConstructor = context.builtIns.any.constructors.single()
irBlockBody.statements.add(IrDelegatingConstructorCallImpl(ktElement.startOffset, ktElement.endOffset, anyConstructor, null))
irBlockBody.statements.add(
IrDelegatingConstructorCallImpl(
ktElement.startOffset, ktElement.endOffset,
context.symbolTable.referenceConstructor(anyConstructor),
null
)
)
}
private fun generateEnumSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) {
val enumConstructor = context.builtIns.enum.constructors.single()
irBlockBody.statements.add(IrEnumConstructorCallImpl(ktElement.startOffset, ktElement.endOffset, enumConstructor))
irBlockBody.statements.add(
IrEnumConstructorCallImpl(
ktElement.startOffset, ktElement.endOffset,
context.symbolTable.referenceConstructor(enumConstructor)
)
)
}
private fun generateEnumEntrySuperConstructorCall(ktEnumEntry: KtEnumEntry, enumEntryDescriptor: ClassDescriptor): IrExpression {
@@ -249,7 +273,10 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
fun generateEnumEntryInitializer(ktEnumEntry: KtEnumEntry, enumEntryDescriptor: ClassDescriptor): IrExpression {
if (ktEnumEntry.declarations.isNotEmpty()) {
val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!!
return IrEnumConstructorCallImpl(ktEnumEntry.startOffset, ktEnumEntry.endOffset, enumEntryConstructor)
return IrEnumConstructorCallImpl(
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
context.symbolTable.referenceConstructor(enumEntryConstructor)
)
}
return generateEnumConstructorCallOrSuperCall(ktEnumEntry, enumEntryDescriptor.containingDeclaration as ClassDescriptor)
@@ -265,7 +292,6 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
val ktSuperCallElement = ktEnumEntry.superTypeListEntries.firstOrNull()
if (ktSuperCallElement != null) {
return statementGenerator.generateEnumConstructorCall(getResolvedCall(ktSuperCallElement)!!, ktEnumEntry)
}
val enumDefaultConstructorCall = getResolvedCall(ktEnumEntry)
@@ -273,9 +299,16 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
return statementGenerator.generateEnumConstructorCall(enumDefaultConstructorCall, ktEnumEntry)
}
// No-argument enum entry constructor
val enumClassConstructor = enumClassDescriptor.constructors.find { it.valueParameters.isEmpty() }!!
return IrEnumConstructorCallImpl(ktEnumEntry.startOffset, ktEnumEntry.endOffset, enumClassConstructor)
// Default enum entry constructor
val enumClassConstructor =
enumClassDescriptor.constructors.singleOrNull {
it.valueParameters.isEmpty() ||
it.valueParameters.all { it.hasDefaultValue() }
} ?: throw AssertionError("Enum class $enumClassDescriptor should have a default constructor")
return IrEnumConstructorCallImpl(
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
context.symbolTable.referenceConstructor(enumClassConstructor)
)
}
private fun StatementGenerator.generateEnumConstructorCall(constructorCall: ResolvedCall<out CallableDescriptor>, ktEnumEntry: KtEnumEntry) =
@@ -128,7 +128,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
java.lang.Boolean.TRUE == bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, whenExpression)
if (isExhaustive) {
val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.noWhenBranchMatchedException)
val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.noWhenBranchMatchedExceptionSymbol)
irWhen.branches.add(IrBranchImpl.elseBranch(call))
}
}
@@ -186,9 +186,14 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
val inOperator = getInfixOperator(ktCondition.operationReference.getReferencedNameElementType())
val irInCall = CallGenerator(statementGenerator).generateCall(ktCondition, inCall, inOperator)
return when (inOperator) {
IrStatementOrigin.IN -> irInCall
IrStatementOrigin.IN ->
irInCall
IrStatementOrigin.NOT_IN ->
IrUnaryPrimitiveImpl(ktCondition.startOffset, ktCondition.endOffset, IrStatementOrigin.EXCL, context.irBuiltIns.booleanNot, irInCall)
IrUnaryPrimitiveImpl(
ktCondition.startOffset, ktCondition.endOffset,
IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol,
irInCall
)
else -> throw AssertionError("Expected 'in' or '!in', got $inOperator")
}
}
@@ -196,7 +201,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
private fun generateEqualsCondition(irSubject: IrVariable, ktCondition: KtWhenConditionWithExpression): IrBinaryPrimitiveImpl =
IrBinaryPrimitiveImpl(
ktCondition.startOffset, ktCondition.endOffset,
IrStatementOrigin.EQEQ, context.irBuiltIns.eqeq,
IrStatementOrigin.EQEQ, context.irBuiltIns.eqeqSymbol,
irSubject.defaultLoad(), statementGenerator.generateExpression(ktCondition.expression!!)
)
}
@@ -20,14 +20,13 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi2ir.intermediate.*
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
@@ -66,14 +65,15 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
generateValueReference(startOffset, endOffset, descriptor.classDescriptor!!, null, origin)
is ClassDescriptor -> {
val classValueType = descriptor.classValueType!!
generateSingletonReference(descriptor, startOffset, endOffset, classValueType)
statementGenerator.generateSingletonReference(descriptor, startOffset, endOffset, classValueType)
}
is PropertyDescriptor -> {
generateCall(startOffset, endOffset, statementGenerator.pregenerateCall(resolvedCall!!))
}
is SyntheticFieldDescriptor -> {
val receiver = statementGenerator.generateBackingFieldReceiver(startOffset, endOffset, resolvedCall, descriptor)
IrGetFieldImpl(startOffset, endOffset, descriptor.propertyDescriptor, receiver?.load())
val field = statementGenerator.context.symbolTable.referenceField(descriptor.propertyDescriptor)
IrGetFieldImpl(startOffset, endOffset, field, receiver?.load())
}
is VariableDescriptor ->
generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin)
@@ -89,22 +89,23 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
origin: IrStatementOrigin? = null
) =
@Suppress("DEPRECATION")
if (descriptor is LocalVariableDescriptor && descriptor.isDelegated)
IrCallImpl(startOffset, endOffset, descriptor.type, descriptor.getter!!, typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY)
if (descriptor is LocalVariableDescriptor && descriptor.isDelegated) {
val getter = context.symbolTable.referenceFunction(descriptor.getter!!)
IrCallImpl(startOffset, endOffset, descriptor.type, getter, typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY)
}
else
IrGetValueImpl(startOffset, endOffset, descriptor, origin)
IrGetValueImpl(startOffset, endOffset, context.symbolTable.referenceValue(descriptor), origin)
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression {
val descriptor = call.descriptor as? ClassConstructorDescriptor
?: throw AssertionError("Class constructor expected: ${call.descriptor}")
return call.callReceiver.call { dispatchReceiver, extensionReceiver ->
val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, descriptor, getTypeArguments(call.original))
irCall.dispatchReceiver = dispatchReceiver?.load()
irCall.extensionReceiver = extensionReceiver?.load()
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
}
}
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression =
call.callReceiver.call { dispatchReceiver, extensionReceiver ->
val descriptor = call.descriptor as? ClassConstructorDescriptor
?: throw AssertionError("Class constructor expected: ${call.descriptor}")
val constructorSymbol = context.symbolTable.referenceConstructor(descriptor)
val irCall = IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, getTypeArguments(call.original))
irCall.dispatchReceiver = dispatchReceiver?.load()
irCall.extensionReceiver = extensionReceiver?.load()
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
}
fun generateEnumConstructorSuperCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression {
val constructorDescriptor = call.descriptor
@@ -115,7 +116,8 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
return call.callReceiver.call { dispatchReceiver, extensionReceiver ->
if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver")
if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver")
val irCall = IrEnumConstructorCallImpl(startOffset, endOffset, constructorDescriptor)
val constructorSymbol = context.symbolTable.referenceConstructor(constructorDescriptor)
val irCall = IrEnumConstructorCallImpl(startOffset, endOffset, constructorSymbol)
addParametersToCall(startOffset, endOffset, call, irCall, constructorDescriptor.returnType)
}
}
@@ -127,16 +129,31 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
call: CallBuilder
): IrExpression {
return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
descriptor.getter?.let { getter ->
IrGetterCallImpl(startOffset, endOffset, getter,
getTypeArguments(call.original),
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
IrStatementOrigin.GET_PROPERTY,
call.superQualifier)
} ?: IrGetFieldImpl(startOffset, endOffset, descriptor,
dispatchReceiverValue?.load(),
IrStatementOrigin.GET_PROPERTY, call.superQualifier)
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
val getterDescriptor = descriptor.getter
if (getterDescriptor != null) {
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor)
IrGetterCallImpl(
startOffset, endOffset,
getterSymbol,
getTypeArguments(call.original),
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
IrStatementOrigin.GET_PROPERTY,
superQualifierSymbol
)
}
else {
val fieldSymbol = context.symbolTable.referenceField(descriptor)
IrGetFieldImpl(
startOffset, endOffset,
fieldSymbol,
dispatchReceiverValue?.load(),
IrStatementOrigin.GET_PROPERTY,
superQualifierSymbol
)
}
}
}
@@ -146,19 +163,26 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
endOffset: Int,
origin: IrStatementOrigin?,
call: CallBuilder
): IrExpression {
val returnType = descriptor.returnType!!
): IrExpression =
call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
val returnType = descriptor.returnType!!
val functionSymbol = context.symbolTable.referenceFunction(descriptor)
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
val irCall = IrCallImpl(
startOffset, endOffset,
returnType,
functionSymbol,
getTypeArguments(call.original),
origin,
superQualifierSymbol
)
irCall.dispatchReceiver = dispatchReceiverValue?.load()
irCall.extensionReceiver = extensionReceiverValue?.load()
return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
val irCall = IrCallImpl(startOffset, endOffset, returnType, descriptor, getTypeArguments(call.original), origin, call.superQualifier)
irCall.dispatchReceiver = dispatchReceiverValue?.load()
irCall.extensionReceiver = extensionReceiverValue?.load()
addParametersToCall(startOffset, endOffset, call, irCall, returnType)
}
addParametersToCall(startOffset, endOffset, call, irCall, returnType)
}
}
private fun addParametersToCall(startOffset: Int, endOffset: Int, call: CallBuilder, irCall: IrCallWithIndexedArgumentsBase, returnType: KotlinType): IrExpression =
private fun addParametersToCall(startOffset: Int, endOffset: Int, call: CallBuilder, irCall: IrFunctionAccessExpression, returnType: KotlinType): IrExpression =
if (call.isValueArgumentReorderingRequired()) {
generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType)
}
@@ -171,7 +195,7 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
}
private fun generateCallWithArgumentReordering(
irCall: IrMemberAccessExpression,
irCall: IrFunctionAccessExpression,
startOffset: Int,
endOffset: Int,
call: CallBuilder,
@@ -48,11 +48,20 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
IrDeclarationOrigin.DEFINED,
descriptor
).buildWithScope { irClass ->
if (irClass.descriptor.canHaveInitializersWithInstanceReference()) {
irClass.newInstanceReceiver = context.symbolTable.declareValueParameter(
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
IrDeclarationOrigin.NEW_INSTANCE_RECEIVER,
irClass.descriptor.thisAsReceiverParameter
)
}
declarationGenerator.generateTypeParameterDeclarations(irClass, descriptor.declaredTypeParameters)
generatePrimaryConstructor(irClass, ktClassOrObject)
generatePropertiesDeclaredInPrimaryConstructor(irClass, ktClassOrObject)
val irPrimaryConstructor = generatePrimaryConstructor(irClass, ktClassOrObject)
if (irPrimaryConstructor != null) {
generatePropertiesDeclaredInPrimaryConstructor(irClass, irPrimaryConstructor, ktClassOrObject)
}
generateMembersDeclaredInSupertypeList(irClass, ktClassOrObject)
@@ -70,6 +79,9 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
}
}
private fun ClassDescriptor.canHaveInitializersWithInstanceReference(): Boolean =
kind != ClassKind.INTERFACE
private fun generateFakeOverrideMemberDeclarations(irClass: IrClass) {
irClass.descriptor.unsubstitutedMemberScope.getContributedDescriptors()
.mapNotNull {
@@ -137,7 +149,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
ktDelegateExpression.startOffset, ktDelegateExpression.endOffset,
IrDeclarationOrigin.DELEGATE,
delegateDescriptor,
createBodyGenerator(irClass.descriptor).generateExpressionBody(ktDelegateExpression)
createBodyGenerator(irClass.symbol).generateExpressionBody(ktDelegateExpression)
)
irClass.addMember(irDelegateField)
@@ -189,33 +201,35 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
delegated
).buildWithScope { irFunction ->
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden)
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden, irFunction)
}
private fun generateDelegateFunctionBody(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrBlockBodyImpl {
private fun generateDelegateFunctionBody(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor,
irDelegatedFunction: IrSimpleFunction): IrBlockBodyImpl {
val startOffset = irDelegate.startOffset
val endOffset = irDelegate.endOffset
val dispatchReceiver = delegated.dispatchReceiverParameter ?:
throw AssertionError("Delegated member should have a dispatch receiver: $delegated")
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
val returnType = overridden.returnType!!
val irCall = IrCallImpl(startOffset, endOffset, returnType, overridden, null)
irCall.dispatchReceiver = IrGetFieldImpl(startOffset, endOffset, irDelegate.descriptor,
IrGetValueImpl(startOffset, endOffset, dispatchReceiver)
)
irCall.extensionReceiver = delegated.extensionReceiverParameter?.let { extensionReceiver ->
IrGetValueImpl(startOffset, endOffset, extensionReceiver)
}
val irCall = IrCallImpl(startOffset, endOffset, returnType, context.symbolTable.referenceFunction(overridden), null)
irCall.dispatchReceiver =
IrGetFieldImpl(
startOffset, endOffset, irDelegate.symbol,
IrGetValueImpl(startOffset, endOffset, irDelegatedFunction.dispatchReceiverParameter!!.symbol)
)
irCall.extensionReceiver =
irDelegatedFunction.extensionReceiverParameter?.let { extensionReceiver ->
IrGetValueImpl(startOffset, endOffset, extensionReceiver.symbol)
}
irCall.mapValueParameters { overriddenValueParameter ->
val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index]
IrGetValueImpl(startOffset, endOffset, delegatedValueParameter)
val irDelegatedValueParameter = irDelegatedFunction.getIrValueParameter(delegatedValueParameter)
IrGetValueImpl(startOffset, endOffset, irDelegatedValueParameter.symbol)
}
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
irBlockBody.statements.add(irCall)
}
else {
val irReturn = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, delegated, irCall)
val irReturn = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, irDelegatedFunction.symbol, irCall)
irBlockBody.statements.add(irReturn)
}
return irBlockBody
@@ -229,22 +243,31 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
EnumClassMembersGenerator(context).generateSpecialMembers(irClass)
}
private fun generatePrimaryConstructor(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
private fun generatePrimaryConstructor(irClass: IrClass, ktClassOrObject: KtClassOrObject): IrConstructor? {
val classDescriptor = irClass.descriptor
if (DescriptorUtils.isAnnotationClass(classDescriptor)) return
if (DescriptorUtils.isAnnotationClass(classDescriptor)) return null
val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return
val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return null
val irPrimaryConstructor = FunctionGenerator(declarationGenerator).generatePrimaryConstructor(primaryConstructorDescriptor, ktClassOrObject)
irClass.addMember(irPrimaryConstructor)
return irPrimaryConstructor
}
private fun generatePropertiesDeclaredInPrimaryConstructor(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
private fun generatePropertiesDeclaredInPrimaryConstructor(
irClass: IrClass,
irPrimaryConstructor: IrConstructor,
ktClassOrObject: KtClassOrObject
) {
ktClassOrObject.primaryConstructor?.let { ktPrimaryConstructor ->
for (ktParameter in ktPrimaryConstructor.valueParameters) {
ktPrimaryConstructor.valueParameters.forEachIndexed { i, ktParameter ->
val irValueParameter = irPrimaryConstructor.valueParameters[i]
if (ktParameter.hasValOrVar()) {
irClass.addMember(PropertyGenerator(declarationGenerator).generatePropertyForPrimaryConstructorParameter(ktParameter))
val irProperty = PropertyGenerator(declarationGenerator)
.generatePropertyForPrimaryConstructorParameter(ktParameter, irValueParameter)
irClass.addMember(irProperty)
}
}
}
@@ -267,7 +290,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
enumEntryDescriptor
).buildWithScope { irEnumEntry ->
irEnumEntry.initializerExpression =
BodyGenerator(enumEntryDescriptor.containingDeclaration, context)
createBodyGenerator(irEnumEntry.symbol)
.generateEnumEntryInitializer(ktEnumEntry, enumEntryDescriptor)
if (ktEnumEntry.declarations.isNotEmpty()) {
@@ -26,7 +26,9 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.putDefault
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi2ir.containsNull
@@ -46,21 +48,23 @@ class DataClassMembersGenerator(
MyDataClassMethodGenerator(ktClassOrObject, irClass).generate()
}
private fun declareSimpleFunction(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, function: FunctionDescriptor) =
context.symbolTable.declareSimpleFunction(startOffset, endOffset, origin, function)
private inner class MemberFunctionBuilder(
val irClass: IrClass,
val function: FunctionDescriptor,
val origin: IrDeclarationOrigin,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET
) : IrBlockBodyBuilder(context, Scope(function), startOffset, endOffset) {
lateinit var irFunction: IrFunction
endOffset: Int = UNDEFINED_OFFSET,
val irFunction: IrFunction = declareSimpleFunction(startOffset, endOffset, origin, function)
) : IrBlockBodyBuilder(context, Scope(irFunction.symbol), startOffset, endOffset) {
inline fun addToClass(builder: MemberFunctionBuilder.(IrFunction) -> Unit): IrFunction {
irFunction.buildWithScope {
builder(irFunction)
irFunction.body = doBuild()
}
inline fun addToClass(body: MemberFunctionBuilder.(IrFunction) -> Unit): IrFunction {
irFunction = this@DataClassMembersGenerator.context.symbolTable
.declareSimpleFunction(startOffset, endOffset, origin, function)
body(irFunction)
irFunction.body = doBuild()
irClass.declarations.add(irFunction)
return irFunction
}
@@ -68,6 +72,12 @@ class DataClassMembersGenerator(
fun putDefault(parameter: ValueParameterDescriptor, value: IrExpression) {
irFunction.putDefault(parameter, irExprBody(value))
}
fun irThis(): IrExpression =
IrGetValueImpl(startOffset, endOffset, irFunction.dispatchReceiverParameter!!.symbol)
fun irOther(): IrExpression =
IrGetValueImpl(startOffset, endOffset, irFunction.valueParameters[0].symbol)
}
private inner class MyDataClassMethodGenerator(
@@ -94,23 +104,31 @@ class DataClassMembersGenerator(
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter) ?:
throw AssertionError("No definition for data class constructor parameter $parameter")
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
buildMember(function, ktParameter) {
+irReturn(irGet(irThis(), property))
+irReturn(irGet(irThis(), getPropertyGetterSymbol(parameter)))
}
}
private fun getPropertyGetterSymbol(parameter: ValueParameterDescriptor): IrFunctionSymbol {
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
return getPropertyGetterSymbol(property)
}
private fun getPropertyGetterSymbol(property: PropertyDescriptor) =
context.symbolTable.referenceFunction(property.getter!!)
override fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>) {
val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor ?:
throw AssertionError("Data class should have a primary constructor: $classDescriptor")
val constructorSymbol = context.symbolTable.referenceConstructor(dataClassConstructor)
buildMember(function) {
buildMember(function) { irFunction ->
function.valueParameters.forEach { parameter ->
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
putDefault(parameter, irGet(irThis(), property))
putDefault(parameter, irGet(irThis(), getPropertyGetterSymbol(parameter)))
}
+irReturn(irCall(dataClassConstructor).mapValueParameters { irGet(function.valueParameters[it.index]) })
+irReturn(irCall(constructorSymbol, dataClassConstructor.returnType).mapValueParameters {
irGet(irFunction.valueParameters[it.index].symbol)
})
}
}
@@ -118,43 +136,52 @@ class DataClassMembersGenerator(
buildMember(function) {
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
+irIfThenReturnFalse(irNotIs(irOther(), classDescriptor.defaultType))
val otherWithCast = defineTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
val otherWithCast = irTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
for (property in properties) {
+irIfThenReturnFalse(
irNotEquals(irGet(irThis(), property),
irGet(irGet(otherWithCast), property)))
irNotEquals(irGet(irThis(), getPropertyGetterSymbol(property)),
irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))))
}
+irReturnTrue()
}
}
private val INT = context.builtIns.int
private val INT_TYPE = context.builtIns.intType
private val intClass = context.builtIns.int
private val intType = context.builtIns.intType
private val IMUL = INT.findFirstFunction("times") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, INT_TYPE) }
private val IADD = INT.findFirstFunction("plus") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, INT_TYPE) }
private val intTimes =
intClass.findFirstFunction("times") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, intType) }
.let { context.symbolTable.referenceFunction(it) }
private fun getHashCodeFunction(type: KotlinType): CallableDescriptor {
private val intPlus =
intClass.findFirstFunction("plus") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, intType) }
.let { context.symbolTable.referenceFunction(it) }
private fun getHashCodeFunction(type: KotlinType): IrFunctionSymbol {
val typeConstructorDescriptor = type.constructor.declarationDescriptor
when (typeConstructorDescriptor) {
is ClassDescriptor ->
return typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
return when (typeConstructorDescriptor) {
is ClassDescriptor -> {
val hashCodeDescriptor: CallableDescriptor = typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
context.symbolTable.referenceFunction(hashCodeDescriptor)
}
is TypeParameterDescriptor ->
return getHashCodeFunction(context.builtIns.anyType) // TODO
getHashCodeFunction(context.builtIns.anyType) // TODO
else ->
throw AssertionError("Unexpected type: $type")
}
}
override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
buildMember(function) {
val result = defineTemporaryVar(irInt(0), "result")
val result = irTemporaryVar(irInt(0), "result").symbol
var first = true
for (property in properties) {
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
val irNewValue =
if (first) hashCodeOfProperty
else irCallOp(IADD, irCallOp(IMUL, irGet(result), irInt(31)), hashCodeOfProperty)
else irCallOp(intPlus, irCallOp(intTimes, irGet(result), irInt(31)), hashCodeOfProperty)
+irSetVar(result, irNewValue)
first = false
}
@@ -162,18 +189,20 @@ class DataClassMembersGenerator(
}
}
private fun MemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression =
when {
property.type.containsNull() ->
irLet(irGet(receiver, property)) { variable ->
irIfNull(context.builtIns.intType, irGet(variable), irInt(0), getHashCodeOf(irGet(variable)))
}
else ->
getHashCodeOf(irGet(receiver, property))
}
private fun MemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression {
val getterSymbol = getPropertyGetterSymbol(property)
return when {
property.type.containsNull() ->
irLetS(irGet(receiver, getterSymbol)) { variable ->
irIfNull(context.builtIns.intType, irGet(variable), irInt(0), getHashCodeOf(irGet(variable)))
}
else ->
getHashCodeOf(irGet(receiver, getterSymbol))
}
}
private fun MemberFunctionBuilder.getHashCodeOf(irValue: IrExpression): IrExpression =
irCall(getHashCodeFunction(irValue.type)).apply { dispatchReceiver = irValue }
irCall(getHashCodeFunction(irValue.type), intType).apply { dispatchReceiver = irValue }
override fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
buildMember(function) {
@@ -183,7 +212,7 @@ class DataClassMembersGenerator(
for (property in properties) {
if (!first) irConcat.addArgument(irString(", "))
irConcat.addArgument(irString(property.name.asString() + "="))
irConcat.addArgument(irGet(irThis(), property))
irConcat.addArgument(irGet(irThis(), getPropertyGetterSymbol(property)))
first = false
}
irConcat.addArgument(irString(")"))
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrErrorDeclarationImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeAliasImpl
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -74,7 +75,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
context.symbolTable.declareAnonymousInitializer(
ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
).apply {
body = createBodyGenerator(classDescriptor).generateAnonymousInitializerBody(ktAnonymousInitializer)
body = createBodyGenerator(symbol).generateAnonymousInitializerBody(ktAnonymousInitializer)
}
@@ -90,8 +91,8 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
}
}
fun generateInitializerBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrExpressionBody =
createBodyGenerator(scopeOwner).generateExpressionBody(ktBody)
fun generateInitializerBody(scopeOwnerSymbol: IrSymbol, ktBody: KtExpression): IrExpressionBody =
createBodyGenerator(scopeOwnerSymbol).generateExpressionBody(ktBody)
fun generateFakeOverrideDeclaration(memberDescriptor: CallableMemberDescriptor, ktElement: KtElement? = null): IrDeclaration {
assert(memberDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
@@ -137,5 +138,5 @@ abstract class DeclarationGeneratorExtension(val declarationGenerator: Declarati
}
}
fun Generator.createBodyGenerator(scopeOwnerDescriptor: DeclarationDescriptor) =
BodyGenerator(scopeOwnerDescriptor, context)
fun Generator.createBodyGenerator(scopeOwnerSymbol: IrSymbol) =
BodyGenerator(scopeOwnerSymbol, context)
@@ -28,9 +28,11 @@ import org.jetbrains.kotlin.ir.descriptors.IrLocalDelegatedPropertyDelegateDescr
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPropertyDelegate
@@ -46,33 +48,38 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
fun generateDelegatedProperty(
ktProperty: KtProperty,
ktDelegate: KtPropertyDelegate,
propertyDescriptor: PropertyDescriptor,
irDelegateInitializer: IrExpressionBody
propertyDescriptor: PropertyDescriptor
): IrProperty {
val kPropertyType = getKPropertyTypeForDelegatedProperty(propertyDescriptor)
val irDelegate = generateDelegateFieldForProperty(propertyDescriptor, kPropertyType, irDelegateInitializer, ktDelegate)
val delegateDescriptor = irDelegate.descriptor as IrPropertyDelegateDescriptor
val kPropertyType = getKPropertyTypeForDelegatedProperty(propertyDescriptor)
val irProperty = IrPropertyImpl(
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED, true,
propertyDescriptor, irDelegate)
propertyDescriptor
).apply {
backingField = generateDelegateFieldForProperty(propertyDescriptor, kPropertyType, ktDelegate)
}
val delegateReceiverValue = createBackingFieldValueForDelegate(delegateDescriptor, ktDelegate)
val irDelegate = irProperty.backingField!!
val thisClass = propertyDescriptor.containingDeclaration as? ClassDescriptor
val delegateReceiverValue = createBackingFieldValueForDelegate(irDelegate.symbol, thisClass, ktDelegate)
val getterDescriptor = propertyDescriptor.getter!!
irProperty.getter = generateDelegatedPropertyAccessorExceptBody(ktProperty, ktDelegate, getterDescriptor).also { irGetter ->
irGetter.body = generateDelegatedPropertyGetterBody(
irProperty.getter = generateDelegatedPropertyAccessor(ktProperty, ktDelegate, getterDescriptor) { irGetter ->
generateDelegatedPropertyGetterBody(
irGetter,
ktDelegate, getterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor)
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor, irGetter.symbol)
)
}
if (propertyDescriptor.isVar) {
val setterDescriptor = propertyDescriptor.setter!!
irProperty.setter = generateDelegatedPropertyAccessorExceptBody(ktProperty, ktDelegate, setterDescriptor).also { irSetter ->
irSetter.body = generateDelegatedPropertySetterBody(
irProperty.setter = generateDelegatedPropertyAccessor(ktProperty, ktDelegate, setterDescriptor) { irSetter ->
generateDelegatedPropertySetterBody(
irSetter,
ktDelegate, setterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor)
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor, irSetter.symbol)
)
}
}
@@ -80,10 +87,11 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
return irProperty
}
private fun generateDelegatedPropertyAccessorExceptBody(
private inline fun generateDelegatedPropertyAccessor(
ktProperty: KtProperty,
ktDelegate: KtPropertyDelegate,
accessorDescriptor: PropertyAccessorDescriptor
accessorDescriptor: PropertyAccessorDescriptor,
generateBody: (IrFunction) -> IrBody
): IrFunction =
context.symbolTable.declareSimpleFunction(
ktDelegate.startOffset, ktDelegate.endOffset,
@@ -91,6 +99,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
accessorDescriptor
).buildWithScope { irGetter ->
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irGetter, ktProperty, null)
irGetter.body = generateBody(irGetter)
}
@@ -102,10 +111,12 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
private fun generateDelegateFieldForProperty(
propertyDescriptor: PropertyDescriptor,
kPropertyType: KotlinType,
irDelegateInitializer: IrExpressionBody,
ktDelegate: KtPropertyDelegate
): IrField {
val irActualDelegateInitializer = generateInitializerBodyForPropertyDelegate(propertyDescriptor, kPropertyType, irDelegateInitializer, ktDelegate)
val irActualDelegateInitializer = generateInitializerBodyForPropertyDelegate(
propertyDescriptor, kPropertyType, ktDelegate,
context.symbolTable.referenceField(propertyDescriptor)
)
val delegateType = irActualDelegateInitializer.expression.type
val delegateDescriptor = createPropertyDelegateDescriptor(propertyDescriptor, delegateType, kPropertyType)
@@ -119,44 +130,78 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
private fun generateInitializerBodyForPropertyDelegate(
property: VariableDescriptorWithAccessors,
kPropertyType: KotlinType,
irDelegateInitializer: IrExpressionBody,
ktDelegate: KtPropertyDelegate
ktDelegate: KtPropertyDelegate,
scopeOwner: IrSymbol
): IrExpressionBody {
val ktDelegateExpression = ktDelegate.expression!!
val irDelegateInitializer = declarationGenerator.generateInitializerBody(scopeOwner, ktDelegateExpression)
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, property)
?: return irDelegateInitializer
val statementGenerator = BodyGenerator(property, context).createStatementGenerator()
val statementGenerator = createBodyGenerator(scopeOwner).createStatementGenerator()
val provideDelegateCall = statementGenerator.pregenerateCall(provideDelegateResolvedCall)
provideDelegateCall.setExplicitReceiverValue(OnceExpressionValue(irDelegateInitializer.expression))
provideDelegateCall.irValueArgumentsByIndex[1] = createCallableReference(ktDelegate, kPropertyType, property)
provideDelegateCall.irValueArgumentsByIndex[1] = createCallableReference(ktDelegate, kPropertyType, property, scopeOwner)
val irProvideDelegate = CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, provideDelegateCall)
return IrExpressionBodyImpl(irProvideDelegate)
}
private fun createBackingFieldValueForDelegate(delegateDescriptor: IrPropertyDelegateDescriptor, ktDelegate: KtPropertyDelegate): IntermediateValue {
val thisClass = delegateDescriptor.correspondingProperty.containingDeclaration as? ClassDescriptor
val thisValue = thisClass?.let {
RematerializableValue(IrGetValueImpl(ktDelegate.startOffset, ktDelegate.endOffset, thisClass.thisAsReceiverParameter))
}
return BackingFieldLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor, thisValue, null)
private fun createBackingFieldValueForDelegate(irDelegateField: IrFieldSymbol, thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue {
val thisValue = createThisValueForDelegate(thisClass, ktDelegate)
return BackingFieldLValue(ktDelegate.startOffset, ktDelegate.endOffset,
irDelegateField.descriptor.type,
irDelegateField,
thisValue,
null)
}
private fun createCallableReference(ktElement: KtElement, type: KotlinType, referencedDescriptor: CallableDescriptor): IrCallableReference =
IrCallableReferenceImpl(ktElement.startOffset, ktElement.endOffset, type,
referencedDescriptor, null, IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE)
private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? =
thisClass?.let {
generateExpressionValue(it.thisAsReceiverParameter.type) {
IrGetValueImpl(
ktDelegate.startOffset, ktDelegate.endOffset,
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
)
}
}
private fun createCallableReference(
ktElement: KtElement,
type: KotlinType,
referencedDescriptor: CallableDescriptor,
statementGenerator: StatementGenerator
): IrCallableReference =
ReflectionReferencesGenerator(statementGenerator).generateCallableReference(
ktElement.startOffset, ktElement.endOffset, type,
referencedDescriptor,
null, IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE
)
private fun createCallableReference(
ktElement: KtElement,
type: KotlinType,
referencedDescriptor: CallableDescriptor,
scopeOwner: IrSymbol
): IrCallableReference =
createCallableReference(
ktElement, type, referencedDescriptor,
createBodyGenerator(scopeOwner).createStatementGenerator()
)
fun generateLocalDelegatedProperty(
ktProperty: KtProperty,
ktDelegate: KtPropertyDelegate,
variableDescriptor: VariableDescriptorWithAccessors,
irDelegateInitializer: IrExpression
scopeOwnerSymbol: IrSymbol
): IrLocalDelegatedProperty {
val kPropertyType = getKPropertyTypeForLocalDelegatedProperty(variableDescriptor)
val irActualDelegateInitializer =
generateInitializerBodyForPropertyDelegate(
variableDescriptor, kPropertyType,
IrExpressionBodyImpl(irDelegateInitializer), ktDelegate
ktDelegate,
scopeOwnerSymbol
).expression
val delegateType = irActualDelegateInitializer.type
@@ -171,40 +216,53 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
variableDescriptor, irDelegate)
val getterDescriptor = variableDescriptor.getter!!
val delegateReceiverValue = createVariableValueForDelegate(delegateDescriptor, ktDelegate)
irLocalDelegatedProperty.getter = createLocalPropertyAccessor(
getterDescriptor, ktDelegate,
generateDelegatedPropertyGetterBody(
ktDelegate, getterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, delegateDescriptor.correspondingLocalProperty)
)
)
val delegateReceiverValue = createVariableValueForDelegate(irDelegate.symbol, ktDelegate)
irLocalDelegatedProperty.getter =
createLocalPropertyAccessor(getterDescriptor, ktDelegate) { irGetter ->
generateDelegatedPropertyGetterBody(
irGetter,
ktDelegate, getterDescriptor, delegateReceiverValue,
createCallableReference(
ktDelegate, delegateDescriptor.kPropertyType,
delegateDescriptor.correspondingLocalProperty,
irGetter.symbol
)
)
}
if (variableDescriptor.isVar) {
val setterDescriptor = variableDescriptor.setter!!
irLocalDelegatedProperty.setter = createLocalPropertyAccessor(
setterDescriptor, ktDelegate,
generateDelegatedPropertySetterBody(
ktDelegate, setterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, delegateDescriptor.correspondingLocalProperty)
)
)
irLocalDelegatedProperty.setter =
createLocalPropertyAccessor(setterDescriptor, ktDelegate) { irSetter ->
generateDelegatedPropertySetterBody(
irSetter, ktDelegate, setterDescriptor, delegateReceiverValue,
createCallableReference(
ktDelegate, delegateDescriptor.kPropertyType,
delegateDescriptor.correspondingLocalProperty,
irSetter.symbol
)
)
}
}
return irLocalDelegatedProperty
}
private fun createVariableValueForDelegate(delegateDescriptor: IrLocalDelegatedPropertyDelegateDescriptor, ktDelegate: KtPropertyDelegate) =
VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor)
private fun createVariableValueForDelegate(irDelegate: IrVariableSymbol, ktDelegate: KtPropertyDelegate) =
VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, irDelegate)
private fun createLocalPropertyAccessor(getterDescriptor: VariableAccessorDescriptor, ktDelegate: KtPropertyDelegate, irBody: IrBody) =
private fun createLocalPropertyAccessor(
getterDescriptor: VariableAccessorDescriptor, ktDelegate: KtPropertyDelegate,
generateBody: (IrFunction) -> IrBody
) =
context.symbolTable.declareSimpleFunction(
ktDelegate.startOffset, ktDelegate.endOffset,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
getterDescriptor
).apply {
body = irBody
).buildWithScope {
it.body = generateBody(it)
}
private fun createLocalPropertyDelegatedDescriptor(
@@ -225,35 +283,38 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
): IrPropertyDelegateDescriptor =
IrPropertyDelegateDescriptorImpl(propertyDescriptor, delegateType, kPropertyType)
fun generateDelegatedPropertyGetterBody(
private fun generateDelegatedPropertyGetterBody(
irGetter: IrFunction,
ktDelegate: KtPropertyDelegate,
getterDescriptor: VariableAccessorDescriptor,
delegateReceiverValue: IntermediateValue,
irPropertyReference: IrCallableReference
): IrBody = with(BodyGenerator(getterDescriptor, context)) {
irBlockBody(ktDelegate) {
val statementGenerator = createStatementGenerator()
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
}
}
): IrBody =
with(createBodyGenerator(irGetter.symbol)) {
irBlockBody(ktDelegate) {
val statementGenerator = createStatementGenerator()
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
}
}
fun generateDelegatedPropertySetterBody(
private fun generateDelegatedPropertySetterBody(
irSetter: IrFunction,
ktDelegate: KtPropertyDelegate,
setterDescriptor: VariableAccessorDescriptor,
delegateReceiverValue: IntermediateValue,
irPropertyReference: IrCallableReference
): IrBody = with(BodyGenerator(setterDescriptor, context)) {
): IrBody = with(createBodyGenerator(irSetter.symbol)) {
irBlockBody(ktDelegate) {
val statementGenerator = createStatementGenerator()
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(setterDescriptor.valueParameters[0])
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(irSetter.valueParameters[0].symbol)
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
}
}
@@ -66,7 +66,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
ktFunction.startOffset, ktFunction.endOffset, origin, descriptor
).buildWithScope { irFunction ->
generateFunctionParameterDeclarations(irFunction, ktFunction, ktReceiver)
irFunction.body = createBodyGenerator(descriptor).generateBody()
irFunction.body = createBodyGenerator(irFunction.symbol).generateBody()
}
fun generateFunctionParameterDeclarations(
@@ -93,15 +93,14 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
val ktBodyExpression = ktAccessor?.bodyExpression
irAccessor.body =
if (ktBodyExpression != null)
createBodyGenerator(descriptor).generateFunctionBody(ktBodyExpression)
createBodyGenerator(irAccessor.symbol).generateFunctionBody(ktBodyExpression)
else
generateDefaultAccessorBody(ktProperty, descriptor)
generateDefaultAccessorBody(ktProperty, descriptor, irAccessor)
}
fun generateDefaultAccessorForPrimaryConstructorParameter(
descriptor: PropertyAccessorDescriptor,
ktParameter: KtParameter,
isGetter: Boolean
ktParameter: KtParameter
): IrFunction =
context.symbolTable.declareSimpleFunction(
ktParameter.startOffsetOrUndefined,
@@ -109,43 +108,55 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
descriptor
).buildWithScope { irAccessor ->
val accessorDescriptor = irAccessor.descriptor
declarationGenerator.generateTypeParameterDeclarations(irAccessor, accessorDescriptor.typeParameters)
declarationGenerator.generateTypeParameterDeclarations(irAccessor, descriptor.typeParameters)
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irAccessor)
irAccessor.body =
if (isGetter) generateDefaultGetterBody(ktParameter, descriptor as PropertyGetterDescriptor)
else generateDefaultSetterBody(ktParameter, descriptor as PropertySetterDescriptor)
irAccessor.body = generateDefaultAccessorBody(ktParameter, descriptor, irAccessor)
}
private fun generateDefaultAccessorBody(ktProperty: KtElement, accessor: PropertyAccessorDescriptor) =
private fun generateDefaultAccessorBody(ktProperty: KtElement, accessor: PropertyAccessorDescriptor, irAccessor: IrSimpleFunction) =
when (accessor) {
is PropertyGetterDescriptor -> generateDefaultGetterBody(ktProperty, accessor)
is PropertySetterDescriptor -> generateDefaultSetterBody(ktProperty, accessor)
is PropertyGetterDescriptor -> generateDefaultGetterBody(ktProperty, accessor, irAccessor)
is PropertySetterDescriptor -> generateDefaultSetterBody(ktProperty, accessor, irAccessor)
else -> throw AssertionError("Should be getter or setter: $accessor")
}
private fun generateDefaultGetterBody(ktProperty: KtElement, getter: PropertyGetterDescriptor): IrBlockBody {
private fun generateDefaultGetterBody(ktProperty: KtElement, getter: PropertyGetterDescriptor, irAccessor: IrSimpleFunction): IrBlockBody {
val property = getter.correspondingProperty
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
irBody.statements.add(IrReturnImpl(ktProperty.startOffset, ktProperty.endOffset, context.builtIns.nothingType, getter,
IrGetFieldImpl(ktProperty.startOffset, ktProperty.endOffset, property, receiver)))
irBody.statements.add(
IrReturnImpl(
ktProperty.startOffset, ktProperty.endOffset, context.builtIns.nothingType,
irAccessor.symbol,
IrGetFieldImpl(
ktProperty.startOffset, ktProperty.endOffset,
context.symbolTable.referenceField(property),
receiver
)
)
)
return irBody
}
private fun generateDefaultSetterBody(ktProperty: KtElement, setter: PropertySetterDescriptor): IrBlockBody {
private fun generateDefaultSetterBody(ktProperty: KtElement, setter: PropertySetterDescriptor, irAccessor: IrSimpleFunction): IrBlockBody {
val property = setter.correspondingProperty
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
val setterParameter = setter.valueParameters.single()
irBody.statements.add(IrSetFieldImpl(ktProperty.startOffset, ktProperty.endOffset, property, receiver,
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, setterParameter)))
val setterParameter = irAccessor.valueParameters.single().symbol
irBody.statements.add(
IrSetFieldImpl(
ktProperty.startOffset, ktProperty.endOffset,
context.symbolTable.referenceField(property),
receiver,
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, setterParameter)
)
)
return irBody
}
@@ -153,7 +164,8 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
val containingDeclaration = property.containingDeclaration
val receiver = when (containingDeclaration) {
is ClassDescriptor ->
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, containingDeclaration.thisAsReceiverParameter)
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset,
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter))
else -> null
}
return receiver
@@ -189,7 +201,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
ktConstructorElement.startOffset, ktConstructorElement.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor
).buildWithScope { irConstructor ->
generateFunctionParameterDeclarations(irConstructor, ktParametersElement, null)
irConstructor.body = createBodyGenerator(constructorDescriptor).generateBody()
irConstructor.body = createBodyGenerator(irConstructor.symbol).generateBody()
}
fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
@@ -212,7 +224,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
generateReceiverParameterDeclaration(it, ktReceiverParameterElement ?: ktParameterOwner)
}
val bodyGenerator = createBodyGenerator(functionDescriptor)
val bodyGenerator = createBodyGenerator(irFunction.symbol)
functionDescriptor.valueParameters.mapTo(irFunction.valueParameters) { valueParameterDescriptor ->
val ktParameter = DescriptorToSourceUtils.getSourceFromDescriptor(valueParameterDescriptor) as? KtParameter
generateValueParameterDeclaration(valueParameterDescriptor, ktParameter, bodyGenerator)
@@ -45,8 +45,13 @@ class LocalClassGenerator(statementGenerator: StatementGenerator): StatementGene
"Object literal constructor should have no value parameters: $objectConstructor"
}
irBlock.statements.add(IrCallImpl(ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType,
objectConstructor, null, IrStatementOrigin.OBJECT_LITERAL))
irBlock.statements.add(
IrCallImpl(
ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType,
context.symbolTable.referenceConstructor(objectConstructor),
null, IrStatementOrigin.OBJECT_LITERAL
)
)
return irBlock
}
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -35,9 +35,10 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrStatementOrigin.LAMBDA)
irBlock.statements.add(irLambdaFunction)
irBlock.statements.add(
IrCallableReferenceImpl(
IrFunctionReferenceImpl(
ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType,
irLambdaFunction.descriptor, null, IrStatementOrigin.LAMBDA
irLambdaFunction.symbol,
null, IrStatementOrigin.LAMBDA
)
)
return irBlock
@@ -56,9 +57,10 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
irBlock.statements.add(irFun)
irBlock.statements.add(
IrCallableReferenceImpl(
IrFunctionReferenceImpl(
ktFun.startOffset, ktFun.endOffset, funExpressionType,
irFun.descriptor, null, IrStatementOrigin.ANONYMOUS_FUNCTION
irFun.symbol,
null, IrStatementOrigin.ANONYMOUS_FUNCTION
)
)
@@ -119,8 +119,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
return irBlock(expression, IrStatementOrigin.ELVIS, resultType) {
val temporary = defineTemporary(irArgument0, "elvis_lhs")
+irIfNull(resultType, irGet(temporary), irArgument1, irGet(temporary))
val temporary = irTemporary(irArgument0, "elvis_lhs")
+irIfNull(resultType, irGet(temporary.symbol), irArgument1, irGet(temporary.symbol))
}
}
@@ -146,7 +146,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
IrStatementOrigin.IN ->
irContainsCall
IrStatementOrigin.NOT_IN ->
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN, context.irBuiltIns.booleanNot,
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN,
context.irBuiltIns.booleanNotSymbol,
irContainsCall)
else ->
throw AssertionError("Unexpected in-operator $irOperator")
@@ -159,14 +160,16 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
val irIdentityEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset, irOperator, context.irBuiltIns.eqeqeq,
val irIdentityEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset, irOperator,
context.irBuiltIns.eqeqeqSymbol,
irArgument0, irArgument1)
return when (irOperator) {
IrStatementOrigin.EQEQEQ ->
irIdentityEquals
IrStatementOrigin.EXCLEQEQ ->
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ, context.irBuiltIns.booleanNot,
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ,
context.irBuiltIns.booleanNotSymbol,
irIdentityEquals)
else ->
throw AssertionError("Unexpected identity operator $irOperator")
@@ -179,14 +182,17 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
val irEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset,
irOperator, context.irBuiltIns.eqeq, irArgument0, irArgument1)
irOperator,
context.irBuiltIns.eqeqSymbol,
irArgument0, irArgument1)
return when (irOperator) {
IrStatementOrigin.EQEQ ->
irEquals
IrStatementOrigin.EXCLEQ ->
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQ,
context.irBuiltIns.booleanNot, irEquals)
context.irBuiltIns.booleanNotSymbol,
irEquals)
else ->
throw AssertionError("Unexpected equality operator $irOperator")
}
@@ -198,15 +204,15 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val irCompareToCall = CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(compareToCall), origin)
val compareToZeroDescriptor = when (origin) {
IrStatementOrigin.LT -> context.irBuiltIns.lt0
IrStatementOrigin.LTEQ -> context.irBuiltIns.lteq0
IrStatementOrigin.GT -> context.irBuiltIns.gt0
IrStatementOrigin.GTEQ -> context.irBuiltIns.gteq0
val compareToZeroSymbol = when (origin) {
IrStatementOrigin.LT -> context.irBuiltIns.lt0Symbol
IrStatementOrigin.LTEQ -> context.irBuiltIns.lteq0Symbol
IrStatementOrigin.GT -> context.irBuiltIns.gt0Symbol
IrStatementOrigin.GTEQ -> context.irBuiltIns.gteq0Symbol
else -> throw AssertionError("Unexpected comparison operator: $origin")
}
return IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, origin, compareToZeroDescriptor, irCompareToCall)
return IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, origin, compareToZeroSymbol, irCompareToCall)
}
private fun generateExclExclOperator(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
@@ -217,8 +223,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val resultType = irArgument.type.makeNotNullable()
return irBlock(ktOperator, origin, resultType) {
val temporary = defineTemporary(irArgument, "notnull")
+irIfNull(resultType, irGet(temporary), irThrowNpe(origin), irGet(temporary))
val temporary = irTemporary(irArgument, "notnull")
+irIfNull(resultType, irGet(temporary.symbol), irThrowNpe(origin), irGet(temporary.symbol))
}
}
@@ -41,8 +41,7 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
generateSimpleProperty(ktProperty, propertyDescriptor)
}
fun generatePropertyForPrimaryConstructorParameter(ktParameter: KtParameter): IrDeclaration {
val valueParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
fun generatePropertyForPrimaryConstructorParameter(ktParameter: KtParameter, irValueParameter: IrValueParameter): IrDeclaration {
val propertyDescriptor = getOrFail(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, ktParameter)
return IrPropertyImpl(
@@ -54,18 +53,19 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
generatePropertyBackingField(ktParameter, propertyDescriptor) {
IrExpressionBodyImpl(IrGetValueImpl(
ktParameter.startOffset, ktParameter.endOffset,
valueParameterDescriptor, IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
irValueParameter.symbol,
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
))
}
val getter = propertyDescriptor.getter ?:
throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
irProperty.getter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter, isGetter = true)
irProperty.getter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter)
if (propertyDescriptor.isVar) {
val setter = propertyDescriptor.setter ?:
throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
irProperty.setter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktParameter, isGetter = false)
irProperty.setter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktParameter)
}
}
}
@@ -73,21 +73,24 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
private inline fun generatePropertyBackingField(
ktPropertyElement: KtElement,
propertyDescriptor: PropertyDescriptor,
generateInitializer: () -> IrExpressionBody?
generateInitializer: (IrField) -> IrExpressionBody?
) : IrField =
context.symbolTable.declareField(
ktPropertyElement.startOffset, ktPropertyElement.endOffset,
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
propertyDescriptor,
generateInitializer()
)
propertyDescriptor
).also {
it.initializer = generateInitializer(it)
}
private fun generateDelegatedProperty(ktProperty: KtProperty, ktDelegate: KtPropertyDelegate, propertyDescriptor: PropertyDescriptor): IrProperty {
val ktDelegateExpression = ktDelegate.expression!!
val irDelegateInitializer = declarationGenerator.generateInitializerBody(propertyDescriptor, ktDelegateExpression)
return DelegatedPropertyGenerator(declarationGenerator).generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor, irDelegateInitializer)
}
private fun generateDelegatedProperty(
ktProperty: KtProperty,
ktDelegate: KtPropertyDelegate,
propertyDescriptor: PropertyDescriptor
): IrProperty =
DelegatedPropertyGenerator(declarationGenerator)
.generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor)
private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrProperty =
IrPropertyImpl(
@@ -97,8 +100,10 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
).apply {
backingField =
if (propertyDescriptor.hasBackingField())
generatePropertyBackingField(ktProperty, propertyDescriptor) {
ktProperty.initializer?.let { declarationGenerator.generateInitializerBody(propertyDescriptor, it) }
generatePropertyBackingField(ktProperty, propertyDescriptor) { irField ->
ktProperty.initializer?.let { ktInitializer ->
declarationGenerator.generateInitializerBody(irField.symbol, ktInitializer)
}
}
else
null
@@ -16,17 +16,17 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetClassImpl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
@@ -43,15 +43,19 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor
val typeClass = typeConstructorDeclaration as? ClassifierDescriptor ?:
throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
IrClassReferenceImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType, typeClass)
IrClassReferenceImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
context.symbolTable.referenceClassifier(typeClass))
}
}
fun generateCallableReference(ktCallableReference: KtCallableReferenceExpression): IrExpression {
val resolvedCall = getResolvedCall(ktCallableReference.callableReference)!!
val irCallableRef = IrCallableReferenceImpl(ktCallableReference.startOffset, ktCallableReference.endOffset,
getInferredTypeWithImplicitCastsOrFail(ktCallableReference),
resolvedCall.resultingDescriptor, null)
val irCallableRef = generateCallableReference(
ktCallableReference.startOffset, ktCallableReference.endOffset,
getInferredTypeWithImplicitCastsOrFail(ktCallableReference),
resolvedCall.resultingDescriptor,
typeArguments = null
)
resolvedCall.dispatchReceiver?.let { dispatchReceiver ->
if (dispatchReceiver !is TransientReceiver) {
irCallableRef.dispatchReceiver = statementGenerator.generateReceiver(ktCallableReference, dispatchReceiver).load()
@@ -66,5 +70,64 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
return irCallableRef
}
fun generateCallableReference(
startOffset: Int,
endOffset: Int,
type: KotlinType,
callableDescriptor: CallableDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null
): IrCallableReference =
when (callableDescriptor) {
is FunctionDescriptor ->
generateFunctionReference(
startOffset, endOffset, type,
context.symbolTable.referenceFunction(callableDescriptor),
typeArguments,
origin
)
is PropertyDescriptor ->
generatePropertyReference(startOffset, endOffset, type, callableDescriptor, typeArguments, origin)
else ->
throw AssertionError("Unexpected callable reference: $callableDescriptor")
}
private fun generatePropertyReference(
startOffset: Int,
endOffset: Int,
type: KotlinType,
propertyDescriptor: PropertyDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin?
): IrPropertyReference {
val getterDescriptor = propertyDescriptor.getter
val setterDescriptor = propertyDescriptor.setter
val fieldSymbol = if (getterDescriptor == null) context.symbolTable.referenceField(propertyDescriptor) else null
val getterSymbol = getterDescriptor?.let { context.symbolTable.referenceFunction(it) }
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it) }
return IrPropertyReferenceImpl(
startOffset, endOffset, type,
propertyDescriptor,
fieldSymbol, getterSymbol, setterSymbol,
typeArguments,
origin
)
}
fun generateFunctionReference(
startOffset: Int,
endOffset: Int,
type: KotlinType,
symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin?
): IrFunctionReference =
IrFunctionReferenceImpl(
startOffset, endOffset, type,
symbol,
typeArguments,
origin
)
}
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeAliasImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -74,7 +75,8 @@ class StatementGenerator(
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property)
property.delegate?.let { ktDelegate ->
return generateLocalDelegatedProperty(property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors)
return generateLocalDelegatedProperty(property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors,
bodyGenerator.scopeOwnerSymbol)
}
return context.symbolTable.declareVariable(
@@ -86,12 +88,11 @@ class StatementGenerator(
private fun generateLocalDelegatedProperty(
ktProperty: KtProperty,
ktDelegate: KtPropertyDelegate,
variableDescriptor: VariableDescriptorWithAccessors
variableDescriptor: VariableDescriptorWithAccessors,
scopeOwnerSymbol: IrSymbol
): IrStatement =
DelegatedPropertyGenerator(context).generateLocalDelegatedProperty(
ktProperty, ktDelegate, variableDescriptor,
ktDelegate.expression!!.genExpr()
)
DelegatedPropertyGenerator(context)
.generateLocalDelegatedProperty(ktProperty, ktDelegate, variableDescriptor, scopeOwnerSymbol)
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
val irBlock = IrCompositeImpl(multiDeclaration.startOffset, multiDeclaration.endOffset,
@@ -144,8 +145,10 @@ class StatementGenerator(
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
val returnTarget = getReturnExpressionTarget(expression)
val irReturnedExpression = expression.returnedExpression?.genExpr() ?:
IrGetObjectValueImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, context.builtIns.unit)
return IrReturnImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType, returnTarget, irReturnedExpression)
IrGetObjectValueImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType,
context.symbolTable.referenceClass(context.builtIns.unit))
return IrReturnImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType,
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression)
}
private fun scopeOwnerAsCallable() =
@@ -297,10 +300,12 @@ class StatementGenerator(
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
return when (referenceTarget) {
is ClassDescriptor ->
IrGetValueImpl(expression.startOffset, expression.endOffset, referenceTarget.thisAsReceiverParameter)
IrGetValueImpl(expression.startOffset, expression.endOffset,
context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter))
is CallableDescriptor -> {
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
IrGetValueImpl(expression.startOffset, expression.endOffset, extensionReceiver)
IrGetValueImpl(expression.startOffset, expression.endOffset,
context.symbolTable.referenceValueParameter(extensionReceiver))
}
else ->
error("Expected this or receiver: $referenceTarget")
@@ -98,6 +98,18 @@ class SymbolTable {
operator fun set(d: D, s: S) {
descriptorToSymbol[d] = s
}
fun dumpTo(stringBuilder: StringBuilder): StringBuilder =
stringBuilder.also {
it.append("owner=")
it.append(owner)
it.append("; ")
descriptorToSymbol.keys.joinTo(prefix = "[", postfix = "]", buffer = it)
it.append('\n')
parent?.dumpTo(it)
}
fun dump(): String = dumpTo(StringBuilder()).toString()
}
private var currentScope: Scope? = null
@@ -131,9 +143,12 @@ class SymbolTable {
currentScope = currentScope?.parent
if (currentScope != null && unboundSymbols.isNotEmpty()) {
throw AssertionError("")
throw AssertionError("Local scope contains unbound symbols: ${unboundSymbols.joinToString { it.descriptor.toString() }}")
}
}
fun dump(): String =
currentScope?.dump() ?: "<none>"
}
private val classSymbolTable = FlatSymbolTable<ClassDescriptor, IrClass, IrClassSymbol>()
@@ -148,14 +163,11 @@ class SymbolTable {
private val scopedSymbolTables = listOf(typeParameterSymbolTable, valueParameterSymbolTable, variableSymbolTable)
fun declareFile(fileEntry: SourceManager.FileEntry, packageFragmentDescriptor: PackageFragmentDescriptor): IrFile =
IrFileImpl(
fileEntry, packageFragmentDescriptor,
IrFileSymbolImpl(packageFragmentDescriptor)
)
IrFileImpl(fileEntry, IrFileSymbolImpl(packageFragmentDescriptor))
fun declareAnonymousInitializer(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor): IrAnonymousInitializer =
IrAnonymousInitializerImpl(
startOffset, endOffset, origin, descriptor,
startOffset, endOffset, origin,
IrAnonymousInitializerSymbolImpl(descriptor)
)
@@ -163,7 +175,7 @@ class SymbolTable {
classSymbolTable.declare(
descriptor,
{ IrClassSymbolImpl(descriptor) },
{ IrClassImpl(startOffset, endOffset, origin, descriptor, it) }
{ IrClassImpl(startOffset, endOffset, origin, it) }
)
@@ -176,7 +188,7 @@ class SymbolTable {
constructorSymbolTable.declare(
descriptor,
{ IrConstructorSymbolImpl(descriptor) },
{ IrConstructorImpl(startOffset, endOffset, origin, descriptor, it) }
{ IrConstructorImpl(startOffset, endOffset, origin, it) }
)
fun referenceConstructor(descriptor: ClassConstructorDescriptor) =
@@ -188,7 +200,7 @@ class SymbolTable {
enumEntrySymbolTable.declare(
descriptor,
{ IrEnumEntrySymbolImpl(descriptor) },
{ IrEnumEntryImpl(startOffset, endOffset, origin, descriptor, it) }
{ IrEnumEntryImpl(startOffset, endOffset, origin, it) }
)
fun referenceEnumEntry(descriptor: ClassDescriptor) =
@@ -200,7 +212,7 @@ class SymbolTable {
fieldSymbolTable.declare(
descriptor,
{ IrFieldSymbolImpl(descriptor) },
{ IrFieldImpl(startOffset, endOffset, origin, descriptor, it) }
{ IrFieldImpl(startOffset, endOffset, origin, it) }
)
fun declareField(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor,
@@ -216,23 +228,26 @@ class SymbolTable {
simpleFunctionSymbolTable.declare(
descriptor,
{ IrSimpleFunctionSymbolImpl(descriptor) },
{ IrFunctionImpl(startOffset, endOffset, origin, descriptor, it) }
{ IrFunctionImpl(startOffset, endOffset, origin, it) }
)
fun referenceSimpleFunction(descriptor: FunctionDescriptor) =
simpleFunctionSymbolTable.referenced(descriptor) { IrSimpleFunctionSymbolImpl(descriptor) }
fun referenceDeclaredFunction(descriptor: FunctionDescriptor) =
simpleFunctionSymbolTable.referenced(descriptor) { throw AssertionError("Function is not declared: $descriptor") }
val unboundSimpleFunctions: Set<IrSimpleFunctionSymbol> get() = simpleFunctionSymbolTable.unboundSymbols
fun declareTypeParameter(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: TypeParameterDescriptor) : IrTypeParameter =
typeParameterSymbolTable.declareLocal(
descriptor,
{ IrTypeParameterSymbolImpl(descriptor) },
{ IrTypeParameterImpl(startOffset, endOffset, origin, descriptor, it) }
{ IrTypeParameterImpl(startOffset, endOffset, origin, it) }
)
fun referenceTypeParameter(descriptor: TypeParameterDescriptor) =
typeParameterSymbolTable.referenced(descriptor) { IrTypeParameterSymbolImpl(descriptor) }
typeParameterSymbolTable.referenced(descriptor) { throw AssertionError("Undefined type parameter referenced: $descriptor") }
val unboundTypeParameters: Set<IrTypeParameterSymbol> get() = typeParameterSymbolTable.unboundSymbols
@@ -240,11 +255,13 @@ class SymbolTable {
valueParameterSymbolTable.declareLocal(
descriptor,
{ IrValueParameterSymbolImpl(descriptor) },
{ IrValueParameterImpl(startOffset, endOffset, origin, descriptor, it) }
{ IrValueParameterImpl(startOffset, endOffset, origin, it) }
)
fun referenceValueParameter(descriptor: ParameterDescriptor) =
valueParameterSymbolTable.referenced(descriptor) { IrValueParameterSymbolImpl(descriptor) }
valueParameterSymbolTable.referenced(descriptor) {
throw AssertionError("Undefined parameter referenced: $descriptor\n${valueParameterSymbolTable.dump()}")
}
val unboundValueParameters: Set<IrValueParameterSymbol> get() = valueParameterSymbolTable.unboundSymbols
@@ -252,18 +269,20 @@ class SymbolTable {
variableSymbolTable.declareLocal(
descriptor,
{ IrVariableSymbolImpl(descriptor) },
{ IrVariableImpl(startOffset, endOffset, origin, descriptor, it) }
{ IrVariableImpl(startOffset, endOffset, origin, it) }
)
fun declareVariable(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: VariableDescriptor,
irInitializerExpression: IrExpression?
fun declareVariable(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
descriptor: VariableDescriptor,
irInitializerExpression: IrExpression?
): IrVariable =
declareVariable(startOffset, endOffset, origin, descriptor).apply {
initializer = irInitializerExpression
}
fun referenceVariable(descriptor: VariableDescriptor) =
variableSymbolTable.referenced(descriptor) { IrVariableSymbolImpl(descriptor) }
variableSymbolTable.referenced(descriptor) { throw AssertionError("Undefined variable referenced: $descriptor") }
val unboundVariables: Set<IrVariableSymbol> get() = variableSymbolTable.unboundSymbols
@@ -274,6 +293,36 @@ class SymbolTable {
fun leaveScope(owner: DeclarationDescriptor) {
scopedSymbolTables.forEach { it.leaveScope(owner) }
}
fun referenceFunction(callable: CallableDescriptor): IrFunctionSymbol =
when (callable) {
is ClassConstructorDescriptor ->
constructorSymbolTable.referenced(callable) { IrConstructorSymbolImpl(callable) }
is FunctionDescriptor ->
simpleFunctionSymbolTable.referenced(callable) { IrSimpleFunctionSymbolImpl(callable) }
else ->
throw IllegalArgumentException("Unexpected callable descriptor: $callable")
}
fun referenceValue(value: ValueDescriptor): IrValueSymbol =
when (value) {
is ParameterDescriptor ->
valueParameterSymbolTable.referenced(value) { throw AssertionError("Undefined parameter referenced: $value") }
is VariableDescriptor ->
variableSymbolTable.referenced(value) { throw AssertionError("Undefined variable referenced: $value") }
else ->
throw IllegalArgumentException("Unexpected value descriptor: $value")
}
fun referenceClassifier(classifier: ClassifierDescriptor): IrClassifierSymbol =
when (classifier) {
is TypeParameterDescriptor ->
typeParameterSymbolTable.referenced(classifier) { throw AssertionError("Undefined type parameter referenced: $classifier") }
is ClassDescriptor ->
classSymbolTable.referenced(classifier) { IrClassSymbolImpl(classifier) }
else ->
throw IllegalArgumentException("Unexpected classifier descriptor: $classifier")
}
}
inline fun <T> SymbolTable.withScope(owner: DeclarationDescriptor, block: () -> T): T {
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCatchImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl
@@ -36,8 +38,16 @@ class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val ktCatchBody = ktCatchClause.catchBody!!
val catchParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktCatchParameter)
val irCatchResult = statementGenerator.generateExpression(ktCatchBody)
val irCatch = IrCatchImpl(ktCatchClause.startOffset, ktCatchClause.endOffset,
catchParameterDescriptor, irCatchResult)
val irCatch = IrCatchImpl(
ktCatchClause.startOffset, ktCatchClause.endOffset,
context.symbolTable.declareVariable(
ktCatchParameter.startOffset, ktCatchParameter.endOffset,
IrDeclarationOrigin.CATCH_PARAMETER,
catchParameterDescriptor
),
irCatchResult
)
irTryCatch.catches.add(irCatch)
}
@@ -16,27 +16,26 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.types.KotlinType
class BackingFieldLValue(
val startOffset: Int,
val endOffset: Int,
val descriptor: PropertyDescriptor,
override val type: KotlinType,
val symbol: IrFieldSymbol,
val receiver: IntermediateValue?,
val origin: IrStatementOrigin?
) : LValue, AssignmentReceiver {
override val type: KotlinType get() = descriptor.type
override fun store(irExpression: IrExpression): IrExpression =
IrSetFieldImpl(startOffset, endOffset, descriptor, receiver?.load(), irExpression, origin)
IrSetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), irExpression, origin)
override fun load(): IrExpression =
IrGetFieldImpl(startOffset, endOffset, descriptor, receiver?.load(), origin)
IrGetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), origin)
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
withLValue(this)
@@ -16,25 +16,25 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.types.KotlinType
class DelegatedLocalPropertyLValue(
val startOffset: Int,
val endOffset: Int,
val descriptor: VariableDescriptorWithAccessors,
override val type: KotlinType,
val getterSymbol: IrSimpleFunctionSymbol?,
val setterSymbol: IrSimpleFunctionSymbol?,
val origin: IrStatementOrigin? = null
) : LValue, AssignmentReceiver {
override val type: KotlinType get() = descriptor.type
override fun load(): IrExpression =
IrCallImpl(startOffset, endOffset, descriptor.type, descriptor.getter!!, null, origin)
IrCallImpl(startOffset, endOffset, type, getterSymbol!!, null, origin)
override fun store(irExpression: IrExpression): IrExpression =
IrCallImpl(startOffset, endOffset, descriptor.type, descriptor.setter!!, null, origin).apply {
IrCallImpl(startOffset, endOffset, type, setterSymbol!!, null, origin).apply {
putValueArgument(0, irExpression)
}
@@ -32,7 +32,8 @@ class LValueWithGetterAndSetterCalls(
val origin: IrStatementOrigin? = null
) : LValue {
private val descriptor: CallableDescriptor =
getterCall?.descriptor ?: setterCall?.descriptor ?:
getterCall?.descriptor ?:
setterCall?.descriptor ?:
throw AssertionError("Call-based LValue should have either a getter or a setter call")
override fun load(): IrExpression {
@@ -0,0 +1,155 @@
/*
* 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.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.types.KotlinType
abstract class PropertyLValueBase(
val scope: Scope,
val startOffset: Int,
val endOffset: Int,
val origin: IrStatementOrigin?,
override val type: KotlinType,
val callReceiver: CallReceiver,
val superQualifier: IrClassSymbol?
) : LValue, AssignmentReceiver {
override fun assign(withLValue: (LValue) -> IrExpression) =
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
val dispatchReceiverVariable2 = dispatchReceiverValue?.let {
scope.createTemporaryVariable(dispatchReceiverValue.load(), "this")
}
val dispatchReceiverValue2 = dispatchReceiverVariable2?.let { VariableLValue(it) }
val extensionReceiverVariable2 = extensionReceiverValue?.let {
scope.createTemporaryVariable(extensionReceiverValue.load(), "receiver")
}
val extensionReceiverValue2 = extensionReceiverVariable2?.let { VariableLValue(it) }
val irResultExpression = withLValue(withReceiver(dispatchReceiverValue2, extensionReceiverValue2))
val irBlock = IrBlockImpl(startOffset, endOffset, irResultExpression.type, origin)
irBlock.addIfNotNull(dispatchReceiverVariable2)
irBlock.addIfNotNull(extensionReceiverVariable2)
irBlock.statements.add(irResultExpression)
irBlock
}
override fun assign(value: IrExpression): IrExpression =
store(value)
protected abstract fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase
}
class FieldPropertyLValue(
scope: Scope,
startOffset: Int,
endOffset: Int,
origin: IrStatementOrigin?,
val field: IrFieldSymbol,
callReceiver: CallReceiver,
superQualifier: IrClassSymbol?
) : PropertyLValueBase(scope, startOffset, endOffset, origin, field.descriptor.type, callReceiver, superQualifier) {
override fun load(): IrExpression =
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
assert(extensionReceiverValue == null) { "Field can't have an extension receiver: ${field.descriptor}" }
IrGetFieldImpl(
startOffset, endOffset,
field,
dispatchReceiverValue?.load(),
origin,
superQualifier
)
}
override fun store(irExpression: IrExpression) =
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
assert(extensionReceiverValue == null) { "Field can't have an extension receiver: ${field.descriptor}" }
IrSetFieldImpl(
startOffset, endOffset,
field,
dispatchReceiverValue?.load(),
irExpression,
origin,
superQualifier
)
}
override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase =
FieldPropertyLValue(
scope, startOffset, endOffset, origin,
field,
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
superQualifier
)
}
class AccessorPropertyLValue(
scope: Scope,
startOffset: Int,
endOffset: Int,
origin: IrStatementOrigin?,
type: KotlinType,
val getter: IrFunctionSymbol?,
val setter: IrFunctionSymbol?,
val typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
callReceiver: CallReceiver,
superQualifier: IrClassSymbol?
) : PropertyLValueBase(scope, startOffset, endOffset, origin, type, callReceiver, superQualifier) {
override fun load(): IrExpression =
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
IrGetterCallImpl(
startOffset, endOffset,
getter!!,
typeArguments,
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
origin,
superQualifier
)
}
override fun store(irExpression: IrExpression) =
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
IrSetterCallImpl(
startOffset, endOffset,
setter!!,
typeArguments,
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
irExpression,
origin,
superQualifier
)
}
override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase =
AccessorPropertyLValue(
scope, startOffset, endOffset, origin,
type, getter, setter,
typeArguments,
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
superQualifier
)
}
@@ -1,94 +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.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.types.KotlinType
class SimplePropertyLValue(
val context: GeneratorContext,
val scope: Scope,
val startOffset: Int,
val endOffset: Int,
val origin: IrStatementOrigin?,
val descriptor: PropertyDescriptor,
val typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
val callReceiver: CallReceiver,
val superQualifier: ClassDescriptor?
) : LValue, AssignmentReceiver {
override val type: KotlinType get() = descriptor.type
override fun load(): IrExpression =
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
descriptor.getter?.let { getter ->
IrGetterCallImpl(startOffset, endOffset, getter, typeArguments,
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
origin,
superQualifier)
} ?: IrGetFieldImpl(startOffset, endOffset, descriptor,
dispatchReceiverValue?.load(), origin, superQualifier)
}
override fun store(irExpression: IrExpression) =
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
descriptor.setter?.let { setter ->
IrSetterCallImpl(startOffset, endOffset, setter, typeArguments,
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
irExpression,
origin,
superQualifier)
} ?: IrSetFieldImpl(startOffset, endOffset, descriptor,
dispatchReceiverValue?.load(), irExpression, origin, superQualifier)
}
override fun assign(withLValue: (LValue) -> IrExpression) =
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
val dispatchReceiverTmp = dispatchReceiverValue?.let {
scope.createTemporaryVariable(dispatchReceiverValue.load(), "this")
}
val dispatchReceiverValue2 = dispatchReceiverTmp?.let { VariableLValue(it) }
val extensionReceiverTmp = extensionReceiverValue?.let {
scope.createTemporaryVariable(extensionReceiverValue.load(), "receiver")
}
val extensionReceiverValue2 = extensionReceiverTmp?.let { VariableLValue(it) }
val irResultExpression = withLValue(
SimplePropertyLValue(context, scope, startOffset, endOffset, origin, descriptor, typeArguments,
SimpleCallReceiver(dispatchReceiverValue2, extensionReceiverValue2),
superQualifier)
)
val irBlock = IrBlockImpl(startOffset, endOffset, irResultExpression.type, origin)
irBlock.addIfNotNull(dispatchReceiverTmp)
irBlock.addIfNotNull(extensionReceiverTmp)
irBlock.statements.add(irResultExpression)
irBlock
}
override fun assign(value: IrExpression): IrExpression =
store(value)
}
@@ -16,30 +16,36 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetVariableImpl
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
class VariableLValue(
val startOffset: Int,
val endOffset: Int,
val descriptor: VariableDescriptor,
val symbol: IrValueSymbol,
val origin: IrStatementOrigin? = null
) : LValue, AssignmentReceiver {
constructor(irVariable: IrVariable, origin: IrStatementOrigin? = null) : this(
irVariable.startOffset, irVariable.endOffset, irVariable.descriptor, origin)
irVariable.startOffset, irVariable.endOffset, irVariable.symbol, origin)
override val type: KotlinType get() = descriptor.type
override val type: KotlinType get() = symbol.descriptor.type
override fun load(): IrExpression =
IrGetValueImpl(startOffset, endOffset, descriptor, origin)
IrGetValueImpl(startOffset, endOffset, symbol, origin)
override fun store(irExpression: IrExpression): IrExpression =
IrSetVariableImpl(startOffset, endOffset, descriptor, irExpression, origin)
IrSetVariableImpl(
startOffset, endOffset,
symbol.assertedCast<IrVariableSymbol> { "Not a variable: ${symbol.descriptor}" },
irExpression, origin
)
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
withLValue(this)
@@ -50,10 +50,19 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
return element
}
override fun visitCallableReference(expression: IrCallableReference): IrExpression =
expression.transformPostfix {
transformReceiverArguments()
}
private fun IrMemberAccessExpression.transformReceiverArguments() {
dispatchReceiver = dispatchReceiver?.cast(descriptor.dispatchReceiverParameter?.type)
extensionReceiver = extensionReceiver?.cast(descriptor.extensionReceiverParameter?.type)
}
override fun visitMemberAccess(expression: IrMemberAccessExpression): IrExpression =
expression.transformPostfix {
dispatchReceiver = dispatchReceiver?.cast(descriptor.dispatchReceiverParameter?.type)
extensionReceiver = extensionReceiver?.cast(descriptor.extensionReceiverParameter?.type)
transformReceiverArguments()
for (index in descriptor.valueParameters.indices) {
val argument = getValueArgument(index) ?: continue
val parameterType = descriptor.valueParameters[index].type
@@ -16,16 +16,16 @@
package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
inline fun IrBuilderWithScope.irLet(
@@ -42,12 +42,40 @@ inline fun IrBuilderWithScope.irLet(
return irBlock
}
inline fun IrBuilderWithScope.irLetS(
value: IrExpression,
origin: IrStatementOrigin? = null,
nameHint: String? = null,
body: (IrValueSymbol) -> IrExpression
): IrExpression {
val irTemporary = scope.createTemporaryVariable(value, nameHint)
val irResult = body(irTemporary.symbol)
val irBlock = IrBlockImpl(startOffset, endOffset, irResult.type, origin)
irBlock.statements.add(irTemporary)
irBlock.statements.add(irResult)
return irBlock
}
fun <T : IrElement> IrStatementsBuilder<T>.irTemporary(value: IrExpression, nameHint: String? = null): IrVariable {
val temporary = scope.createTemporaryVariable(value, nameHint)
+temporary
return temporary
}
fun <T : IrElement> IrStatementsBuilder<T>.defineTemporary(value: IrExpression, nameHint: String? = null): VariableDescriptor {
val temporary = scope.createTemporaryVariable(value, nameHint)
+temporary
return temporary.descriptor
}
fun <T : IrElement> IrStatementsBuilder<T>.irTemporaryVar(value: IrExpression, nameHint: String? = null): IrVariable {
val temporary = scope.createTemporaryVariable(value, nameHint, isMutable = true)
+temporary
return temporary
}
fun <T : IrElement> IrStatementsBuilder<T>.defineTemporaryVar(value: IrExpression, nameHint: String? = null): VariableDescriptor {
val temporary = scope.createTemporaryVariable(value, nameHint, isMutable = true)
+temporary
@@ -58,7 +86,11 @@ fun IrBuilderWithScope.irExprBody(value: IrExpression) =
IrExpressionBodyImpl(startOffset, endOffset, value)
fun IrBuilderWithScope.irReturn(value: IrExpression) =
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, scope.assertCastOwner(), value)
IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType,
scope.scopeOwnerSymbol.assertedCast<IrFunctionSymbol> {
"Function scope expected: ${scope.scopeOwner}"
},
value)
fun IrBuilderWithScope.irReturnTrue() =
irReturn(IrConstImpl(startOffset, endOffset, context.builtIns.booleanType, IrConstKind.Boolean, true))
@@ -73,7 +105,7 @@ fun IrBuilderWithScope.irIfNull(type: KotlinType, subject: IrExpression, thenPar
irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart)
fun IrBuilderWithScope.irThrowNpe(origin: IrStatementOrigin) =
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, context.irBuiltIns.throwNpe)
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, context.irBuiltIns.throwNpeSymbol)
fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnTrue())
@@ -81,20 +113,12 @@ fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) =
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnFalse())
fun IrBuilderWithScope.irThis() =
scope.classOwner().let { classOwner ->
IrGetValueImpl(startOffset, endOffset, classOwner.thisAsReceiverParameter)
}
fun IrBuilderWithScope.irGet(variable: VariableDescriptor) =
fun IrBuilderWithScope.irGet(variable: IrValueSymbol) =
IrGetValueImpl(startOffset, endOffset, variable)
fun IrBuilderWithScope.irSetVar(variable: VariableDescriptor, value: IrExpression) =
fun IrBuilderWithScope.irSetVar(variable: IrVariableSymbol, value: IrExpression) =
IrSetVariableImpl(startOffset, endOffset, variable, value, IrStatementOrigin.EQ)
fun IrBuilderWithScope.irOther() =
irGet(scope.functionOwner().valueParameters.single())
fun IrBuilderWithScope.irEqeqeq(arg1: IrExpression, arg2: IrExpression) =
context.eqeqeq(startOffset, endOffset, arg1, arg2)
@@ -102,22 +126,28 @@ fun IrBuilderWithScope.irNull() =
IrConstImpl.constNull(startOffset, endOffset, context.builtIns.nullableNothingType)
fun IrBuilderWithScope.irEqualsNull(argument: IrExpression) =
primitiveOp2(startOffset, endOffset, context.irBuiltIns.eqeq, IrStatementOrigin.EQEQ,
primitiveOp2(startOffset, endOffset, context.irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ,
argument, irNull())
fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) =
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNot, IrStatementOrigin.EXCLEQ,
primitiveOp2(startOffset, endOffset, context.irBuiltIns.eqeq, IrStatementOrigin.EXCLEQ,
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCLEQ,
primitiveOp2(startOffset, endOffset, context.irBuiltIns.eqeqSymbol, IrStatementOrigin.EXCLEQ,
arg1, arg2))
fun IrBuilderWithScope.irGet(receiver: IrExpression, property: PropertyDescriptor): IrExpression =
IrGetterCallImpl(startOffset, endOffset, property.getter!!, null, receiver, null, IrStatementOrigin.GET_PROPERTY)
fun IrBuilderWithScope.irGet(receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall =
IrGetterCallImpl(startOffset, endOffset, getterSymbol, null, receiver, null, IrStatementOrigin.GET_PROPERTY)
fun IrBuilderWithScope.irCall(callee: CallableDescriptor) =
IrCallImpl(startOffset, endOffset, callee.returnType!!, callee, null)
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, type: KotlinType): IrCall =
IrCallImpl(startOffset, endOffset, type, callee, null)
fun IrBuilderWithScope.irCallOp(callee: CallableDescriptor, dispatchReceiver: IrExpression, argument: IrExpression) =
IrCallImpl(startOffset, endOffset, callee.returnType!!, callee, null).apply {
fun IrBuilderWithScope.irCallOp(callee: IrFunctionSymbol, dispatchReceiver: IrExpression, argument: IrExpression): IrCall =
irCall(callee, callee.descriptor.returnType!!).apply {
this.dispatchReceiver = dispatchReceiver
putValueArgument(0, argument)
}
fun IrBuilderWithScope.irCallOp(callee: IrFunctionSymbol, type: KotlinType, dispatchReceiver: IrExpression, argument: IrExpression): IrCall =
irCall(callee, type).apply {
this.dispatchReceiver = dispatchReceiver
putValueArgument(0, argument)
}
@@ -16,32 +16,38 @@
package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrWhen
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
fun primitiveOp1(startOffset: Int, endOffset: Int, primitiveOpDescriptor: CallableDescriptor, origin: IrStatementOrigin,
argument: IrExpression): IrExpression =
IrUnaryPrimitiveImpl(startOffset, endOffset, origin, primitiveOpDescriptor, argument)
fun primitiveOp1(startOffset: Int, endOffset: Int,
primitiveOpSymbol: IrSimpleFunctionSymbol,
origin: IrStatementOrigin,
argument: IrExpression
): IrExpression =
IrUnaryPrimitiveImpl(startOffset, endOffset, origin, primitiveOpSymbol, argument)
fun primitiveOp2(startOffset: Int, endOffset: Int, primitiveOpDescriptor: CallableDescriptor, origin: IrStatementOrigin,
argument1: IrExpression, argument2: IrExpression): IrExpression =
IrBinaryPrimitiveImpl(startOffset, endOffset, origin, primitiveOpDescriptor, argument1, argument2)
fun primitiveOp2(startOffset: Int, endOffset: Int,
primitiveOpSymbol: IrSimpleFunctionSymbol,
origin: IrStatementOrigin,
argument1: IrExpression, argument2: IrExpression
): IrExpression =
IrBinaryPrimitiveImpl(startOffset, endOffset, origin, primitiveOpSymbol, argument1, argument2)
fun IrGeneratorContext.constNull(startOffset: Int, endOffset: Int): IrExpression =
IrConstImpl.constNull(startOffset, endOffset, builtIns.nullableNothingType)
fun IrGeneratorContext.equalsNull(startOffset: Int, endOffset: Int, argument: IrExpression): IrExpression =
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeq, IrStatementOrigin.EQEQ,
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeqSymbol, IrStatementOrigin.EQEQ,
argument, constNull(startOffset, endOffset))
fun IrGeneratorContext.eqeqeq(startOffset: Int, endOffset: Int, argument1: IrExpression, argument2: IrExpression): IrExpression =
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeqeq, IrStatementOrigin.EQEQEQ, argument1, argument2)
primitiveOp2(startOffset, endOffset, irBuiltIns.eqeqeqSymbol, IrStatementOrigin.EQEQEQ, argument1, argument2)
fun IrGeneratorContext.throwNpe(startOffset: Int, endOffset: Int, origin: IrStatementOrigin): IrExpression =
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, irBuiltIns.throwNpe)
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, irBuiltIns.throwNpeSymbol)
// a || b == if (a) true else b
fun IrGeneratorContext.oror(startOffset: Int, endOffset: Int, a: IrExpression, b: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.OROR): IrWhen =
@@ -16,21 +16,35 @@
package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
class Scope(val scopeOwner: DeclarationDescriptor) {
class Scope(val scopeOwnerSymbol: IrSymbol) {
val scopeOwner: DeclarationDescriptor get() = scopeOwnerSymbol.descriptor
@Deprecated("Creates unbound symbol")
constructor(scopeOwner: ClassDescriptor) : this(IrClassSymbolImpl(scopeOwner))
@Deprecated("C")
private var lastTemporaryIndex: Int = 0
private fun nextTemporaryIndex(): Int = lastTemporaryIndex++
private fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null, isMutable: Boolean = false): IrTemporaryVariableDescriptor =
fun createDescriptorForTemporaryVariable(type: KotlinType, nameHint: String? = null, isMutable: Boolean = false): IrTemporaryVariableDescriptor =
IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier(getNameForTemporary(nameHint)), type, isMutable)
private fun getNameForTemporary(nameHint: String?): String {
@@ -45,3 +59,12 @@ class Scope(val scopeOwner: DeclarationDescriptor) {
irExpression
)
}
@Deprecated("Creates unbound symbol")
fun Scope(descriptor: DeclarationDescriptor) =
when (descriptor) {
is ClassDescriptor -> Scope(IrClassSymbolImpl(descriptor))
is FunctionDescriptor -> Scope(createFunctionSymbol(descriptor))
is PropertyDescriptor -> Scope(IrFieldSymbolImpl(descriptor))
else -> throw AssertionError("Unexpected scopeOwner descriptor: $descriptor")
}
@@ -28,8 +28,10 @@ fun Scope.functionOwner(): FunctionDescriptor =
assertCastOwner()
fun Scope.classOwner(): ClassDescriptor =
when (scopeOwner) {
is ClassDescriptor -> scopeOwner
is MemberDescriptor -> scopeOwner.containingDeclaration as ClassDescriptor
else -> throw AssertionError("Unexpected scopeOwner: $scopeOwner")
scopeOwner.let {
when (it) {
is ClassDescriptor -> it
is MemberDescriptor -> it.containingDeclaration as ClassDescriptor
else -> throw AssertionError("Unexpected scopeOwner: $scopeOwner")
}
}
@@ -24,6 +24,8 @@ interface IrClass : IrSymbolDeclaration<IrClassSymbol>, IrDeclarationContainer,
get() = IrDeclarationKind.CLASS
override val descriptor: ClassDescriptor
var newInstanceReceiver: IrValueParameter?
}
fun IrClass.addMember(member: IrDeclaration) {
@@ -27,6 +27,8 @@ interface IrDeclarationOrigin {
object ENUM_CLASS_SPECIAL_MEMBER : IrDeclarationOriginImpl("ENUM_CLASS_SPECIAL_MEMBER")
object GENERATED_DATA_CLASS_MEMBER : IrDeclarationOriginImpl("GENERATED_DATA_CLASS_MEMBER")
object LOCAL_FUNCTION_FOR_LAMBDA : IrDeclarationOriginImpl("LOCAL_FUNCTION_FOR_LAMBDA")
object CATCH_PARAMETER : IrDeclarationOriginImpl("CATCH_PARAMETER")
object NEW_INSTANCE_RECEIVER : IrDeclarationOriginImpl("NEW_INSTANCE_RECEIVER")
object IR_TEMPORARY_VARIABLE : IrDeclarationOriginImpl("IR_TEMPORARY_VARIABLE")
}
@@ -21,16 +21,27 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.checkAnnotationName
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.symbols.IrExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrPackageFragmentSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.name.FqName
interface IrFile : IrElement, IrDeclarationContainer, IrSymbolOwner {
interface IrPackageFragment : IrElement, IrDeclarationContainer, IrSymbolOwner {
val packageFragmentDescriptor: PackageFragmentDescriptor
override val symbol: IrPackageFragmentSymbol
}
interface IrExternalPackageFragment : IrPackageFragment {
override val symbol: IrExternalPackageFragmentSymbol
}
interface IrFile : IrPackageFragment {
override val symbol: IrFileSymbol
val fileEntry: SourceManager.FileEntry
val fileAnnotations: MutableList<AnnotationDescriptor>
val packageFragmentDescriptor: PackageFragmentDescriptor
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrFile =
accept(transformer, data) as IrFile
@@ -20,10 +20,12 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
interface IrFunction : IrDeclaration, IrTypeParametersContainer {
interface IrFunction : IrDeclaration, IrTypeParametersContainer, IrSymbolOwner {
override val descriptor: FunctionDescriptor
override val symbol : IrFunctionSymbol
var dispatchReceiverParameter: IrValueParameter?
var extensionReceiverParameter: IrValueParameter?
@@ -38,7 +40,6 @@ interface IrSimpleFunction : IrFunction, IrSymbolDeclaration<IrSimpleFunctionSym
get() = IrDeclarationKind.FUNCTION
}
fun IrFunction.getIrValueParameter(parameter: ValueParameterDescriptor): IrValueParameter =
valueParameters.getOrElse(parameter.index) {
throw AssertionError("No IrValueParameter for $parameter")
@@ -29,12 +29,10 @@ class IrAnonymousInitializerImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: ClassDescriptor,
override val symbol: IrAnonymousInitializerSymbol
) : IrDeclarationBase(startOffset, endOffset, origin), IrAnonymousInitializer {
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrAnonymousInitializerSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrAnonymousInitializerSymbolImpl(descriptor))
constructor(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
@@ -43,6 +41,8 @@ class IrAnonymousInitializerImpl(
this.body = body
}
override val descriptor: ClassDescriptor get() = symbol.descriptor
override lateinit var body: IrBlockBody
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -30,12 +30,10 @@ class IrClassImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: ClassDescriptor,
override val symbol: IrClassSymbol
) : IrDeclarationBase(startOffset, endOffset, origin), IrClass {
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrClassSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrClassSymbolImpl(descriptor))
constructor(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
@@ -44,6 +42,10 @@ class IrClassImpl(
addAll(members)
}
override val descriptor: ClassDescriptor get() = symbol.descriptor
override var newInstanceReceiver: IrValueParameter? = null
override val declarations: MutableList<IrDeclaration> = ArrayList()
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
@@ -52,11 +54,13 @@ class IrClassImpl(
visitor.visitClass(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
newInstanceReceiver?.accept(visitor, data)
typeParameters.forEach { it.accept(visitor, data) }
declarations.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
newInstanceReceiver = newInstanceReceiver?.transform(transformer, data)
typeParameters.transform { it.transform(transformer, data) }
declarations.transform { it.transform(transformer, data) as IrDeclaration }
}
@@ -19,19 +19,21 @@ package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
class IrConstructorImpl(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
override val descriptor: ClassConstructorDescriptor,
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val symbol: IrConstructorSymbol
) : IrFunctionBase(startOffset, endOffset, origin), IrConstructor {
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassConstructorDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrConstructorSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrConstructorSymbolImpl(descriptor))
constructor(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassConstructorDescriptor,
@@ -40,6 +42,8 @@ class IrConstructorImpl(
this.body = body
}
override val descriptor: ClassConstructorDescriptor get() = symbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitConstructor(this, data)
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
@@ -30,12 +31,10 @@ class IrEnumEntryImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: ClassDescriptor,
override val symbol: IrEnumEntrySymbol
) : IrDeclarationBase(startOffset, endOffset, origin), IrEnumEntry {
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrEnumEntrySymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrEnumEntrySymbolImpl(descriptor))
constructor(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassDescriptor,
@@ -45,6 +44,7 @@ class IrEnumEntryImpl(
this.initializerExpression = initializerExpression
}
override val descriptor: ClassDescriptor get() = symbol.descriptor
override var correspondingClass: IrClass? = null
override lateinit var initializerExpression: IrExpression
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2017 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.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
import org.jetbrains.kotlin.ir.symbols.IrExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
class IrExternalPackageFragmentImpl(
override val symbol: IrExternalPackageFragmentSymbol
) : IrExternalPackageFragment, IrElementBase(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
override val packageFragmentDescriptor: PackageFragmentDescriptor get() = symbol.descriptor
override val declarations: MutableList<IrDeclaration> = ArrayList()
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitExternalPackageFragment(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
declarations.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
declarations.forEachIndexed { i, irDeclaration ->
declarations[i] = irDeclaration.transform(transformer, data) as IrDeclaration
}
}
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
@@ -30,12 +31,10 @@ class IrFieldImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: PropertyDescriptor,
override val symbol: IrFieldSymbol
): IrDeclarationBase(startOffset, endOffset, origin), IrField {
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrFieldSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrFieldSymbolImpl(descriptor))
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor,
initializer: IrExpressionBody?
@@ -43,6 +42,8 @@ class IrFieldImpl(
this.initializer = initializer
}
override val descriptor: PropertyDescriptor = symbol.descriptor
override var initializer: IrExpressionBody? = null
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -31,12 +31,10 @@ import java.util.*
class IrFileImpl(
override val fileEntry: SourceManager.FileEntry,
override val packageFragmentDescriptor: PackageFragmentDescriptor,
override val symbol: IrFileSymbol
) : IrElementBase(0, fileEntry.maxOffset), IrFile {
constructor(fileEntry: SourceManager.FileEntry, packageFragmentDescriptor: PackageFragmentDescriptor)
: this(fileEntry, packageFragmentDescriptor,
IrFileSymbolImpl(packageFragmentDescriptor))
: this(fileEntry, IrFileSymbolImpl(packageFragmentDescriptor))
constructor(
fileEntry: SourceManager.FileEntry,
@@ -48,6 +46,8 @@ class IrFileImpl(
this.declarations.addAll(declarations)
}
override val packageFragmentDescriptor: PackageFragmentDescriptor get() = symbol.descriptor
override val fileAnnotations: MutableList<AnnotationDescriptor> = SmartList()
override val declarations: MutableList<IrDeclaration> = ArrayList()
@@ -28,12 +28,12 @@ class IrFunctionImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: FunctionDescriptor,
override val symbol: IrSimpleFunctionSymbol
) : IrFunctionBase(startOffset, endOffset, origin), IrSimpleFunction {
override val descriptor: FunctionDescriptor = symbol.descriptor
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: FunctionDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrSimpleFunctionSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrSimpleFunctionSymbolImpl(descriptor))
constructor(
startOffset: Int,
@@ -28,12 +28,12 @@ class IrTypeParameterImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: TypeParameterDescriptor,
override val symbol: IrTypeParameterSymbol
) : IrDeclarationBase(startOffset, endOffset, origin), IrTypeParameter {
override val descriptor: TypeParameterDescriptor get() = symbol.descriptor
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: TypeParameterDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrTypeParameterSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrTypeParameterSymbolImpl(descriptor))
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitTypeParameter(this, data)
@@ -29,12 +29,12 @@ class IrValueParameterImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: ParameterDescriptor,
override val symbol: IrValueParameterSymbol
) : IrDeclarationBase(startOffset, endOffset, origin), IrValueParameter {
override val descriptor: ParameterDescriptor = symbol.descriptor
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ParameterDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrValueParameterSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrValueParameterSymbolImpl(descriptor))
constructor(
startOffset: Int,
@@ -29,12 +29,10 @@ class IrVariableImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: VariableDescriptor,
override val symbol: IrVariableSymbol
) : IrDeclarationBase(startOffset, endOffset, origin), IrVariable {
constructor(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: VariableDescriptor) :
this(startOffset, endOffset, origin, descriptor,
IrVariableSymbolImpl(descriptor))
this(startOffset, endOffset, origin, IrVariableSymbolImpl(descriptor))
constructor(
startOffset: Int,
@@ -46,6 +44,8 @@ class IrVariableImpl(
this.initializer = initializer
}
override val descriptor: VariableDescriptor get() = symbol.descriptor
override var initializer: IrExpression? = null
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2017 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.ir.descriptors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
@@ -22,13 +22,44 @@ 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.ir.declarations.IrDeclarationOriginImpl
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
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.Variance
class BuiltinsOperatorsBuilder(val packageFragment: PackageFragmentDescriptor, val builtIns: KotlinBuiltIns) {
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule, KOTLIN_INTERNAL_IR_FQN)
val irBuiltInsExternalPackageFragment = IrExternalPackageFragmentImpl(IrExternalPackageFragmentSymbolImpl(packageFragment))
object IR_BUILTINS_STUB : IrDeclarationOriginImpl("IR_BUILTINS_STUB")
private val stubBuilder = IrDeclarationStubBuilder(IR_BUILTINS_STUB)
private fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrSimpleFunction {
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType)
for ((i, valueParameterType) in valueParameterTypes.withIndex()) {
operatorDescriptor.addValueParameter(
IrBuiltinValueParameterDescriptorImpl(operatorDescriptor, Name.identifier("arg$i"), i, valueParameterType)
)
}
return addStubToPackageFragment(operatorDescriptor)
}
private fun addStubToPackageFragment(descriptor: SimpleFunctionDescriptor): IrSimpleFunction {
val irSimpleFunction = stubBuilder.buildSimpleFunctionStub(IrSimpleFunctionSymbolImpl(descriptor))
irBuiltInsExternalPackageFragment.declarations.add(irSimpleFunction)
return irSimpleFunction
}
private fun <T : SimpleFunctionDescriptor> T.addStub(): IrSimpleFunction =
addStubToPackageFragment(this)
val bool = builtIns.booleanType
val any = builtIns.anyType
val anyN = builtIns.nullableAnyType
@@ -36,32 +67,37 @@ class BuiltinsOperatorsBuilder(val packageFragment: PackageFragmentDescriptor, v
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)
for ((i, valueParameterType) in valueParameterTypes.withIndex()) {
operatorDescriptor.addValueParameter(
IrBuiltinValueParameterDescriptorImpl(operatorDescriptor, Name.identifier("arg$i"), i, valueParameterType))
}
return operatorDescriptor
}
}
val eqeqeqFun = defineOperator("EQEQEQ", bool, listOf(anyN, anyN))
val eqeqFun = defineOperator("EQEQ", bool, listOf(anyN, anyN))
val lt0Fun = defineOperator("LT0", bool, listOf(int))
val lteq0Fun = defineOperator("LTEQ0", bool, listOf(int))
val gt0Fun = defineOperator("GT0", bool, listOf(int))
val gteq0Fun = defineOperator("GTEQ0", bool, listOf(int))
val throwNpeFun = defineOperator("THROW_NPE", nothing, listOf())
val booleanNotFun = defineOperator("NOT", bool, listOf(bool))
val noWhenBranchMatchedExceptionFun = defineOperator("noWhenBranchMatchedException", unit, listOf())
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule, KOTLIN_INTERNAL_IR_FQN)
private val builder = BuiltinsOperatorsBuilder(packageFragment, builtIns)
val eqeqeq = eqeqeqFun.descriptor
val eqeq = eqeqFun.descriptor
val lt0 = lt0Fun.descriptor
val lteq0 = lteq0Fun.descriptor
val gt0 = gt0Fun.descriptor
val gteq0 = gteq0Fun.descriptor
val throwNpe = throwNpeFun.descriptor
val booleanNot = booleanNotFun.descriptor
val noWhenBranchMatchedException = noWhenBranchMatchedExceptionFun.descriptor
val eqeqeq: FunctionDescriptor = builder.run { defineOperator("EQEQEQ", bool, listOf(anyN, anyN)) }
val eqeq: FunctionDescriptor = builder.run { defineOperator("EQEQ", bool, listOf(anyN, anyN)) }
val lt0: FunctionDescriptor = builder.run { defineOperator("LT0", bool, listOf(int)) }
val lteq0: FunctionDescriptor = builder.run { defineOperator("LTEQ0", bool, listOf(int)) }
val gt0: FunctionDescriptor = builder.run { defineOperator("GT0", bool, listOf(int)) }
val gteq0: FunctionDescriptor = builder.run { defineOperator("GTEQ0", bool, listOf(int)) }
val throwNpe: FunctionDescriptor = builder.run { defineOperator("THROW_NPE", nothing, listOf()) }
val booleanNot: FunctionDescriptor = builder.run { defineOperator("NOT", bool, listOf(bool)) }
val eqeqeqSymbol = eqeqeqFun.symbol
val eqeqSymbol = eqeqFun.symbol
val lt0Symbol = lt0Fun.symbol
val lteq0Symbol = lteq0Fun.symbol
val gt0Symbol = gt0Fun.symbol
val gteq0Symbol = gteq0Fun.symbol
val throwNpeSymbol = throwNpeFun.symbol
val booleanNotSymbol = booleanNotFun.symbol
val noWhenBranchMatchedExceptionSymbol = noWhenBranchMatchedExceptionFun.symbol
val noWhenBranchMatchedException: FunctionDescriptor = builder.run { defineOperator("noWhenBranchMatchedException", unit, listOf()) }
val enumValueOf: FunctionDescriptor =
val enumValueOfFun =
SimpleFunctionDescriptorImpl.create(
packageFragment,
Annotations.EMPTY,
@@ -81,7 +117,9 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) {
val returnType = KotlinTypeFactory.simpleType(Annotations.EMPTY, typeParameterT.typeConstructor, listOf(), false)
initialize(null, null, listOf(typeParameterT), listOf(valueParameterName), returnType, Modality.FINAL, Visibilities.PUBLIC)
}
}.addStub()
val enumValueOf = enumValueOfFun.descriptor
val enumValueOfSymbol = enumValueOfFun.symbol
companion object {
val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir")
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
import java.util.*
interface IrBuiltinOperatorDescriptor : FunctionDescriptor
interface IrBuiltinOperatorDescriptor : SimpleFunctionDescriptor
interface IrBuiltinValueParameterDescriptor : ValueParameterDescriptor
@@ -36,7 +36,7 @@ abstract class IrBuiltinOperatorDescriptorBase(containingDeclaration: Declaratio
{
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
override fun getExtensionReceiverParameter(): ReceiverParameterDescriptor? = null
override fun getOriginal(): FunctionDescriptor = this
override fun getOriginal(): SimpleFunctionDescriptor = this
override fun substitute(substitutor: TypeSubstitutor): FunctionDescriptor = throw UnsupportedOperationException()
override fun getOverriddenDescriptors(): Collection<FunctionDescriptor> = emptyList()
override fun setOverriddenDescriptors(overriddenDescriptors: Collection<CallableMemberDescriptor>) = throw UnsupportedOperationException()
@@ -59,10 +59,10 @@ abstract class IrBuiltinOperatorDescriptorBase(containingDeclaration: Declaratio
override fun hasStableParameterNames(): Boolean = true
override fun hasSynthesizedParameterNames(): Boolean = false
override fun copy(newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?, kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean): FunctionDescriptor =
override fun copy(newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?,
kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean) =
throw UnsupportedOperationException()
override fun newCopyBuilder(): FunctionDescriptor.CopyBuilder<out FunctionDescriptor> =
override fun newCopyBuilder() =
throw UnsupportedOperationException()
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2017 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.ir.descriptors
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class IrDeclarationStubBuilder(val defaultOrigin: IrDeclarationOrigin) {
fun buildSimpleFunctionStub(symbol: IrSimpleFunctionSymbol, origin: IrDeclarationOrigin = defaultOrigin): IrSimpleFunction =
IrFunctionImpl(symbol.descriptor.startOffset, symbol.descriptor.endOffset, origin, symbol)
.buildTypeParameterStubs(symbol.descriptor.typeParameters, origin)
.buildValueParameterStubs(symbol.descriptor, origin)
fun buildTypeParameterStub(symbol: IrTypeParameterSymbol, origin: IrDeclarationOrigin = defaultOrigin): IrTypeParameter =
IrTypeParameterImpl(symbol.descriptor.startOffset, symbol.descriptor.endOffset, origin, symbol)
fun buildValueParameterStub(symbol: IrValueParameterSymbol, origin: IrDeclarationOrigin = defaultOrigin): IrValueParameter =
IrValueParameterImpl(symbol.descriptor.startOffset, symbol.descriptor.endOffset, origin, symbol)
private fun <T : IrTypeParametersContainer>
T.buildTypeParameterStubs(typeParameterDescriptors: List<TypeParameterDescriptor>, origin: IrDeclarationOrigin): T =
apply {
typeParameterDescriptors.forEach { typeParameterDescriptor ->
typeParameters.add(
buildTypeParameterStub(IrTypeParameterSymbolImpl(typeParameterDescriptor), origin)
)
}
}
private fun <T : IrFunction>
T.buildValueParameterStubs(functionDescriptor: FunctionDescriptor, origin: IrDeclarationOrigin): T =
apply {
val valueParameterDescriptors = ArrayList<ParameterDescriptor>(functionDescriptor.valueParameters.size + 2).apply {
addIfNotNull(functionDescriptor.dispatchReceiverParameter)
addIfNotNull(functionDescriptor.extensionReceiverParameter)
addAll(functionDescriptor.valueParameters)
}
valueParameterDescriptors.forEach { valueParameterDescriptor ->
valueParameters.add(
buildValueParameterStub(IrValueParameterSymbolImpl(valueParameterDescriptor), origin)
)
}
}
private val DeclarationDescriptorWithSource.startOffset
get() = psiElement?.startOffset ?: UNDEFINED_OFFSET
private val DeclarationDescriptorWithSource.endOffset
get() = psiElement?.startOffset ?: UNDEFINED_OFFSET
private val DeclarationDescriptorWithSource.psiElement: PsiElement?
get() = source.safeAs<PsiSourceElement>()?.psi
}
@@ -16,14 +16,20 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
interface IrCall : IrMemberAccessExpression {
interface IrCall : IrFunctionAccessExpression {
val superQualifier: ClassDescriptor?
val superQualifierSymbol: IrClassSymbol?
}
interface IrCallWithShallowCopy : IrCall {
fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?): IrCall
fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall
@Deprecated("Creates unbound symbols")
fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall
}
@@ -16,5 +16,24 @@
package org.jetbrains.kotlin.ir.expressions
interface IrCallableReference : IrMemberAccessExpression
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
interface IrCallableReference : IrMemberAccessExpression {
override val descriptor: CallableMemberDescriptor
}
interface IrFunctionReference : IrCallableReference {
override val descriptor: FunctionDescriptor
val symbol: IrFunctionSymbol
}
interface IrPropertyReference : IrCallableReference {
override val descriptor: PropertyDescriptor
val field: IrFieldSymbol?
val getter: IrFunctionSymbol?
val setter: IrFunctionSymbol?
}
@@ -17,9 +17,11 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
interface IrClassReference : IrDeclarationReference {
override val descriptor: ClassifierDescriptor
override val symbol: IrClassifierSymbol
}
@@ -18,17 +18,25 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
interface IrDeclarationReference : IrExpression {
val descriptor: DeclarationDescriptor
val symbol: IrSymbol
}
interface IrGetSingletonValue : IrDeclarationReference {
override val descriptor: ClassDescriptor
}
interface IrGetObjectValue : IrGetSingletonValue
interface IrGetObjectValue : IrGetSingletonValue {
override val symbol: IrClassSymbol
}
interface IrGetEnumValue : IrGetSingletonValue
interface IrGetEnumValue : IrGetSingletonValue {
override val symbol: IrEnumEntrySymbol
}
@@ -17,8 +17,10 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
interface IrDelegatingConstructorCall : IrMemberAccessExpression {
interface IrDelegatingConstructorCall : IrFunctionAccessExpression {
override val descriptor: ClassConstructorDescriptor
override val symbol: IrConstructorSymbol
}
@@ -17,8 +17,10 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
interface IrEnumConstructorCall : IrMemberAccessExpression {
interface IrEnumConstructorCall : IrFunctionAccessExpression {
override val descriptor: ClassConstructorDescriptor
override val symbol: IrConstructorSymbol
}
@@ -18,10 +18,16 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
interface IrFieldAccessExpression : IrDeclarationReference {
override val descriptor: PropertyDescriptor
override val symbol: IrFieldSymbol
val superQualifier: ClassDescriptor?
val superQualifierSymbol: IrClassSymbol?
var receiver: IrExpression?
val origin: IrStatementOrigin?
}
@@ -17,8 +17,10 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
interface IrInstanceInitializerCall : IrExpression {
val classDescriptor: ClassDescriptor
val classSymbol: IrClassSymbol
}
@@ -16,17 +16,16 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.types.KotlinType
interface IrMemberAccessExpression : IrDeclarationReference {
interface IrMemberAccessExpression : IrExpression {
var dispatchReceiver: IrExpression?
var extensionReceiver: IrExpression?
val descriptor: CallableMemberDescriptor
val origin: IrStatementOrigin?
override val descriptor: CallableDescriptor
// NB `typeParameterDescriptor` should be taken from `descriptor.original`
fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): KotlinType?
@@ -36,6 +35,11 @@ interface IrMemberAccessExpression : IrDeclarationReference {
fun removeValueArgument(index: Int)
}
interface IrFunctionAccessExpression : IrMemberAccessExpression, IrDeclarationReference {
override val descriptor: FunctionDescriptor
override val symbol: IrFunctionSymbol
}
fun IrMemberAccessExpression.getValueArgument(valueParameterDescriptor: ValueParameterDescriptor) =
getValueArgument(valueParameterDescriptor.index)
@@ -17,10 +17,12 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
interface IrReturn : IrExpression {
var value: IrExpression
val returnTarget: CallableDescriptor
val returnTargetSymbol: IrFunctionSymbol
}
@@ -18,6 +18,10 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
interface IrTry : IrExpression {
@@ -30,6 +34,7 @@ interface IrTry : IrExpression {
interface IrCatch : IrElement {
val parameter: VariableDescriptor
var catchParameter: IrVariable
var result: IrExpression
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrCatch =
@@ -18,9 +18,12 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
interface IrValueAccessExpression : IrDeclarationReference {
override val descriptor: ValueDescriptor
override val symbol: IrValueSymbol
val origin: IrStatementOrigin?
}
@@ -30,6 +33,7 @@ interface IrGetValue : IrValueAccessExpression, IrExpressionWithCopy {
interface IrSetVariable : IrValueAccessExpression {
override val descriptor: VariableDescriptor
override val symbol: IrVariableSymbol
var value: IrExpression
}
@@ -16,12 +16,14 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -29,21 +31,40 @@ class IrCallImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val descriptor: CallableDescriptor,
override val symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val origin: IrStatementOrigin? = null,
override val superQualifier: ClassDescriptor? = null
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, descriptor.valueParameters.size, typeArguments), IrCallWithShallowCopy {
override val superQualifierSymbol: IrClassSymbol? = null
) : IrCall,
IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, symbol.descriptor.valueParameters.size, typeArguments)
{
@Deprecated("Creates unbound symbols")
constructor(
startOffset: Int, endOffset: Int, descriptor: CallableDescriptor,
startOffset: Int,
endOffset: Int,
calleeDescriptor: CallableMemberDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : this(startOffset, endOffset, descriptor.returnType!!, descriptor, typeArguments, origin, superQualifier)
superQualifierDescriptor: ClassDescriptor? = null
) : this(
startOffset, endOffset,
calleeDescriptor.returnType!!,
createFunctionSymbol(calleeDescriptor),
typeArguments, origin,
createClassSymbolOrNull(superQualifierDescriptor)
)
constructor(
startOffset: Int, endOffset: Int,
symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol.descriptor.returnType!!, symbol, typeArguments, origin, superQualifierSymbol)
override val descriptor: FunctionDescriptor = symbol.descriptor
override val superQualifier: ClassDescriptor? = superQualifierSymbol?.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitCall(this, data)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrCallImpl(startOffset, endOffset, type, newCallee, typeArguments, newOrigin, newSuperQualifier)
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -0,0 +1,100 @@
/*
* Copyright 2010-2017 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.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
abstract class IrCallableReferenceBase(
startOffset: Int,
endOffset: Int,
type: KotlinType,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
numValueArguments: Int,
override val origin: IrStatementOrigin? = null
) : IrCallableReference,
IrCallWithIndexedArgumentsBase(
startOffset, endOffset,
type,
numValueArguments,
typeArguments,
origin
)
class IrFunctionReferenceImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null
) : IrFunctionReference,
IrCallableReferenceBase(
startOffset, endOffset, type, typeArguments,
symbol.descriptor.valueParameters.size,
origin
)
{
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null
) : this(startOffset, endOffset, type, createFunctionSymbol(descriptor), typeArguments, origin)
override val descriptor: FunctionDescriptor get() = symbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitFunctionReference(this, data)
}
class IrPropertyReferenceImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val descriptor: PropertyDescriptor,
override val field: IrFieldSymbol?,
override val getter: IrFunctionSymbol?,
override val setter: IrFunctionSymbol?,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val origin: IrStatementOrigin? = null
) : IrPropertyReference,
IrMemberAccessExpressionBase(startOffset, endOffset, type, typeArguments)
{
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitPropertyReference(this, data)
private fun throwNoValueArguments(): Nothing {
throw UnsupportedOperationException("Property reference $descriptor has no value arguments")
}
override fun getValueArgument(index: Int): IrExpression? = throwNoValueArguments()
override fun putValueArgument(index: Int, valueArgument: IrExpression?) = throwNoValueArguments()
override fun removeValueArgument(index: Int) = throwNoValueArguments()
}
@@ -1,38 +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.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrCallableReference
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
class IrCallableReferenceImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val descriptor: CallableDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val origin: IrStatementOrigin? = null
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, descriptor.valueParameters.size, typeArguments, origin),
IrCallableReference {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitCallableReference(this, data)
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.ir.expressions.IrClassReference
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -25,9 +26,15 @@ class IrClassReferenceImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: ClassifierDescriptor
) : IrTerminalDeclarationReferenceBase<ClassifierDescriptor>(startOffset, endOffset, type, descriptor), IrClassReference {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitClassReference(this, data)
}
symbol: IrClassifierSymbol
) : IrClassReference,
IrTerminalDeclarationReferenceBase<IrClassifierSymbol, ClassifierDescriptor>(
startOffset, endOffset, type,
symbol, symbol.descriptor
)
{
override val descriptor: ClassifierDescriptor get() = symbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitClassReference(this, data)
}
@@ -18,11 +18,13 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.expressions.IrDeclarationReference
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.types.KotlinType
abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
abstract class IrDeclarationReferenceBase<out S: IrSymbol, out D : DeclarationDescriptor>(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val symbol: S,
override val descriptor: D
) : IrExpressionBase(startOffset, endOffset, type), IrDeclarationReference
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.KotlinType
@@ -26,10 +28,28 @@ import org.jetbrains.kotlin.types.KotlinType
class IrDelegatingConstructorCallImpl(
startOffset: Int,
endOffset: Int,
override val descriptor: ClassConstructorDescriptor,
override val symbol: IrConstructorSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size, typeArguments),
IrDelegatingConstructorCall {
) : IrDelegatingConstructorCall,
IrCallWithIndexedArgumentsBase(
startOffset, endOffset,
symbol.descriptor.builtIns.unitType,
symbol.descriptor.valueParameters.size,
typeArguments
)
{
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int,
endOffset: Int,
constructorDescriptor: ClassConstructorDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
) : this(startOffset, endOffset,
IrConstructorSymbolImpl(constructorDescriptor),
typeArguments)
override val descriptor: ClassConstructorDescriptor get() = symbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitDelegatingConstructorCall(this, data)
}
@@ -18,15 +18,23 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
class IrEnumConstructorCallImpl(
startOffset: Int,
endOffset: Int,
override val descriptor: ClassConstructorDescriptor
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size, null),
IrEnumConstructorCall {
override val symbol: IrConstructorSymbol
) : IrEnumConstructorCall,
IrCallWithIndexedArgumentsBase(
startOffset, endOffset,
symbol.descriptor.builtIns.unitType,
symbol.descriptor.valueParameters.size,
null
) {
override val descriptor: ClassConstructorDescriptor get() = symbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitEnumConstructorCall(this, data)
}
@@ -21,12 +21,20 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.types.KotlinType
abstract class IrFieldExpressionBase(
startOffset: Int, endOffset: Int, descriptor: PropertyDescriptor, type: KotlinType,
startOffset: Int, endOffset: Int,
override val symbol: IrFieldSymbol,
type: KotlinType,
override val origin: IrStatementOrigin? = null,
override val superQualifier: ClassDescriptor? = null
) : IrDeclarationReferenceBase<PropertyDescriptor>(startOffset, endOffset, type, descriptor), IrFieldAccessExpression {
override val superQualifierSymbol: IrClassSymbol?
) : IrExpressionBase(startOffset, endOffset, type), IrFieldAccessExpression {
override val descriptor: PropertyDescriptor get() = symbol.descriptor
override val superQualifier: ClassDescriptor? get() = superQualifierSymbol?.descriptor
override final var receiver: IrExpression? = null
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue
import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -25,8 +26,10 @@ class IrGetEnumValueImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: ClassDescriptor
) : IrTerminalDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetEnumValue {
symbol: IrEnumEntrySymbol
) : IrGetEnumValue,
IrTerminalDeclarationReferenceBase<IrEnumEntrySymbol, ClassDescriptor>(startOffset, endOffset, type, symbol, symbol.descriptor)
{
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitGetEnumValue(this, data)
}
@@ -21,19 +21,56 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetField
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
class IrGetFieldImpl(
startOffset: Int, endOffset: Int, descriptor: PropertyDescriptor,
startOffset: Int, endOffset: Int,
symbol: IrFieldSymbol,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : IrFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type, origin, superQualifier), IrGetField {
superQualifierSymbol: IrClassSymbol? = null
) : IrGetField,
IrFieldExpressionBase(startOffset, endOffset, symbol, symbol.descriptor.type, origin, superQualifierSymbol)
{
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int, endOffset: Int, descriptor: PropertyDescriptor, receiver: IrExpression?,
startOffset: Int, endOffset: Int,
propertyDescriptor: PropertyDescriptor,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : this(startOffset, endOffset, descriptor, origin, superQualifier) {
) : this(
startOffset, endOffset,
IrFieldSymbolImpl(propertyDescriptor),
origin,
createClassSymbolOrNull(superQualifier)
)
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int, endOffset: Int,
propertyDescriptor: PropertyDescriptor,
receiver: IrExpression?,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : this(
startOffset, endOffset,
IrFieldSymbolImpl(propertyDescriptor),
receiver, origin,
createClassSymbolOrNull(superQualifier)
)
constructor(
startOffset: Int, endOffset: Int,
symbol: IrFieldSymbol,
receiver: IrExpression?,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, origin, superQualifierSymbol) {
this.receiver = receiver
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -25,8 +26,10 @@ class IrGetObjectValueImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: ClassDescriptor
) : IrTerminalDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetObjectValue {
symbol: IrClassSymbol
) : IrGetObjectValue,
IrTerminalDeclarationReferenceBase<IrClassSymbol, ClassDescriptor>(startOffset, endOffset, type, symbol, symbol.descriptor)
{
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitGetObjectValue(this, data)
}
@@ -19,15 +19,27 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createValueSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
class IrGetValueImpl(
startOffset: Int, endOffset: Int, descriptor: ValueDescriptor,
startOffset: Int, endOffset: Int,
symbol: IrValueSymbol,
override val origin: IrStatementOrigin? = null
) : IrTerminalDeclarationReferenceBase<ValueDescriptor>(startOffset, endOffset, descriptor.type, descriptor), IrGetValue {
) : IrGetValue,
IrTerminalDeclarationReferenceBase<IrValueSymbol, ValueDescriptor>(startOffset, endOffset, symbol.descriptor.type, symbol, symbol.descriptor)
{
@Deprecated("Creates unbound reference")
constructor(
startOffset: Int, endOffset: Int,
descriptor: ValueDescriptor,
origin: IrStatementOrigin? = null
) : this(startOffset, endOffset, createValueSymbol(descriptor), origin)
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitGetValue(this, data)
override fun copy(): IrGetValue =
IrGetValueImpl(startOffset, endOffset, descriptor, origin)
IrGetValueImpl(startOffset, endOffset, symbol, origin)
}
@@ -18,14 +18,17 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.expressions.IrInstanceInitializerCall
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
class IrInstanceInitializerCallImpl(
startOffset: Int,
endOffset: Int,
override val classDescriptor: ClassDescriptor
) : IrTerminalExpressionBase(startOffset, endOffset, classDescriptor.builtIns.unitType), IrInstanceInitializerCall {
override val classSymbol: IrClassSymbol
) : IrTerminalExpressionBase(startOffset, endOffset, classSymbol.descriptor.builtIns.unitType), IrInstanceInitializerCall {
override val classDescriptor: ClassDescriptor get() = classSymbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitInstanceInitializerCall(this, data)
}
@@ -16,13 +16,14 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -32,9 +33,12 @@ abstract class IrPrimitiveCallBase(
startOffset: Int,
endOffset: Int,
override val origin: IrStatementOrigin?,
override val descriptor: CallableDescriptor
) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall {
override val symbol: IrFunctionSymbol
) : IrExpressionBase(startOffset, endOffset, symbol.descriptor.returnType!!), IrCall {
override val descriptor: FunctionDescriptor get() = symbol.descriptor
override val superQualifier: ClassDescriptor? get() = null
override val superQualifierSymbol: IrClassSymbol? get() = null
override var dispatchReceiver: IrExpression?
get() = null
set(value) {
@@ -66,8 +70,8 @@ abstract class IrPrimitiveCallBase(
}
}
class IrNullaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor) :
IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor), IrCallWithShallowCopy {
class IrNullaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, symbol: IrFunctionSymbol) :
IrPrimitiveCallBase(startOffset, endOffset, origin, symbol), IrCallWithShallowCopy {
override fun getValueArgument(index: Int): IrExpression? = null
override fun putValueArgument(index: Int, valueArgument: IrExpression?) {
@@ -82,16 +86,44 @@ class IrNullaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStateme
// no children
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) =
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall =
IrNullaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrNullaryPrimitiveImpl(startOffset, endOffset, newOrigin, createFunctionSymbol(newCallee))
}
class IrUnaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor) :
IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor), IrCallWithShallowCopy {
class IrUnaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, symbol: IrFunctionSymbol) :
IrPrimitiveCallBase(startOffset, endOffset, origin, symbol), IrCallWithShallowCopy {
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor,
startOffset: Int, endOffset: Int,
origin: IrStatementOrigin?,
functionDescriptor: FunctionDescriptor
) : this(
startOffset, endOffset, origin,
createFunctionSymbol(functionDescriptor)
)
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int, endOffset: Int,
origin: IrStatementOrigin?,
functionDescriptor: FunctionDescriptor,
argument: IrExpression
) : this(startOffset, endOffset, origin, descriptor) {
) : this(
startOffset, endOffset, origin,
createFunctionSymbol(functionDescriptor),
argument
)
constructor(
startOffset: Int, endOffset: Int,
origin: IrStatementOrigin?,
symbol: IrFunctionSymbol,
argument: IrExpression
) : this(startOffset, endOffset, origin, symbol) {
this.argument = argument
}
@@ -119,16 +151,38 @@ class IrUnaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatement
argument = argument.transform(transformer, data)
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) =
IrUnaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall =
IrUnaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrUnaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee)
}
class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor) :
IrPrimitiveCallBase(startOffset, endOffset, origin, descriptor), IrCallWithShallowCopy {
class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, symbol: IrFunctionSymbol) :
IrPrimitiveCallBase(startOffset, endOffset, origin, symbol), IrCallWithShallowCopy {
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, descriptor: CallableDescriptor,
startOffset: Int, endOffset: Int, origin: IrStatementOrigin?,
descriptor: FunctionDescriptor
) : this(startOffset, endOffset, origin,
createFunctionSymbol(descriptor))
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int, endOffset: Int, origin: IrStatementOrigin?,
descriptor: FunctionDescriptor,
argument0: IrExpression, argument1: IrExpression
) : this(startOffset, endOffset, origin, descriptor) {
) : this(
startOffset, endOffset, origin,
createFunctionSymbol(descriptor),
argument0, argument1
)
constructor(
startOffset: Int, endOffset: Int, origin: IrStatementOrigin?,
symbol: IrFunctionSymbol,
argument0: IrExpression, argument1: IrExpression
) : this(startOffset, endOffset, origin, symbol) {
this.argument0 = argument0
this.argument1 = argument1
}
@@ -163,6 +217,9 @@ class IrBinaryPrimitiveImpl(startOffset: Int, endOffset: Int, origin: IrStatemen
argument1 = argument1.transform(transformer, data)
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) =
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall =
IrBinaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrBinaryPrimitiveImpl(startOffset, endOffset, newOrigin, newCallee)
}
@@ -16,13 +16,17 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -31,11 +35,14 @@ import java.lang.UnsupportedOperationException
abstract class IrPropertyAccessorCallBase(
startOffset: Int, endOffset: Int,
override val descriptor: CallableDescriptor,
override val symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val origin: IrStatementOrigin? = null,
override val superQualifier: ClassDescriptor? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!, typeArguments), IrCall {
override val superQualifierSymbol: IrClassSymbol? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, symbol.descriptor.returnType!!, typeArguments), IrCall {
override val descriptor: FunctionDescriptor get() = symbol.descriptor
override val superQualifier: ClassDescriptor? get() = superQualifierSymbol?.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitCall(this, data)
}
@@ -47,19 +54,19 @@ abstract class IrPropertyAccessorCallBase(
class IrGetterCallImpl(
startOffset: Int, endOffset: Int,
descriptor: CallableDescriptor,
symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, typeArguments, origin, superQualifier), IrCallWithShallowCopy {
superQualifierSymbol: IrClassSymbol? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy {
constructor(startOffset: Int, endOffset: Int,
descriptor: CallableDescriptor,
symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
dispatchReceiver: IrExpression?,
extensionReceiver: IrExpression?,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : this(startOffset, endOffset, descriptor, typeArguments, origin, superQualifier) {
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol) {
this.dispatchReceiver = dispatchReceiver
this.extensionReceiver = extensionReceiver
}
@@ -74,26 +81,35 @@ class IrGetterCallImpl(
throw UnsupportedOperationException("Property getter call has no arguments")
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) =
IrGetterCallImpl(startOffset, endOffset, newCallee, typeArguments, newOrigin, newSuperQualifier)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall =
IrGetterCallImpl(startOffset, endOffset, newCallee, typeArguments, dispatchReceiver, extensionReceiver, newOrigin, newSuperQualifier)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrGetterCallImpl(
startOffset, endOffset,
createFunctionSymbol(newCallee),
typeArguments, dispatchReceiver, extensionReceiver,
newOrigin,
createClassSymbolOrNull(newSuperQualifier)
)
}
class IrSetterCallImpl(
startOffset: Int, endOffset: Int,
descriptor: CallableDescriptor,
symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, typeArguments, origin, superQualifier), IrCallWithShallowCopy {
superQualifierSymbol: IrClassSymbol? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy {
constructor(startOffset: Int, endOffset: Int,
descriptor: CallableDescriptor,
symbol: IrFunctionSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
dispatchReceiver: IrExpression?,
extensionReceiver: IrExpression?,
argument: IrExpression,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : this(startOffset, endOffset, descriptor, typeArguments, origin, superQualifier) {
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol) {
this.dispatchReceiver = dispatchReceiver
this.extensionReceiver = extensionReceiver
putValueArgument(SETTER_ARGUMENT_INDEX, argument)
@@ -114,9 +130,18 @@ class IrSetterCallImpl(
argumentImpl = null
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) =
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall =
IrSetterCallImpl(startOffset, endOffset, newCallee, typeArguments, newOrigin, newSuperQualifier)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrSetterCallImpl(
startOffset, endOffset,
createFunctionSymbol(newCallee),
typeArguments,
newOrigin,
createClassSymbolOrNull(newSuperQualifier)
)
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
super.transformChildren(transformer, data)
argumentImpl = argumentImpl?.transform(transformer, data)
@@ -17,8 +17,11 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrReturn
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
@@ -28,11 +31,19 @@ class IrReturnImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val returnTarget: CallableDescriptor,
override val returnTargetSymbol: IrFunctionSymbol,
override var value: IrExpression
) : IrExpressionBase(startOffset, endOffset, type), IrReturn {
constructor(startOffset: Int, endOffset: Int, returnTarget: CallableDescriptor, value: IrExpression) :
this(startOffset, endOffset, returnTarget.builtIns.nothingType, returnTarget, value)
constructor(startOffset: Int, endOffset: Int, returnTargetSymbol: IrFunctionSymbol, value: IrExpression) :
this(startOffset, endOffset, returnTargetSymbol.descriptor.builtIns.nothingType, returnTargetSymbol, value)
@Deprecated("Creates unbound symbol")
constructor(startOffset: Int, endOffset: Int, returnTargetDescriptor: FunctionDescriptor, value: IrExpression) :
this(startOffset, endOffset, returnTargetDescriptor.builtIns.nothingType,
createFunctionSymbol(returnTargetDescriptor),
value)
override val returnTarget: CallableDescriptor get() = returnTargetSymbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitReturn(this, data)
@@ -21,23 +21,64 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrSetField
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.typeUtil.builtIns
class IrSetFieldImpl(
startOffset: Int, endOffset: Int,
descriptor: PropertyDescriptor,
symbol: IrFieldSymbol,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : IrFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type.builtIns.unitType, origin, superQualifier), IrSetField {
superQualifierSymbol: IrClassSymbol? = null
) : IrSetField,
IrFieldExpressionBase(
startOffset, endOffset,
symbol,
symbol.descriptor.type.builtIns.unitType,
origin,
superQualifierSymbol
)
{
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int, endOffset: Int, descriptor: PropertyDescriptor,
startOffset: Int, endOffset: Int,
propertyDescriptor: PropertyDescriptor,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : this(
startOffset, endOffset,
IrFieldSymbolImpl(propertyDescriptor),
origin,
createClassSymbolOrNull(superQualifier)
)
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int, endOffset: Int,
propertyDescriptor: PropertyDescriptor,
receiver: IrExpression?,
value: IrExpression,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : this(startOffset, endOffset, descriptor, origin, superQualifier) {
) : this(
startOffset, endOffset,
IrFieldSymbolImpl(propertyDescriptor),
receiver, value, origin,
createClassSymbolOrNull(superQualifier)
)
constructor(
startOffset: Int, endOffset: Int,
symbol: IrFieldSymbol,
receiver: IrExpression?,
value: IrExpression,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, origin, superQualifierSymbol) {
this.receiver = receiver
this.value = value
}
@@ -20,23 +20,27 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
class IrSetVariableImpl(
startOffset: Int, endOffset: Int,
override val descriptor: VariableDescriptor,
override val symbol: IrVariableSymbol,
override val origin: IrStatementOrigin?
) : IrExpressionBase(startOffset, endOffset, descriptor.builtIns.unitType), IrSetVariable {
) : IrExpressionBase(startOffset, endOffset, symbol.descriptor.builtIns.unitType), IrSetVariable {
constructor(
startOffset: Int, endOffset: Int, descriptor: VariableDescriptor,
startOffset: Int, endOffset: Int,
symbol: IrVariableSymbol,
value: IrExpression,
origin: IrStatementOrigin?
) : this(startOffset, endOffset, descriptor, origin) {
) : this(startOffset, endOffset, symbol, origin) {
this.value = value
}
override val descriptor: VariableDescriptor get() = symbol.descriptor
override lateinit var value: IrExpression
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -17,16 +17,19 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.expressions.IrDeclarationReference
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
abstract class IrTerminalDeclarationReferenceBase<out D : DeclarationDescriptor>(
abstract class IrTerminalDeclarationReferenceBase<out S: IrSymbol, out D : DeclarationDescriptor>(
startOffset: Int,
endOffset: Int,
type: KotlinType,
symbol: S,
descriptor: D
) : IrDeclarationReferenceBase<D>(startOffset, endOffset, type, descriptor) {
) : IrDeclarationReferenceBase<S, D>(startOffset, endOffset, type, symbol, descriptor), IrDeclarationReference {
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
// No children
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrCatch
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrTry
@@ -62,19 +63,24 @@ class IrTryImpl(startOffset: Int, endOffset: Int, type: KotlinType) :
}
}
class IrCatchImpl(startOffset: Int, endOffset: Int,
override val parameter: VariableDescriptor,
override var result: IrExpression
class IrCatchImpl(
startOffset: Int, endOffset: Int,
override var catchParameter: IrVariable,
override var result: IrExpression
) : IrCatch, IrElementBase(startOffset, endOffset) {
override val parameter: VariableDescriptor get() = catchParameter.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitCatch(this, data)
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
catchParameter.accept(visitor, data)
result.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
catchParameter = catchParameter.transform(transformer, data) as IrVariable
result = result.transform(transformer, data)
}
}
@@ -24,26 +24,38 @@ interface IrSymbol {
val descriptor: DeclarationDescriptor
}
interface IrBindableSymbol<out D : DeclarationDescriptor, B : IrSymbolOwner> : IrSymbol{
interface IrBindableSymbol<out D : DeclarationDescriptor, B : IrSymbolOwner> : IrSymbol {
override val owner: B
override val descriptor: D
fun bind(owner: B)
}
interface IrPackageFragmentSymbol : IrSymbol {
override val descriptor: PackageFragmentDescriptor
}
interface IrFileSymbol : IrPackageFragmentSymbol, IrBindableSymbol<PackageFragmentDescriptor, IrFile>
interface IrExternalPackageFragmentSymbol : IrPackageFragmentSymbol, IrBindableSymbol<PackageFragmentDescriptor, IrExternalPackageFragment>
interface IrAnonymousInitializerSymbol : IrBindableSymbol<ClassDescriptor, IrAnonymousInitializer>
interface IrClassSymbol : IrBindableSymbol<ClassDescriptor, IrClass>
interface IrEnumEntrySymbol : IrBindableSymbol<ClassDescriptor, IrEnumEntry>
interface IrFileSymbol : IrBindableSymbol<PackageFragmentDescriptor, IrFile>
interface IrFieldSymbol : IrBindableSymbol<PropertyDescriptor, IrField>
interface IrTypeParameterSymbol : IrBindableSymbol<TypeParameterDescriptor, IrTypeParameter>
interface IrValueParameterSymbol : IrBindableSymbol<ParameterDescriptor, IrValueParameter>
interface IrVariableSymbol : IrBindableSymbol<VariableDescriptor, IrVariable>
interface IrClassifierSymbol : IrSymbol {
override val descriptor: ClassifierDescriptor
}
interface IrClassSymbol : IrClassifierSymbol, IrBindableSymbol<ClassDescriptor, IrClass>
interface IrTypeParameterSymbol : IrClassifierSymbol, IrBindableSymbol<TypeParameterDescriptor, IrTypeParameter>
interface IrValueSymbol : IrSymbol {
override val descriptor: ValueDescriptor
}
interface IrValueParameterSymbol : IrValueSymbol, IrBindableSymbol<ParameterDescriptor, IrValueParameter>
interface IrVariableSymbol : IrValueSymbol, IrBindableSymbol<VariableDescriptor, IrVariable>
interface IrFunctionSymbol : IrSymbol {
override val descriptor: FunctionDescriptor
}
interface IrConstructorSymbol : IrFunctionSymbol, IrBindableSymbol<ClassConstructorDescriptor, IrConstructor>
interface IrSimpleFunctionSymbol : IrFunctionSymbol, IrBindableSymbol<FunctionDescriptor, IrSimpleFunction>
@@ -20,9 +20,10 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.*
abstract class IrBindableSymbolBase<out D : DeclarationDescriptor, B : IrSymbolOwner>(
override val descriptor: D
) : IrBindableSymbol<D, B> {
abstract class IrSymbolBase<out D : DeclarationDescriptor>(override val descriptor: D) : IrSymbol
abstract class IrBindableSymbolBase<out D : DeclarationDescriptor, B : IrSymbolOwner>(descriptor: D) :
IrBindableSymbol<D, B>, IrSymbolBase<D>(descriptor) {
private var _owner: B? = null
override val owner: B
get() = _owner ?: throw IllegalStateException("Symbol for $descriptor is unbound")
@@ -35,6 +36,14 @@ abstract class IrBindableSymbolBase<out D : DeclarationDescriptor, B : IrSymbolO
}
}
class IrFileSymbolImpl(descriptor: PackageFragmentDescriptor) :
IrBindableSymbolBase<PackageFragmentDescriptor, IrFile>(descriptor),
IrFileSymbol
class IrExternalPackageFragmentSymbolImpl(descriptor: PackageFragmentDescriptor) :
IrBindableSymbolBase<PackageFragmentDescriptor, IrExternalPackageFragment>(descriptor),
IrExternalPackageFragmentSymbol
class IrAnonymousInitializerSymbolImpl(descriptor: ClassDescriptor) :
IrBindableSymbolBase<ClassDescriptor, IrAnonymousInitializer>(descriptor),
IrAnonymousInitializerSymbol
@@ -43,14 +52,13 @@ class IrClassSymbolImpl(descriptor: ClassDescriptor) :
IrBindableSymbolBase<ClassDescriptor, IrClass>(descriptor),
IrClassSymbol
fun createClassSymbolOrNull(descriptor: ClassDescriptor?) =
descriptor?.let { IrClassSymbolImpl(it) }
class IrEnumEntrySymbolImpl(descriptor: ClassDescriptor) :
IrBindableSymbolBase<ClassDescriptor, IrEnumEntry>(descriptor),
IrEnumEntrySymbol
class IrFileSymbolImpl(descriptor: PackageFragmentDescriptor) :
IrBindableSymbolBase<PackageFragmentDescriptor, IrFile>(descriptor),
IrFileSymbol
class IrFieldSymbolImpl(descriptor: PropertyDescriptor) :
IrBindableSymbolBase<PropertyDescriptor, IrField>(descriptor),
IrFieldSymbol
@@ -67,10 +75,24 @@ class IrVariableSymbolImpl(descriptor: VariableDescriptor) :
IrBindableSymbolBase<VariableDescriptor, IrVariable>(descriptor),
IrVariableSymbol
fun createValueSymbol(descriptor: ValueDescriptor): IrValueSymbol =
when (descriptor) {
is ParameterDescriptor -> IrValueParameterSymbolImpl(descriptor)
is VariableDescriptor -> IrVariableSymbolImpl(descriptor)
else -> throw IllegalArgumentException("Unexpected descriptor kind: $descriptor")
}
class IrSimpleFunctionSymbolImpl(descriptor: FunctionDescriptor) :
IrBindableSymbolBase<FunctionDescriptor, IrSimpleFunction>(descriptor),
IrSimpleFunctionSymbol
class IrConstructorSymbolImpl(descriptor: ClassConstructorDescriptor) :
IrBindableSymbolBase<ClassConstructorDescriptor, IrConstructor>(descriptor),
IrConstructorSymbol
IrConstructorSymbol
fun createFunctionSymbol(descriptor: CallableMemberDescriptor): IrFunctionSymbol =
when (descriptor) {
is ClassConstructorDescriptor -> IrConstructorSymbolImpl(descriptor)
is FunctionDescriptor -> IrSimpleFunctionSymbolImpl(descriptor)
else -> throw IllegalArgumentException("Unexpected descriptor kind: $descriptor")
}
@@ -16,65 +16,67 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
open class DeepCopyIrTree : IrElementTransformerVoid() {
protected open fun mapDeclarationOrigin(declarationOrigin: IrDeclarationOrigin) = declarationOrigin
protected open fun mapStatementOrigin(statementOrigin: IrStatementOrigin?) = statementOrigin
protected open fun mapFileEntry(fileEntry: SourceManager.FileEntry) = fileEntry
inline fun <reified T : IrElement> T.deepCopy(): T {
val remapper = DeepCopySymbolsRemapper()
acceptVoid(remapper)
return transform(DeepCopyIrTree(remapper), null) as T
}
protected open fun mapModuleDescriptor(descriptor: ModuleDescriptor) = descriptor
protected open fun mapPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor) = descriptor
protected open fun mapClassDeclaration(descriptor: ClassDescriptor) = descriptor
protected open fun mapTypeAliasDeclaration(descriptor: TypeAliasDescriptor) = descriptor
protected open fun mapFunctionDeclaration(descriptor: FunctionDescriptor) = descriptor
protected open fun mapConstructorDeclaration(descriptor: ClassConstructorDescriptor) = descriptor
protected open fun mapPropertyDeclaration(descriptor: PropertyDescriptor) = descriptor
protected open fun mapLocalPropertyDeclaration(descriptor: VariableDescriptorWithAccessors) = descriptor
protected open fun mapEnumEntryDeclaration(descriptor: ClassDescriptor) = descriptor
protected open fun mapVariableDeclaration(descriptor: VariableDescriptor) = descriptor
protected open fun mapCatchParameterDeclaration(descriptor: VariableDescriptor) = mapVariableDeclaration(descriptor)
protected open fun mapErrorDeclaration(descriptor: DeclarationDescriptor) = descriptor
protected open fun mapSuperQualifier(qualifier: ClassDescriptor?) = qualifier
protected open fun mapClassReference(descriptor: ClassDescriptor) = descriptor
protected open fun mapValueReference(descriptor: ValueDescriptor) = descriptor
protected open fun mapVariableReference(descriptor: VariableDescriptor) = descriptor
protected open fun mapPropertyReference(descriptor: PropertyDescriptor) = descriptor
protected open fun mapCallee(descriptor: CallableDescriptor) = descriptor
protected open fun mapDelegatedConstructorCallee(descriptor: ClassConstructorDescriptor) = descriptor
protected open fun mapEnumConstructorCallee(descriptor: ClassConstructorDescriptor) = descriptor
protected open fun mapCallableReference(descriptor: CallableDescriptor) = descriptor
protected open fun mapClassifierReference(descriptor: ClassifierDescriptor) = descriptor
protected open fun mapReturnTarget(descriptor: CallableDescriptor) = mapCallee(descriptor)
class DeepCopyIrTree(private val symbolsRemapper: DeepCopySymbolsRemapper) : IrElementTransformerVoid() {
private fun mapDeclarationOrigin(origin: IrDeclarationOrigin) = origin
private fun mapStatementOrigin(origin: IrStatementOrigin?) = origin
private inline fun <reified T : IrElement> T.transform() =
transform(this@DeepCopyIrTree, null) as T
private inline fun <reified T : IrElement> List<T>.transform() =
map { it.transform() }
private inline fun <reified T : IrElement> List<T>.transformTo(destination: MutableList<T>) =
mapTo(destination) { it.transform() }
private fun <T : IrDeclarationContainer> T.transformDeclarationsTo(destination: T) =
declarations.transformTo(destination.declarations)
override fun visitElement(element: IrElement): IrElement =
throw IllegalArgumentException("Unsupported element type: $element")
override fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment =
IrModuleFragmentImpl(
mapModuleDescriptor(declaration.descriptor),
declaration.descriptor,
declaration.irBuiltins,
declaration.files.map { it.transform(this, null) }
declaration.files.transform()
)
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: Nothing?): IrExternalPackageFragment =
IrExternalPackageFragmentImpl(
symbolsRemapper.getDeclaredExternalPackageFragment(declaration.symbol)
).apply {
declaration.transformDeclarationsTo(this)
}
override fun visitFile(declaration: IrFile): IrFile =
IrFileImpl(
mapFileEntry(declaration.fileEntry),
mapPackageFragmentDescriptor(declaration.packageFragmentDescriptor),
declaration.fileAnnotations.toMutableList(),
declaration.declarations.map { it.transform(this, null) as IrDeclaration }
)
declaration.fileEntry,
symbolsRemapper.getDeclaredFile(declaration.symbol)
).apply {
fileAnnotations.addAll(declaration.fileAnnotations)
declaration.transformDeclarationsTo(this)
}
override fun visitDeclaration(declaration: IrDeclaration): IrStatement =
throw IllegalArgumentException("Unsupported declaration type: $declaration")
@@ -83,151 +85,127 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
IrClassImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapClassDeclaration(declaration.descriptor),
declaration.declarations.map { it.transform(this, null) as IrDeclaration }
symbolsRemapper.getDeclaredClass(declaration.symbol)
).apply {
transformTypeParameters(declaration, descriptor.declaredTypeParameters)
newInstanceReceiver = declaration.newInstanceReceiver?.transform()
declaration.typeParameters.transformTo(typeParameters)
declaration.transformDeclarationsTo(this)
}
override fun visitTypeAlias(declaration: IrTypeAlias): IrTypeAlias =
IrTypeAliasImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapTypeAliasDeclaration(declaration.descriptor)
declaration.descriptor
)
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction =
IrFunctionImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapFunctionDeclaration(declaration.descriptor),
declaration.body?.transform(this, null)
).transformParameters(declaration)
symbolsRemapper.getDeclaredFunction(declaration.symbol)
).transformFunctionChildren(declaration)
override fun visitConstructor(declaration: IrConstructor): IrConstructor =
IrConstructorImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapConstructorDeclaration(declaration.descriptor),
declaration.body!!.transform(this, null)
).transformParameters(declaration)
symbolsRemapper.getDeclaredConstructor(declaration.symbol)
).transformFunctionChildren(declaration)
private fun <T : IrTypeParametersContainer> T.transformTypeParameters(original: T, myTypeParameters: List<TypeParameterDescriptor>): T =
private fun <T : IrFunction> T.transformFunctionChildren(declaration: T): T =
apply {
original.typeParameters.mapTo(typeParameters) { originalTypeParameter ->
copyTypeParameter(originalTypeParameter, myTypeParameters[originalTypeParameter.descriptor.index])
}
declaration.typeParameters.transformTo(typeParameters)
dispatchReceiverParameter = declaration.dispatchReceiverParameter?.transform()
extensionReceiverParameter = declaration.extensionReceiverParameter?.transform()
declaration.valueParameters.transformTo(valueParameters)
body = declaration.body?.transform()
}
private fun <T : IrFunction> T.transformParameters(original: T): T =
apply {
transformTypeParameters(original, descriptor.typeParameters)
transformValueParameters(original)
}
private fun <T : IrFunction> T.transformValueParameters(original: T) =
apply {
dispatchReceiverParameter = original.dispatchReceiverParameter?.let {
copyValueParameter(it, descriptor.dispatchReceiverParameter ?: throw AssertionError("No dispatch receiver in $descriptor"))
}
extensionReceiverParameter = original.extensionReceiverParameter?.let {
copyValueParameter(it, descriptor.extensionReceiverParameter ?: throw AssertionError("No extension receiver in $descriptor"))
}
original.valueParameters.mapIndexedTo(valueParameters) { i, originalValueParameter ->
copyValueParameter(originalValueParameter, descriptor.valueParameters[i])
}
}
private fun copyTypeParameter(
originalTypeParameter: IrTypeParameter,
newTypeParameterDescriptor: TypeParameterDescriptor
): IrTypeParameterImpl =
IrTypeParameterImpl(
originalTypeParameter.startOffset, originalTypeParameter.endOffset,
mapDeclarationOrigin(originalTypeParameter.origin),
newTypeParameterDescriptor
)
private fun copyValueParameter(
originalValueParameter: IrValueParameter,
newParameterDescriptor: ParameterDescriptor
): IrValueParameterImpl =
IrValueParameterImpl(
originalValueParameter.startOffset, originalValueParameter.endOffset,
mapDeclarationOrigin(originalValueParameter.origin),
newParameterDescriptor,
originalValueParameter.defaultValue?.transform(this@DeepCopyIrTree, null)
)
// TODO visitTypeParameter
// TODO visitValueParameter
override fun visitProperty(declaration: IrProperty): IrProperty =
IrPropertyImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
declaration.isDelegated,
mapPropertyDeclaration(declaration.descriptor),
declaration.backingField?.transform(this, null) as? IrField,
declaration.getter?.transform(this, null) as? IrFunction,
declaration.setter?.transform(this, null) as? IrFunction
declaration.descriptor,
declaration.backingField?.transform(),
declaration.getter?.transform(),
declaration.setter?.transform()
)
override fun visitField(declaration: IrField): IrField =
IrFieldImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapPropertyDeclaration(declaration.descriptor),
declaration.initializer?.transform(this, null) as? IrExpressionBody
)
symbolsRemapper.getDeclaredField(declaration.symbol)
).apply {
initializer = declaration.initializer?.transform()
}
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrLocalDelegatedProperty =
IrLocalDelegatedPropertyImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapLocalPropertyDeclaration(declaration.descriptor),
declaration.delegate.transform(this, null) as IrVariable,
declaration.getter.transform(this, null) as IrFunction,
declaration.setter?.transform(this, null) as IrFunction?
declaration.descriptor,
declaration.delegate.transform(),
declaration.getter.transform(),
declaration.setter?.transform()
)
override fun visitEnumEntry(declaration: IrEnumEntry): IrEnumEntry =
IrEnumEntryImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapEnumEntryDeclaration(declaration.descriptor),
declaration.correspondingClass?.transform(this, null) as? IrClass,
declaration.initializerExpression.transform(this, null)
)
symbolsRemapper.getDeclaredEnumEntry(declaration.symbol)
).apply {
correspondingClass = declaration.correspondingClass?.transform()
initializerExpression = declaration.initializerExpression.transform()
}
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer): IrAnonymousInitializer =
IrAnonymousInitializerImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapClassDeclaration(declaration.descriptor),
declaration.body.transform(this, null) as IrBlockBody
)
IrAnonymousInitializerSymbolImpl(declaration.descriptor)
).apply {
body = declaration.body.transform()
}
override fun visitVariable(declaration: IrVariable): IrVariable =
IrVariableImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
mapVariableDeclaration(declaration.descriptor),
declaration.initializer?.transform(this, null) as? IrExpression
symbolsRemapper.getDeclaredVariable(declaration.symbol)
).apply {
initializer = declaration.initializer?.transform()
}
override fun visitTypeParameter(declaration: IrTypeParameter): IrTypeParameter =
IrTypeParameterImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
symbolsRemapper.getDeclaredTypeParameter(declaration.symbol)
)
override fun visitValueParameter(declaration: IrValueParameter): IrValueParameter =
IrValueParameterImpl(
declaration.startOffset, declaration.endOffset,
mapDeclarationOrigin(declaration.origin),
symbolsRemapper.getDeclaredValueParameter(declaration.symbol)
).apply {
defaultValue = declaration.defaultValue?.transform()
}
override fun visitBody(body: IrBody): IrBody =
throw IllegalArgumentException("Unsupported body type: $body")
override fun visitExpressionBody(body: IrExpressionBody): IrExpressionBody =
IrExpressionBodyImpl(body.expression.transform(this, null))
IrExpressionBodyImpl(body.expression.transform())
override fun visitBlockBody(body: IrBlockBody): IrBlockBody =
IrBlockBodyImpl(
body.startOffset, body.endOffset,
body.statements.map { it.transform(this, null) }
body.statements.map { it.transform() }
)
override fun visitSyntheticBody(body: IrSyntheticBody): IrSyntheticBody =
@@ -243,13 +221,13 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
IrVarargImpl(
expression.startOffset, expression.endOffset,
expression.type, expression.varargElementType,
expression.elements.map { it.transform(this, null) as IrVarargElement }
expression.elements.transform()
)
override fun visitSpreadElement(spread: IrSpreadElement): IrSpreadElement =
IrSpreadElementImpl(
spread.startOffset, spread.endOffset,
spread.expression.transform(this, null)
spread.expression.transform()
)
override fun visitBlock(expression: IrBlock): IrBlock =
@@ -257,7 +235,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.startOffset, expression.endOffset,
expression.type,
mapStatementOrigin(expression.origin),
expression.statements.map { it.transform(this, null) }
expression.statements.map { it.transform() }
)
override fun visitComposite(expression: IrComposite): IrComposite =
@@ -265,97 +243,101 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.startOffset, expression.endOffset,
expression.type,
mapStatementOrigin(expression.origin),
expression.statements.map { it.transform(this, null) }
expression.statements.map { it.transform() }
)
override fun visitStringConcatenation(expression: IrStringConcatenation): IrStringConcatenation =
IrStringConcatenationImpl(
expression.startOffset, expression.endOffset,
expression.type,
expression.arguments.map { it.transform(this, null) }
expression.arguments.map { it.transform() }
)
override fun visitGetObjectValue(expression: IrGetObjectValue): IrGetObjectValue =
IrGetObjectValueImpl(
expression.startOffset, expression.endOffset,
expression.type,
mapClassReference(expression.descriptor)
symbolsRemapper.getReferencedClass(expression.symbol)
)
override fun visitGetEnumValue(expression: IrGetEnumValue): IrGetEnumValue =
IrGetEnumValueImpl(
expression.startOffset, expression.endOffset,
expression.type,
mapClassReference(expression.descriptor)
symbolsRemapper.getReferencedEnumEntry(expression.symbol)
)
override fun visitGetValue(expression: IrGetValue): IrGetValue =
IrGetValueImpl(
expression.startOffset, expression.endOffset,
mapValueReference(expression.descriptor),
symbolsRemapper.getReferencedValue(expression.symbol),
mapStatementOrigin(expression.origin)
)
override fun visitSetVariable(expression: IrSetVariable): IrSetVariable =
IrSetVariableImpl(
expression.startOffset, expression.endOffset,
mapVariableReference(expression.descriptor),
expression.value.transform(this, null),
symbolsRemapper.getReferencedVariable(expression.symbol),
expression.value.transform(),
mapStatementOrigin(expression.origin)
)
override fun visitGetField(expression: IrGetField): IrGetField =
IrGetFieldImpl(
expression.startOffset, expression.endOffset,
mapPropertyReference(expression.descriptor),
expression.receiver?.transform(this, null),
symbolsRemapper.getReferencedField(expression.symbol),
expression.receiver?.transform(),
mapStatementOrigin(expression.origin),
mapSuperQualifier(expression.superQualifier)
symbolsRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
)
override fun visitSetField(expression: IrSetField): IrSetField =
IrSetFieldImpl(
expression.startOffset, expression.endOffset,
mapPropertyReference(expression.descriptor),
expression.receiver?.transform(this, null),
expression.value.transform(this, null),
symbolsRemapper.getReferencedField(expression.symbol),
expression.receiver?.transform(),
expression.value.transform(),
mapStatementOrigin(expression.origin),
mapSuperQualifier(expression.superQualifier)
symbolsRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
)
override fun visitCall(expression: IrCall): IrCall =
shallowCopyCall(expression).transformValueArguments(expression)
protected fun shallowCopyCall(expression: IrCall) =
private fun shallowCopyCall(expression: IrCall) =
when (expression) {
is IrCallWithShallowCopy ->
expression.shallowCopy(
mapStatementOrigin(expression.origin),
mapCallee(expression.descriptor),
mapSuperQualifier(expression.superQualifier)
symbolsRemapper.getReferencedFunction(expression.symbol),
symbolsRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
)
else ->
IrCallImpl(
expression.startOffset, expression.endOffset,
expression.type,
mapCallee(expression.descriptor),
symbolsRemapper.getReferencedFunction(expression.symbol),
expression.getTypeArgumentsMap(),
mapStatementOrigin(expression.origin),
mapSuperQualifier(expression.superQualifier)
symbolsRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
)
}
protected fun <T : IrMemberAccessExpression> T.transformValueArguments(original: IrMemberAccessExpression): T =
private fun <T : IrMemberAccessExpression> T.transformReceiverArguments(original: T): T =
apply {
dispatchReceiver = original.dispatchReceiver?.transform(this@DeepCopyIrTree, null)
extensionReceiver = original.extensionReceiver?.transform(this@DeepCopyIrTree, null)
mapValueParameters { valueParameter ->
original.getValueArgument(valueParameter)?.transform(this@DeepCopyIrTree, null)
}
Unit
dispatchReceiver = original.dispatchReceiver?.transform()
extensionReceiver = original.extensionReceiver?.transform()
}
protected fun IrMemberAccessExpression.getTypeArgumentsMap(): Map<TypeParameterDescriptor, KotlinType>? {
private fun <T : IrMemberAccessExpression> T.transformValueArguments(original: T): T =
apply {
transformReceiverArguments(original)
mapValueParameters { valueParameter ->
original.getValueArgument(valueParameter)?.transform()
}
}
private fun IrMemberAccessExpression.getTypeArgumentsMap(): Map<TypeParameterDescriptor, KotlinType>? {
if (this is IrMemberAccessExpressionBase) return typeArguments
val typeParameters = descriptor.original.typeParameters
@@ -368,28 +350,40 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrDelegatingConstructorCall =
IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset,
mapDelegatedConstructorCallee(expression.descriptor),
symbolsRemapper.getReferencedConstructor(expression.symbol),
expression.getTypeArgumentsMap()
).transformValueArguments(expression)
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall =
IrEnumConstructorCallImpl(
expression.startOffset, expression.endOffset,
mapEnumConstructorCallee(expression.descriptor)
symbolsRemapper.getReferencedConstructor(expression.symbol)
).transformValueArguments(expression)
override fun visitGetClass(expression: IrGetClass): IrGetClass =
IrGetClassImpl(
expression.startOffset, expression.endOffset,
expression.type,
expression.argument.transform(this, null)
expression.argument.transform()
)
override fun visitCallableReference(expression: IrCallableReference): IrCallableReference =
IrCallableReferenceImpl(
override fun visitFunctionReference(expression: IrFunctionReference): IrFunctionReference =
IrFunctionReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type,
mapCallableReference(expression.descriptor),
symbolsRemapper.getReferencedFunction(expression.symbol),
expression.getTypeArgumentsMap(),
mapStatementOrigin(expression.origin)
).transformValueArguments(expression)
override fun visitPropertyReference(expression: IrPropertyReference): IrExpression =
IrPropertyReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type,
expression.descriptor,
expression.field?.let { symbolsRemapper.getReferencedField(it) },
expression.getter?.let { symbolsRemapper.getReferencedFunction(it) },
expression.setter?.let { symbolsRemapper.getReferencedFunction(it) },
expression.getTypeArgumentsMap(),
mapStatementOrigin(expression.origin)
).transformValueArguments(expression)
@@ -398,13 +392,13 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
IrClassReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type,
mapClassifierReference(expression.descriptor)
symbolsRemapper.getReferencedClassifier(expression.symbol)
)
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall): IrInstanceInitializerCall =
IrInstanceInitializerCallImpl(
expression.startOffset, expression.endOffset,
mapClassReference(expression.classDescriptor)
symbolsRemapper.getReferencedClass(expression.classSymbol)
)
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrTypeOperatorCall =
@@ -413,7 +407,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.type,
expression.operator,
expression.typeOperand,
expression.argument.transform(this, null)
expression.argument.transform()
)
override fun visitWhen(expression: IrWhen): IrWhen =
@@ -421,21 +415,21 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.startOffset, expression.endOffset,
expression.type,
mapStatementOrigin(expression.origin),
expression.branches.map { it.transform(this, null) }
expression.branches.map { it.transform() }
)
override fun visitBranch(branch: IrBranch): IrBranch =
IrBranchImpl(
branch.startOffset, branch.endOffset,
branch.condition.transform(this, null),
branch.result.transform(this, null)
branch.condition.transform(),
branch.result.transform()
)
override fun visitElseBranch(branch: IrElseBranch): IrElseBranch =
IrElseBranchImpl(
branch.startOffset, branch.endOffset,
branch.condition.transform(this, null),
branch.result.transform(this, null)
branch.condition.transform(),
branch.result.transform()
)
private val transformedLoops = HashMap<IrLoop, IrLoop>()
@@ -443,26 +437,24 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
private fun getTransformedLoop(irLoop: IrLoop): IrLoop =
transformedLoops.getOrElse(irLoop) { getNonTransformedLoop(irLoop) }
protected open fun getNonTransformedLoop(irLoop: IrLoop): IrLoop =
private fun getNonTransformedLoop(irLoop: IrLoop): IrLoop =
throw AssertionError("Outer loop was not transformed: ${irLoop.render()}")
override fun visitWhileLoop(loop: IrWhileLoop): IrWhileLoop {
val newLoop = IrWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type, mapStatementOrigin(loop.origin))
transformedLoops[loop] = newLoop
newLoop.label = loop.label
newLoop.condition = loop.condition.transform(this, null)
newLoop.body = loop.body?.transform(this, null)
return newLoop
}
override fun visitWhileLoop(loop: IrWhileLoop): IrWhileLoop =
IrWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type, mapStatementOrigin(loop.origin)).also { newLoop ->
transformedLoops[loop] = newLoop
newLoop.label = loop.label
newLoop.condition = loop.condition.transform()
newLoop.body = loop.body?.transform()
}
override fun visitDoWhileLoop(loop: IrDoWhileLoop): IrDoWhileLoop {
val newLoop = IrDoWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type, mapStatementOrigin(loop.origin))
transformedLoops[loop] = newLoop
newLoop.label = loop.label
newLoop.condition = loop.condition.transform(this, null)
newLoop.body = loop.body?.transform(this, null)
return newLoop
}
override fun visitDoWhileLoop(loop: IrDoWhileLoop): IrDoWhileLoop =
IrDoWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type, mapStatementOrigin(loop.origin)).also { newLoop ->
transformedLoops[loop] = newLoop
newLoop.label = loop.label
newLoop.condition = loop.condition.transform()
newLoop.body = loop.body?.transform()
}
override fun visitBreak(jump: IrBreak): IrBreak =
IrBreakImpl(
@@ -482,38 +474,35 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
IrTryImpl(
aTry.startOffset, aTry.endOffset,
aTry.type,
aTry.tryResult.transform(this, null),
aTry.catches.map { it.transform(this, null) },
aTry.finallyExpression?.transform(this, null)
aTry.tryResult.transform(),
aTry.catches.map { it.transform() },
aTry.finallyExpression?.transform()
)
override fun visitCatch(aCatch: IrCatch): IrCatch =
IrCatchImpl(
aCatch.startOffset, aCatch.endOffset,
mapCatchParameterDeclaration(aCatch.parameter),
aCatch.result.transform(this, null)
aCatch.catchParameter.transform(),
aCatch.result.transform()
)
override fun visitReturn(expression: IrReturn): IrReturn =
IrReturnImpl(
expression.startOffset, expression.endOffset,
expression.type,
mapReturnTarget(expression.returnTarget),
expression.value.transform(this, null)
symbolsRemapper.getReferencedFunction(expression.returnTargetSymbol),
expression.value.transform()
)
override fun visitThrow(expression: IrThrow): IrThrow =
IrThrowImpl(
expression.startOffset, expression.endOffset,
expression.type,
expression.value.transform(this, null)
expression.value.transform()
)
override fun visitErrorDeclaration(declaration: IrErrorDeclaration): IrErrorDeclaration =
IrErrorDeclarationImpl(
declaration.startOffset, declaration.endOffset,
mapErrorDeclaration(declaration.descriptor)
)
IrErrorDeclarationImpl(declaration.startOffset, declaration.endOffset, declaration.descriptor)
override fun visitErrorExpression(expression: IrErrorExpression): IrErrorExpression =
IrErrorExpressionImpl(
@@ -528,7 +517,8 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.type,
expression.description
).apply {
explicitReceiver = expression.explicitReceiver?.transform(this@DeepCopyIrTree, null)
expression.arguments.mapTo(arguments) { it.transform(this@DeepCopyIrTree, null) }
explicitReceiver = expression.explicitReceiver?.transform()
expression.arguments.transformTo(arguments)
}
}
}
@@ -0,0 +1,145 @@
/*
* Copyright 2010-2017 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.ir.util
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
class DeepCopySymbolsRemapper : IrElementVisitorVoid {
private val classes = hashMapOf<IrClassSymbol, IrClassSymbol>()
private val constructors = hashMapOf<IrConstructorSymbol, IrConstructorSymbol>()
private val enumEntries = hashMapOf<IrEnumEntrySymbol, IrEnumEntrySymbol>()
private val externalPackageFragments = hashMapOf<IrExternalPackageFragmentSymbol, IrExternalPackageFragmentSymbol>()
private val fields = hashMapOf<IrFieldSymbol, IrFieldSymbol>()
private val files = hashMapOf<IrFileSymbol, IrFileSymbol>()
private val functions = hashMapOf<IrSimpleFunctionSymbol, IrSimpleFunctionSymbol>()
private val typeParameters = hashMapOf<IrTypeParameterSymbol, IrTypeParameterSymbol>()
private val valueParameters = hashMapOf<IrValueParameterSymbol, IrValueParameterSymbol>()
private val variables = hashMapOf<IrVariableSymbol, IrVariableSymbol>()
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
private inline fun <D : DeclarationDescriptor, B : IrSymbolOwner, reified S : IrBindableSymbol<D, B>>
remapSymbol(map: MutableMap<S, S>, owner: B, createNewSymbol: (S) -> S) {
val symbol = owner.symbol as S
map[symbol] = createNewSymbol(symbol)
}
override fun visitClass(declaration: IrClass) {
remapSymbol(classes, declaration) { IrClassSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitConstructor(declaration: IrConstructor) {
remapSymbol(constructors, declaration) { IrConstructorSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitEnumEntry(declaration: IrEnumEntry) {
remapSymbol(enumEntries, declaration) { IrEnumEntrySymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment) {
remapSymbol(externalPackageFragments, declaration) { IrExternalPackageFragmentSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitField(declaration: IrField) {
remapSymbol(fields, declaration) { IrFieldSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitFile(declaration: IrFile) {
remapSymbol(files, declaration) { IrFileSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
remapSymbol(functions, declaration) { IrSimpleFunctionSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitTypeParameter(declaration: IrTypeParameter) {
remapSymbol(typeParameters, declaration) { IrTypeParameterSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitValueParameter(declaration: IrValueParameter) {
remapSymbol(valueParameters, declaration) { IrValueParameterSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
override fun visitVariable(declaration: IrVariable) {
remapSymbol(variables, declaration) { IrVariableSymbolImpl(it.descriptor) }
declaration.acceptChildrenVoid(this)
}
private fun <T : IrSymbol> Map<T, T>.getDeclared(symbol: T) =
getOrElse(symbol) {
throw IllegalArgumentException("Non-remapped symbol $symbol ${symbol.descriptor}")
}
private fun <T : IrSymbol> Map<T, T>.getReferenced(symbol: T) =
getOrElse(symbol) { symbol }
fun getDeclaredClass(symbol: IrClassSymbol): IrClassSymbol = classes.getDeclared(symbol)
fun getDeclaredFunction(symbol: IrSimpleFunctionSymbol): IrSimpleFunctionSymbol = functions.getDeclared(symbol)
fun getDeclaredField(symbol: IrFieldSymbol): IrFieldSymbol = fields.getDeclared(symbol)
fun getDeclaredFile(symbol: IrFileSymbol): IrFileSymbol = files.getDeclared(symbol)
fun getDeclaredConstructor(symbol: IrConstructorSymbol): IrConstructorSymbol = constructors.getDeclared(symbol)
fun getDeclaredEnumEntry(symbol: IrEnumEntrySymbol): IrEnumEntrySymbol = enumEntries.getDeclared(symbol)
fun getDeclaredExternalPackageFragment(symbol: IrExternalPackageFragmentSymbol): IrExternalPackageFragmentSymbol = externalPackageFragments.getDeclared(symbol)
fun getDeclaredVariable(symbol: IrVariableSymbol): IrVariableSymbol = variables.getDeclared(symbol)
fun getDeclaredTypeParameter(symbol: IrTypeParameterSymbol): IrTypeParameterSymbol = typeParameters.getDeclared(symbol)
fun getDeclaredValueParameter(symbol: IrValueParameterSymbol): IrValueParameterSymbol = valueParameters.getDeclared(symbol)
fun getReferencedClass(symbol: IrClassSymbol): IrClassSymbol = classes.getReferenced(symbol)
fun getReferencedClassOrNull(symbol: IrClassSymbol?): IrClassSymbol? = symbol?.let { classes.getReferenced(it) }
fun getReferencedEnumEntry(symbol: IrEnumEntrySymbol): IrEnumEntrySymbol = enumEntries.getReferenced(symbol)
fun getReferencedVariable(symbol: IrVariableSymbol): IrVariableSymbol = variables.getReferenced(symbol)
fun getReferencedField(symbol: IrFieldSymbol): IrFieldSymbol = fields.getReferenced(symbol)
fun getReferencedConstructor(symbol: IrConstructorSymbol): IrConstructorSymbol = constructors.getReferenced(symbol)
fun getReferencedValue(symbol: IrValueSymbol): IrValueSymbol =
when (symbol) {
is IrValueParameterSymbol -> valueParameters.getReferenced(symbol)
is IrVariableSymbol -> variables.getReferenced(symbol)
else -> throw IllegalArgumentException("Unexpected symbol $symbol ${symbol.descriptor}")
}
fun getReferencedFunction(symbol: IrFunctionSymbol): IrFunctionSymbol =
when (symbol) {
is IrSimpleFunctionSymbol -> functions.getReferenced(symbol)
is IrConstructorSymbol -> constructors.getReferenced(symbol)
else -> throw IllegalArgumentException("Unexpected symbol $symbol ${symbol.descriptor}")
}
fun getReferencedClassifier(symbol: IrClassifierSymbol): IrClassifierSymbol =
when (symbol) {
is IrClassSymbol -> classes.getReferenced(symbol)
is IrTypeParameterSymbol -> typeParameters.getReferenced(symbol)
else -> throw IllegalArgumentException("Unexpected symbol $symbol ${symbol.descriptor}")
}
}
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -71,6 +68,14 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
}
}
override fun visitClass(declaration: IrClass, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.newInstanceReceiver?.accept(this, "\$new")
declaration.typeParameters.dumpElements()
declaration.declarations.dumpElements()
}
}
override fun visitFunction(declaration: IrFunction, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.typeParameters.dumpElements()
@@ -81,6 +86,15 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
}
}
override fun visitConstructor(declaration: IrConstructor, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.typeParameters.dumpElements()
declaration.dispatchReceiverParameter?.accept(this, "\$outer")
declaration.valueParameters.dumpElements()
declaration.body?.accept(this, "")
}
}
override fun visitProperty(declaration: IrProperty, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.typeParameters.dumpElements()
@@ -40,6 +40,9 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitModuleFragment(declaration: IrModuleFragment, data: Nothing?): String =
"MODULE_FRAGMENT ${declaration.descriptor.ref()}"
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: Nothing?): String =
"EXTERNAL_PACKAGE_FRAGMENT ${declaration.packageFragmentDescriptor.fqName}"
override fun visitFile(declaration: IrFile, data: Nothing?): String =
"FILE ${declaration.name}"
@@ -170,8 +173,30 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitThrow(expression: IrThrow, data: Nothing?): String =
"THROW type=${expression.type.render()}"
override fun visitCallableReference(expression: IrCallableReference, data: Nothing?): String =
"CALLABLE_REFERENCE '${expression.descriptor.ref()}' type=${expression.type.render()} origin=${expression.origin}"
override fun visitFunctionReference(expression: IrFunctionReference, data: Nothing?): String =
"FUNCTION_REFERENCE '${expression.descriptor.ref()}' type=${expression.type.render()} origin=${expression.origin}"
override fun visitPropertyReference(expression: IrPropertyReference, data: Nothing?): String =
buildString {
append("PROPERTY_REFERENCE ")
append("'${expression.descriptor.ref()}' ")
appendNullableAttribute("field=", expression.field) { "'${it.descriptor.ref()}'" }
appendNullableAttribute("getter=", expression.getter) { "'${it.descriptor.ref()}'" }
appendNullableAttribute("setter=", expression.setter) { "'${it.descriptor.ref()}'" }
append("type=${expression.type.render()} ")
append("origin=${expression.origin}")
}
private inline fun <T : Any> StringBuilder.appendNullableAttribute(prefix: String, value: T?, toString: (T) -> String) {
append(prefix)
if (value != null) {
append(toString(value))
}
else {
append("null")
}
append(" ")
}
override fun visitClassReference(expression: IrClassReference, data: Nothing?): String =
"CLASS_REFERENCE '${expression.descriptor.ref()}' type=${expression.type.render()}"
@@ -23,16 +23,19 @@ import org.jetbrains.kotlin.ir.expressions.*
interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
override fun visitElement(element: IrElement, data: D): IrElement =
element.apply { transformChildren(this@IrElementTransformer, data) }
element.also { it.transformChildren(this, data) }
override fun visitModuleFragment(declaration: IrModuleFragment, data: D): IrModuleFragment =
declaration.apply { transformChildren(this@IrElementTransformer, data) }
declaration.also { it.transformChildren(this, data) }
override fun visitFile(declaration: IrFile, data: D): IrFile =
declaration.apply { transformChildren(this@IrElementTransformer, data) }
declaration.also { it.transformChildren(this, data) }
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: D): IrExternalPackageFragment =
declaration.also { it.transformChildren(this, data) }
override fun visitDeclaration(declaration: IrDeclaration, data: D): IrStatement =
declaration.apply { transformChildren(this@IrElementTransformer, data) }
declaration.also { it.transformChildren(this, data) }
override fun visitClass(declaration: IrClass, data: D) = visitDeclaration(declaration, data)
override fun visitTypeAlias(declaration: IrTypeAlias, data: D) = visitDeclaration(declaration, data)
@@ -49,20 +52,20 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
override fun visitValueParameter(declaration: IrValueParameter, data: D) = visitDeclaration(declaration, data)
override fun visitBody(body: IrBody, data: D): IrBody =
body.apply { transformChildren(this@IrElementTransformer, data) }
body.also { it.transformChildren(this, data) }
override fun visitExpressionBody(body: IrExpressionBody, data: D) = visitBody(body, data)
override fun visitBlockBody(body: IrBlockBody, data: D) = visitBody(body, data)
override fun visitSyntheticBody(body: IrSyntheticBody, data: D) = visitBody(body, data)
override fun visitExpression(expression: IrExpression, data: D): IrExpression =
expression.apply { transformChildren(this@IrElementTransformer, data) }
expression.also { it.transformChildren(this, data) }
override fun <T> visitConst(expression: IrConst<T>, data: D) = visitExpression(expression, data)
override fun visitVararg(expression: IrVararg, data: D) = visitExpression(expression, data)
override fun visitSpreadElement(spread: IrSpreadElement, data: D): IrSpreadElement =
spread.apply { transformChildren(this@IrElementTransformer, data) }
spread.also { it.transformChildren(this, data) }
override fun visitContainerExpression(expression: IrContainerExpression, data: D) = visitExpression(expression, data)
override fun visitBlock(expression: IrBlock, data: D) = visitContainerExpression(expression, data)
@@ -79,13 +82,17 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
override fun visitFieldAccess(expression: IrFieldAccessExpression, data: D) = visitDeclarationReference(expression, data)
override fun visitGetField(expression: IrGetField, data: D) = visitFieldAccess(expression, data)
override fun visitSetField(expression: IrSetField, data: D) = visitFieldAccess(expression, data)
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: D): IrElement = visitDeclarationReference(expression, data)
override fun visitCall(expression: IrCall, data: D) = visitMemberAccess(expression, data)
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitMemberAccess(expression, data)
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: D) = visitMemberAccess(expression, data)
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: D): IrElement = visitExpression(expression, data)
override fun visitFunctionAccess(expression: IrFunctionAccessExpression, data: D): IrElement = visitMemberAccess(expression, data)
override fun visitCall(expression: IrCall, data: D) = visitFunctionAccess(expression, data)
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitFunctionAccess(expression, data)
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: D) = visitFunctionAccess(expression, data)
override fun visitGetClass(expression: IrGetClass, data: D) = visitExpression(expression, data)
override fun visitCallableReference(expression: IrCallableReference, data: D) = visitMemberAccess(expression, data)
override fun visitFunctionReference(expression: IrFunctionReference, data: D) = visitCallableReference(expression, data)
override fun visitPropertyReference(expression: IrPropertyReference, data: D) = visitCallableReference(expression, data)
override fun visitClassReference(expression: IrClassReference, data: D) = visitDeclarationReference(expression, data)
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: D) = visitExpression(expression, data)
@@ -95,15 +102,15 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
override fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data)
override fun visitBranch(branch: IrBranch, data: D): IrBranch =
branch.apply {
condition = condition.transform(this@IrElementTransformer, data)
result = result.transform(this@IrElementTransformer, data)
branch.also {
it.condition = it.condition.transform(this, data)
it.result = it.result.transform(this, data)
}
override fun visitElseBranch(branch: IrElseBranch, data: D): IrElseBranch =
branch.apply {
condition = condition.transform(this@IrElementTransformer, data)
result = result.transform(this@IrElementTransformer, data)
branch.also {
it.condition = it.condition.transform(this, data)
it.result = it.result.transform(this, data)
}
override fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
@@ -112,7 +119,7 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
override fun visitTry(aTry: IrTry, data: D) = visitExpression(aTry, data)
override fun visitCatch(aCatch: IrCatch, data: D): IrCatch =
aCatch.apply { transformChildren(this@IrElementTransformer, data) }
aCatch.also { it.transformChildren(this, data) }
override fun visitBreakContinue(jump: IrBreakContinue, data: D) = visitExpression(jump, data)
override fun visitBreak(jump: IrBreak, data: D) = visitBreakContinue(jump, data)
@@ -22,16 +22,25 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitElement(element: IrElement): IrElement = element.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
private fun <T : IrElement> T.transformChildren() = apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitElement(element: IrElement): IrElement = element.transformChildren()
override final fun visitElement(element: IrElement, data: Nothing?): IrElement = visitElement(element)
open fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment = declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment = declaration.transformChildren()
override final fun visitModuleFragment(declaration: IrModuleFragment, data: Nothing?): IrModuleFragment = visitModuleFragment(declaration)
open fun visitFile(declaration: IrFile): IrFile = declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitPackageFragment(declaration: IrPackageFragment): IrPackageFragment = declaration.transformChildren()
override fun visitPackageFragment(declaration: IrPackageFragment, data: Nothing?): IrElement = visitPackageFragment(declaration)
open fun visitFile(declaration: IrFile): IrFile = visitPackageFragment(declaration) as IrFile
override final fun visitFile(declaration: IrFile, data: Nothing?): IrFile = visitFile(declaration)
open fun visitDeclaration(declaration: IrDeclaration): IrStatement = declaration.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitExternalPackageFragment(declaration: IrExternalPackageFragment) = visitPackageFragment(declaration) as IrExternalPackageFragment
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: Nothing?): IrExternalPackageFragment =
visitExternalPackageFragment(declaration)
open fun visitDeclaration(declaration: IrDeclaration): IrStatement = declaration.transformChildren()
override final fun visitDeclaration(declaration: IrDeclaration, data: Nothing?): IrStatement = visitDeclaration(declaration)
open fun visitClass(declaration: IrClass) = visitDeclaration(declaration)
@@ -73,8 +82,7 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitVariable(declaration: IrVariable) = visitDeclaration(declaration)
override final fun visitVariable(declaration: IrVariable, data: Nothing?) = visitVariable(declaration)
open fun visitBody(body: IrBody): IrBody =
body.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitBody(body: IrBody): IrBody = body.transformChildren()
override final fun visitBody(body: IrBody, data: Nothing?): IrBody = visitBody(body)
open fun visitExpressionBody(body: IrExpressionBody) = visitBody(body)
@@ -86,7 +94,7 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitSyntheticBody(body: IrSyntheticBody) = visitBody(body)
override final fun visitSyntheticBody(body: IrSyntheticBody, data: Nothing?) = visitSyntheticBody(body)
open fun visitExpression(expression: IrExpression): IrExpression = expression.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitExpression(expression: IrExpression): IrExpression = expression.transformChildren()
override final fun visitExpression(expression: IrExpression, data: Nothing?): IrExpression = visitExpression(expression)
open fun <T> visitConst(expression: IrConst<T>) = visitExpression(expression)
@@ -95,7 +103,7 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitVararg(expression: IrVararg) = visitExpression(expression)
override final fun visitVararg(expression: IrVararg, data: Nothing?) = visitVararg(expression)
open fun visitSpreadElement(spread: IrSpreadElement) = spread.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitSpreadElement(spread: IrSpreadElement) = spread.transformChildren()
override final fun visitSpreadElement(spread: IrSpreadElement, data: Nothing?): IrSpreadElement = visitSpreadElement(spread)
open fun visitContainerExpression(expression: IrContainerExpression) = visitExpression(expression)
@@ -140,9 +148,12 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitSetField(expression: IrSetField) = visitFieldAccess(expression)
override final fun visitSetField(expression: IrSetField, data: Nothing?) = visitSetField(expression)
open fun visitMemberAccess(expression: IrMemberAccessExpression) = visitDeclarationReference(expression)
open fun visitMemberAccess(expression: IrMemberAccessExpression) = visitExpression(expression)
override final fun visitMemberAccess(expression: IrMemberAccessExpression, data: Nothing?) = visitMemberAccess(expression)
open fun visitFunctionAccess(expression: IrFunctionAccessExpression) = visitMemberAccess(expression)
override fun visitFunctionAccess(expression: IrFunctionAccessExpression, data: Nothing?) = visitFunctionAccess(expression)
open fun visitCall(expression: IrCall) = visitMemberAccess(expression)
override final fun visitCall(expression: IrCall, data: Nothing?) = visitCall(expression)
@@ -158,6 +169,12 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitCallableReference(expression: IrCallableReference) = visitMemberAccess(expression)
override final fun visitCallableReference(expression: IrCallableReference, data: Nothing?) = visitCallableReference(expression)
open fun visitFunctionReference(expression: IrFunctionReference) = visitCallableReference(expression)
override final fun visitFunctionReference(expression: IrFunctionReference, data: Nothing?): IrElement = visitFunctionReference(expression)
open fun visitPropertyReference(expression: IrPropertyReference) = visitCallableReference(expression)
override final fun visitPropertyReference(expression: IrPropertyReference, data: Nothing?): IrElement = visitPropertyReference(expression)
open fun visitClassReference(expression: IrClassReference) = visitDeclarationReference(expression)
override final fun visitClassReference(expression: IrClassReference, data: Nothing?) = visitClassReference(expression)
@@ -170,10 +187,10 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitWhen(expression: IrWhen) = visitExpression(expression)
override final fun visitWhen(expression: IrWhen, data: Nothing?) = visitWhen(expression)
open fun visitBranch(branch: IrBranch) = branch.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitBranch(branch: IrBranch) = branch.transformChildren()
override final fun visitBranch(branch: IrBranch, data: Nothing?): IrBranch = visitBranch(branch)
open fun visitElseBranch(branch: IrElseBranch) = branch.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
open fun visitElseBranch(branch: IrElseBranch) = branch.transformChildren()
override final fun visitElseBranch(branch: IrElseBranch, data: Nothing?): IrElseBranch = visitElseBranch(branch)
open fun visitLoop(loop: IrLoop) = visitExpression(loop)
@@ -23,7 +23,9 @@ import org.jetbrains.kotlin.ir.expressions.*
interface IrElementVisitor<out R, in D> {
fun visitElement(element: IrElement, data: D): R
fun visitModuleFragment(declaration: IrModuleFragment, data: D) = visitElement(declaration, data)
fun visitFile(declaration: IrFile, data: D) = visitElement(declaration, data)
fun visitPackageFragment(declaration: IrPackageFragment, data: D) = visitElement(declaration, data)
fun visitFile(declaration: IrFile, data: D) = visitPackageFragment(declaration, data)
fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: D) = visitPackageFragment(declaration, data)
fun visitDeclaration(declaration: IrDeclaration, data: D) = visitElement(declaration, data)
fun visitClass(declaration: IrClass, data: D) = visitDeclaration(declaration, data)
@@ -65,13 +67,18 @@ interface IrElementVisitor<out R, in D> {
fun visitFieldAccess(expression: IrFieldAccessExpression, data: D) = visitDeclarationReference(expression, data)
fun visitGetField(expression: IrGetField, data: D) = visitFieldAccess(expression, data)
fun visitSetField(expression: IrSetField, data: D) = visitFieldAccess(expression, data)
fun visitMemberAccess(expression: IrMemberAccessExpression, data: D) = visitDeclarationReference(expression, data)
fun visitCall(expression: IrCall, data: D) = visitMemberAccess(expression, data)
fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitMemberAccess(expression, data)
fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: D) = visitMemberAccess(expression, data)
fun visitMemberAccess(expression: IrMemberAccessExpression, data: D) = visitExpression(expression, data)
fun visitFunctionAccess(expression: IrFunctionAccessExpression, data: D) = visitMemberAccess(expression, data)
fun visitCall(expression: IrCall, data: D) = visitFunctionAccess(expression, data)
fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitFunctionAccess(expression, data)
fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: D) = visitFunctionAccess(expression, data)
fun visitGetClass(expression: IrGetClass, data: D) = visitExpression(expression, data)
fun visitCallableReference(expression: IrCallableReference, data: D) = visitMemberAccess(expression, data)
fun visitFunctionReference(expression: IrFunctionReference, data: D) = visitCallableReference(expression, data)
fun visitPropertyReference(expression: IrPropertyReference, data: D) = visitCallableReference(expression, data)
fun visitClassReference(expression: IrClassReference, data: D) = visitDeclarationReference(expression, data)
fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: D) = visitExpression(expression, data)
@@ -26,8 +26,14 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
fun visitModuleFragment(declaration: IrModuleFragment) = visitElement(declaration)
override fun visitModuleFragment(declaration: IrModuleFragment, data: Nothing?) = visitModuleFragment(declaration)
fun visitFile(declaration: IrFile) = visitElement(declaration)
fun visitPackageFragment(declaration: IrPackageFragment) = visitElement(declaration)
override fun visitPackageFragment(declaration: IrPackageFragment, data: Nothing?) = visitPackageFragment(declaration)
fun visitExternalPackageFragment(declaration: IrExternalPackageFragment) = visitPackageFragment(declaration)
override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: Nothing?) = visitExternalPackageFragment(declaration)
fun visitFile(declaration: IrFile) = visitPackageFragment(declaration)
override fun visitFile(declaration: IrFile, data: Nothing?) = visitFile(declaration)
fun visitDeclaration(declaration: IrDeclaration) = visitElement(declaration)
@@ -138,16 +144,19 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
fun visitSetField(expression: IrSetField) = visitFieldAccess(expression)
override fun visitSetField(expression: IrSetField, data: Nothing?) = visitSetField(expression)
fun visitMemberAccess(expression: IrMemberAccessExpression) = visitDeclarationReference(expression)
fun visitMemberAccess(expression: IrMemberAccessExpression) = visitExpression(expression)
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: Nothing?) = visitMemberAccess(expression)
fun visitCall(expression: IrCall) = visitMemberAccess(expression)
fun visitFunctionAccess(expression: IrFunctionAccessExpression) = visitMemberAccess(expression)
override fun visitFunctionAccess(expression: IrFunctionAccessExpression, data: Nothing?) = visitFunctionAccess(expression)
fun visitCall(expression: IrCall) = visitFunctionAccess(expression)
override fun visitCall(expression: IrCall, data: Nothing?) = visitCall(expression)
fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) = visitMemberAccess(expression)
fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) = visitFunctionAccess(expression)
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: Nothing?) = visitDelegatingConstructorCall(expression)
fun visitEnumConstructorCall(expression: IrEnumConstructorCall) = visitMemberAccess(expression)
fun visitEnumConstructorCall(expression: IrEnumConstructorCall) = visitFunctionAccess(expression)
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: Nothing?) = visitEnumConstructorCall(expression)
fun visitGetClass(expression: IrGetClass) = visitExpression(expression)
@@ -156,6 +165,12 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
fun visitCallableReference(expression: IrCallableReference) = visitMemberAccess(expression)
override fun visitCallableReference(expression: IrCallableReference, data: Nothing?) = visitCallableReference(expression)
fun visitFunctionReference(expression: IrFunctionReference) = visitCallableReference(expression)
override fun visitFunctionReference(expression: IrFunctionReference, data: Nothing?) = visitFunctionReference(expression)
fun visitPropertyReference(expression: IrPropertyReference) = visitCallableReference(expression)
override fun visitPropertyReference(expression: IrPropertyReference, data: Nothing?) = visitPropertyReference(expression)
fun visitClassReference(expression: IrClassReference) = visitDeclarationReference(expression)
override fun visitClassReference(expression: IrClassReference, data: Nothing?) = visitClassReference(expression)
@@ -1,5 +1,6 @@
FILE /argumentReorderingInDelegatingConstructorCall.kt
CLASS CLASS Base
$new: VALUE_PARAMETER <receiver: Base>
CONSTRUCTOR public constructor Base(x: kotlin.Int, y: kotlin.Int)
VALUE_PARAMETER value-parameter x: kotlin.Int
VALUE_PARAMETER value-parameter y: kotlin.Int
@@ -30,6 +31,7 @@ FILE /argumentReorderingInDelegatingConstructorCall.kt
FUN FAKE_OVERRIDE public open override fun hashCode(): kotlin.Int
FUN FAKE_OVERRIDE public open override fun toString(): kotlin.String
CLASS CLASS Test1
$new: VALUE_PARAMETER <receiver: Test1>
CONSTRUCTOR public constructor Test1(xx: kotlin.Int, yy: kotlin.Int)
VALUE_PARAMETER value-parameter xx: kotlin.Int
VALUE_PARAMETER value-parameter yy: kotlin.Int
@@ -51,6 +53,7 @@ FILE /argumentReorderingInDelegatingConstructorCall.kt
FUN FAKE_OVERRIDE public open override fun hashCode(): kotlin.Int
FUN FAKE_OVERRIDE public open override fun toString(): kotlin.String
CLASS CLASS Test2
$new: VALUE_PARAMETER <receiver: Test2>
CONSTRUCTOR public constructor Test2(xx: kotlin.Int, yy: kotlin.Int)
VALUE_PARAMETER value-parameter xx: kotlin.Int
VALUE_PARAMETER value-parameter yy: kotlin.Int
+3
View File
@@ -1,5 +1,6 @@
FILE /classMembers.kt
CLASS CLASS C
$new: VALUE_PARAMETER <receiver: C>
CONSTRUCTOR public constructor C(x: kotlin.Int, y: kotlin.Int, z: kotlin.Int = ...)
VALUE_PARAMETER value-parameter x: kotlin.Int
VALUE_PARAMETER value-parameter y: kotlin.Int
@@ -84,6 +85,7 @@ FILE /classMembers.kt
CALL 'println(Any?): Unit' type=kotlin.Unit origin=null
message: CONST String type=kotlin.String value='2'
CLASS CLASS NestedClass
$new: VALUE_PARAMETER <receiver: NestedClass>
CONSTRUCTOR public constructor NestedClass()
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
@@ -115,6 +117,7 @@ FILE /classMembers.kt
FUN FAKE_OVERRIDE public open override fun hashCode(): kotlin.Int
FUN FAKE_OVERRIDE public open override fun toString(): kotlin.String
CLASS OBJECT companion object of C
$new: VALUE_PARAMETER <receiver: companion object of C>
CONSTRUCTOR private constructor Companion()
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'

Some files were not shown because too many files have changed in this diff Show More