Refactoring: Rename closure methods in CalculatedClosure, add a method for getting receiver labels
This commit is contained in:
@@ -513,12 +513,12 @@ public class AsmUtil {
|
||||
public static void genClosureFields(@NotNull CalculatedClosure closure, ClassBuilder v, KotlinTypeMapper typeMapper) {
|
||||
List<Pair<String, Type>> allFields = new ArrayList<>();
|
||||
|
||||
ClassifierDescriptor captureThis = closure.getCaptureThis();
|
||||
ClassifierDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||
if (captureThis != null) {
|
||||
allFields.add(Pair.create(CAPTURED_THIS_FIELD, typeMapper.mapType(captureThis)));
|
||||
}
|
||||
|
||||
KotlinType captureReceiverType = closure.getCaptureReceiverType();
|
||||
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
||||
if (captureReceiverType != null && !CallableReferenceUtilKt.isForCallableReference(closure)) {
|
||||
allFields.add(Pair.create(CAPTURED_RECEIVER_FIELD, typeMapper.mapType(captureReceiverType)));
|
||||
}
|
||||
|
||||
@@ -486,12 +486,12 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
@NotNull Type ownerType
|
||||
) {
|
||||
List<FieldInfo> args = Lists.newArrayList();
|
||||
ClassDescriptor captureThis = closure.getCaptureThis();
|
||||
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||
if (captureThis != null) {
|
||||
Type type = typeMapper.mapType(captureThis);
|
||||
args.add(FieldInfo.createForHiddenField(ownerType, type, CAPTURED_THIS_FIELD));
|
||||
}
|
||||
KotlinType captureReceiverType = closure.getCaptureReceiverType();
|
||||
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
||||
if (captureReceiverType != null) {
|
||||
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiverType), CAPTURED_RECEIVER_FIELD));
|
||||
}
|
||||
|
||||
@@ -1102,7 +1102,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
int paramIndex = 0;
|
||||
|
||||
if (putThis) {
|
||||
ClassDescriptor captureThis = closure.getCaptureThis();
|
||||
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||
if (captureThis != null) {
|
||||
StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
|
||||
assert !isPrimitive(thisOrOuter.type) : "This or outer should be non primitive: " + thisOrOuter.type;
|
||||
@@ -1110,7 +1110,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
KotlinType captureReceiver = closure.getCaptureReceiverType();
|
||||
KotlinType captureReceiver = closure.getCapturedReceiverFromOuterContext();
|
||||
if (captureReceiver != null) {
|
||||
StackValue capturedReceiver =
|
||||
functionReferenceReceiver != null ? functionReferenceReceiver :
|
||||
@@ -1135,7 +1135,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassNotAny(classDescriptor);
|
||||
if (superClass != null) {
|
||||
pushClosureOnStack(
|
||||
superClass, putThis && closure.getCaptureThis() == null, callGenerator, /* functionReferenceReceiver = */ null
|
||||
superClass, putThis && closure.getCapturedOuterClassDescriptor() == null, callGenerator, /* functionReferenceReceiver = */ null
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -668,14 +668,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void pushCapturedFieldsOnStack(InstructionAdapter iv, MutableClosure closure) {
|
||||
ClassDescriptor captureThis = closure.getCaptureThis();
|
||||
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||
if (captureThis != null) {
|
||||
iv.load(0, classAsmType);
|
||||
Type type = typeMapper.mapType(captureThis);
|
||||
iv.getfield(classAsmType.getInternalName(), CAPTURED_THIS_FIELD, type.getDescriptor());
|
||||
}
|
||||
|
||||
KotlinType captureReceiver = closure.getCaptureReceiverType();
|
||||
KotlinType captureReceiver = closure.getCapturedReceiverFromOuterContext();
|
||||
if (captureReceiver != null) {
|
||||
iv.load(0, classAsmType);
|
||||
Type type = typeMapper.mapType(captureReceiver);
|
||||
|
||||
@@ -86,10 +86,10 @@ public class JvmCodegenUtil {
|
||||
}
|
||||
|
||||
public static boolean isConst(@NotNull CalculatedClosure closure) {
|
||||
return closure.getCaptureThis() == null &&
|
||||
closure.getCaptureReceiverType() == null &&
|
||||
closure.getCaptureVariables().isEmpty() &&
|
||||
!closure.isSuspend();
|
||||
return closure.getCapturedOuterClassDescriptor() == null &&
|
||||
closure.getCapturedReceiverFromOuterContext() == null &&
|
||||
closure.getCaptureVariables().isEmpty() &&
|
||||
!closure.isSuspend();
|
||||
}
|
||||
|
||||
private static boolean isCallInsideSameClassAsFieldRepresentingProperty(
|
||||
@@ -259,7 +259,7 @@ public class JvmCodegenUtil {
|
||||
) {
|
||||
//for compilation against sources
|
||||
if (closure != null) {
|
||||
return closure.getCaptureThis();
|
||||
return closure.getCapturedOuterClassDescriptor();
|
||||
}
|
||||
|
||||
//for compilation against binaries
|
||||
|
||||
@@ -72,9 +72,9 @@ class PropertyReferenceCodegen(
|
||||
private val wrapperMethod = getWrapperMethodForPropertyReference(target, getFunction.valueParameters.size)
|
||||
|
||||
private val closure = bindingContext.get(CodegenBinding.CLOSURE, classDescriptor)!!.apply {
|
||||
assert((captureReceiverType != null) == (receiverType != null)) {
|
||||
assert((capturedReceiverFromOuterContext != null) == (receiverType != null)) {
|
||||
"Bound property reference can only be generated with the type of the receiver. " +
|
||||
"Captured type = $captureReceiverType, actual type = $receiverType"
|
||||
"Captured type = $capturedReceiverFromOuterContext, actual type = $receiverType"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
@@ -33,10 +34,13 @@ public interface CalculatedClosure {
|
||||
ClassDescriptor getClosureClass();
|
||||
|
||||
@Nullable
|
||||
ClassDescriptor getCaptureThis();
|
||||
ClassDescriptor getCapturedOuterClassDescriptor();
|
||||
|
||||
@Nullable
|
||||
KotlinType getCaptureReceiverType();
|
||||
KotlinType getCapturedReceiverFromOuterContext();
|
||||
|
||||
@NotNull
|
||||
String getCapturedReceiverLabel(BindingContext bindingContext);
|
||||
|
||||
@NotNull
|
||||
Map<DeclarationDescriptor, EnclosedValueDescriptor> getCaptureVariables();
|
||||
|
||||
+1
-1
@@ -403,7 +403,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
if (receiverType != null) {
|
||||
closure.setCaptureReceiverType(receiverType);
|
||||
closure.setCustomCapturedReceiverType(receiverType);
|
||||
}
|
||||
|
||||
super.visitCallableReferenceExpression(expression);
|
||||
|
||||
@@ -184,7 +184,7 @@ public class CodegenBinding {
|
||||
MutableClosure closure = new MutableClosure(classDescriptor, enclosing);
|
||||
|
||||
if (classDescriptor.isInner()) {
|
||||
closure.setCaptureThis();
|
||||
closure.setNeedsCaptureOuterClass();
|
||||
}
|
||||
|
||||
trace.record(ASM_TYPE, classDescriptor, asmType);
|
||||
|
||||
@@ -19,8 +19,11 @@ package org.jetbrains.kotlin.codegen.binding;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil;
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.name.NameUtils;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
@@ -73,16 +76,16 @@ public final class MutableClosure implements CalculatedClosure {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDescriptor getCaptureThis() {
|
||||
public ClassDescriptor getCapturedOuterClassDescriptor() {
|
||||
return captureThis ? enclosingClass : null;
|
||||
}
|
||||
|
||||
public void setCaptureThis() {
|
||||
public void setNeedsCaptureOuterClass() {
|
||||
this.captureThis = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinType getCaptureReceiverType() {
|
||||
public KotlinType getCapturedReceiverFromOuterContext() {
|
||||
if (captureReceiverType != null) {
|
||||
return captureReceiverType;
|
||||
}
|
||||
@@ -96,23 +99,36 @@ public final class MutableClosure implements CalculatedClosure {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setCaptureReceiver() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getCapturedReceiverLabel(BindingContext bindingContext) {
|
||||
if (captureReceiverType != null) {
|
||||
// Should effectively be returned only for callable references
|
||||
return AsmUtil.CAPTURED_RECEIVER_FIELD;
|
||||
} else if (enclosingFunWithReceiverDescriptor != null) {
|
||||
return AsmUtil.CAPTURED_RECEIVER_FIELD;
|
||||
} else {
|
||||
throw new IllegalStateException("Closure does not capture an outer receiver");
|
||||
}
|
||||
}
|
||||
|
||||
public void setNeedsCaptureReceiverFromOuterContext() {
|
||||
if (enclosingFunWithReceiverDescriptor == null) {
|
||||
throw new IllegalStateException("Extension receiver parameter should exist");
|
||||
}
|
||||
this.captureEnclosingReceiver = true;
|
||||
}
|
||||
|
||||
public void setCustomCapturedReceiverType(@NotNull KotlinType type) {
|
||||
this.captureReceiverType = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<DeclarationDescriptor, EnclosedValueDescriptor> getCaptureVariables() {
|
||||
return captureVariables != null ? captureVariables : Collections.emptyMap();
|
||||
}
|
||||
|
||||
public void setCaptureReceiverType(@NotNull KotlinType type) {
|
||||
this.captureReceiverType = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<Pair<String, Type>> getRecordedFields() {
|
||||
|
||||
@@ -47,7 +47,7 @@ fun CalculatedClosure.isForCallableReference(): Boolean =
|
||||
closureClass.isSyntheticClassForCallableReference()
|
||||
|
||||
fun CalculatedClosure.isForBoundCallableReference(): Boolean =
|
||||
isForCallableReference() && captureReceiverType != null
|
||||
isForCallableReference() && capturedReceiverFromOuterContext != null
|
||||
|
||||
fun InstructionAdapter.loadBoundReferenceReceiverParameter(index: Int, type: Type) {
|
||||
load(index, type)
|
||||
|
||||
@@ -224,7 +224,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
if (closure == null) {
|
||||
throw new IllegalStateException("Can't capture this for context without closure: " + this);
|
||||
}
|
||||
closure.setCaptureThis();
|
||||
closure.setNeedsCaptureOuterClass();
|
||||
}
|
||||
return StackValue.changeReceiverForFieldAndSharedVar(outerExpression.invoke(), prefix);
|
||||
}
|
||||
@@ -567,7 +567,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
if (myOuter != null && resultValue != null && !isStaticField(resultValue)) {
|
||||
closure.setCaptureThis();
|
||||
closure.setNeedsCaptureOuterClass();
|
||||
}
|
||||
return resultValue;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class ConstructorContext extends MethodContext {
|
||||
|
||||
@Override
|
||||
public StackValue getOuterExpression(StackValue prefix, boolean ignoreNoOuter) {
|
||||
StackValue stackValue = closure != null && closure.getCaptureThis() != null ? LOCAL_1 : null;
|
||||
StackValue stackValue = closure != null && closure.getCapturedOuterClassDescriptor() != null ? LOCAL_1 : null;
|
||||
if (!ignoreNoOuter && stackValue == null) {
|
||||
throw new UnsupportedOperationException("Don't know how to generate outer expression for " + getContextDescriptor());
|
||||
}
|
||||
|
||||
@@ -138,16 +138,19 @@ public interface LocalLookup {
|
||||
MutableClosure closure,
|
||||
Type classType
|
||||
) {
|
||||
if (closure.getEnclosingReceiverDescriptor() != d) {
|
||||
ReceiverParameterDescriptor enclosingReceiverDescriptor = closure.getEnclosingReceiverDescriptor();
|
||||
if (enclosingReceiverDescriptor != d) {
|
||||
return null;
|
||||
}
|
||||
|
||||
KotlinType receiverType = closure.getEnclosingReceiverDescriptor().getType();
|
||||
assert(enclosingReceiverDescriptor != null);
|
||||
|
||||
KotlinType receiverType = enclosingReceiverDescriptor.getType();
|
||||
Type type = state.getTypeMapper().mapType(receiverType);
|
||||
StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(
|
||||
type, receiverType, classType, CAPTURED_RECEIVER_FIELD, false, StackValue.LOCAL_0, d
|
||||
);
|
||||
closure.setCaptureReceiver();
|
||||
closure.setNeedsCaptureReceiverFromOuterContext();
|
||||
|
||||
return innerValue;
|
||||
}
|
||||
|
||||
@@ -570,7 +570,8 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
codegen.v
|
||||
)
|
||||
|
||||
val captureThisType = closure.captureThis?.let(typeMapper::mapType)
|
||||
val captureThis = closure.capturedOuterClassDescriptor
|
||||
val captureThisType = captureThis?.let(typeMapper::mapType)
|
||||
if (captureThisType != null) {
|
||||
StackValue.field(
|
||||
captureThisType, Type.getObjectType(v.thisName), AsmUtil.CAPTURED_THIS_FIELD,
|
||||
@@ -666,7 +667,7 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
].sure { "There must be a jvm view defined for $originalSuspendDescriptor" }
|
||||
|
||||
if (suspendFunctionView.dispatchReceiverParameter != null) {
|
||||
closure.setCaptureThis()
|
||||
closure.setNeedsCaptureOuterClass()
|
||||
}
|
||||
|
||||
return CoroutineCodegenForNamedFunction(
|
||||
|
||||
@@ -251,8 +251,9 @@ class PsiExpressionLambda(
|
||||
|
||||
override val capturedVars: List<CapturedParamDesc> by lazy {
|
||||
arrayListOf<CapturedParamDesc>().apply {
|
||||
if (closure.captureThis != null) {
|
||||
val type = typeMapper.mapType(closure.captureThis!!)
|
||||
val captureThis = closure.capturedOuterClassDescriptor
|
||||
if (captureThis != null) {
|
||||
val type = typeMapper.mapType(captureThis)
|
||||
val descriptor = EnclosedValueDescriptor(
|
||||
AsmUtil.CAPTURED_THIS_FIELD, null,
|
||||
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0),
|
||||
@@ -261,8 +262,8 @@ class PsiExpressionLambda(
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
}
|
||||
|
||||
if (closure.captureReceiverType != null) {
|
||||
val type = typeMapper.mapType(closure.captureReceiverType!!).let {
|
||||
if (closure.capturedReceiverFromOuterContext != null) {
|
||||
val type = typeMapper.mapType(closure.capturedReceiverFromOuterContext!!).let {
|
||||
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
||||
}
|
||||
val descriptor = EnclosedValueDescriptor(
|
||||
|
||||
@@ -1573,7 +1573,7 @@ public class KotlinTypeMapper {
|
||||
writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType(), descriptor);
|
||||
}
|
||||
|
||||
KotlinType captureReceiverType = closure != null ? closure.getCaptureReceiverType() : null;
|
||||
KotlinType captureReceiverType = closure != null ? closure.getCapturedReceiverFromOuterContext() : null;
|
||||
if (captureReceiverType != null) {
|
||||
writeParameter(sw, JvmMethodParameterKind.RECEIVER, captureReceiverType, descriptor);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user