Explicitly pass jvmDefaultMode
This commit is contained in:
committed by
Mikhail Bogdanov
parent
954ef7d7d6
commit
bfd709290b
@@ -22,9 +22,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.HashCode;
|
|||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
import org.jetbrains.kotlin.config.JvmTarget;
|
import org.jetbrains.kotlin.config.*;
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
@@ -308,9 +306,9 @@ public class AsmUtil {
|
|||||||
return new Method(name, Type.getMethodDescriptor(returnType, parameterTypes));
|
return new Method(name, Type.getMethodDescriptor(returnType, parameterTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
public static boolean isAbstractMethod(FunctionDescriptor functionDescriptor, OwnerKind kind, JvmDefaultMode jvmDefaultMode) {
|
||||||
return (functionDescriptor.getModality() == Modality.ABSTRACT ||
|
return (functionDescriptor.getModality() == Modality.ABSTRACT ||
|
||||||
(isJvmInterface(functionDescriptor.getContainingDeclaration()) && !hasJvmDefaultAnnotation(functionDescriptor)))
|
(isJvmInterface(functionDescriptor.getContainingDeclaration()) && !hasJvmDefaultAnnotation(functionDescriptor, jvmDefaultMode)))
|
||||||
&& !isStaticMethod(kind, functionDescriptor);
|
&& !isStaticMethod(kind, functionDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,10 +323,15 @@ public class AsmUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind, GenerationState state) {
|
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind, GenerationState state) {
|
||||||
return getMethodAsmFlags(functionDescriptor, kind, state.getDeprecationProvider());
|
return getMethodAsmFlags(functionDescriptor, kind, state.getDeprecationProvider(), state.getJvmDefaultMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind, DeprecationResolver deprecationResolver) {
|
public static int getMethodAsmFlags(
|
||||||
|
FunctionDescriptor functionDescriptor,
|
||||||
|
OwnerKind kind,
|
||||||
|
DeprecationResolver deprecationResolver,
|
||||||
|
JvmDefaultMode jvmDefaultMode
|
||||||
|
) {
|
||||||
int flags = getCommonCallableFlags(functionDescriptor, kind, deprecationResolver);
|
int flags = getCommonCallableFlags(functionDescriptor, kind, deprecationResolver);
|
||||||
|
|
||||||
for (AnnotationCodegen.JvmFlagAnnotation flagAnnotation : AnnotationCodegen.METHOD_FLAGS) {
|
for (AnnotationCodegen.JvmFlagAnnotation flagAnnotation : AnnotationCodegen.METHOD_FLAGS) {
|
||||||
@@ -356,7 +359,7 @@ public class AsmUtil {
|
|||||||
flags |= ACC_STATIC;
|
flags |= ACC_STATIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAbstractMethod(functionDescriptor, kind)) {
|
if (isAbstractMethod(functionDescriptor, kind, jvmDefaultMode)) {
|
||||||
flags |= ACC_ABSTRACT;
|
flags |= ACC_ABSTRACT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
|||||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||||
FunctionDescriptor interfaceFun = entry.getKey();
|
FunctionDescriptor interfaceFun = entry.getKey();
|
||||||
//skip java 8 default methods
|
//skip java 8 default methods
|
||||||
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) && !hasJvmDefaultAnnotation(interfaceFun)) {
|
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) && !hasJvmDefaultAnnotation(interfaceFun, state.getJvmDefaultMode())) {
|
||||||
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
|
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -447,7 +447,7 @@ public class FunctionCodegen {
|
|||||||
) {
|
) {
|
||||||
OwnerKind contextKind = methodContext.getContextKind();
|
OwnerKind contextKind = methodContext.getContextKind();
|
||||||
if (!state.getClassBuilderMode().generateBodies
|
if (!state.getClassBuilderMode().generateBodies
|
||||||
|| isAbstractMethod(functionDescriptor, contextKind)
|
|| isAbstractMethod(functionDescriptor, contextKind, state.getJvmDefaultMode())
|
||||||
|| shouldSkipMethodBodyInAbiMode(state.getClassBuilderMode(), origin)
|
|| shouldSkipMethodBodyInAbiMode(state.getClassBuilderMode(), origin)
|
||||||
) {
|
) {
|
||||||
generateLocalVariableTable(
|
generateLocalVariableTable(
|
||||||
@@ -732,7 +732,7 @@ public class FunctionCodegen {
|
|||||||
@NotNull JvmDefaultMode jvmDefaultMode
|
@NotNull JvmDefaultMode jvmDefaultMode
|
||||||
) {
|
) {
|
||||||
return OwnerKind.DEFAULT_IMPLS == context.getContextKind() &&
|
return OwnerKind.DEFAULT_IMPLS == context.getContextKind() &&
|
||||||
hasJvmDefaultAnnotation(functionDescriptor) &&
|
hasJvmDefaultAnnotation(functionDescriptor, jvmDefaultMode) &&
|
||||||
jvmDefaultMode.isCompatibility();
|
jvmDefaultMode.isCompatibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1000,7 +1000,7 @@ public class FunctionCodegen {
|
|||||||
public void generateBridges(@NotNull FunctionDescriptor descriptor) {
|
public void generateBridges(@NotNull FunctionDescriptor descriptor) {
|
||||||
if (descriptor instanceof ConstructorDescriptor) return;
|
if (descriptor instanceof ConstructorDescriptor) return;
|
||||||
if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return;
|
if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return;
|
||||||
if (JvmBridgesImplKt.isAbstractOnJvmIgnoringActualModality(descriptor)) return;
|
if (JvmBridgesImplKt.isAbstractOnJvmIgnoringActualModality(descriptor, state.getJvmDefaultMode())) return;
|
||||||
|
|
||||||
// equals(Any?), hashCode(), toString() never need bridges
|
// equals(Any?), hashCode(), toString() never need bridges
|
||||||
if (isMethodOfAny(descriptor)) return;
|
if (isMethodOfAny(descriptor)) return;
|
||||||
@@ -1036,7 +1036,7 @@ public class FunctionCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) {
|
if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION, state.getJvmDefaultMode())) {
|
||||||
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
|
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
|
||||||
assert overridden != null;
|
assert overridden != null;
|
||||||
|
|
||||||
@@ -1460,7 +1460,7 @@ public class FunctionCodegen {
|
|||||||
iv.invokespecial(parentInternalName, delegateTo.getName(), delegateTo.getDescriptor(), false);
|
iv.invokespecial(parentInternalName, delegateTo.getName(), delegateTo.getDescriptor(), false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (hasJvmDefaultAnnotation(descriptor)) {
|
if (hasJvmDefaultAnnotation(descriptor, state.getJvmDefaultMode())) {
|
||||||
iv.invokeinterface(v.getThisName(), delegateTo.getName(), delegateTo.getDescriptor());
|
iv.invokeinterface(v.getThisName(), delegateTo.getName(), delegateTo.getDescriptor());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1650,7 +1650,7 @@ public class FunctionCodegen {
|
|||||||
assert isInterface(containingDeclaration) : "'processInterfaceMethod' method should be called only for interfaces, but: " +
|
assert isInterface(containingDeclaration) : "'processInterfaceMethod' method should be called only for interfaces, but: " +
|
||||||
containingDeclaration;
|
containingDeclaration;
|
||||||
|
|
||||||
if (hasJvmDefaultAnnotation(memberDescriptor)) {
|
if (hasJvmDefaultAnnotation(memberDescriptor, mode)) {
|
||||||
return (kind != OwnerKind.DEFAULT_IMPLS && !isSynthetic) ||
|
return (kind != OwnerKind.DEFAULT_IMPLS && !isSynthetic) ||
|
||||||
(kind == OwnerKind.DEFAULT_IMPLS && (isSynthetic || mode.isCompatibility()));
|
(kind == OwnerKind.DEFAULT_IMPLS && (isSynthetic || mode.isCompatibility()));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.codegen
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.bridges.*
|
import org.jetbrains.kotlin.backend.common.bridges.*
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -29,17 +30,17 @@ class DescriptorBasedFunctionHandleForJvm(
|
|||||||
For non-@JvmDefault interfaces function, its body is generated in a separate place (DefaultImpls) and
|
For non-@JvmDefault interfaces function, its body is generated in a separate place (DefaultImpls) and
|
||||||
the method in the interface is abstract so we must not generate bridges for such cases.
|
the method in the interface is abstract so we must not generate bridges for such cases.
|
||||||
*/
|
*/
|
||||||
override val isAbstract: Boolean = super.isAbstract || isAbstractOnJvmIgnoringActualModality(descriptor)
|
override val isAbstract: Boolean = super.isAbstract || isAbstractOnJvmIgnoringActualModality(descriptor, state.jvmDefaultMode)
|
||||||
|
|
||||||
override val mayBeUsedAsSuperImplementation: Boolean =
|
override val mayBeUsedAsSuperImplementation: Boolean =
|
||||||
super.mayBeUsedAsSuperImplementation || descriptor.isJvmDefaultOrPlatformDependent()
|
super.mayBeUsedAsSuperImplementation || descriptor.isJvmDefaultOrPlatformDependent(state.jvmDefaultMode)
|
||||||
|
|
||||||
private val asmMethod by lazy(LazyThreadSafetyMode.NONE) {
|
private val asmMethod by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
state.typeMapper.mapAsmMethod(descriptor)
|
state.typeMapper.mapAsmMethod(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isDeclaration: Boolean =
|
override val isDeclaration: Boolean =
|
||||||
descriptor.kind.isReal || needToGenerateDelegationToDefaultImpls(descriptor)
|
descriptor.kind.isReal || needToGenerateDelegationToDefaultImpls(descriptor, state.jvmDefaultMode)
|
||||||
|
|
||||||
override val mightBeIncorrectCode: Boolean
|
override val mightBeIncorrectCode: Boolean
|
||||||
get() = state.classBuilderMode.mightBeIncorrectCode
|
get() = state.classBuilderMode.mightBeIncorrectCode
|
||||||
@@ -65,23 +66,23 @@ private fun FunctionDescriptor.containerEntityForEqualityAndHashCode(): Any =
|
|||||||
private val FunctionDescriptor.isJavaForKotlinOverrideProperty: Boolean
|
private val FunctionDescriptor.isJavaForKotlinOverrideProperty: Boolean
|
||||||
get() = this is PropertyAccessorDescriptor && correspondingProperty is JavaForKotlinOverridePropertyDescriptor
|
get() = this is PropertyAccessorDescriptor && correspondingProperty is JavaForKotlinOverridePropertyDescriptor
|
||||||
|
|
||||||
private fun CallableMemberDescriptor.isJvmDefaultOrPlatformDependent() =
|
private fun CallableMemberDescriptor.isJvmDefaultOrPlatformDependent(jvmDefaultMode: JvmDefaultMode) =
|
||||||
hasJvmDefaultAnnotation() || hasPlatformDependentAnnotation()
|
hasJvmDefaultAnnotation(jvmDefaultMode) || hasPlatformDependentAnnotation()
|
||||||
|
|
||||||
private fun needToGenerateDelegationToDefaultImpls(descriptor: FunctionDescriptor): Boolean {
|
private fun needToGenerateDelegationToDefaultImpls(descriptor: FunctionDescriptor, jvmDefaultMode: JvmDefaultMode): Boolean {
|
||||||
if (findInterfaceImplementation(descriptor) == null) return false
|
if (findInterfaceImplementation(descriptor) == null) return false
|
||||||
val overriddenFromInterface = findImplementationFromInterface(descriptor) ?: return false
|
val overriddenFromInterface = findImplementationFromInterface(descriptor) ?: return false
|
||||||
|
|
||||||
return !overriddenFromInterface.isJvmDefaultOrPlatformDependent()
|
return !overriddenFromInterface.isJvmDefaultOrPlatformDependent(jvmDefaultMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return return true for interface method not annotated with @JvmDefault or @PlatformDependent
|
* @return return true for interface method not annotated with @JvmDefault or @PlatformDependent
|
||||||
*/
|
*/
|
||||||
fun isAbstractOnJvmIgnoringActualModality(descriptor: FunctionDescriptor): Boolean {
|
fun isAbstractOnJvmIgnoringActualModality(descriptor: FunctionDescriptor, jvmDefaultMode: JvmDefaultMode): Boolean {
|
||||||
if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) return false
|
if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) return false
|
||||||
|
|
||||||
return !descriptor.isJvmDefaultOrPlatformDependent()
|
return !descriptor.isJvmDefaultOrPlatformDependent(jvmDefaultMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <Signature> generateBridgesForFunctionDescriptorForJvm(
|
fun <Signature> generateBridgesForFunctionDescriptorForJvm(
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
|||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
import org.jetbrains.kotlin.config.ApiVersion;
|
import org.jetbrains.kotlin.config.ApiVersion;
|
||||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags;
|
import org.jetbrains.kotlin.config.JvmAnalysisFlags;
|
||||||
|
import org.jetbrains.kotlin.config.JvmDefaultMode;
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||||
@@ -67,7 +68,7 @@ public class JvmCodegenUtil {
|
|||||||
private JvmCodegenUtil() {
|
private JvmCodegenUtil() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isNonDefaultInterfaceMember(@NotNull CallableMemberDescriptor descriptor) {
|
public static boolean isNonDefaultInterfaceMember(@NotNull CallableMemberDescriptor descriptor, @NotNull JvmDefaultMode jvmDefaultMode) {
|
||||||
if (!isJvmInterface(descriptor.getContainingDeclaration())) {
|
if (!isJvmInterface(descriptor.getContainingDeclaration())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,7 @@ public class JvmCodegenUtil {
|
|||||||
return descriptor.getModality() == Modality.ABSTRACT;
|
return descriptor.getModality() == Modality.ABSTRACT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !hasJvmDefaultAnnotation(descriptor);
|
return !hasJvmDefaultAnnotation(descriptor, jvmDefaultMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isJvmInterface(@Nullable DeclarationDescriptor descriptor) {
|
public static boolean isJvmInterface(@Nullable DeclarationDescriptor descriptor) {
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
ClassDescriptor classDescriptor = ((ClassContext) outermost).getContextDescriptor();
|
ClassDescriptor classDescriptor = ((ClassContext) outermost).getContextDescriptor();
|
||||||
if (context instanceof MethodContext) {
|
if (context instanceof MethodContext) {
|
||||||
FunctionDescriptor functionDescriptor = ((MethodContext) context).getFunctionDescriptor();
|
FunctionDescriptor functionDescriptor = ((MethodContext) context).getFunctionDescriptor();
|
||||||
if (isInterface(functionDescriptor.getContainingDeclaration()) && !hasJvmDefaultAnnotation(functionDescriptor)) {
|
if (isInterface(functionDescriptor.getContainingDeclaration()) && !hasJvmDefaultAnnotation(functionDescriptor, state.getJvmDefaultMode())) {
|
||||||
return typeMapper.mapDefaultImpls(classDescriptor);
|
return typeMapper.mapDefaultImpls(classDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -744,7 +744,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
|
|
||||||
protected final void generateSyntheticAccessors() {
|
protected final void generateSyntheticAccessors() {
|
||||||
for (AccessorForCallableDescriptor<?> accessor : ((CodegenContext<?>) context).getAccessors()) {
|
for (AccessorForCallableDescriptor<?> accessor : ((CodegenContext<?>) context).getAccessors()) {
|
||||||
boolean hasJvmDefaultAnnotation = hasJvmDefaultAnnotation(accessor.getCalleeDescriptor());
|
boolean hasJvmDefaultAnnotation = hasJvmDefaultAnnotation(accessor.getCalleeDescriptor(), state.getJvmDefaultMode());
|
||||||
OwnerKind kind = context.getContextKind();
|
OwnerKind kind = context.getContextKind();
|
||||||
|
|
||||||
if (!isInterface(context.getContextDescriptor()) ||
|
if (!isInterface(context.getContextDescriptor()) ||
|
||||||
@@ -934,7 +934,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
|
|
||||||
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
|
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
|
||||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) &&
|
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) &&
|
||||||
!isNonDefaultInterfaceMember(functionDescriptor) &&
|
!isNonDefaultInterfaceMember(functionDescriptor, state.getJvmDefaultMode()) &&
|
||||||
!isJvmStaticInObjectOrClass &&
|
!isJvmStaticInObjectOrClass &&
|
||||||
!InlineClassesUtilsKt.isInlineClass(functionDescriptor.getContainingDeclaration());
|
!InlineClassesUtilsKt.isInlineClass(functionDescriptor.getContainingDeclaration());
|
||||||
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
|
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
|
||||||
|
|||||||
@@ -438,7 +438,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
@NotNull D descriptor,
|
@NotNull D descriptor,
|
||||||
@Nullable ClassDescriptor superCallTarget,
|
@Nullable ClassDescriptor superCallTarget,
|
||||||
@NotNull GenerationState state) {
|
@NotNull GenerationState state) {
|
||||||
if (superCallTarget != null && !isNonDefaultInterfaceMember(descriptor)) {
|
if (superCallTarget != null && !isNonDefaultInterfaceMember(descriptor, state.getJvmDefaultMode())) {
|
||||||
CodegenContext afterInline = getFirstCrossInlineOrNonInlineContext();
|
CodegenContext afterInline = getFirstCrossInlineOrNonInlineContext();
|
||||||
CodegenContext c = afterInline.findParentContextWithDescriptor(superCallTarget);
|
CodegenContext c = afterInline.findParentContextWithDescriptor(superCallTarget);
|
||||||
assert c != null : "Couldn't find a context for a super-call: " + descriptor;
|
assert c != null : "Couldn't find a context for a super-call: " + descriptor;
|
||||||
@@ -593,8 +593,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
CodegenContext properContext = getFirstCrossInlineOrNonInlineContext();
|
CodegenContext properContext = getFirstCrossInlineOrNonInlineContext();
|
||||||
DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
|
DeclarationDescriptor enclosing = descriptor.getContainingDeclaration();
|
||||||
boolean isInliningContext = properContext.isInlineMethodContext();
|
boolean isInliningContext = properContext.isInlineMethodContext();
|
||||||
boolean sameJvmDefault = hasJvmDefaultAnnotation(descriptor) ==
|
boolean sameJvmDefault = hasJvmDefaultAnnotation(descriptor, getState().getJvmDefaultMode()) ==
|
||||||
isCallableMemberWithJvmDefaultAnnotation(properContext.contextDescriptor) ||
|
isCallableMemberWithJvmDefaultAnnotation(properContext.contextDescriptor, getState().getJvmDefaultMode()) ||
|
||||||
properContext.contextDescriptor instanceof AccessorForCallableDescriptor;
|
properContext.contextDescriptor instanceof AccessorForCallableDescriptor;
|
||||||
if (!isInliningContext && (
|
if (!isInliningContext && (
|
||||||
!properContext.hasThisDescriptor() ||
|
!properContext.hasThisDescriptor() ||
|
||||||
@@ -651,7 +651,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasJvmDefaultAnnotation(descriptor) && descriptorContext instanceof DefaultImplsClassContext) {
|
if (hasJvmDefaultAnnotation(descriptor, getState().getJvmDefaultMode()) && descriptorContext instanceof DefaultImplsClassContext) {
|
||||||
descriptorContext = ((DefaultImplsClassContext) descriptorContext).getInterfaceContext();
|
descriptorContext = ((DefaultImplsClassContext) descriptorContext).getInterfaceContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
|||||||
when {
|
when {
|
||||||
DescriptorUtils.isInterface(descriptor) &&
|
DescriptorUtils.isInterface(descriptor) &&
|
||||||
innerDescriptor !is ClassDescriptor &&
|
innerDescriptor !is ClassDescriptor &&
|
||||||
!innerDescriptor.isCallableMemberWithJvmDefaultAnnotation() ->
|
!innerDescriptor.isCallableMemberWithJvmDefaultAnnotation(state.jvmDefaultMode) ->
|
||||||
OwnerKind.DEFAULT_IMPLS
|
OwnerKind.DEFAULT_IMPLS
|
||||||
else ->
|
else ->
|
||||||
OwnerKind.IMPLEMENTATION
|
OwnerKind.IMPLEMENTATION
|
||||||
|
|||||||
+2
-1
@@ -54,6 +54,7 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
|||||||
private val isParamAssertionsDisabled = state.isParamAssertionsDisabled
|
private val isParamAssertionsDisabled = state.isParamAssertionsDisabled
|
||||||
private val unifiedNullChecks = state.unifiedNullChecks
|
private val unifiedNullChecks = state.unifiedNullChecks
|
||||||
override val metadataVersion = state.metadataVersion
|
override val metadataVersion = state.metadataVersion
|
||||||
|
private val jvmDefaultMode = state.jvmDefaultMode
|
||||||
|
|
||||||
override fun shouldUseTypeTable(): Boolean = useTypeTable
|
override fun shouldUseTypeTable(): Boolean = useTypeTable
|
||||||
override fun shouldSerializeFunction(descriptor: FunctionDescriptor): Boolean {
|
override fun shouldSerializeFunction(descriptor: FunctionDescriptor): Boolean {
|
||||||
@@ -98,7 +99,7 @@ class JvmSerializerExtension @JvmOverloads constructor(
|
|||||||
if (
|
if (
|
||||||
isInterface(classDescriptor) &&
|
isInterface(classDescriptor) &&
|
||||||
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors().any {
|
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors().any {
|
||||||
it is CallableMemberDescriptor && it.hasJvmDefaultAnnotation()
|
it is CallableMemberDescriptor && it.hasJvmDefaultAnnotation(jvmDefaultMode) //TODO: new requirements for new option
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
builder.addVersionRequirement(
|
builder.addVersionRequirement(
|
||||||
|
|||||||
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.codegen.inline.FictitiousArrayConstructor
|
|||||||
import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory
|
import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory
|
||||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.*
|
import org.jetbrains.kotlin.descriptors.impl.*
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
@@ -89,6 +86,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
private val namePreprocessor: ((ClassDescriptor) -> String?)? = null
|
private val namePreprocessor: ((ClassDescriptor) -> String?)? = null
|
||||||
) : KotlinTypeMapperBase() {
|
) : KotlinTypeMapperBase() {
|
||||||
private val isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
private val isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||||
|
val jvmDefaultMode = languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)
|
||||||
|
|
||||||
private val typeMappingConfiguration = object : TypeMappingConfiguration<Type> {
|
private val typeMappingConfiguration = object : TypeMappingConfiguration<Type> {
|
||||||
override fun commonSupertype(types: Collection<KotlinType>): KotlinType {
|
override fun commonSupertype(types: Collection<KotlinType>): KotlinType {
|
||||||
@@ -424,7 +422,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
|
|
||||||
val functionParent = descriptor.original.containingDeclaration
|
val functionParent = descriptor.original.containingDeclaration
|
||||||
|
|
||||||
var functionDescriptor = findSuperDeclaration(descriptor.original, superCall)
|
var functionDescriptor = findSuperDeclaration(descriptor.original, superCall, jvmDefaultMode)
|
||||||
|
|
||||||
val signature: JvmMethodSignature
|
val signature: JvmMethodSignature
|
||||||
val returnKotlinType: KotlinType?
|
val returnKotlinType: KotlinType?
|
||||||
@@ -449,8 +447,8 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
|
|
||||||
baseMethodDescriptor = findBaseDeclaration(functionDescriptor).original
|
baseMethodDescriptor = findBaseDeclaration(functionDescriptor).original
|
||||||
val ownerForDefault = baseMethodDescriptor.containingDeclaration as ClassDescriptor
|
val ownerForDefault = baseMethodDescriptor.containingDeclaration as ClassDescriptor
|
||||||
isDefaultMethodInInterface = isJvmInterface(ownerForDefault) && baseMethodDescriptor.hasJvmDefaultAnnotation()
|
isDefaultMethodInInterface = isJvmInterface(ownerForDefault) && baseMethodDescriptor.hasJvmDefaultAnnotation(jvmDefaultMode)
|
||||||
ownerForDefaultImpl = if (isJvmInterface(ownerForDefault) && !baseMethodDescriptor.hasJvmDefaultAnnotation())
|
ownerForDefaultImpl = if (isJvmInterface(ownerForDefault) && !baseMethodDescriptor.hasJvmDefaultAnnotation(jvmDefaultMode))
|
||||||
mapDefaultImpls(ownerForDefault)
|
mapDefaultImpls(ownerForDefault)
|
||||||
else
|
else
|
||||||
mapClass(ownerForDefault)
|
mapClass(ownerForDefault)
|
||||||
@@ -458,7 +456,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
if (isInterface && (superCall || descriptor.visibility == Visibilities.PRIVATE || isAccessor(descriptor))) {
|
if (isInterface && (superCall || descriptor.visibility == Visibilities.PRIVATE || isAccessor(descriptor))) {
|
||||||
thisClass = mapClass(functionParent)
|
thisClass = mapClass(functionParent)
|
||||||
dispatchReceiverKotlinType = functionParent.defaultType
|
dispatchReceiverKotlinType = functionParent.defaultType
|
||||||
if (declarationOwner is JavaClassDescriptor || declarationFunctionDescriptor.hasJvmDefaultAnnotation()) {
|
if (declarationOwner is JavaClassDescriptor || declarationFunctionDescriptor.hasJvmDefaultAnnotation(jvmDefaultMode)) {
|
||||||
invokeOpcode = INVOKESPECIAL
|
invokeOpcode = INVOKESPECIAL
|
||||||
signature = mapSignatureSkipGeneric(functionDescriptor)
|
signature = mapSignatureSkipGeneric(functionDescriptor)
|
||||||
returnKotlinType = functionDescriptor.returnType
|
returnKotlinType = functionDescriptor.returnType
|
||||||
@@ -469,7 +467,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
val originalDescriptor = descriptor.original
|
val originalDescriptor = descriptor.original
|
||||||
signature = mapSignatureSkipGeneric(originalDescriptor, OwnerKind.DEFAULT_IMPLS)
|
signature = mapSignatureSkipGeneric(originalDescriptor, OwnerKind.DEFAULT_IMPLS)
|
||||||
returnKotlinType = getReturnValueType(originalDescriptor)
|
returnKotlinType = getReturnValueType(originalDescriptor)
|
||||||
if (descriptor is AccessorForCallableDescriptor<*> && descriptor.calleeDescriptor.hasJvmDefaultAnnotation()) {
|
if (descriptor is AccessorForCallableDescriptor<*> && descriptor.calleeDescriptor.hasJvmDefaultAnnotation(jvmDefaultMode)) {
|
||||||
owner = mapClass(functionParent)
|
owner = mapClass(functionParent)
|
||||||
isInterfaceMember = true
|
isInterfaceMember = true
|
||||||
} else {
|
} else {
|
||||||
@@ -1510,7 +1508,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//NB: similar platform agnostic code in DescriptorUtils.unwrapFakeOverride
|
//NB: similar platform agnostic code in DescriptorUtils.unwrapFakeOverride
|
||||||
private fun findSuperDeclaration(descriptor: FunctionDescriptor, isSuperCall: Boolean): FunctionDescriptor {
|
private fun findSuperDeclaration(descriptor: FunctionDescriptor, isSuperCall: Boolean, jvmDefaultMode: JvmDefaultMode): FunctionDescriptor {
|
||||||
var current = descriptor
|
var current = descriptor
|
||||||
while (current.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
while (current.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||||
val classCallable = current.overriddenDescriptors.firstOrNull { !isInterface(it.containingDeclaration) }
|
val classCallable = current.overriddenDescriptors.firstOrNull { !isInterface(it.containingDeclaration) }
|
||||||
@@ -1519,7 +1517,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
current = classCallable
|
current = classCallable
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (isSuperCall && !current.hasJvmDefaultAnnotation() && !isInterface(current.containingDeclaration)) {
|
if (isSuperCall && !current.hasJvmDefaultAnnotation(jvmDefaultMode) && !isInterface(current.containingDeclaration)) {
|
||||||
//Don't unwrap fake overrides from class to interface cause substituted override would be implicitly generated
|
//Don't unwrap fake overrides from class to interface cause substituted override would be implicitly generated
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,18 @@ package org.jetbrains.kotlin.config
|
|||||||
enum class JvmDefaultMode(val description: String) {
|
enum class JvmDefaultMode(val description: String) {
|
||||||
DISABLE("disable"),
|
DISABLE("disable"),
|
||||||
ENABLE("enable"),
|
ENABLE("enable"),
|
||||||
ENABLE_WITH_DEFAULT_IMPLS("compatibility");
|
ENABLE_WITH_DEFAULT_IMPLS("compatibility"),
|
||||||
|
ALL_COMPATIBILITY("all-compatibility"),
|
||||||
|
ALL_INCOMPATIBLE("all");
|
||||||
|
|
||||||
val isEnabled
|
val isEnabled
|
||||||
get() = this != DISABLE
|
get() = this != DISABLE
|
||||||
|
|
||||||
val isCompatibility
|
val isCompatibility
|
||||||
get() = this == ENABLE_WITH_DEFAULT_IMPLS
|
get() = this == ENABLE_WITH_DEFAULT_IMPLS || this == ALL_COMPATIBILITY
|
||||||
|
|
||||||
|
val forAllMehtodsWithBody
|
||||||
|
get() = this == ALL_COMPATIBILITY || this == ALL_INCOMPATIBLE
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve.jvm
|
package org.jetbrains.kotlin.resolve.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
@@ -35,7 +36,7 @@ object JvmDelegationFilter : DelegationFilter {
|
|||||||
//We always have only one implementation otherwise it's an error in kotlin and java
|
//We always have only one implementation otherwise it's an error in kotlin and java
|
||||||
val realMember = DescriptorUtils.unwrapFakeOverride(interfaceMember)
|
val realMember = DescriptorUtils.unwrapFakeOverride(interfaceMember)
|
||||||
return !isJavaDefaultMethod(realMember) &&
|
return !isJavaDefaultMethod(realMember) &&
|
||||||
!realMember.hasJvmDefaultAnnotation() &&
|
!realMember.hasJvmDefaultAnnotation(languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)) &&
|
||||||
!isBuiltInMemberMappedToJavaDefault(realMember)
|
!isBuiltInMemberMappedToJavaDefault(realMember)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.jvm.annotations
|
package org.jetbrains.kotlin.resolve.jvm.annotations
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
@@ -40,11 +41,11 @@ fun DeclarationDescriptor.findJvmFieldAnnotation(): AnnotationDescriptor? =
|
|||||||
fun DeclarationDescriptor.hasJvmFieldAnnotation(): Boolean =
|
fun DeclarationDescriptor.hasJvmFieldAnnotation(): Boolean =
|
||||||
findJvmFieldAnnotation() != null
|
findJvmFieldAnnotation() != null
|
||||||
|
|
||||||
fun DeclarationDescriptor.isCallableMemberWithJvmDefaultAnnotation(): Boolean =
|
fun DeclarationDescriptor.isCallableMemberWithJvmDefaultAnnotation(jvmDefault: JvmDefaultMode): Boolean =
|
||||||
this is CallableMemberDescriptor && hasJvmDefaultAnnotation()
|
this is CallableMemberDescriptor && hasJvmDefaultAnnotation(jvmDefault)
|
||||||
|
|
||||||
fun CallableMemberDescriptor.hasJvmDefaultAnnotation(): Boolean =
|
fun CallableMemberDescriptor.hasJvmDefaultAnnotation(jvmDefault: JvmDefaultMode): Boolean =
|
||||||
DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)
|
jvmDefault.forAllMehtodsWithBody || DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)
|
||||||
|
|
||||||
fun CallableMemberDescriptor.hasPlatformDependentAnnotation(): Boolean =
|
fun CallableMemberDescriptor.hasPlatformDependentAnnotation(): Boolean =
|
||||||
DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME)
|
DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME)
|
||||||
|
|||||||
+4
-2
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
import org.jetbrains.kotlin.config.JvmTarget
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
@@ -61,13 +62,14 @@ class InterfaceDefaultMethodCallChecker(val jvmTarget: JvmTarget) : CallChecker
|
|||||||
val realDescriptor = unwrapFakeOverride(descriptor)
|
val realDescriptor = unwrapFakeOverride(descriptor)
|
||||||
val realDescriptorOwner = realDescriptor.containingDeclaration as? ClassDescriptor ?: return
|
val realDescriptorOwner = realDescriptor.containingDeclaration as? ClassDescriptor ?: return
|
||||||
|
|
||||||
if (isInterface(realDescriptorOwner) && (realDescriptor is JavaCallableMemberDescriptor || realDescriptor.hasJvmDefaultAnnotation())) {
|
val jvmDefaultMode = context.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)
|
||||||
|
if (isInterface(realDescriptorOwner) && (realDescriptor is JavaCallableMemberDescriptor || realDescriptor.hasJvmDefaultAnnotation(jvmDefaultMode))) {
|
||||||
val bindingContext = context.trace.bindingContext
|
val bindingContext = context.trace.bindingContext
|
||||||
val thisForSuperCall = getSuperCallLabelTarget(bindingContext, superCallExpression)
|
val thisForSuperCall = getSuperCallLabelTarget(bindingContext, superCallExpression)
|
||||||
|
|
||||||
if (thisForSuperCall != null && DescriptorUtils.isInterface(thisForSuperCall)) {
|
if (thisForSuperCall != null && DescriptorUtils.isInterface(thisForSuperCall)) {
|
||||||
val declarationWithCall = findInterfaceMember(thisForSuperCall, superCallExpression, bindingContext)
|
val declarationWithCall = findInterfaceMember(thisForSuperCall, superCallExpression, bindingContext)
|
||||||
if (declarationWithCall?.hasJvmDefaultAnnotation() == false) {
|
if (declarationWithCall?.hasJvmDefaultAnnotation(jvmDefaultMode) == false) {
|
||||||
context.trace.report(INTERFACE_CANT_CALL_DEFAULT_METHOD_VIA_SUPER.on(reportOn))
|
context.trace.report(INTERFACE_CANT_CALL_DEFAULT_METHOD_VIA_SUPER.on(reportOn))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-5
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||||
|
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
import org.jetbrains.kotlin.config.JvmTarget
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||||
@@ -40,9 +41,9 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
|
|||||||
if (descriptor is ClassDescriptor) {
|
if (descriptor is ClassDescriptor) {
|
||||||
val hasDeclaredJvmDefaults =
|
val hasDeclaredJvmDefaults =
|
||||||
descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance<CallableMemberDescriptor>().any {
|
descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance<CallableMemberDescriptor>().any {
|
||||||
it.kind.isReal && it.hasJvmDefaultAnnotation()
|
it.kind.isReal && it.hasJvmDefaultAnnotation(jvmDefaultMode)
|
||||||
}
|
}
|
||||||
if (!hasDeclaredJvmDefaults && !checkJvmDefaultsInHierarchy(descriptor, jvmDefaultMode.isEnabled)) {
|
if (!hasDeclaredJvmDefaults && !checkJvmDefaultsInHierarchy(descriptor, jvmDefaultMode)) {
|
||||||
context.trace.report(ErrorsJvm.JVM_DEFAULT_THROUGH_INHERITANCE.on(declaration))
|
context.trace.report(ErrorsJvm.JVM_DEFAULT_THROUGH_INHERITANCE.on(declaration))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +66,15 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkJvmDefaultsInHierarchy(descriptor: DeclarationDescriptor, enableJvmDefault: Boolean): Boolean {
|
private fun checkJvmDefaultsInHierarchy(descriptor: DeclarationDescriptor, jvmDefaultMode: JvmDefaultMode): Boolean {
|
||||||
if (enableJvmDefault) return true
|
if (jvmDefaultMode.isEnabled) return true
|
||||||
|
|
||||||
if (descriptor !is ClassDescriptor) return true
|
if (descriptor !is ClassDescriptor) return true
|
||||||
|
|
||||||
return descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance<CallableMemberDescriptor>()
|
return descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance<CallableMemberDescriptor>()
|
||||||
.all { memberDescriptor ->
|
.all { memberDescriptor ->
|
||||||
memberDescriptor.kind.isReal || OverridingUtil.filterOutOverridden(memberDescriptor.overriddenDescriptors.toSet()).all {
|
memberDescriptor.kind.isReal || OverridingUtil.filterOutOverridden(memberDescriptor.overriddenDescriptors.toSet()).all {
|
||||||
!isInterface(it.containingDeclaration) || !it.hasJvmDefaultAnnotation() || it.modality == Modality.ABSTRACT
|
!isInterface(it.containingDeclaration) || !it.hasJvmDefaultAnnotation(jvmDefaultMode) || it.modality == Modality.ABSTRACT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ class JvmDefaultSuperCallChecker : CallChecker {
|
|||||||
if (getSuperCallExpression(resolvedCall.call) == null) return
|
if (getSuperCallExpression(resolvedCall.call) == null) return
|
||||||
|
|
||||||
val resultingDescriptor = resolvedCall.resultingDescriptor as? CallableMemberDescriptor ?: return
|
val resultingDescriptor = resolvedCall.resultingDescriptor as? CallableMemberDescriptor ?: return
|
||||||
if (!resultingDescriptor.hasJvmDefaultAnnotation()) return
|
if (!resultingDescriptor.hasJvmDefaultAnnotation(jvmDefaultMode)) return
|
||||||
|
|
||||||
if (DescriptorUtils.isInterface(resultingDescriptor.containingDeclaration)) {
|
if (DescriptorUtils.isInterface(resultingDescriptor.containingDeclaration)) {
|
||||||
context.trace.report(ErrorsJvm.USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL.on(reportOn))
|
context.trace.report(ErrorsJvm.USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL.on(reportOn))
|
||||||
|
|||||||
@@ -248,7 +248,12 @@ private fun KtUltraLightClass.lightMethod(
|
|||||||
val name = if (descriptor is ConstructorDescriptor) name else support.typeMapper.mapFunctionName(descriptor, OwnerKind.IMPLEMENTATION)
|
val name = if (descriptor is ConstructorDescriptor) name else support.typeMapper.mapFunctionName(descriptor, OwnerKind.IMPLEMENTATION)
|
||||||
|
|
||||||
val accessFlags: Int by lazyPub {
|
val accessFlags: Int by lazyPub {
|
||||||
val asmFlags = AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION, support.deprecationResolver)
|
val asmFlags = AsmUtil.getMethodAsmFlags(
|
||||||
|
descriptor,
|
||||||
|
OwnerKind.IMPLEMENTATION,
|
||||||
|
support.deprecationResolver,
|
||||||
|
support.typeMapper.jvmDefaultMode,
|
||||||
|
)
|
||||||
packMethodFlags(asmFlags, JvmCodegenUtil.isJvmInterface(kotlinOrigin.resolve() as? ClassDescriptor))
|
packMethodFlags(asmFlags, JvmCodegenUtil.isJvmInterface(kotlinOrigin.resolve() as? ClassDescriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user