SyntheticAccessorLowering refactoring
This commit is contained in:
+63
-51
@@ -43,7 +43,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import kotlin.properties.Delegates
|
|
||||||
|
|
||||||
interface StubContext {
|
interface StubContext {
|
||||||
val irClassContext: IrClassContext
|
val irClassContext: IrClassContext
|
||||||
@@ -117,11 +116,11 @@ class SyntheticAccessorLowering(val state: GenerationState) : FileLoweringPass,
|
|||||||
override fun visitClass(declaration: IrClass, data: IrClassContext?): IrStatement {
|
override fun visitClass(declaration: IrClass, data: IrClassContext?): IrStatement {
|
||||||
val classContext = (declaration.descriptor.codegenContext as StubContext).irClassContext
|
val classContext = (declaration.descriptor.codegenContext as StubContext).irClassContext
|
||||||
return super.visitClass(declaration, classContext).apply {
|
return super.visitClass(declaration, classContext).apply {
|
||||||
lower(this as IrClass, classContext)
|
lower(classContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun lower(irCLass: IrClass, data: IrClassContext) {
|
fun lower(data: IrClassContext) {
|
||||||
val codegenContext = data.codegenContext
|
val codegenContext = data.codegenContext
|
||||||
val accessors = codegenContext.accessors
|
val accessors = codegenContext.accessors
|
||||||
val allAccessors =
|
val allAccessors =
|
||||||
@@ -131,70 +130,83 @@ class SyntheticAccessorLowering(val state: GenerationState) : FileLoweringPass,
|
|||||||
listOf(if (it.isWithSyntheticGetterAccessor) it.getter else null, if (it.isWithSyntheticSetterAccessor) it.setter else null).filterNotNull()
|
listOf(if (it.isWithSyntheticGetterAccessor) it.getter else null, if (it.isWithSyntheticSetterAccessor) it.setter else null).filterNotNull()
|
||||||
}
|
}
|
||||||
).filterIsInstance<AccessorForCallableDescriptor<*>>()
|
).filterIsInstance<AccessorForCallableDescriptor<*>>()
|
||||||
|
val irClassToAddAccessor = data.irClass
|
||||||
|
|
||||||
allAccessors.forEach { accessor ->
|
allAccessors.forEach { accessor ->
|
||||||
val accessorOwner = (accessor as FunctionDescriptor).containingDeclaration as ClassOrPackageFragmentDescriptor
|
addAccessorToClass(accessor, irClassToAddAccessor, state.typeMapper)
|
||||||
val body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
|
||||||
val accessorDescriptor = accessor.toStatic(accessorOwner, Name.identifier(state.typeMapper.mapAsmMethod(accessor).name))
|
|
||||||
val syntheticFunction = IrFunctionImpl(
|
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
|
|
||||||
accessorDescriptor, body
|
|
||||||
)
|
|
||||||
val calleeDescriptor = accessor.calleeDescriptor as FunctionDescriptor
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: IrClassContext?): IrElement {
|
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: IrClassContext?): IrElement {
|
||||||
val superResult = super.visitMemberAccess(expression, data)
|
val superResult = super.visitMemberAccess(expression, data)
|
||||||
val descriptor = expression.descriptor
|
return createSyntheticAccessorCallForFunction(superResult, expression, data?.codegenContext, state.typeMapper)
|
||||||
if (descriptor is FunctionDescriptor) {
|
}
|
||||||
val directAccessor = data!!.codegenContext.accessibleDescriptor(JvmCodegenUtil.getDirectMember(descriptor), (expression as? IrCall)?.superQualifier)
|
|
||||||
val accessor = actualAccessor(descriptor, directAccessor)
|
|
||||||
|
|
||||||
if (accessor is AccessorForCallableDescriptor<*> && descriptor !is AccessorForCallableDescriptor<*>) {
|
companion object {
|
||||||
val accessorOwner = accessor.containingDeclaration as ClassOrPackageFragmentDescriptor
|
fun createSyntheticAccessorCallForFunction(superResult: IrElement, expression: IrMemberAccessExpression, codegenContext: CodegenContext<*>?, typeMapper: KotlinTypeMapper): IrElement {
|
||||||
val staticAccessor = descriptor.toStatic(accessorOwner, Name.identifier(state.typeMapper.mapAsmMethod(accessor as FunctionDescriptor).name)) //TODO change call
|
|
||||||
val call = IrCallImpl(expression.startOffset, expression.endOffset, staticAccessor, emptyMap(), expression.origin/*TODO super*/)
|
val descriptor = expression.descriptor
|
||||||
//copyAllArgsToValueParams(call, expression)
|
if (descriptor is FunctionDescriptor) {
|
||||||
expression.receiverAndArgs().forEachIndexed { i, irExpression ->
|
val directAccessor = codegenContext!!.accessibleDescriptor(JvmCodegenUtil.getDirectMember(descriptor), (expression as? IrCall)?.superQualifier)
|
||||||
call.putValueArgument(i, irExpression)
|
val accessor = Companion.actualAccessor(descriptor, directAccessor)
|
||||||
|
|
||||||
|
if (accessor is AccessorForCallableDescriptor<*> && descriptor !is AccessorForCallableDescriptor<*>) {
|
||||||
|
val accessorOwner = accessor.containingDeclaration as ClassOrPackageFragmentDescriptor
|
||||||
|
val staticAccessor = descriptor.toStatic(accessorOwner, Name.identifier(typeMapper.mapAsmMethod(accessor as FunctionDescriptor).name)) //TODO change call
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
return call
|
||||||
}
|
}
|
||||||
return call
|
|
||||||
}
|
}
|
||||||
|
return superResult
|
||||||
}
|
}
|
||||||
return superResult
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun actualAccessor(descriptor: FunctionDescriptor, calculatedAccessor: CallableMemberDescriptor): CallableMemberDescriptor {
|
fun addAccessorToClass(accessor: AccessorForCallableDescriptor<*>, irClassToAddAccessor: IrClass, typeMapper: KotlinTypeMapper) {
|
||||||
if (calculatedAccessor is AccessorForPropertyDescriptor) {
|
val accessorOwner = (accessor as FunctionDescriptor).containingDeclaration as ClassOrPackageFragmentDescriptor
|
||||||
val isGetter = descriptor is PropertyGetterDescriptor
|
val body = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||||
val propertyAccessor = if (isGetter) calculatedAccessor.getter!! else calculatedAccessor.setter!!
|
val accessorDescriptor = accessor.toStatic(accessorOwner, Name.identifier(typeMapper.mapAsmMethod(accessor).name))
|
||||||
if (isGetter && calculatedAccessor.isWithSyntheticGetterAccessor || !isGetter && calculatedAccessor.isWithSyntheticSetterAccessor) {
|
val syntheticFunction = IrFunctionImpl(
|
||||||
return propertyAccessor
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR,
|
||||||
|
accessorDescriptor, body
|
||||||
|
)
|
||||||
|
val calleeDescriptor = accessor.calleeDescriptor as FunctionDescriptor
|
||||||
|
val returnExpr = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, calleeDescriptor)
|
||||||
|
Companion.copyAllArgsToValueParams(returnExpr, accessorDescriptor)
|
||||||
|
body.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, accessor, returnExpr))
|
||||||
|
irClassToAddAccessor.declarations.add(syntheticFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun actualAccessor(descriptor: FunctionDescriptor, calculatedAccessor: CallableMemberDescriptor): CallableMemberDescriptor {
|
||||||
|
if (calculatedAccessor is AccessorForPropertyDescriptor) {
|
||||||
|
val isGetter = descriptor is PropertyGetterDescriptor
|
||||||
|
val propertyAccessor = if (isGetter) calculatedAccessor.getter!! else calculatedAccessor.setter!!
|
||||||
|
if (isGetter && calculatedAccessor.isWithSyntheticGetterAccessor || !isGetter && calculatedAccessor.isWithSyntheticSetterAccessor) {
|
||||||
|
return propertyAccessor
|
||||||
|
}
|
||||||
|
return descriptor
|
||||||
|
|
||||||
}
|
}
|
||||||
return descriptor
|
return calculatedAccessor
|
||||||
|
|
||||||
}
|
|
||||||
return calculatedAccessor
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun copyAllArgsToValueParams(call: IrCallImpl, fromDescriptor: CallableMemberDescriptor) {
|
|
||||||
var offset = 0
|
|
||||||
val newDescriptor = call.descriptor
|
|
||||||
newDescriptor.dispatchReceiverParameter?.let {
|
|
||||||
call.dispatchReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[offset++])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newDescriptor.extensionReceiverParameter?.let {
|
private fun copyAllArgsToValueParams(call: IrCallImpl, fromDescriptor: CallableMemberDescriptor) {
|
||||||
call.extensionReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[offset++])
|
var offset = 0
|
||||||
}
|
val newDescriptor = call.descriptor
|
||||||
|
newDescriptor.dispatchReceiverParameter?.let {
|
||||||
|
call.dispatchReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[offset++])
|
||||||
|
}
|
||||||
|
|
||||||
call.descriptor.valueParameters.forEachIndexed { i, _ ->
|
newDescriptor.extensionReceiverParameter?.let {
|
||||||
call.putValueArgument(i, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[i + offset]))
|
call.extensionReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[offset++])
|
||||||
|
}
|
||||||
|
|
||||||
|
call.descriptor.valueParameters.forEachIndexed { i, _ ->
|
||||||
|
call.putValueArgument(i, IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, fromDescriptor.valueParameters[i + offset]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user