Refactoring: Rename closure methods in CalculatedClosure, add a method for getting receiver labels

This commit is contained in:
Yan Zhulanow
2018-08-28 15:21:06 +05:00
parent 6f7741b6bb
commit 11d4a6bf5c
17 changed files with 67 additions and 42 deletions
@@ -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();
@@ -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);
}