Minor: reformat
This commit is contained in:
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
|
import org.jetbrains.kotlin.resolve.PropertyImportedFromObject
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
@@ -46,14 +45,14 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
|||||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||||
|
|
||||||
class PropertyReferenceCodegen(
|
class PropertyReferenceCodegen(
|
||||||
state: GenerationState,
|
state: GenerationState,
|
||||||
parentCodegen: MemberCodegen<*>,
|
parentCodegen: MemberCodegen<*>,
|
||||||
context: ClassContext,
|
context: ClassContext,
|
||||||
expression: KtElement,
|
expression: KtElement,
|
||||||
classBuilder: ClassBuilder,
|
classBuilder: ClassBuilder,
|
||||||
private val localVariableDescriptorForReference: VariableDescriptor,
|
private val localVariableDescriptorForReference: VariableDescriptor,
|
||||||
private val target: VariableDescriptor,
|
private val target: VariableDescriptor,
|
||||||
private val receiverType: Type?
|
private val receiverType: Type?
|
||||||
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
|
) : MemberCodegen<KtElement>(state, parentCodegen, context, expression, classBuilder) {
|
||||||
private val classDescriptor = context.contextDescriptor
|
private val classDescriptor = context.contextDescriptor
|
||||||
private val asmType = typeMapper.mapClass(classDescriptor)
|
private val asmType = typeMapper.mapClass(classDescriptor)
|
||||||
@@ -64,10 +63,10 @@ class PropertyReferenceCodegen(
|
|||||||
private val isLocalDelegatedProperty = target is LocalVariableDescriptor
|
private val isLocalDelegatedProperty = target is LocalVariableDescriptor
|
||||||
|
|
||||||
private val getFunction =
|
private val getFunction =
|
||||||
if (isLocalDelegatedProperty)
|
if (isLocalDelegatedProperty)
|
||||||
(localVariableDescriptorForReference as VariableDescriptorWithAccessors).getter!!
|
(localVariableDescriptorForReference as VariableDescriptorWithAccessors).getter!!
|
||||||
else
|
else
|
||||||
findGetFunction(localVariableDescriptorForReference).original
|
findGetFunction(localVariableDescriptorForReference).original
|
||||||
|
|
||||||
// e.g. mutableProperty0(Lkotlin/jvm/internal/MutablePropertyReference0;)Lkotlin/reflect/KMutableProperty0;
|
// e.g. mutableProperty0(Lkotlin/jvm/internal/MutablePropertyReference0;)Lkotlin/reflect/KMutableProperty0;
|
||||||
private val wrapperMethod = getWrapperMethodForPropertyReference(target, getFunction.valueParameters.size)
|
private val wrapperMethod = getWrapperMethodForPropertyReference(target, getFunction.valueParameters.size)
|
||||||
@@ -75,7 +74,7 @@ class PropertyReferenceCodegen(
|
|||||||
private val closure = bindingContext.get(CodegenBinding.CLOSURE, classDescriptor)!!.apply {
|
private val closure = bindingContext.get(CodegenBinding.CLOSURE, classDescriptor)!!.apply {
|
||||||
assert((captureReceiverType != null) == (receiverType != null)) {
|
assert((captureReceiverType != null) == (receiverType != null)) {
|
||||||
"Bound property reference can only be generated with the type of the receiver. " +
|
"Bound property reference can only be generated with the type of the receiver. " +
|
||||||
"Captured type = $captureReceiverType, actual type = $receiverType"
|
"Captured type = $captureReceiverType, actual type = $receiverType"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,13 +85,13 @@ class PropertyReferenceCodegen(
|
|||||||
|
|
||||||
override fun generateDeclaration() {
|
override fun generateDeclaration() {
|
||||||
v.defineClass(
|
v.defineClass(
|
||||||
element,
|
element,
|
||||||
state.classFileVersion,
|
state.classFileVersion,
|
||||||
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForClass(classDescriptor),
|
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForClass(classDescriptor),
|
||||||
asmType.internalName,
|
asmType.internalName,
|
||||||
null,
|
null,
|
||||||
superAsmType.internalName,
|
superAsmType.internalName,
|
||||||
emptyArray()
|
emptyArray()
|
||||||
)
|
)
|
||||||
|
|
||||||
v.visitSource(element.containingFile.name, null)
|
v.visitSource(element.containingFile.name, null)
|
||||||
@@ -102,8 +101,7 @@ class PropertyReferenceCodegen(
|
|||||||
override fun generateBody() {
|
override fun generateBody() {
|
||||||
if (JvmCodegenUtil.isConst(closure)) {
|
if (JvmCodegenUtil.isConst(closure)) {
|
||||||
generateConstInstance(asmType, wrapperMethod.returnType)
|
generateConstInstance(asmType, wrapperMethod.returnType)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
AsmUtil.genClosureFields(closure, v, typeMapper)
|
AsmUtil.genClosureFields(closure, v, typeMapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,8 +133,7 @@ class PropertyReferenceCodegen(
|
|||||||
assert(!shouldHaveBoundReferenceReceiver) { "No bound reference receiver in constructor parameters: $constructorArgs" }
|
assert(!shouldHaveBoundReferenceReceiver) { "No bound reference receiver in constructor parameters: $constructorArgs" }
|
||||||
load(0, OBJECT_TYPE)
|
load(0, OBJECT_TYPE)
|
||||||
invokespecial(superAsmType.internalName, "<init>", "()V", false)
|
invokespecial(superAsmType.internalName, "<init>", "()V", false)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val (receiverIndex, receiverType) = receiverIndexAndType
|
val (receiverIndex, receiverType) = receiverIndexAndType
|
||||||
load(0, OBJECT_TYPE)
|
load(0, OBJECT_TYPE)
|
||||||
loadBoundReferenceReceiverParameter(receiverIndex, receiverType)
|
loadBoundReferenceReceiverParameter(receiverIndex, receiverType)
|
||||||
@@ -148,16 +145,44 @@ class PropertyReferenceCodegen(
|
|||||||
private fun generateAccessors() {
|
private fun generateAccessors() {
|
||||||
val getFunction = findGetFunction(localVariableDescriptorForReference)
|
val getFunction = findGetFunction(localVariableDescriptorForReference)
|
||||||
val getImpl = createFakeOpenDescriptor(getFunction, classDescriptor)
|
val getImpl = createFakeOpenDescriptor(getFunction, classDescriptor)
|
||||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, getImpl, PropertyReferenceGenerationStrategy(true, getFunction, target, asmType, receiverType, element, state, false))
|
functionCodegen.generateMethod(
|
||||||
|
JvmDeclarationOrigin.NO_ORIGIN,
|
||||||
|
getImpl,
|
||||||
|
PropertyReferenceGenerationStrategy(
|
||||||
|
true,
|
||||||
|
getFunction,
|
||||||
|
target,
|
||||||
|
asmType,
|
||||||
|
receiverType,
|
||||||
|
element,
|
||||||
|
state,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if (!ReflectionTypes.isNumberedKMutablePropertyType(localVariableDescriptorForReference.type)) return
|
if (!ReflectionTypes.isNumberedKMutablePropertyType(localVariableDescriptorForReference.type)) return
|
||||||
val setFunction = localVariableDescriptorForReference.type.memberScope.getContributedFunctions(OperatorNameConventions.SET, NoLookupLocation.FROM_BACKEND).single()
|
val setFunction = localVariableDescriptorForReference.type.memberScope.getContributedFunctions(
|
||||||
|
OperatorNameConventions.SET,
|
||||||
|
NoLookupLocation.FROM_BACKEND
|
||||||
|
).single()
|
||||||
val setImpl = createFakeOpenDescriptor(setFunction, classDescriptor)
|
val setImpl = createFakeOpenDescriptor(setFunction, classDescriptor)
|
||||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, setImpl, PropertyReferenceGenerationStrategy(false, setFunction, target, asmType, receiverType, element, state, false))
|
functionCodegen.generateMethod(
|
||||||
|
JvmDeclarationOrigin.NO_ORIGIN,
|
||||||
|
setImpl,
|
||||||
|
PropertyReferenceGenerationStrategy(
|
||||||
|
false,
|
||||||
|
setFunction,
|
||||||
|
target,
|
||||||
|
asmType,
|
||||||
|
receiverType,
|
||||||
|
element,
|
||||||
|
state,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private fun generateMethod(debugString: String, access: Int, method: Method, generate: InstructionAdapter.() -> Unit) {
|
private fun generateMethod(debugString: String, access: Int, method: Method, generate: InstructionAdapter.() -> Unit) {
|
||||||
v.generateMethod(debugString, access, method, element, JvmDeclarationOrigin.NO_ORIGIN, state, generate)
|
v.generateMethod(debugString, access, method, element, JvmDeclarationOrigin.NO_ORIGIN, state, generate)
|
||||||
}
|
}
|
||||||
@@ -171,8 +196,7 @@ class PropertyReferenceCodegen(
|
|||||||
if (JvmCodegenUtil.isConst(closure)) {
|
if (JvmCodegenUtil.isConst(closure)) {
|
||||||
assert(receiverValue == null) { "No receiver expected for unbound property reference: $classDescriptor" }
|
assert(receiverValue == null) { "No receiver expected for unbound property reference: $classDescriptor" }
|
||||||
iv.getstatic(asmType.internalName, JvmAbi.INSTANCE_FIELD, wrapperMethod.returnType.descriptor)
|
iv.getstatic(asmType.internalName, JvmAbi.INSTANCE_FIELD, wrapperMethod.returnType.descriptor)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
assert(receiverValue != null) { "Receiver expected for bound property reference: $classDescriptor" }
|
assert(receiverValue != null) { "Receiver expected for bound property reference: $classDescriptor" }
|
||||||
iv.anew(asmType)
|
iv.anew(asmType)
|
||||||
iv.dup()
|
iv.dup()
|
||||||
@@ -203,7 +227,7 @@ class PropertyReferenceCodegen(
|
|||||||
fun getSignatureString(callable: CallableDescriptor, state: GenerationState): String {
|
fun getSignatureString(callable: CallableDescriptor, state: GenerationState): String {
|
||||||
if (callable is LocalVariableDescriptor) {
|
if (callable is LocalVariableDescriptor) {
|
||||||
val asmType = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, callable)
|
val asmType = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, callable)
|
||||||
?: throw AssertionError("No delegated property metadata owner for $callable")
|
?: throw AssertionError("No delegated property metadata owner for $callable")
|
||||||
val localDelegatedProperties = CodegenBinding.getLocalDelegatedProperties(state.bindingContext, asmType)
|
val localDelegatedProperties = CodegenBinding.getLocalDelegatedProperties(state.bindingContext, asmType)
|
||||||
val index = localDelegatedProperties?.indexOf(callable) ?: -1
|
val index = localDelegatedProperties?.indexOf(callable) ?: -1
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
@@ -215,8 +239,7 @@ class PropertyReferenceCodegen(
|
|||||||
val accessor = when (callable) {
|
val accessor = when (callable) {
|
||||||
is FunctionDescriptor -> callable
|
is FunctionDescriptor -> callable
|
||||||
is VariableDescriptorWithAccessors ->
|
is VariableDescriptorWithAccessors ->
|
||||||
callable.getter ?:
|
callable.getter ?: DescriptorFactory.createDefaultGetter(callable as PropertyDescriptor, Annotations.EMPTY).apply {
|
||||||
DescriptorFactory.createDefaultGetter(callable as PropertyDescriptor, Annotations.EMPTY).apply {
|
|
||||||
initialize(callable.type)
|
initialize(callable.type)
|
||||||
}
|
}
|
||||||
else -> error("Unsupported callable reference: $callable")
|
else -> error("Unsupported callable reference: $callable")
|
||||||
@@ -251,20 +274,24 @@ class PropertyReferenceCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun findGetFunction(localVariableDescriptorForReference: VariableDescriptor) = localVariableDescriptorForReference.type.memberScope.getContributedFunctions(OperatorNameConventions.GET, NoLookupLocation.FROM_BACKEND).single()
|
fun findGetFunction(localVariableDescriptorForReference: VariableDescriptor) =
|
||||||
|
localVariableDescriptorForReference.type.memberScope.getContributedFunctions(
|
||||||
|
OperatorNameConventions.GET,
|
||||||
|
NoLookupLocation.FROM_BACKEND
|
||||||
|
).single()
|
||||||
}
|
}
|
||||||
|
|
||||||
class PropertyReferenceGenerationStrategy(
|
class PropertyReferenceGenerationStrategy(
|
||||||
val isGetter: Boolean,
|
val isGetter: Boolean,
|
||||||
private val originalFunctionDesc: FunctionDescriptor,
|
private val originalFunctionDesc: FunctionDescriptor,
|
||||||
val target: VariableDescriptor,
|
val target: VariableDescriptor,
|
||||||
val asmType: Type,
|
val asmType: Type,
|
||||||
val receiverType: Type?,
|
val receiverType: Type?,
|
||||||
val expression: KtElement,
|
val expression: KtElement,
|
||||||
state: GenerationState,
|
state: GenerationState,
|
||||||
private val isInliningStrategy: Boolean
|
private val isInliningStrategy: Boolean
|
||||||
) :
|
) :
|
||||||
FunctionGenerationStrategy.CodegenBased(state) {
|
FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
val v = codegen.v
|
val v = codegen.v
|
||||||
val typeMapper = state.typeMapper
|
val typeMapper = state.typeMapper
|
||||||
@@ -276,11 +303,11 @@ class PropertyReferenceCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (receiverType != null) {
|
if (receiverType != null) {
|
||||||
val expectedReceiver = target.extensionReceiverParameter?.type ?: (target.containingDeclaration as? ClassDescriptor)?.defaultType
|
val expectedReceiver =
|
||||||
|
target.extensionReceiverParameter?.type ?: (target.containingDeclaration as? ClassDescriptor)?.defaultType
|
||||||
val expectedReceiverType = if (expectedReceiver != null) typeMapper.mapType(expectedReceiver) else receiverType
|
val expectedReceiverType = if (expectedReceiver != null) typeMapper.mapType(expectedReceiver) else receiverType
|
||||||
capturedBoundReferenceReceiver(asmType, expectedReceiverType, isInliningStrategy).put(expectedReceiverType, v)
|
capturedBoundReferenceReceiver(asmType, expectedReceiverType, isInliningStrategy).put(expectedReceiverType, v)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val receivers = originalFunctionDesc.valueParameters.dropLast(if (isGetter) 0 else 1)
|
val receivers = originalFunctionDesc.valueParameters.dropLast(if (isGetter) 0 else 1)
|
||||||
receivers.forEachIndexed { i, valueParameterDescriptor ->
|
receivers.forEachIndexed { i, valueParameterDescriptor ->
|
||||||
StackValue.local(i + 1, OBJECT_TYPE).put(typeMapper.mapType(valueParameterDescriptor), valueParameterDescriptor.type, v)
|
StackValue.local(i + 1, OBJECT_TYPE).put(typeMapper.mapType(valueParameterDescriptor), valueParameterDescriptor.type, v)
|
||||||
@@ -289,15 +316,14 @@ class PropertyReferenceCodegen(
|
|||||||
|
|
||||||
val value = if (target is LocalVariableDescriptor) {
|
val value = if (target is LocalVariableDescriptor) {
|
||||||
codegen.findLocalOrCapturedValue(target)!!
|
codegen.findLocalOrCapturedValue(target)!!
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
codegen.intermediateValueForProperty(target as PropertyDescriptor, false, null, StackValue.none())
|
codegen.intermediateValueForProperty(target as PropertyDescriptor, false, null, StackValue.none())
|
||||||
|
}
|
||||||
|
|
||||||
codegen.markStartLineNumber(expression)
|
codegen.markStartLineNumber(expression)
|
||||||
if (isGetter) {
|
if (isGetter) {
|
||||||
value.put(OBJECT_TYPE, v)
|
value.put(OBJECT_TYPE, v)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val functionDescriptor = codegen.context.functionDescriptor
|
val functionDescriptor = codegen.context.functionDescriptor
|
||||||
value.store(StackValue.local(codegen.frameMap.getIndex(functionDescriptor.valueParameters.last()), OBJECT_TYPE), v)
|
value.store(StackValue.local(codegen.frameMap.getIndex(functionDescriptor.valueParameters.last()), OBJECT_TYPE), v)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user