Support default arguments for expected declarations
#KT-21913 Fixed
This commit is contained in:
@@ -12,6 +12,7 @@ import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.Bridge;
|
||||
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations;
|
||||
@@ -73,6 +74,7 @@ import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DEC
|
||||
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
@@ -585,8 +587,10 @@ public class FunctionCodegen {
|
||||
methodEnd = new Label();
|
||||
}
|
||||
else {
|
||||
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(),
|
||||
functionDescriptor));
|
||||
FrameMap frameMap = createFrameMap(
|
||||
parentCodegen.state, signature, functionDescriptor.getExtensionReceiverParameter(),
|
||||
functionDescriptor.getValueParameters(), isStaticMethod(context.getContextKind(), functionDescriptor)
|
||||
);
|
||||
if (context.isInlineMethodContext()) {
|
||||
functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
}
|
||||
@@ -1046,7 +1050,7 @@ public class FunctionCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDefaultNeeded(functionDescriptor)) {
|
||||
if (!isDefaultNeeded(functionDescriptor, function)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1106,8 +1110,19 @@ public class FunctionCodegen {
|
||||
GenerationState state = parentCodegen.state;
|
||||
JvmMethodSignature signature = state.getTypeMapper().mapSignatureWithGeneric(functionDescriptor, methodContext.getContextKind());
|
||||
|
||||
List<ValueParameterDescriptor> originalParameters = functionDescriptor.getValueParameters();
|
||||
List<ValueParameterDescriptor> valueParameters;
|
||||
if (functionDescriptor.isActual() && CollectionsKt.none(originalParameters, ValueParameterDescriptor::declaresDefaultValue)) {
|
||||
FunctionDescriptor expected = CodegenUtil.findExpectedFunctionForActual(functionDescriptor);
|
||||
assert expected != null : "Expected function should have been found earlier for " + functionDescriptor;
|
||||
valueParameters = expected.getValueParameters();
|
||||
}
|
||||
else {
|
||||
valueParameters = originalParameters;
|
||||
}
|
||||
|
||||
boolean isStatic = isStaticMethod(methodContext.getContextKind(), functionDescriptor);
|
||||
FrameMap frameMap = createFrameMap(state, functionDescriptor, signature, isStatic);
|
||||
FrameMap frameMap = createFrameMap(state, signature, functionDescriptor.getExtensionReceiverParameter(), valueParameters, isStatic);
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), methodContext, state, parentCodegen);
|
||||
|
||||
@@ -1123,7 +1138,6 @@ public class FunctionCodegen {
|
||||
capturedArgumentsCount++;
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
|
||||
assert valueParameters.size() > 0 : "Expecting value parameters to generate default function " + functionDescriptor;
|
||||
int firstMaskIndex = frameMap.enterTemp(Type.INT_TYPE);
|
||||
for (int index = 1; index < valueParameters.size(); index++) {
|
||||
@@ -1191,10 +1205,11 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FrameMap createFrameMap(
|
||||
private static FrameMap createFrameMap(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FunctionDescriptor function,
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@Nullable ReceiverParameterDescriptor extensionReceiverParameter,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
boolean isStatic
|
||||
) {
|
||||
FrameMap frameMap = new FrameMap();
|
||||
@@ -1204,9 +1219,8 @@ public class FunctionCodegen {
|
||||
|
||||
for (JvmMethodParameterSignature parameter : signature.getValueParameters()) {
|
||||
if (parameter.getKind() == JvmMethodParameterKind.RECEIVER) {
|
||||
ReceiverParameterDescriptor receiverParameter = function.getExtensionReceiverParameter();
|
||||
if (receiverParameter != null) {
|
||||
frameMap.enter(receiverParameter, state.getTypeMapper().mapType(receiverParameter));
|
||||
if (extensionReceiverParameter != null) {
|
||||
frameMap.enter(extensionReceiverParameter, state.getTypeMapper().mapType(extensionReceiverParameter));
|
||||
}
|
||||
else {
|
||||
frameMap.enterTemp(parameter.getAsmType());
|
||||
@@ -1217,7 +1231,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : function.getValueParameters()) {
|
||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||
frameMap.enter(parameter, state.getTypeMapper().mapType(parameter));
|
||||
}
|
||||
|
||||
@@ -1245,17 +1259,23 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDefaultNeeded(FunctionDescriptor functionDescriptor) {
|
||||
boolean needed = false;
|
||||
if (functionDescriptor != null) {
|
||||
for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) {
|
||||
if (parameterDescriptor.declaresDefaultValue()) {
|
||||
needed = true;
|
||||
break;
|
||||
private boolean isDefaultNeeded(@NotNull FunctionDescriptor descriptor, @Nullable KtNamedFunction function) {
|
||||
if (descriptor.isActual()) {
|
||||
FunctionDescriptor expected = CodegenUtil.findExpectedFunctionForActual(descriptor);
|
||||
if (expected != null && CollectionsKt.any(expected.getValueParameters(), ValueParameterDescriptor::declaresDefaultValue)) {
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(expected);
|
||||
if (element == null) {
|
||||
if (function != null) {
|
||||
state.getDiagnostics().report(EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(function));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return needed;
|
||||
|
||||
return CollectionsKt.any(descriptor.getValueParameters(), ValueParameterDescriptor::declaresDefaultValue);
|
||||
}
|
||||
|
||||
private void generateBridge(
|
||||
|
||||
@@ -280,8 +280,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
val parentContext = context.parentContext ?: error("Context has no parent: " + context)
|
||||
val methodContext = parentContext.intoFunction(callableDescriptor)
|
||||
|
||||
val smap: SMAP
|
||||
if (callDefault) {
|
||||
val smap = if (callDefault) {
|
||||
val implementationOwner = state.typeMapper.mapImplementationOwner(callableDescriptor)
|
||||
val parentCodegen = FakeMemberCodegen(
|
||||
codegen.parentCodegen, inliningFunction!!, methodContext.parentContext as FieldOwnerContext<*>,
|
||||
@@ -293,13 +292,13 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
throw IllegalStateException("Property accessors with default parameters not supported " + callableDescriptor)
|
||||
}
|
||||
FunctionCodegen.generateDefaultImplBody(
|
||||
methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||
inliningFunction as KtNamedFunction?, parentCodegen, asmMethod
|
||||
methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||
inliningFunction as KtNamedFunction?, parentCodegen, asmMethod
|
||||
)
|
||||
smap = createSMAPWithDefaultMapping(inliningFunction, parentCodegen.orCreateSourceMapper.resultMappings)
|
||||
createSMAPWithDefaultMapping(inliningFunction, parentCodegen.orCreateSourceMapper.resultMappings)
|
||||
}
|
||||
else {
|
||||
smap = generateMethodBody(maxCalcAdapter, callableDescriptor, methodContext, inliningFunction!!, jvmSignature, null)
|
||||
generateMethodBody(maxCalcAdapter, callableDescriptor, methodContext, inliningFunction!!, jvmSignature, null)
|
||||
}
|
||||
maxCalcAdapter.visitMaxs(-1, -1)
|
||||
maxCalcAdapter.visitEnd()
|
||||
|
||||
Reference in New Issue
Block a user