Generate 'DefaultImpls' for jvm 8 target only within compiler option

This commit is contained in:
Michael Bogdanov
2016-09-12 12:05:45 +03:00
parent ca41f01468
commit dd4d5e3aa1
15 changed files with 145 additions and 26 deletions
@@ -79,6 +79,7 @@ import java.util.Set;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isAnnotationOrJvm6Interface;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8Interface;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceMember;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
@@ -163,9 +164,7 @@ public class FunctionCodegen {
OwnerKind contextKind = methodContext.getContextKind();
if (isInterface(functionDescriptor.getContainingDeclaration()) &&
functionDescriptor.getVisibility() == Visibilities.PRIVATE &&
(isJvm8InterfaceMember(functionDescriptor, state)
? contextKind == OwnerKind.DEFAULT_IMPLS
: contextKind != OwnerKind.DEFAULT_IMPLS)) {
!processInterfaceMember(functionDescriptor, contextKind, state)) {
return;
}
@@ -199,7 +198,7 @@ public class FunctionCodegen {
generateBridges(functionDescriptor);
if (isJvm8InterfaceMember(functionDescriptor, state) && contextKind != OwnerKind.DEFAULT_IMPLS) {
if (isJvm8InterfaceMember(functionDescriptor, state) && contextKind != OwnerKind.DEFAULT_IMPLS && state.getGenerateDefaultImplsForJvm8()) {
generateDelegateForDefaultImpl(functionDescriptor, origin.getElement());
}
@@ -771,7 +770,7 @@ public class FunctionCodegen {
) {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
if (kind != OwnerKind.DEFAULT_IMPLS && isInterface(contextClass)) {
if (isInterface(contextClass) && !processInterface(contextClass, kind, state)) {
return;
}
@@ -1157,4 +1156,21 @@ public class FunctionCodegen {
}
);
}
public static boolean processInterfaceMember(
@NotNull CallableMemberDescriptor function,
@NotNull OwnerKind kind,
@NotNull GenerationState state
) {
return processInterface(function.getContainingDeclaration(), kind, state);
}
public static boolean processInterface(
@NotNull DeclarationDescriptor contextClass,
@NotNull OwnerKind kind,
@NotNull GenerationState state
) {
assert isInterface(contextClass) : "'processInterface' method should be called only for interfaces, but: " + contextClass;
return isJvm8Interface(contextClass, state) ? kind != OwnerKind.DEFAULT_IMPLS : kind == OwnerKind.DEFAULT_IMPLS;
}
}
@@ -231,7 +231,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Override
protected void generateDefaultImplsIfNeeded() {
if (isInterface(descriptor) && !isLocal) {
if (isInterface(descriptor) && !isLocal && (!isJvm8Interface(descriptor, state) || state.getGenerateDefaultImplsForJvm8())) {
Type defaultImplsType = state.getTypeMapper().mapDefaultImpls(descriptor);
ClassBuilder defaultImplsBuilder =
state.getFactory().newVisitor(JvmDeclarationOriginKt.DefaultImpls(myClass, descriptor), defaultImplsType, myClass.getContainingFile());
@@ -79,7 +79,7 @@ public class JvmCodegenUtil {
return !state.isJvm8Target();
}
private static boolean isJvm8Interface(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) {
public static boolean isJvm8Interface(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) {
return DescriptorUtils.isInterface(descriptor) && !isAnnotationOrJvm6Interface(descriptor, state);
}
@@ -275,7 +275,8 @@ public class PropertyCodegen {
DeclarationDescriptor contextDescriptor = context.getContextDescriptor();
if (!isInterface(contextDescriptor) ||
(isJvm8Interface(contextDescriptor, state) ? kind != OwnerKind.DEFAULT_IMPLS : kind == OwnerKind.DEFAULT_IMPLS)) {
(FunctionCodegen.processInterface(contextDescriptor, kind, state) ||
(kind == OwnerKind.DEFAULT_IMPLS && state.getGenerateDefaultImplsForJvm8()))) {
int flags = ACC_DEPRECATED | ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC;
Method syntheticMethod = getSyntheticMethodSignature(descriptor);
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(descriptor), flags, syntheticMethod.getName(),
@@ -157,6 +157,7 @@ class GenerationState @JvmOverloads constructor(
val useTypeTableInSerializer: Boolean = configuration.getBoolean(JVMConfigurationKeys.USE_TYPE_TABLE)
val inheritMultifileParts: Boolean = configuration.getBoolean(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS)
val isJvm8Target: Boolean = configuration.get(JVMConfigurationKeys.JVM_TARGET) == JvmTarget.JVM_1_8
val generateDefaultImplsForJvm8: Boolean = configuration.getBoolean(JVMConfigurationKeys.INTERFACE_COMPATIBILITY)
val rootContext: CodegenContext<*> = RootContext(this)