Propagate KotlinType into create method for coroutines
#KT-27526 Fixed
This commit is contained in:
@@ -638,10 +638,18 @@ public class AsmUtil {
|
|||||||
) {
|
) {
|
||||||
assert !info.isStatic();
|
assert !info.isStatic();
|
||||||
Type fieldType = info.getFieldType();
|
Type fieldType = info.getFieldType();
|
||||||
|
KotlinType fieldKotlinType = info.getFieldKotlinType();
|
||||||
|
KotlinType nullableAny;
|
||||||
|
if (fieldKotlinType != null) {
|
||||||
|
nullableAny = fieldKotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
||||||
|
} else {
|
||||||
|
nullableAny = null;
|
||||||
|
}
|
||||||
|
|
||||||
iv.load(ownerIndex, info.getOwnerType());//this
|
iv.load(ownerIndex, info.getOwnerType());//this
|
||||||
if (cast) {
|
if (cast) {
|
||||||
iv.load(index, AsmTypes.OBJECT_TYPE); //param
|
iv.load(index, AsmTypes.OBJECT_TYPE); //param
|
||||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, fieldType, iv);
|
StackValue.coerce(AsmTypes.OBJECT_TYPE, nullableAny, fieldType, fieldKotlinType, iv);
|
||||||
} else {
|
} else {
|
||||||
iv.load(index, fieldType); //param
|
iv.load(index, fieldType); //param
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
|
import org.jetbrains.kotlin.types.SimpleType;
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
@@ -490,13 +491,14 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
List<FieldInfo> args = Lists.newArrayList();
|
List<FieldInfo> args = Lists.newArrayList();
|
||||||
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||||
if (captureThis != null) {
|
if (captureThis != null) {
|
||||||
Type type = typeMapper.mapType(captureThis);
|
SimpleType thisType = captureThis.getDefaultType();
|
||||||
args.add(FieldInfo.createForHiddenField(ownerType, type, CAPTURED_THIS_FIELD));
|
Type type = typeMapper.mapType(thisType);
|
||||||
|
args.add(FieldInfo.createForHiddenField(ownerType, type, thisType, CAPTURED_THIS_FIELD));
|
||||||
}
|
}
|
||||||
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
KotlinType captureReceiverType = closure.getCapturedReceiverFromOuterContext();
|
||||||
if (captureReceiverType != null) {
|
if (captureReceiverType != null) {
|
||||||
String fieldName = closure.getCapturedReceiverFieldName(typeMapper.getBindingContext(), languageVersionSettings);
|
String fieldName = closure.getCapturedReceiverFieldName(typeMapper.getBindingContext(), languageVersionSettings);
|
||||||
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiverType), fieldName));
|
args.add(FieldInfo.createForHiddenField(ownerType, typeMapper.mapType(captureReceiverType), captureReceiverType, fieldName));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (EnclosedValueDescriptor enclosedValueDescriptor : closure.getCaptureVariables().values()) {
|
for (EnclosedValueDescriptor enclosedValueDescriptor : closure.getCaptureVariables().values()) {
|
||||||
@@ -505,7 +507,10 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
ExpressionTypingUtils.isLocalFunction(descriptor)) {
|
ExpressionTypingUtils.isLocalFunction(descriptor)) {
|
||||||
args.add(
|
args.add(
|
||||||
FieldInfo.createForHiddenField(
|
FieldInfo.createForHiddenField(
|
||||||
ownerType, enclosedValueDescriptor.getType(), enclosedValueDescriptor.getFieldName()
|
ownerType,
|
||||||
|
enclosedValueDescriptor.getType(),
|
||||||
|
enclosedValueDescriptor.getKotlinType(),
|
||||||
|
enclosedValueDescriptor.getFieldName()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isNonCompanionObject;
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isNonCompanionObject;
|
||||||
@@ -29,7 +31,9 @@ public class FieldInfo {
|
|||||||
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
|
ClassDescriptor ownerDescriptor = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class);
|
||||||
assert ownerDescriptor != null : "Owner not found for class: " + classDescriptor;
|
assert ownerDescriptor != null : "Owner not found for class: " + classDescriptor;
|
||||||
Type ownerType = typeMapper.mapClass(ownerDescriptor);
|
Type ownerType = typeMapper.mapClass(ownerDescriptor);
|
||||||
return new FieldInfo(ownerType, typeMapper.mapType(classDescriptor), classDescriptor.getName().asString(), true);
|
KotlinType fieldKotlinType = classDescriptor.getDefaultType();
|
||||||
|
Type fieldType = typeMapper.mapType(fieldKotlinType);
|
||||||
|
return new FieldInfo(ownerType, fieldType, fieldKotlinType, classDescriptor.getName().asString(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -38,23 +42,43 @@ public class FieldInfo {
|
|||||||
@NotNull KotlinTypeMapper typeMapper,
|
@NotNull KotlinTypeMapper typeMapper,
|
||||||
@NotNull String name
|
@NotNull String name
|
||||||
) {
|
) {
|
||||||
Type type = typeMapper.mapType(classDescriptor);
|
Type owner = typeMapper.mapClass(classDescriptor);
|
||||||
return new FieldInfo(type, type, name, true);
|
KotlinType fieldKotlinType = classDescriptor.getDefaultType();
|
||||||
|
Type fieldType = typeMapper.mapType(fieldKotlinType);
|
||||||
|
return new FieldInfo(owner, fieldType, fieldKotlinType, name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static FieldInfo createForHiddenField(@NotNull Type owner, @NotNull Type fieldType, @NotNull String fieldName) {
|
public static FieldInfo createForHiddenField(@NotNull Type owner, @NotNull Type fieldType, @NotNull String fieldName) {
|
||||||
return new FieldInfo(owner, fieldType, fieldName, false);
|
return createForHiddenField(owner, fieldType, null, fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static FieldInfo createForHiddenField(
|
||||||
|
@NotNull Type owner,
|
||||||
|
@NotNull Type fieldType,
|
||||||
|
@Nullable KotlinType fieldKotlinType,
|
||||||
|
@NotNull String fieldName
|
||||||
|
) {
|
||||||
|
return new FieldInfo(owner, fieldType, fieldKotlinType, fieldName, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Type fieldType;
|
private final Type fieldType;
|
||||||
|
private final KotlinType fieldKotlinType;
|
||||||
private final Type ownerType;
|
private final Type ownerType;
|
||||||
private final String fieldName;
|
private final String fieldName;
|
||||||
private final boolean isStatic;
|
private final boolean isStatic;
|
||||||
|
|
||||||
private FieldInfo(@NotNull Type ownerType, @NotNull Type fieldType, @NotNull String fieldName, boolean isStatic) {
|
private FieldInfo(
|
||||||
|
@NotNull Type ownerType,
|
||||||
|
@NotNull Type fieldType,
|
||||||
|
@Nullable KotlinType fieldKotlinType,
|
||||||
|
@NotNull String fieldName,
|
||||||
|
boolean isStatic
|
||||||
|
) {
|
||||||
this.ownerType = ownerType;
|
this.ownerType = ownerType;
|
||||||
this.fieldType = fieldType;
|
this.fieldType = fieldType;
|
||||||
|
this.fieldKotlinType = fieldKotlinType;
|
||||||
this.fieldName = fieldName;
|
this.fieldName = fieldName;
|
||||||
this.isStatic = isStatic;
|
this.isStatic = isStatic;
|
||||||
}
|
}
|
||||||
@@ -64,6 +88,11 @@ public class FieldInfo {
|
|||||||
return fieldType;
|
return fieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public KotlinType getFieldKotlinType() {
|
||||||
|
return fieldKotlinType;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Type getOwnerType() {
|
public Type getOwnerType() {
|
||||||
return ownerType;
|
return ownerType;
|
||||||
|
|||||||
@@ -340,7 +340,19 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Field field(@NotNull Type type, @NotNull Type owner, @NotNull String name, boolean isStatic, @NotNull StackValue receiver) {
|
public static Field field(@NotNull Type type, @NotNull Type owner, @NotNull String name, boolean isStatic, @NotNull StackValue receiver) {
|
||||||
return field(type, null, owner, name, isStatic, receiver, null);
|
return field(type, null, owner, name, isStatic, receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Field field(
|
||||||
|
@NotNull Type type,
|
||||||
|
@Nullable KotlinType kotlinType,
|
||||||
|
@NotNull Type owner,
|
||||||
|
@NotNull String name,
|
||||||
|
boolean isStatic,
|
||||||
|
@NotNull StackValue receiver
|
||||||
|
) {
|
||||||
|
return field(type, kotlinType, owner, name, isStatic, receiver, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -363,7 +375,14 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Field field(@NotNull FieldInfo info, @NotNull StackValue receiver) {
|
public static Field field(@NotNull FieldInfo info, @NotNull StackValue receiver) {
|
||||||
return field(info.getFieldType(), Type.getObjectType(info.getOwnerInternalName()), info.getFieldName(), info.isStatic(), receiver);
|
return field(
|
||||||
|
info.getFieldType(),
|
||||||
|
info.getFieldKotlinType(),
|
||||||
|
Type.getObjectType(info.getOwnerInternalName()),
|
||||||
|
info.getFieldName(),
|
||||||
|
info.isStatic(),
|
||||||
|
receiver
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+13
-2
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||||
import org.jetbrains.kotlin.codegen.StackValue;
|
import org.jetbrains.kotlin.codegen.StackValue;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
public final class EnclosedValueDescriptor {
|
public final class EnclosedValueDescriptor {
|
||||||
@@ -29,18 +30,21 @@ public final class EnclosedValueDescriptor {
|
|||||||
private final StackValue.StackValueWithSimpleReceiver innerValue;
|
private final StackValue.StackValueWithSimpleReceiver innerValue;
|
||||||
private final StackValue instanceValue;
|
private final StackValue instanceValue;
|
||||||
private final Type type;
|
private final Type type;
|
||||||
|
private final KotlinType kotlinType;
|
||||||
|
|
||||||
public EnclosedValueDescriptor(
|
public EnclosedValueDescriptor(
|
||||||
@NotNull String fieldName,
|
@NotNull String fieldName,
|
||||||
@Nullable DeclarationDescriptor descriptor,
|
@Nullable DeclarationDescriptor descriptor,
|
||||||
@NotNull StackValue.StackValueWithSimpleReceiver innerValue,
|
@NotNull StackValue.StackValueWithSimpleReceiver innerValue,
|
||||||
@NotNull Type type
|
@NotNull Type type,
|
||||||
|
@Nullable KotlinType kotlinType
|
||||||
) {
|
) {
|
||||||
this.fieldName = fieldName;
|
this.fieldName = fieldName;
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
this.innerValue = innerValue;
|
this.innerValue = innerValue;
|
||||||
this.instanceValue = innerValue;
|
this.instanceValue = innerValue;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.kotlinType = kotlinType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnclosedValueDescriptor(
|
public EnclosedValueDescriptor(
|
||||||
@@ -48,13 +52,15 @@ public final class EnclosedValueDescriptor {
|
|||||||
@Nullable DeclarationDescriptor descriptor,
|
@Nullable DeclarationDescriptor descriptor,
|
||||||
@NotNull StackValue.StackValueWithSimpleReceiver innerValue,
|
@NotNull StackValue.StackValueWithSimpleReceiver innerValue,
|
||||||
@NotNull StackValue.Field instanceValue,
|
@NotNull StackValue.Field instanceValue,
|
||||||
@NotNull Type type
|
@NotNull Type type,
|
||||||
|
@Nullable KotlinType kotlinType
|
||||||
) {
|
) {
|
||||||
this.fieldName = name;
|
this.fieldName = name;
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
this.innerValue = innerValue;
|
this.innerValue = innerValue;
|
||||||
this.instanceValue = instanceValue;
|
this.instanceValue = instanceValue;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.kotlinType = kotlinType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -82,6 +88,11 @@ public final class EnclosedValueDescriptor {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public KotlinType getKotlinType() {
|
||||||
|
return kotlinType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return fieldName + " " + type + " -> " + descriptor;
|
return fieldName + " " + type + " -> " + descriptor;
|
||||||
|
|||||||
@@ -63,11 +63,11 @@ public interface LocalLookup {
|
|||||||
if (sharedVarType != null) {
|
if (sharedVarType != null) {
|
||||||
StackValue.Field wrapperValue = StackValue.receiverWithRefWrapper(localType, classType, fieldName, thiz, vd);
|
StackValue.Field wrapperValue = StackValue.receiverWithRefWrapper(localType, classType, fieldName, thiz, vd);
|
||||||
innerValue = StackValue.fieldForSharedVar(localType, classType, fieldName, wrapperValue, vd);
|
innerValue = StackValue.fieldForSharedVar(localType, classType, fieldName, wrapperValue, vd);
|
||||||
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, wrapperValue, type);
|
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, wrapperValue, type, kotlinType);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
innerValue = StackValue.field(type, kotlinType, classType, fieldName, false, thiz, vd);
|
innerValue = StackValue.field(type, kotlinType, classType, fieldName, false, thiz, vd);
|
||||||
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, type);
|
enclosedValueDescriptor = new EnclosedValueDescriptor(fieldName, d, innerValue, type, kotlinType);
|
||||||
}
|
}
|
||||||
|
|
||||||
closure.captureVariable(enclosedValueDescriptor);
|
closure.captureVariable(enclosedValueDescriptor);
|
||||||
@@ -118,7 +118,7 @@ public interface LocalLookup {
|
|||||||
localType, null, classType, fieldName, false, StackValue.LOCAL_0, vd
|
localType, null, classType, fieldName, false, StackValue.LOCAL_0, vd
|
||||||
);
|
);
|
||||||
|
|
||||||
closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType));
|
closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType, null));
|
||||||
|
|
||||||
return innerValue;
|
return innerValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
|||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.org.objectweb.asm.Label;
|
import org.jetbrains.org.objectweb.asm.Label;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
@@ -64,8 +65,9 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
|||||||
public StackValue getReceiverExpression(KotlinTypeMapper typeMapper) {
|
public StackValue getReceiverExpression(KotlinTypeMapper typeMapper) {
|
||||||
assert getCallableDescriptorWithReceiver() != null;
|
assert getCallableDescriptorWithReceiver() != null;
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
Type asmType = typeMapper.mapType(getCallableDescriptorWithReceiver().getExtensionReceiverParameter().getType());
|
KotlinType kotlinType = getCallableDescriptorWithReceiver().getExtensionReceiverParameter().getType();
|
||||||
return StackValue.local(AsmUtil.getReceiverIndex(this, getContextDescriptor()), asmType);
|
Type asmType = typeMapper.mapType(kotlinType);
|
||||||
|
return StackValue.local(AsmUtil.getReceiverIndex(this, getContextDescriptor()), asmType, kotlinType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
// pass captured closure to constructor
|
// pass captured closure to constructor
|
||||||
val constructorParameters = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, owner)
|
val constructorParameters = calculateConstructorParameters(typeMapper, languageVersionSettings, closure, owner)
|
||||||
for (parameter in constructorParameters) {
|
for (parameter in constructorParameters) {
|
||||||
StackValue.field(parameter, thisInstance).put(parameter.fieldType, this)
|
StackValue.field(parameter, thisInstance).put(parameter.fieldType, parameter.fieldKotlinType, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// load resultContinuation
|
// load resultContinuation
|
||||||
@@ -377,7 +377,11 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
load(1, AsmTypes.OBJECT_TYPE)
|
load(1, AsmTypes.OBJECT_TYPE)
|
||||||
iconst(index - 1)
|
iconst(index - 1)
|
||||||
aload(AsmTypes.OBJECT_TYPE)
|
aload(AsmTypes.OBJECT_TYPE)
|
||||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, fieldInfoForCoroutineLambdaParameter.fieldType, this)
|
StackValue.coerce(
|
||||||
|
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||||
|
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||||
|
this
|
||||||
|
)
|
||||||
putfield(
|
putfield(
|
||||||
fieldInfoForCoroutineLambdaParameter.ownerInternalName,
|
fieldInfoForCoroutineLambdaParameter.ownerInternalName,
|
||||||
fieldInfoForCoroutineLambdaParameter.fieldName,
|
fieldInfoForCoroutineLambdaParameter.fieldName,
|
||||||
@@ -386,7 +390,11 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
} else {
|
} else {
|
||||||
if (generateErasedCreate) {
|
if (generateErasedCreate) {
|
||||||
load(index, AsmTypes.OBJECT_TYPE)
|
load(index, AsmTypes.OBJECT_TYPE)
|
||||||
StackValue.coerce(AsmTypes.OBJECT_TYPE, fieldInfoForCoroutineLambdaParameter.fieldType, this)
|
StackValue.coerce(
|
||||||
|
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||||
|
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||||
|
this
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
load(index, fieldInfoForCoroutineLambdaParameter.fieldType)
|
load(index, fieldInfoForCoroutineLambdaParameter.fieldType)
|
||||||
}
|
}
|
||||||
@@ -434,6 +442,7 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
FieldInfo.createForHiddenField(
|
FieldInfo.createForHiddenField(
|
||||||
typeMapper.mapClass(closureContext.thisDescriptor),
|
typeMapper.mapClass(closureContext.thisDescriptor),
|
||||||
typeMapper.mapType(type),
|
typeMapper.mapType(type),
|
||||||
|
type,
|
||||||
name
|
name
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -255,25 +255,27 @@ class PsiExpressionLambda(
|
|||||||
arrayListOf<CapturedParamDesc>().apply {
|
arrayListOf<CapturedParamDesc>().apply {
|
||||||
val captureThis = closure.capturedOuterClassDescriptor
|
val captureThis = closure.capturedOuterClassDescriptor
|
||||||
if (captureThis != null) {
|
if (captureThis != null) {
|
||||||
val type = typeMapper.mapType(captureThis)
|
val kotlinType = captureThis.defaultType
|
||||||
|
val type = typeMapper.mapType(kotlinType)
|
||||||
val descriptor = EnclosedValueDescriptor(
|
val descriptor = EnclosedValueDescriptor(
|
||||||
AsmUtil.CAPTURED_THIS_FIELD, null,
|
AsmUtil.CAPTURED_THIS_FIELD, null,
|
||||||
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0),
|
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0),
|
||||||
type
|
type, kotlinType
|
||||||
)
|
)
|
||||||
add(getCapturedParamInfo(descriptor))
|
add(getCapturedParamInfo(descriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closure.capturedReceiverFromOuterContext != null) {
|
val capturedReceiver = closure.capturedReceiverFromOuterContext
|
||||||
val type = typeMapper.mapType(closure.capturedReceiverFromOuterContext!!).let {
|
if (capturedReceiver != null) {
|
||||||
|
val type = typeMapper.mapType(capturedReceiver).let {
|
||||||
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
|
||||||
}
|
}
|
||||||
|
|
||||||
val fieldName = closure.getCapturedReceiverFieldName(typeMapper.bindingContext, languageVersionSettings)
|
val fieldName = closure.getCapturedReceiverFieldName(typeMapper.bindingContext, languageVersionSettings)
|
||||||
val descriptor = EnclosedValueDescriptor(
|
val descriptor = EnclosedValueDescriptor(
|
||||||
fieldName, null,
|
fieldName, null,
|
||||||
StackValue.field(type, lambdaClassType, fieldName, false, StackValue.LOCAL_0),
|
StackValue.field(type, capturedReceiver, lambdaClassType, fieldName, false, StackValue.LOCAL_0),
|
||||||
type
|
type, capturedReceiver
|
||||||
)
|
)
|
||||||
add(getCapturedParamInfo(descriptor))
|
add(getCapturedParamInfo(descriptor))
|
||||||
}
|
}
|
||||||
|
|||||||
+126
@@ -0,0 +1,126 @@
|
|||||||
|
// WITH_COROUTINES
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// IGNORE_BACKEND: JVM_IR, JS_IR
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
import kotlin.coroutines.intrinsics.*
|
||||||
|
|
||||||
|
inline class BoxAny(val value: Any?) {
|
||||||
|
val intValue: Int get() = value as Int
|
||||||
|
}
|
||||||
|
|
||||||
|
inline class BoxInt(val value: Int)
|
||||||
|
|
||||||
|
inline class BoxLong(val value: Long)
|
||||||
|
|
||||||
|
class EmptyContinuation<T> : Continuation<T> {
|
||||||
|
override val context: CoroutineContext
|
||||||
|
get() = EmptyCoroutineContext
|
||||||
|
|
||||||
|
override fun resumeWith(result: Result<T>) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun foo(block: suspend (BoxAny) -> Unit) {
|
||||||
|
block(BoxAny(1))
|
||||||
|
block.startCoroutineUninterceptedOrReturn(BoxAny(1), EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fooReceiver(block: suspend BoxAny.() -> Unit) {
|
||||||
|
BoxAny(1).block()
|
||||||
|
block.startCoroutineUninterceptedOrReturn(BoxAny(1), EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun bar(block: suspend (BoxInt) -> Unit) {
|
||||||
|
block(BoxInt(2))
|
||||||
|
block.startCoroutineUninterceptedOrReturn(BoxInt(2), EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun barReceiver(block: suspend BoxInt.() -> Unit) {
|
||||||
|
BoxInt(2).block()
|
||||||
|
block.startCoroutineUninterceptedOrReturn(BoxInt(2), EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun baz(block: suspend (BoxLong) -> Unit) {
|
||||||
|
block(BoxLong(3))
|
||||||
|
block.startCoroutineUninterceptedOrReturn(BoxLong(3), EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun bazReceiver(block: suspend BoxLong.() -> Unit) {
|
||||||
|
BoxLong(3).block()
|
||||||
|
block.startCoroutineUninterceptedOrReturn(BoxLong(3), EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun BoxAny.extension(block: suspend BoxAny.() -> Unit) {
|
||||||
|
this.block()
|
||||||
|
block()
|
||||||
|
|
||||||
|
block.startCoroutineUninterceptedOrReturn(this, EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun BoxInt.extension(block: suspend BoxInt.() -> Unit) {
|
||||||
|
this.block()
|
||||||
|
block()
|
||||||
|
|
||||||
|
block.startCoroutineUninterceptedOrReturn(this, EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun BoxLong.extension(block: suspend BoxLong.() -> Unit) {
|
||||||
|
this.block()
|
||||||
|
block()
|
||||||
|
|
||||||
|
block.startCoroutineUninterceptedOrReturn(this, EmptyContinuation())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runBlocking(block: suspend () -> Unit) {
|
||||||
|
block.startCoroutine(object : Continuation<Unit> {
|
||||||
|
override val context: CoroutineContext
|
||||||
|
get() = EmptyCoroutineContext
|
||||||
|
|
||||||
|
override fun resumeWith(result: Result<Unit>) {
|
||||||
|
(block as Function1<Continuation<Unit>, Any?>)(this)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var result = 0
|
||||||
|
runBlocking {
|
||||||
|
foo { boxAny ->
|
||||||
|
result += boxAny.intValue
|
||||||
|
}
|
||||||
|
fooReceiver {
|
||||||
|
result += this.intValue
|
||||||
|
}
|
||||||
|
|
||||||
|
bar { boxInt ->
|
||||||
|
result += boxInt.value
|
||||||
|
}
|
||||||
|
barReceiver {
|
||||||
|
result += value
|
||||||
|
}
|
||||||
|
|
||||||
|
baz { boxLong ->
|
||||||
|
result += boxLong.value.toInt()
|
||||||
|
}
|
||||||
|
bazReceiver {
|
||||||
|
result += this.value.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
val b = BoxAny(4)
|
||||||
|
b.extension {
|
||||||
|
result += intValue
|
||||||
|
}
|
||||||
|
|
||||||
|
val bInt = BoxInt(5)
|
||||||
|
BoxInt(5).extension {
|
||||||
|
result += value + bInt.value
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxLong(6).extension {
|
||||||
|
result += value.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (result == 168) "OK" else "Error: $result"
|
||||||
|
}
|
||||||
+5
@@ -11974,6 +11974,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unboxParameterOfSuspendLambdaBeforeInvoke.kt")
|
||||||
|
public void testUnboxParameterOfSuspendLambdaBeforeInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxParameterOfSuspendLambdaBeforeInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
||||||
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
||||||
|
|||||||
+5
@@ -11974,6 +11974,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unboxParameterOfSuspendLambdaBeforeInvoke.kt")
|
||||||
|
public void testUnboxParameterOfSuspendLambdaBeforeInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxParameterOfSuspendLambdaBeforeInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
||||||
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
||||||
|
|||||||
+5
@@ -11979,6 +11979,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unboxParameterOfSuspendLambdaBeforeInvoke.kt")
|
||||||
|
public void testUnboxParameterOfSuspendLambdaBeforeInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxParameterOfSuspendLambdaBeforeInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
||||||
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
||||||
|
|||||||
+5
@@ -10509,6 +10509,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unboxParameterOfSuspendLambdaBeforeInvoke.kt")
|
||||||
|
public void testUnboxParameterOfSuspendLambdaBeforeInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxParameterOfSuspendLambdaBeforeInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
||||||
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
||||||
|
|||||||
+5
@@ -11554,6 +11554,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unboxParameterOfSuspendLambdaBeforeInvoke.kt")
|
||||||
|
public void testUnboxParameterOfSuspendLambdaBeforeInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxParameterOfSuspendLambdaBeforeInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
@TestMetadata("unboxReceiverOnCallingMethodFromInlineClass.kt")
|
||||||
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
public void testUnboxReceiverOnCallingMethodFromInlineClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/unboxReceiverOnCallingMethodFromInlineClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user