Fix for KT-11969: ProGuard issue with private interface methods

#KT-11969 Fixed
This commit is contained in:
Mikhael Bogdanov
2016-12-22 14:50:52 +01:00
parent 6444ccc962
commit f1c1fcf0fc
14 changed files with 226 additions and 9 deletions
@@ -133,7 +133,7 @@ public class FunctionCodegen {
new FunctionGenerationStrategy.FunctionDefault(state, function));
}
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), functionDescriptor, owner.getContextKind(),
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor, true), functionDescriptor, owner.getContextKind(),
DefaultParameterValueLoader.DEFAULT, function);
generateOverloadsWithDefaultValues(function, functionDescriptor, functionDescriptor);
@@ -66,6 +66,8 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8Interface;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceMember;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
import static org.jetbrains.kotlin.resolve.BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL;
import static org.jetbrains.kotlin.resolve.BindingContext.TYPE_ALIAS;
@@ -375,7 +377,14 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
private Type computeOuterClass(@NotNull CodegenContext<?> context) {
CodegenContext<? extends ClassOrPackageFragmentDescriptor> outermost = context.getClassOrPackageParentContext();
if (outermost instanceof ClassContext) {
return typeMapper.mapType(((ClassContext) outermost).getContextDescriptor());
ClassDescriptor classDescriptor = ((ClassContext) outermost).getContextDescriptor();
if (context instanceof MethodContext) {
FunctionDescriptor functionDescriptor = ((MethodContext) context).getFunctionDescriptor();
if (isInterface(functionDescriptor.getContainingDeclaration()) && !isJvm8InterfaceMember(functionDescriptor, state)) {
return typeMapper.mapDefaultImpls(classDescriptor);
}
}
return typeMapper.mapType(classDescriptor);
}
else if (outermost instanceof MultifileClassFacadeContext || outermost instanceof DelegatingToPartContext) {
Type implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(outermost);
@@ -393,10 +402,17 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
@Nullable
private Method computeEnclosingMethod(@NotNull CodegenContext context) {
if (context instanceof MethodContext) {
Method method = typeMapper.mapAsmMethod(((MethodContext) context).getFunctionDescriptor());
if (!method.getName().equals("<clinit>")) {
return method;
FunctionDescriptor functionDescriptor = ((MethodContext) context).getFunctionDescriptor();
if ("<clinit>".equals(functionDescriptor.getName().asString())) {
return null;
}
if (((MethodContext) context).isDefaultFunctionContext()) {
return typeMapper.mapDefaultMethod(functionDescriptor, context.getContextKind());
}
return typeMapper.mapAsmMethod(functionDescriptor, context.getContextKind());
}
return null;
}
@@ -299,9 +299,14 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return new AnonymousClassContext(codegen.getState().getTypeMapper(), descriptor, ownerKind, this, codegen);
}
@NotNull
public MethodContext intoFunction(FunctionDescriptor descriptor, boolean isDefaultFunctionContext) {
return new MethodContext(descriptor, getContextKind(), this, null, isDefaultFunctionContext);
}
@NotNull
public MethodContext intoFunction(FunctionDescriptor descriptor) {
return new MethodContext(descriptor, getContextKind(), this, null);
return intoFunction(descriptor, false);
}
@NotNull
@@ -34,7 +34,7 @@ public class ConstructorContext extends MethodContext {
@NotNull CodegenContext parent,
@Nullable MutableClosure closure
) {
super(contextDescriptor, kind, parent, closure);
super(contextDescriptor, kind, parent, closure, false);
}
@Override
@@ -27,7 +27,7 @@ class InlineLambdaContext(
closure: MutableClosure?,
val isCrossInline: Boolean,
val isPropertyReference: Boolean
) : MethodContext(functionDescriptor, contextKind, parentContext, closure) {
) : MethodContext(functionDescriptor, contextKind, parentContext, closure, false) {
override fun getFirstCrossInlineOrNonInlineContext(): CodegenContext<*> {
if (isCrossInline) return this
@@ -39,16 +39,19 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
// Note: in case of code inside property accessors, functionDescriptor will be that accessor,
// but CodegenContext#contextDescriptor will be the corresponding property
private final FunctionDescriptor functionDescriptor;
private final boolean isDefaultFunctionContext;
protected MethodContext(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull OwnerKind contextKind,
@NotNull CodegenContext parentContext,
@Nullable MutableClosure closure
@Nullable MutableClosure closure,
boolean isDefaultFunctionContext
) {
super(JvmCodegenUtil.getDirectMember(functionDescriptor), contextKind, parentContext, closure,
parentContext.hasThisDescriptor() ? parentContext.getThisDescriptor() : null, null);
this.functionDescriptor = functionDescriptor;
this.isDefaultFunctionContext = isDefaultFunctionContext;
}
@NotNull
@@ -126,4 +129,8 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
public FunctionDescriptor getFunctionDescriptor() {
return functionDescriptor;
}
public boolean isDefaultFunctionContext() {
return isDefaultFunctionContext;
}
}