Generate synthetic unbox method for each wrapper of inline class

This commit is contained in:
Mikhail Zarechenskiy
2018-02-05 03:46:00 +03:00
parent a59917b6f8
commit 1ac4e9755a
5 changed files with 41 additions and 6 deletions
@@ -83,6 +83,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
generateConstructors();
generateDefaultImplsIfNeeded();
generateErasedInlineClassIfNeeded();
generateUnboxMethodForInlineClass();
}
// Generate _declared_ companions
@@ -148,6 +149,8 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
protected void generateErasedInlineClassIfNeeded() {}
protected void generateUnboxMethodForInlineClass() {}
private static boolean shouldProcessFirst(KtDeclaration declaration) {
return !(declaration instanceof KtProperty || declaration instanceof KtNamedFunction);
}
@@ -241,7 +241,8 @@ public class FunctionCodegen {
isClass(containingDeclaration) &&
((ClassDescriptor) containingDeclaration).isInline() &&
contextKind != OwnerKind.ERASED_INLINE_CLASS &&
functionDescriptor instanceof SimpleFunctionDescriptor;
functionDescriptor instanceof SimpleFunctionDescriptor &&
origin.getOriginKind() != JvmDeclarationOriginKind.UNBOX_METHOD_OF_INLINE_CLASS;
if (isOpenSuspendInClass) {
generateOpenMethodInSuspendClass(
@@ -36,10 +36,7 @@ import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap.PlatformMutabilityMapping;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DelegationResolver;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall;
@@ -251,6 +248,35 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
new ErasedInlineClassBodyCodegen((KtClass) myClass, erasedInlineClassContext, builder, state, this).generate();
}
@Override
protected void generateUnboxMethodForInlineClass() {
if (!(myClass instanceof KtClass)) return;
if (!descriptor.isInline()) return;
Type ownerType = typeMapper.mapClass(descriptor);
ValueParameterDescriptor inlinedValue = InlineClassesUtilsKt.underlyingRepresentation(this.descriptor);
if (inlinedValue == null) return;
Type valueType = typeMapper.mapType(inlinedValue.getType());
SimpleFunctionDescriptor functionDescriptor = InlineClassDescriptorResolver.INSTANCE.createUnboxFunctionDescriptor(this.descriptor);
assert functionDescriptor != null : "FunctionDescriptor for unbox method should be not null during codegen";
functionCodegen.generateMethod(
JvmDeclarationOriginKt.UnboxMethodOfInlineClass(functionDescriptor), functionDescriptor,
new FunctionGenerationStrategy.CodegenBased(state) {
@Override
public void doGenerateBody(
@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature
) {
InstructionAdapter iv = codegen.v;
iv.load(0, OBJECT_TYPE);
iv.getfield(ownerType.getInternalName(), inlinedValue.getName().asString(), valueType.getDescriptor());
iv.areturn(valueType);
}
}
);
}
@Override
protected void generateKotlinMetadataAnnotation() {
generateKotlinClassMetadataAnnotation(descriptor, false);
@@ -30,7 +30,8 @@ enum class JvmDeclarationOriginKind {
SYNTHETIC, // this means that there's no proper descriptor for this jvm declaration,
COLLECTION_STUB,
AUGMENTED_BUILTIN_API,
ERASED_INLINE_CLASS
ERASED_INLINE_CLASS,
UNBOX_METHOD_OF_INLINE_CLASS
}
class JvmDeclarationOrigin(
@@ -83,3 +84,6 @@ fun AugmentedBuiltInApi(descriptor: CallableDescriptor): JvmDeclarationOrigin =
fun ErasedInlineClassOrigin(element: PsiElement?, descriptor: ClassDescriptor): JvmDeclarationOrigin =
JvmDeclarationOrigin(ERASED_INLINE_CLASS, element, descriptor)
fun UnboxMethodOfInlineClass(descriptor: FunctionDescriptor): JvmDeclarationOrigin =
JvmDeclarationOrigin(UNBOX_METHOD_OF_INLINE_CLASS, null, descriptor)
@@ -14,4 +14,5 @@ public final class Foo {
public final method extension(@org.jetbrains.annotations.NotNull p0: java.lang.Object, @org.jetbrains.annotations.NotNull p1: java.lang.String): void
public final method getL(): long
public final method param(p0: double): void
public final method unbox(): long
}