Fix accessor generation for suspend functions

1. JVM view of suspend accessors must be also an instance of AccessorForFunctionDescriptor,
thus `createSubstitutedCopy` should be correctly overidden.

2. accessibleFunctionDescriptor should unwap the initial suspend descriptor,
for the same reasons as for type aliases constructors and etc:
these descriptors are used as keys of the map of accessors, so
to avoid duplication for suspend view and initial suspend descriptor,
we always use the latter one as a key.

 #KT-15907 Fixed
 #KT-15935 Fixed
This commit is contained in:
Denis Zharkov
2017-01-24 12:09:20 +03:00
parent 0693bd6b62
commit 9ca9a988a6
10 changed files with 217 additions and 0 deletions
@@ -20,6 +20,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -28,6 +30,7 @@ import java.util.LinkedHashMap;
public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDescriptor implements AccessorForCallableDescriptor<FunctionDescriptor> {
private final FunctionDescriptor calleeDescriptor;
private final ClassDescriptor superCallTarget;
private final String nameSuffix;
public AccessorForFunctionDescriptor(
@NotNull FunctionDescriptor descriptor,
@@ -39,6 +42,7 @@ public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDe
Name.identifier("access$" + nameSuffix));
this.calleeDescriptor = descriptor;
this.superCallTarget = superCallTarget;
this.nameSuffix = nameSuffix;
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
descriptor instanceof ConstructorDescriptor || CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)
@@ -60,6 +64,19 @@ public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDe
}
}
@NotNull
@Override
protected FunctionDescriptorImpl createSubstitutedCopy(
@NotNull DeclarationDescriptor newOwner,
@Nullable FunctionDescriptor original,
@NotNull Kind kind,
@Nullable Name newName,
@NotNull Annotations annotations,
@NotNull SourceElement source
) {
return new AccessorForFunctionDescriptor(calleeDescriptor, newOwner, superCallTarget, nameSuffix);
}
@NotNull
@Override
public FunctionDescriptor getCalleeDescriptor() {
@@ -2732,6 +2732,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (originalIfSamAdapter != null) {
descriptor = originalIfSamAdapter;
}
descriptor = CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction(descriptor);
// $default method is not private, so you need no accessor to call it
return CallUtilKt.usesDefaultArguments(resolvedCall)
? descriptor