Rename receiver$0 in CallableReference to receiver
#KT-15449 Fixed
This commit is contained in:
@@ -95,6 +95,7 @@ public class AsmUtil {
|
||||
.put(JavaVisibilities.PACKAGE_VISIBILITY, NO_FLAG_PACKAGE_PRIVATE)
|
||||
.build();
|
||||
|
||||
public static final String BOUND_REFERENCE_RECEIVER = "receiver";
|
||||
public static final String RECEIVER_NAME = "$receiver";
|
||||
public static final String CAPTURED_RECEIVER_FIELD = "receiver$0";
|
||||
public static final String CAPTURED_THIS_FIELD = "this$0";
|
||||
|
||||
@@ -91,7 +91,6 @@ import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeProjection;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS;
|
||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
@@ -3269,7 +3268,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
|
||||
if (functionDescriptor != null) {
|
||||
FunctionReferenceGenerationStrategy strategy =
|
||||
new FunctionReferenceGenerationStrategy(state, functionDescriptor, resolvedCall, receiverAsmType, null);
|
||||
new FunctionReferenceGenerationStrategy(state, functionDescriptor, resolvedCall, receiverAsmType, null, false);
|
||||
|
||||
return genClosure(
|
||||
expression, functionDescriptor, strategy, null,
|
||||
|
||||
+5
-2
@@ -42,13 +42,15 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
private final FunctionDescriptor functionDescriptor;
|
||||
private final Type receiverType; // non-null for bound references
|
||||
private final StackValue receiverValue;
|
||||
private final boolean isInliningStrategy;
|
||||
|
||||
public FunctionReferenceGenerationStrategy(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull ResolvedCall<?> resolvedCall,
|
||||
@Nullable Type receiverType,
|
||||
@Nullable StackValue receiverValue
|
||||
@Nullable StackValue receiverValue,
|
||||
boolean isInliningStrategy
|
||||
) {
|
||||
super(state);
|
||||
this.resolvedCall = resolvedCall;
|
||||
@@ -56,6 +58,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
this.functionDescriptor = functionDescriptor;
|
||||
this.receiverType = receiverType;
|
||||
this.receiverValue = receiverValue;
|
||||
this.isInliningStrategy = isInliningStrategy;
|
||||
assert receiverType != null || receiverValue == null
|
||||
: "A receiver value is provided for unbound function reference. Either this is a bound reference and you forgot " +
|
||||
"to pass receiverType, or you accidentally passed some receiverValue for a reference without receiver";
|
||||
@@ -187,7 +190,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
|
||||
if (receiverType != null) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) codegen.getContext().getParentContext().getContextDescriptor();
|
||||
Type asmType = codegen.getState().getTypeMapper().mapClass(classDescriptor);
|
||||
return CallableReferenceUtilKt.capturedBoundReferenceReceiver(asmType, receiverType);
|
||||
return CallableReferenceUtilKt.capturedBoundReferenceReceiver(asmType, receiverType, isInliningStrategy);
|
||||
}
|
||||
|
||||
// 0 is this (the callable reference class), 1 is the invoke() method's first parameter
|
||||
|
||||
@@ -146,12 +146,12 @@ class PropertyReferenceCodegen(
|
||||
private fun generateAccessors() {
|
||||
val getFunction = findGetFunction(localVariableDescriptorForReference)
|
||||
val getImpl = createFakeOpenDescriptor(getFunction, classDescriptor)
|
||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, getImpl, PropertyReferenceGenerationStrategy(true, getFunction, target, asmType, receiverType, element, state))
|
||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, getImpl, PropertyReferenceGenerationStrategy(true, getFunction, target, asmType, receiverType, element, state, false))
|
||||
|
||||
if (!ReflectionTypes.isNumberedKMutablePropertyType(localVariableDescriptorForReference.type)) return
|
||||
val setFunction = localVariableDescriptorForReference.type.memberScope.getContributedFunctions(OperatorNameConventions.SET, NoLookupLocation.FROM_BACKEND).single()
|
||||
val setImpl = createFakeOpenDescriptor(setFunction, classDescriptor)
|
||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, setImpl, PropertyReferenceGenerationStrategy(false, setFunction, target, asmType, receiverType, element, state))
|
||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, setImpl, PropertyReferenceGenerationStrategy(false, setFunction, target, asmType, receiverType, element, state, false))
|
||||
}
|
||||
|
||||
|
||||
@@ -243,7 +243,8 @@ class PropertyReferenceCodegen(
|
||||
val asmType: Type,
|
||||
val receiverType: Type?,
|
||||
val expression: KtElement,
|
||||
state: GenerationState
|
||||
state: GenerationState,
|
||||
val isInliningStrategy: Boolean
|
||||
) :
|
||||
FunctionGenerationStrategy.CodegenBased(state) {
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
@@ -258,7 +259,7 @@ class PropertyReferenceCodegen(
|
||||
val expectedReceiver = target.dispatchReceiverParameter ?: target.extensionReceiverParameter ?:
|
||||
throw AssertionError("receiverType: $receiverType; no dispatch or extension receiver: $target")
|
||||
val expectedReceiverType = typeMapper.mapType(expectedReceiver.type)
|
||||
capturedBoundReferenceReceiver(asmType, expectedReceiverType).put(expectedReceiverType, v)
|
||||
capturedBoundReferenceReceiver(asmType, expectedReceiverType, isInliningStrategy).put(expectedReceiverType, v)
|
||||
}
|
||||
else {
|
||||
val receivers = originalFunctionDesc.valueParameters.dropLast(if (isGetter) 0 else 1)
|
||||
|
||||
@@ -24,10 +24,15 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
fun capturedBoundReferenceReceiver(ownerType: Type, expectedReceiverType: Type): StackValue =
|
||||
fun capturedBoundReferenceReceiver(ownerType: Type, expectedReceiverType: Type, isInliningStrategy: Boolean): StackValue =
|
||||
StackValue.operation(expectedReceiverType) { iv ->
|
||||
iv.load(0, ownerType)
|
||||
iv.getfield(ownerType.internalName, AsmUtil.CAPTURED_RECEIVER_FIELD, AsmTypes.OBJECT_TYPE.descriptor)
|
||||
iv.getfield(
|
||||
ownerType.internalName,
|
||||
//HACK for inliner - it should recognize field as captured receiver
|
||||
if (isInliningStrategy) AsmUtil.CAPTURED_RECEIVER_FIELD else AsmUtil.BOUND_REFERENCE_RECEIVER,
|
||||
AsmTypes.OBJECT_TYPE.descriptor
|
||||
)
|
||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, expectedReceiverType, iv)
|
||||
}
|
||||
|
||||
|
||||
@@ -581,8 +581,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
Type asmType = state.getTypeMapper().mapClass(lambdaInfo.getClassDescriptor());
|
||||
PropertyReferenceInfo info = lambdaInfo.getPropertyReferenceInfo();
|
||||
strategy = new PropertyReferenceCodegen.PropertyReferenceGenerationStrategy(
|
||||
true, info.getGetFunction(), info.getTarget(), asmType, receiverType, lambdaInfo.expression, state
|
||||
);
|
||||
true, info.getGetFunction(), info.getTarget(), asmType, receiverType, lambdaInfo.expression, state, true);
|
||||
}
|
||||
else {
|
||||
strategy = new FunctionReferenceGenerationStrategy(
|
||||
@@ -591,7 +590,8 @@ public class InlineCodegen extends CallGenerator {
|
||||
CallUtilKt
|
||||
.getResolvedCallWithAssert(callableReferenceExpression.getCallableReference(), codegen.getBindingContext()),
|
||||
receiverType,
|
||||
null
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user