Introduced test flag: JVM8_TARGET_WITH_DEFAULTS
This commit is contained in:
@@ -181,7 +181,7 @@ public class AsmUtil {
|
||||
|
||||
public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind, GenerationState state) {
|
||||
return (functionDescriptor.getModality() == Modality.ABSTRACT ||
|
||||
(isJvmInterface(functionDescriptor.getContainingDeclaration()) && !state.isJvm8Target()))
|
||||
(isJvmInterface(functionDescriptor.getContainingDeclaration()) && !state.isJvm8TargetWithDefaults()))
|
||||
&& !isStaticMethod(kind, functionDescriptor);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ public class FunctionCodegen {
|
||||
private final Function1<DeclarationDescriptor, Boolean> IS_PURE_INTERFACE_CHECKER = new Function1<DeclarationDescriptor, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(DeclarationDescriptor descriptor) {
|
||||
return JvmCodegenUtil.isAnnotationOrJvm6Interface(descriptor, state);
|
||||
return JvmCodegenUtil.isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, state);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -201,7 +201,7 @@ public class FunctionCodegen {
|
||||
|
||||
generateBridges(functionDescriptor);
|
||||
|
||||
if (isJvm8InterfaceMember(functionDescriptor, state) && contextKind != OwnerKind.DEFAULT_IMPLS && state.getGenerateDefaultImplsForJvm8()) {
|
||||
if (isJvm8InterfaceWithDefaultsMember(functionDescriptor, state) && contextKind != OwnerKind.DEFAULT_IMPLS && state.getGenerateDefaultImplsForJvm8()) {
|
||||
generateDelegateForDefaultImpl(functionDescriptor, origin.getElement());
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ public class FunctionCodegen {
|
||||
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
|
||||
methodEnd = new Label();
|
||||
}
|
||||
else if (OwnerKind.DEFAULT_IMPLS == context.getContextKind() && isJvm8InterfaceMember(functionDescriptor, parentCodegen.state)) {
|
||||
else if (OwnerKind.DEFAULT_IMPLS == context.getContextKind() && isJvm8InterfaceWithDefaultsMember(functionDescriptor, parentCodegen.state)) {
|
||||
int flags = AsmUtil.getMethodAsmFlags(functionDescriptor, OwnerKind.DEFAULT_IMPLS, context.getState());
|
||||
assert (flags & Opcodes.ACC_ABSTRACT) == 0 : "Interface method with body should be non-abstract" + functionDescriptor;
|
||||
Type type = typeMapper.mapOwner(functionDescriptor);
|
||||
@@ -724,7 +724,7 @@ public class FunctionCodegen {
|
||||
public void generateBridges(@NotNull FunctionDescriptor descriptor) {
|
||||
if (descriptor instanceof ConstructorDescriptor) return;
|
||||
if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return;
|
||||
if (isAnnotationOrJvm6Interface(descriptor.getContainingDeclaration(), state)) return;
|
||||
if (isAnnotationOrJvmInterfaceWithoutDefaults(descriptor.getContainingDeclaration(), state)) return;
|
||||
|
||||
// equals(Any?), hashCode(), toString() never need bridges
|
||||
if (isMethodOfAny(descriptor)) return;
|
||||
@@ -1089,7 +1089,7 @@ public class FunctionCodegen {
|
||||
iv.invokespecial(parentInternalName, delegateTo.getName(), delegateTo.getDescriptor(), false);
|
||||
}
|
||||
else {
|
||||
if (isJvm8InterfaceMember(descriptor, state)) {
|
||||
if (isJvm8InterfaceWithDefaultsMember(descriptor, state)) {
|
||||
iv.invokeinterface(v.getThisName(), delegateTo.getName(), delegateTo.getDescriptor());
|
||||
}
|
||||
else {
|
||||
@@ -1257,6 +1257,6 @@ public class FunctionCodegen {
|
||||
@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;
|
||||
return JvmCodegenUtil.isJvm8InterfaceWithDefaults(contextClass, state) ? kind != OwnerKind.DEFAULT_IMPLS : kind == OwnerKind.DEFAULT_IMPLS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
@Override
|
||||
protected void generateDefaultImplsIfNeeded() {
|
||||
if (isInterface(descriptor) && !isLocal && (!isJvm8Interface(descriptor, state) || state.getGenerateDefaultImplsForJvm8())) {
|
||||
if (isInterface(descriptor) && !isLocal && (!JvmCodegenUtil.isJvm8InterfaceWithDefaults(descriptor, state) || state.getGenerateDefaultImplsForJvm8())) {
|
||||
Type defaultImplsType = state.getTypeMapper().mapDefaultImpls(descriptor);
|
||||
ClassBuilder defaultImplsBuilder =
|
||||
state.getFactory().newVisitor(JvmDeclarationOriginKt.DefaultImpls(myClass.getPsiOrParent(), descriptor), defaultImplsType, myClass.getContainingKtFile());
|
||||
@@ -1293,14 +1293,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateTraitMethods() {
|
||||
if (isAnnotationOrJvm6Interface(descriptor, state)) return;
|
||||
if (isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, state)) return;
|
||||
|
||||
List<FunctionDescriptor> restrictedInheritance = new ArrayList<FunctionDescriptor>();
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
FunctionDescriptor interfaceFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) && !isJvm8InterfaceMember(interfaceFun, state)) {
|
||||
if (state.isJvm8Target() && !JvmCodegenUtil.isJvm8Interface(interfaceFun.getContainingDeclaration(), state)) {
|
||||
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) && !isJvm8InterfaceWithDefaultsMember(interfaceFun, state)) {
|
||||
if (state.isJvm8TargetWithDefaults() && !JvmCodegenUtil.isJvm8InterfaceWithDefaults(interfaceFun.getContainingDeclaration(), state)) {
|
||||
restrictedInheritance.add(interfaceFun);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -30,8 +30,6 @@ import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.RootContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
|
||||
@@ -64,11 +62,11 @@ public class JvmCodegenUtil {
|
||||
private JvmCodegenUtil() {
|
||||
}
|
||||
|
||||
public static boolean isAnnotationOrJvm6Interface(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) {
|
||||
return isAnnotationOrJvm6Interface(descriptor, state.isJvm8Target());
|
||||
public static boolean isAnnotationOrJvmInterfaceWithoutDefaults(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) {
|
||||
return isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, state.isJvm8Target(), state.isJvm8TargetWithDefaults());
|
||||
}
|
||||
|
||||
public static boolean isAnnotationOrJvm6Interface(@NotNull DeclarationDescriptor descriptor, boolean isJvm8Target) {
|
||||
private static boolean isAnnotationOrJvmInterfaceWithoutDefaults(@NotNull DeclarationDescriptor descriptor, boolean isJvm8Target, boolean isJvm8TargetWithDefaults) {
|
||||
if (!isJvmInterface(descriptor)) {
|
||||
return false;
|
||||
}
|
||||
@@ -80,23 +78,24 @@ public class JvmCodegenUtil {
|
||||
KotlinJvmBinaryClass binaryClass = ((KotlinJvmBinarySourceElement) source).getBinaryClass();
|
||||
assert binaryClass instanceof FileBasedKotlinClass :
|
||||
"KotlinJvmBinaryClass should be subclass of FileBasedKotlinClass, but " + binaryClass;
|
||||
return ((FileBasedKotlinClass) binaryClass).getClassVersion() == Opcodes.V1_6;
|
||||
/*TODO need add some flags to compiled code*/
|
||||
return true || ((FileBasedKotlinClass) binaryClass).getClassVersion() == Opcodes.V1_6;
|
||||
}
|
||||
}
|
||||
return !isJvm8Target;
|
||||
return !isJvm8TargetWithDefaults;
|
||||
}
|
||||
|
||||
public static boolean isJvm8Interface(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) {
|
||||
return isJvm8Interface(descriptor, state.isJvm8Target());
|
||||
public static boolean isJvm8InterfaceWithDefaults(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) {
|
||||
return isJvm8InterfaceWithDefaults(descriptor, state.isJvm8Target(), state.isJvm8TargetWithDefaults());
|
||||
}
|
||||
|
||||
public static boolean isJvm8Interface(@NotNull DeclarationDescriptor descriptor, boolean isJvm8Target) {
|
||||
return DescriptorUtils.isInterface(descriptor) && !isAnnotationOrJvm6Interface(descriptor, isJvm8Target);
|
||||
public static boolean isJvm8InterfaceWithDefaults(@NotNull DeclarationDescriptor descriptor, boolean isJvm8Target, boolean isJvm8TargetWithDefaults) {
|
||||
return DescriptorUtils.isInterface(descriptor) && !isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, isJvm8Target, isJvm8TargetWithDefaults);
|
||||
}
|
||||
|
||||
public static boolean isJvm8InterfaceMember(@NotNull CallableMemberDescriptor descriptor, @NotNull GenerationState state) {
|
||||
public static boolean isJvm8InterfaceWithDefaultsMember(@NotNull CallableMemberDescriptor descriptor, @NotNull GenerationState state) {
|
||||
DeclarationDescriptor declaration = descriptor.getContainingDeclaration();
|
||||
return isJvm8Interface(declaration, state);
|
||||
return isJvm8InterfaceWithDefaults(declaration, state);
|
||||
}
|
||||
|
||||
public static boolean isJvmInterface(DeclarationDescriptor descriptor) {
|
||||
|
||||
@@ -66,7 +66,7 @@ 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.isJvm8InterfaceMember;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
@@ -377,7 +377,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
ClassDescriptor classDescriptor = ((ClassContext) outermost).getContextDescriptor();
|
||||
if (context instanceof MethodContext) {
|
||||
FunctionDescriptor functionDescriptor = ((MethodContext) context).getFunctionDescriptor();
|
||||
if (isInterface(functionDescriptor.getContainingDeclaration()) && !isJvm8InterfaceMember(functionDescriptor, state)) {
|
||||
if (isInterface(functionDescriptor.getContainingDeclaration()) && !isJvm8InterfaceWithDefaultsMember(functionDescriptor, state)) {
|
||||
return typeMapper.mapDefaultImpls(classDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapper
|
||||
class KotlinToJvmSignatureMapperImpl : KotlinToJvmSignatureMapper {
|
||||
// We use empty BindingContext, because it is only used by KotlinTypeMapper for purposes irrelevant to the needs of this class
|
||||
private val typeMapper = KotlinTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider,
|
||||
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false)
|
||||
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, false)
|
||||
|
||||
override fun mapToJvmMethodSignature(function: FunctionDescriptor) = typeMapper.mapAsmMethod(function)
|
||||
}
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
|
||||
|
||||
// Avoid errors when some classes are not loaded for some reason
|
||||
private val typeMapper = KotlinTypeMapper(
|
||||
bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, IncompatibleClassTracker.DoNothing, moduleName, false
|
||||
bindingContext, ClassBuilderMode.LIGHT_CLASSES, fileClassesProvider, IncompatibleClassTracker.DoNothing, moduleName, false, false
|
||||
)
|
||||
private val reportDiagnosticsTasks = ArrayList<() -> Unit>()
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ class GenerationState @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
val isJvm8Target: Boolean = configuration.get(JVMConfigurationKeys.JVM_TARGET) == JvmTarget.JVM_1_8
|
||||
val isJvm8TargetWithDefaults: Boolean = isJvm8Target && configuration.getBoolean(JVMConfigurationKeys.JVM8_TARGET_WITH_DEFAULTS)
|
||||
val generateDefaultImplsForJvm8: Boolean = configuration.getBoolean(JVMConfigurationKeys.INTERFACE_COMPATIBILITY)
|
||||
|
||||
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
||||
@@ -134,7 +135,7 @@ class GenerationState @JvmOverloads constructor(
|
||||
val bindingContext: BindingContext = bindingTrace.bindingContext
|
||||
val typeMapper: KotlinTypeMapper = KotlinTypeMapper(
|
||||
this.bindingContext, classBuilderMode, fileClassesProvider, IncompatibleClassTrackerImpl(extraJvmDiagnosticsTrace),
|
||||
this.moduleName, isJvm8Target
|
||||
this.moduleName, isJvm8Target, isJvm8TargetWithDefaults
|
||||
)
|
||||
val intrinsics: IntrinsicMethods = IntrinsicMethods()
|
||||
val samWrapperClasses: SamWrapperClasses = SamWrapperClasses(this)
|
||||
|
||||
@@ -98,6 +98,7 @@ public class KotlinTypeMapper {
|
||||
private final IncompatibleClassTracker incompatibleClassTracker;
|
||||
private final String moduleName;
|
||||
private final boolean isJvm8Target;
|
||||
private final boolean isJvm8TargetWithDefaults;
|
||||
|
||||
private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() {
|
||||
private final Function2<String, String, String> defaultClassNameFactory
|
||||
@@ -153,7 +154,8 @@ public class KotlinTypeMapper {
|
||||
@NotNull JvmFileClassesProvider fileClassesProvider,
|
||||
@NotNull IncompatibleClassTracker incompatibleClassTracker,
|
||||
@NotNull String moduleName,
|
||||
boolean isJvm8Target
|
||||
boolean isJvm8Target,
|
||||
boolean isJvm8TargetWithDefaults
|
||||
) {
|
||||
this.bindingContext = bindingContext;
|
||||
this.classBuilderMode = classBuilderMode;
|
||||
@@ -161,6 +163,7 @@ public class KotlinTypeMapper {
|
||||
this.incompatibleClassTracker = incompatibleClassTracker;
|
||||
this.moduleName = moduleName;
|
||||
this.isJvm8Target = isJvm8Target;
|
||||
this.isJvm8TargetWithDefaults = isJvm8TargetWithDefaults;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -682,7 +685,7 @@ public class KotlinTypeMapper {
|
||||
descriptor = classCallable;
|
||||
continue;
|
||||
}
|
||||
else if (isSuperCall && !isJvm8Target && !isInterface(descriptor.getContainingDeclaration())) {
|
||||
else if (isSuperCall && !isJvm8TargetWithDefaults && !isInterface(descriptor.getContainingDeclaration())) {
|
||||
//Don't unwrap fake overrides from class to interface cause substituted override would be implicitly generated for target 1.6
|
||||
return descriptor;
|
||||
}
|
||||
@@ -738,12 +741,12 @@ public class KotlinTypeMapper {
|
||||
baseMethodDescriptor = findBaseDeclaration(functionDescriptor).getOriginal();
|
||||
ClassDescriptor ownerForDefault = (ClassDescriptor) baseMethodDescriptor.getContainingDeclaration();
|
||||
ownerForDefaultImpl =
|
||||
isJvmInterface(ownerForDefault) && !isJvm8Interface(ownerForDefault) ?
|
||||
isJvmInterface(ownerForDefault) && !isJvm8InterfaceWithDefaults(ownerForDefault) ?
|
||||
mapDefaultImpls(ownerForDefault) : mapClass(ownerForDefault);
|
||||
|
||||
if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE || isAccessor(descriptor))) {
|
||||
thisClass = mapClass(currentOwner);
|
||||
if (declarationOwner instanceof JavaClassDescriptor || isJvm8Interface(declarationOwner)) {
|
||||
if (declarationOwner instanceof JavaClassDescriptor || isJvm8InterfaceWithDefaults(declarationOwner)) {
|
||||
invokeOpcode = INVOKESPECIAL;
|
||||
signature = mapSignatureSkipGeneric(functionDescriptor);
|
||||
owner = thisClass;
|
||||
@@ -782,7 +785,6 @@ public class KotlinTypeMapper {
|
||||
|
||||
signature = mapSignatureSkipGeneric(functionToCall);
|
||||
|
||||
/*TODO: isInterfaceMember?*/
|
||||
ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor
|
||||
? declarationOwner
|
||||
: currentOwner;
|
||||
@@ -828,8 +830,9 @@ public class KotlinTypeMapper {
|
||||
isJvm8Target ? isInterfaceMember : invokeOpcode == INVOKEINTERFACE );
|
||||
}
|
||||
|
||||
private boolean isJvm8Interface(@NotNull ClassDescriptor ownerForDefault) {
|
||||
return isJvmInterface(ownerForDefault) && JvmCodegenUtil.isJvm8Interface(ownerForDefault, isJvm8Target);
|
||||
private boolean isJvm8InterfaceWithDefaults(@NotNull ClassDescriptor ownerForDefault) {
|
||||
return isJvmInterface(ownerForDefault) &&
|
||||
JvmCodegenUtil.isJvm8InterfaceWithDefaults(ownerForDefault, isJvm8Target, isJvm8TargetWithDefaults);
|
||||
}
|
||||
|
||||
public static boolean isAccessor(@NotNull CallableMemberDescriptor descriptor) {
|
||||
|
||||
Reference in New Issue
Block a user