Use symbols in synthetic accessor to access accessor parameters

This commit is contained in:
Mikhael Bogdanov
2018-04-26 17:40:27 +02:00
parent 92e02e35fc
commit e793a7eea7
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrCall
@@ -167,7 +168,7 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
val isConstructor = descriptor is ConstructorDescriptor val isConstructor = descriptor is ConstructorDescriptor
val accessorOwner = accessor.containingDeclaration as ClassOrPackageFragmentDescriptor val accessorOwner = accessor.containingDeclaration as ClassOrPackageFragmentDescriptor
val accessorForIr = val accessorForIr =
accessorToIrAccessor(isConstructor, accessor, context, descriptor, accessorOwner) //TODO change call accessorToIrAccessorDescriptor(isConstructor, accessor, context, descriptor, accessorOwner) //TODO change call
val call = val call =
if (isConstructor && expression is IrDelegatingConstructorCall) if (isConstructor && expression is IrDelegatingConstructorCall)
@@ -187,7 +188,7 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
return superResult return superResult
} }
private fun accessorToIrAccessor(isConstructor: Boolean, accessor: CallableMemberDescriptor, context: JvmBackendContext, descriptor: FunctionDescriptor, accessorOwner: ClassOrPackageFragmentDescriptor): FunctionDescriptor { private fun accessorToIrAccessorDescriptor(isConstructor: Boolean, accessor: CallableMemberDescriptor, context: JvmBackendContext, descriptor: FunctionDescriptor, accessorOwner: ClassOrPackageFragmentDescriptor): FunctionDescriptor {
return if (isConstructor) return if (isConstructor)
(accessor as AccessorForConstructorDescriptor).constructorDescriptorWithMarker( (accessor as AccessorForConstructorDescriptor).constructorDescriptorWithMarker(
context.ir.symbols.defaultConstructorMarker.descriptor.defaultType context.ir.symbols.defaultConstructorMarker.descriptor.defaultType
@@ -199,7 +200,7 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
val accessorOwner = (accessor as FunctionDescriptor).containingDeclaration as ClassOrPackageFragmentDescriptor val accessorOwner = (accessor as FunctionDescriptor).containingDeclaration as ClassOrPackageFragmentDescriptor
val body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET) val body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
val isConstructor = accessor.calleeDescriptor is ConstructorDescriptor val isConstructor = accessor.calleeDescriptor is ConstructorDescriptor
val accessorForIr = accessorToIrAccessor( val accessorForIr = accessorToIrAccessorDescriptor(
isConstructor, accessor, context, isConstructor, accessor, context,
accessor.calleeDescriptor as? FunctionDescriptor ?: return, accessor.calleeDescriptor as? FunctionDescriptor ?: return,
accessorOwner) accessorOwner)
@@ -214,16 +215,23 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
val calleeDescriptor = accessor.calleeDescriptor as FunctionDescriptor val calleeDescriptor = accessor.calleeDescriptor as FunctionDescriptor
val delegationCall = val delegationCall =
if (!isConstructor) if (!isConstructor)
IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, calleeDescriptor) IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, calleeDescriptor)
else IrDelegatingConstructorCallImpl( else IrDelegatingConstructorCallImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET, UNDEFINED_OFFSET,
createFunctionSymbol(accessor.calleeDescriptor) as IrConstructorSymbol, createFunctionSymbol(accessor.calleeDescriptor) as IrConstructorSymbol,
accessor.calleeDescriptor as ClassConstructorDescriptor accessor.calleeDescriptor as ClassConstructorDescriptor
) )
copyAllArgsToValueParams(delegationCall, accessorForIr) copyAllArgsToValueParams(delegationCall, syntheticFunction)
body.statements.add(if (isConstructor) delegationCall else IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, accessor, delegationCall)) body.statements.add(
if (isConstructor) delegationCall else IrReturnImpl(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
syntheticFunction.symbol,
delegationCall
)
)
irClassToAddAccessor.declarations.add(syntheticFunction) irClassToAddAccessor.declarations.add(syntheticFunction)
} }
@@ -240,19 +248,22 @@ class SyntheticAccessorLowering(val context: JvmBackendContext) : FileLoweringPa
return calculatedAccessor return calculatedAccessor
} }
private fun copyAllArgsToValueParams(call: IrMemberAccessExpression, fromDescriptor: CallableMemberDescriptor) { private fun copyAllArgsToValueParams(
call: IrMemberAccessExpression,
syntheticFunction: IrFunction
) {
var offset = 0 var offset = 0
val newDescriptor = call.descriptor val delegateTo = call.descriptor
newDescriptor.dispatchReceiverParameter?.let { delegateTo.dispatchReceiverParameter?.let {
call.dispatchReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[offset++]) call.dispatchReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
} }
newDescriptor.extensionReceiverParameter?.let { delegateTo.extensionReceiverParameter?.let {
call.extensionReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[offset++]) call.extensionReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[offset++].symbol)
} }
call.descriptor.valueParameters.forEachIndexed { i, _ -> call.descriptor.valueParameters.forEachIndexed { i, _ ->
call.putValueArgument(i, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[i + offset])) call.putValueArgument(i, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, syntheticFunction.valueParameters[i + offset].symbol))
} }
} }