Hide constructors accepting inline class parameters
This commit is contained in:
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.HashCode;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.InlineClassManglingUtilsKt;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
@@ -402,6 +403,14 @@ public class AsmUtil {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
if (kind != OwnerKind.ERASED_INLINE_CLASS &&
|
||||
memberDescriptor instanceof ConstructorDescriptor &&
|
||||
!(memberDescriptor instanceof AccessorForConstructorDescriptor) &&
|
||||
InlineClassManglingUtilsKt.shouldHideConstructorDueToInlineClassTypeValueParameters((ConstructorDescriptor) memberDescriptor)
|
||||
) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
if (isEffectivelyInlineOnly(memberDescriptor)) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.codegen.context.ConstructorContext;
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.InlineClassManglingUtilsKt;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -108,9 +109,16 @@ public class ConstructorCodegen {
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
registerAccessorForHiddenConstructorIfNeeded(constructorDescriptor);
|
||||
|
||||
new DefaultParameterValueSubstitutor(state).generatePrimaryConstructorOverloadsIfNeeded(constructorDescriptor, v, memberCodegen, kind, myClass);
|
||||
}
|
||||
|
||||
private void registerAccessorForHiddenConstructorIfNeeded(ClassConstructorDescriptor descriptor) {
|
||||
if (!InlineClassManglingUtilsKt.shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor)) return;
|
||||
context.getAccessor(descriptor, AccessorKind.NORMAL, null, null);
|
||||
}
|
||||
|
||||
public void generateSecondaryConstructor(
|
||||
@NotNull ClassConstructorDescriptor constructorDescriptor,
|
||||
@NotNull Type superClassAsmType
|
||||
@@ -138,6 +146,8 @@ public class ConstructorCodegen {
|
||||
new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded(
|
||||
constructor, constructorDescriptor, constructorDescriptor, kind, v, memberCodegen
|
||||
);
|
||||
|
||||
registerAccessorForHiddenConstructorIfNeeded(constructorDescriptor);
|
||||
}
|
||||
|
||||
private void generateDelegatorToConstructorCall(
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.InlineClassManglingUtilsKt;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegen;
|
||||
import org.jetbrains.kotlin.codegen.when.SwitchCodegenProvider;
|
||||
@@ -2256,10 +2257,23 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
descriptor = CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction(descriptor);
|
||||
|
||||
// $default method is not private, so you need no accessor to call it
|
||||
return CallUtilKt.usesDefaultArguments(resolvedCall)
|
||||
? descriptor
|
||||
: context.accessibleDescriptor(descriptor, getSuperCallTarget(resolvedCall.getCall()));
|
||||
if (CallUtilKt.usesDefaultArguments(resolvedCall)) {
|
||||
// $default method is not private, so you need no accessor to call it
|
||||
return descriptor;
|
||||
}
|
||||
else if (InlineClassManglingUtilsKt.shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor)) {
|
||||
// Constructors with inline class type value parameters should always be called using an accessor.
|
||||
// NB this will require accessors even if the constructor itself is in a different module.
|
||||
return new AccessorForConstructorDescriptor(
|
||||
(ClassConstructorDescriptor) descriptor,
|
||||
descriptor.getContainingDeclaration(),
|
||||
getSuperCallTarget(resolvedCall.getCall()),
|
||||
AccessorKind.NORMAL
|
||||
);
|
||||
}
|
||||
else {
|
||||
return context.accessibleDescriptor(descriptor, getSuperCallTarget(resolvedCall.getCall()));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -27,6 +27,16 @@ fun getInlineClassSignatureManglingSuffix(descriptor: CallableMemberDescriptor):
|
||||
return getInlineClassSignatureManglingSuffix(actualValueParameterTypes)
|
||||
}
|
||||
|
||||
fun shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor: CallableMemberDescriptor): Boolean {
|
||||
if (descriptor !is ClassConstructorDescriptor) return false
|
||||
if (Visibilities.isPrivate(descriptor.visibility)) return false
|
||||
if (descriptor.constructedClass.isInline) return false
|
||||
|
||||
// TODO inner class in inline class
|
||||
|
||||
return descriptor.valueParameters.any { it.type.requiresFunctionNameMangling() }
|
||||
}
|
||||
|
||||
fun getInlineClassSignatureManglingSuffix(valueParameterTypes: List<KotlinType>) =
|
||||
if (valueParameterTypes.none { it.requiresFunctionNameMangling() })
|
||||
null
|
||||
|
||||
Reference in New Issue
Block a user