Fix generation of property accessor to the underlying value

This commit is contained in:
Mikhail Zarechenskiy
2018-02-07 17:50:02 +03:00
parent ce601bebbe
commit 2c279978c8
3 changed files with 43 additions and 9 deletions
@@ -239,20 +239,12 @@ public class FunctionCodegen {
!(containingDeclaration instanceof PackageFragmentDescriptor) &&
origin.getOriginKind() != JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL;
boolean isMethodInInlineClassWrapper =
isClass(containingDeclaration) &&
((ClassDescriptor) containingDeclaration).isInline() &&
contextKind != OwnerKind.ERASED_INLINE_CLASS &&
!(functionDescriptor instanceof ConstructorDescriptor) &&
!KotlinTypeMapper.isAccessor(functionDescriptor) &&
origin.getOriginKind() != JvmDeclarationOriginKind.UNBOX_METHOD_OF_INLINE_CLASS;
if (isOpenSuspendInClass) {
generateOpenMethodInSuspendClass(
origin, functionDescriptor, methodContext, strategy, mv, jvmSignature, asmMethod, flags, staticInCompanionObject
);
}
else if (isMethodInInlineClassWrapper) {
else if (shouldDelegateMethodBodyToInlineClass(origin, functionDescriptor, contextKind, containingDeclaration, bindingContext)) {
generateMethodInsideInlineClassWrapper(origin, functionDescriptor, (ClassDescriptor) containingDeclaration, mv);
}
else {
@@ -262,6 +254,34 @@ public class FunctionCodegen {
}
}
private static boolean shouldDelegateMethodBodyToInlineClass(
@NotNull JvmDeclarationOrigin origin,
@NotNull FunctionDescriptor functionDescriptor,
@NotNull OwnerKind contextKind,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull BindingContext bindingContext
) {
// special kind / function
if (contextKind == OwnerKind.ERASED_INLINE_CLASS) return false;
if (origin.getOriginKind() == JvmDeclarationOriginKind.UNBOX_METHOD_OF_INLINE_CLASS) return false;
// descriptor corresponds to the underlying value
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
PropertyDescriptor property = ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty();
// property for the underlying value
if (JvmCodegenUtil.hasBackingField(property, contextKind, bindingContext)) {
return false;
}
}
// base check
boolean isInlineClass = isClass(containingDeclaration) && ((ClassDescriptor) containingDeclaration).isInline();
boolean simpleFunctionOrProperty =
!(functionDescriptor instanceof ConstructorDescriptor) && !KotlinTypeMapper.isAccessor(functionDescriptor);
return isInlineClass && simpleFunctionOrProperty;
}
private void generateMethodInsideInlineClassWrapper(
@NotNull JvmDeclarationOrigin origin,
@NotNull FunctionDescriptor functionDescriptor,