Support default parameter values for inline class constructors and funs
#KT-26908 #KT-26554 Move default parameter value tests to separate directory
This commit is contained in:
@@ -106,8 +106,10 @@ public class ConstructorCodegen {
|
||||
}
|
||||
);
|
||||
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
OwnerKind ownerKindForDefault = context.getContextKind() == OwnerKind.ERASED_INLINE_CLASS
|
||||
? OwnerKind.ERASED_INLINE_CLASS
|
||||
: OwnerKind.IMPLEMENTATION;
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, ownerKindForDefault, DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
registerAccessorForHiddenConstructorIfNeeded(constructorDescriptor);
|
||||
|
||||
@@ -140,7 +142,10 @@ public class ConstructorCodegen {
|
||||
}
|
||||
);
|
||||
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||
OwnerKind ownerKindForDefault = context.getContextKind() == OwnerKind.ERASED_INLINE_CLASS
|
||||
? OwnerKind.ERASED_INLINE_CLASS
|
||||
: OwnerKind.IMPLEMENTATION;
|
||||
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorDescriptor, ownerKindForDefault,
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
new DefaultParameterValueSubstitutor(state).generateOverloadsIfNeeded(
|
||||
|
||||
+3
-1
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtPureElement
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOriginFromPure
|
||||
@@ -223,7 +224,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
v.aconst(null)
|
||||
|
||||
val defaultMethod = typeMapper.mapDefaultMethod(delegateFunctionDescriptor, contextKind)
|
||||
if (functionDescriptor is ConstructorDescriptor) {
|
||||
if (functionDescriptor is ConstructorDescriptor && !functionDescriptor.containingDeclaration.isInlineClass()) {
|
||||
v.invokespecial(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
|
||||
} else {
|
||||
v.invokestatic(methodOwner.internalName, defaultMethod.name, defaultMethod.descriptor, false)
|
||||
@@ -250,6 +251,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
if (classDescriptor.kind != ClassKind.CLASS) return false
|
||||
|
||||
if (classOrObject.isLocal) return false
|
||||
if (classDescriptor.isInline) return false
|
||||
|
||||
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
|
||||
|
||||
|
||||
@@ -1151,6 +1151,10 @@ public class FunctionCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
if (InlineClassesUtilsKt.isInlineClass(contextClass) && kind != OwnerKind.ERASED_INLINE_CLASS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDefaultNeeded(functionDescriptor, function)) {
|
||||
return;
|
||||
}
|
||||
@@ -1161,7 +1165,9 @@ public class FunctionCodegen {
|
||||
isEffectivelyInlineOnly(functionDescriptor) ?
|
||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
|
||||
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
|
||||
if (!(functionDescriptor instanceof ConstructorDescriptor)) {
|
||||
if (!(functionDescriptor instanceof ConstructorDescriptor &&
|
||||
!InlineClassesUtilsKt.isInlineClass(functionDescriptor.getContainingDeclaration()))
|
||||
) {
|
||||
flags |= ACC_STATIC;
|
||||
}
|
||||
|
||||
@@ -1283,7 +1289,7 @@ public class FunctionCodegen {
|
||||
generator.putValueIfNeeded(new JvmKotlinType(type, null), StackValue.local(parameterIndex, type));
|
||||
}
|
||||
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false);
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, methodContext.getContextKind());
|
||||
|
||||
generator.genCall(method, null, false, codegen);
|
||||
|
||||
|
||||
@@ -1047,6 +1047,9 @@ public class KotlinTypeMapper {
|
||||
else if (isInterface(containingDeclaration)) {
|
||||
return OwnerKind.DEFAULT_IMPLS;
|
||||
}
|
||||
else if (InlineClassesUtilsKt.isInlineClass(containingDeclaration)) {
|
||||
return OwnerKind.ERASED_INLINE_CLASS;
|
||||
}
|
||||
return OwnerKind.IMPLEMENTATION;
|
||||
}
|
||||
|
||||
@@ -1368,8 +1371,12 @@ public class KotlinTypeMapper {
|
||||
) {
|
||||
String descriptor = method.getDescriptor();
|
||||
int maskArgumentsCount = (callableDescriptor.getValueParameters().size() + Integer.SIZE - 1) / Integer.SIZE;
|
||||
String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount);
|
||||
additionalArgs += (isConstructor(method) ? DEFAULT_CONSTRUCTOR_MARKER : OBJECT_TYPE).getDescriptor();
|
||||
Type defaultConstructorMarkerType =
|
||||
isConstructor(method) || isInlineClassConstructor(callableDescriptor)
|
||||
? DEFAULT_CONSTRUCTOR_MARKER
|
||||
: OBJECT_TYPE;
|
||||
String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount)
|
||||
+ defaultConstructorMarkerType.getDescriptor();
|
||||
String result = descriptor.replace(")", additionalArgs + ")");
|
||||
if (dispatchReceiverDescriptor != null && !isConstructor(method)) {
|
||||
return result.replace("(", "(" + dispatchReceiverDescriptor);
|
||||
@@ -1385,6 +1392,11 @@ public class KotlinTypeMapper {
|
||||
return "<init>".equals(method.getName());
|
||||
}
|
||||
|
||||
private static boolean isInlineClassConstructor(@NotNull CallableDescriptor callableDescriptor) {
|
||||
return callableDescriptor instanceof ClassConstructorDescriptor
|
||||
&& InlineClassesUtilsKt.isInlineClass(callableDescriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Method mapDefaultMethod(@NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind kind) {
|
||||
Method jvmSignature = mapAsmMethod(functionDescriptor, kind);
|
||||
|
||||
Reference in New Issue
Block a user