From 28797a31b4d9b7f5c99d162ab19fc6b46f8e529d Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 1 Feb 2024 13:22:48 +0100 Subject: [PATCH] JVM: refactor JvmDefaultMode, remove/rename some entries - remove ENABLE/COMPATIBILITY because they can no longer be used - remove forAllMethodsWithBody because its behavior is now equivalent to isEnabled - inline isCompatibility - inline DEFAULT - rename ALL_INCOMPATIBLE -> ALL --- .../api/fir/components/KtFirMetadataCalculator.kt | 2 +- .../symbol/classes/symbolLightClassUtils.kt | 10 +++------- .../jetbrains/kotlin/codegen/FunctionCodegen.java | 8 ++++---- .../codegen/binding/CodegenAnnotatingVisitor.java | 2 +- .../kotlin/codegen/context/CodegenContext.java | 8 -------- .../serialization/JvmSerializerExtension.kt | 10 +++++----- .../common/arguments/K2JVMCompilerArguments.kt | 10 +++------- .../org/jetbrains/kotlin/cli/jvm/jvmArguments.kt | 8 -------- .../jvm/checkers/FirJvmAnnotationHelper.kt | 2 +- .../checkers/declaration/FirJvmDefaultChecker.kt | 2 +- .../fir/backend/jvm/FirJvmSerializerExtension.kt | 13 ++++++++----- .../resolve/jvm/annotations/jvmAnnotationUtil.kt | 7 +++++-- .../resolve/jvm/checkers/JvmDefaultChecker.kt | 12 +++++++----- .../kotlin/backend/jvm/lower/InterfaceLowering.kt | 14 ++++++++------ .../jvm/lower/PropertyReferenceLowering.kt | 3 ++- .../jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt | 2 +- .../jvm/metadata/DescriptorMetadataSerializer.kt | 7 ++----- .../kotlin/asJava/classes/KtLightClassImpl.kt | 2 +- .../serialization/JvmVersionRequirementTest.kt | 2 +- .../org/jetbrains/kotlin/config/JvmDefaultMode.kt | 15 ++------------- .../kotlin/jps/build/KotlinJpsBuildTest.kt | 2 +- .../kotlin/kapt4/Kapt4EnvironmentConfigurator.kt | 2 +- 22 files changed, 58 insertions(+), 85 deletions(-) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirMetadataCalculator.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirMetadataCalculator.kt index e803ecb1008..3292c1e03bf 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirMetadataCalculator.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirMetadataCalculator.kt @@ -155,7 +155,7 @@ internal class KtFirMetadataCalculator(override val analysisSession: KtFirAnalys metadataVersion = metadataVersion, // Technically we should use JvmDefaultMode.ALL_INCOMPATIBLE because Kapt4 always uses `-Xjvm-default=all`, but it would make // the majority of tests fail because metadata of each interface will have a flag set, compared to Kapt3. - jvmDefaultMode = JvmDefaultMode.DEFAULT, + jvmDefaultMode = JvmDefaultMode.DISABLE, stringTable, null, null diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt index 77ab88b5fab..de1c4b509b7 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt @@ -37,11 +37,7 @@ import org.jetbrains.kotlin.config.JvmDefaultMode import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.lexer.KtTokens.* -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmNameAnnotation -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmOverloadsAnnotation -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation -import org.jetbrains.kotlin.light.classes.symbol.annotations.isHiddenOrSynthetic -import org.jetbrains.kotlin.light.classes.symbol.annotations.toOptionalFilter +import org.jetbrains.kotlin.light.classes.symbol.annotations.* import org.jetbrains.kotlin.light.classes.symbol.copy import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForEnumEntry @@ -560,11 +556,11 @@ internal fun KtSymbolWithMembers.createInnerClasses( ?.let { getModule(it) as? KtSourceModule } ?.languageVersionSettings ?.getFlag(JvmAnalysisFlags.jvmDefaultMode) - ?: JvmDefaultMode.DEFAULT + ?: JvmDefaultMode.DISABLE if (containingClass is SymbolLightClassForInterface && classOrObject?.hasInterfaceDefaultImpls == true && - jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE + jvmDefaultMode != JvmDefaultMode.ALL ) { result.add(SymbolLightClassForInterfaceDefaultImpls(containingClass)) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 969cdd7d345..ae70d15e1a3 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -715,9 +715,9 @@ public class FunctionCodegen { } private static boolean isCompiledInCompatibilityMode(JvmDefaultMode mode, CallableMemberDescriptor descriptor) { - return mode.isCompatibility() || - (mode == JvmDefaultMode.ALL_INCOMPATIBLE && - JvmAnnotationUtilKt.hasJvmDefaultWithCompatibilityAnnotation(descriptor.getContainingDeclaration())); + return mode == JvmDefaultMode.ALL_COMPATIBILITY || + (mode == JvmDefaultMode.ALL && + JvmAnnotationUtilKt.hasJvmDefaultWithCompatibilityAnnotation(descriptor.getContainingDeclaration())); } private static void generateLocalVariableTable( @@ -1681,7 +1681,7 @@ public class FunctionCodegen { // Fake overrides in interfaces should be expanded to implementation to make proper default check if (JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(memberDescriptor, mode)) { boolean isCompatibilityMode = isCompiledInCompatibilityMode(mode, memberDescriptor); - boolean isSyntheticInCompatibilityOrJvmDefault = isSynthetic && (isCompatibilityMode || mode == JvmDefaultMode.ENABLE); + boolean isSyntheticInCompatibilityOrJvmDefault = isSynthetic && isCompatibilityMode; return (kind != OwnerKind.DEFAULT_IMPLS && !isSyntheticInCompatibilityOrJvmDefault) || (kind == OwnerKind.DEFAULT_IMPLS && (isSyntheticInCompatibilityOrJvmDefault || diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index 6f7b0b761d9..ee82d739c07 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -591,7 +591,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { } return AsmUtil.asmTypeByClassId( - DescriptorUtils.isInterface(descriptor) && !jvmDefaultMode.getForAllMethodsWithBody() + DescriptorUtils.isInterface(descriptor) && !jvmDefaultMode.isEnabled() ? classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)) : classId ); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java index bbf792e8cc9..32dee1cb67d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.codegen.*; import org.jetbrains.kotlin.codegen.binding.MutableClosure; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; -import org.jetbrains.kotlin.config.JvmDefaultMode; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities; import org.jetbrains.kotlin.name.Name; @@ -652,13 +651,6 @@ public abstract class CodegenContext { return descriptor; } - //in other default modes there shouldn't be any accessors form DefaultImpls to Interface cause all compiled inside interface - if (getState().getJvmDefaultMode() == JvmDefaultMode.ENABLE && - JvmAnnotationUtilKt.hasJvmDefaultAnnotation(descriptor) && - descriptorContext instanceof DefaultImplsClassContext) { - descriptorContext = ((DefaultImplsClassContext) descriptorContext).getInterfaceContext(); - } - if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; int propertyAccessFlag = getVisibilityAccessFlag(descriptor); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt index e902135fd4d..13490e36883 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.kt @@ -75,17 +75,17 @@ class JvmSerializerExtension @JvmOverloads constructor( } //TODO: support local delegated properties in new defaults scheme val containerAsmType = - if (isInterface(descriptor) && !jvmDefaultMode.forAllMethodsWithBody) typeMapper.mapDefaultImpls(descriptor) else typeMapper.mapClass(descriptor) + if (isInterface(descriptor) && !jvmDefaultMode.isEnabled) typeMapper.mapDefaultImpls(descriptor) else typeMapper.mapClass(descriptor) writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable) writeVersionRequirementForJvmDefaultIfNeeded(descriptor, proto, versionRequirementTable) - if (jvmDefaultMode.forAllMethodsWithBody && isInterface(descriptor)) { + if (jvmDefaultMode.isEnabled && isInterface(descriptor)) { proto.setExtension( JvmProtoBuf.jvmClassFlags, JvmFlags.getClassFlags( - jvmDefaultMode.forAllMethodsWithBody, + true, (JvmDefaultMode.ALL_COMPATIBILITY == jvmDefaultMode && !descriptor.hasJvmDefaultNoCompatibilityAnnotation()) || - (JvmDefaultMode.ALL_INCOMPATIBLE == jvmDefaultMode && descriptor.hasJvmDefaultWithCompatibilityAnnotation()) + (JvmDefaultMode.ALL == jvmDefaultMode && descriptor.hasJvmDefaultWithCompatibilityAnnotation()) ) ) } @@ -99,7 +99,7 @@ class JvmSerializerExtension @JvmOverloads constructor( versionRequirementTable: MutableVersionRequirementTable ) { if (isInterface(classDescriptor)) { - if (jvmDefaultMode == JvmDefaultMode.ALL_INCOMPATIBLE) { + if (jvmDefaultMode == JvmDefaultMode.ALL) { builder.addVersionRequirement( writeVersionRequirement(1, 4, 0, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable) ) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index 3d6ab5500d2..aa50435075f 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -466,7 +466,7 @@ The default value is 'warn'.""" and the class is not annotated with '@JvmDefaultWithoutCompatibility' (see KT-39603 for more details). -Xjvm-default=disable Default behavior. Do not generate JVM default methods.""" ) - var jvmDefault: String = JvmDefaultMode.DEFAULT.description + var jvmDefault: String = JvmDefaultMode.DISABLE.description set(value) { checkFrozen() field = value @@ -846,11 +846,7 @@ This option is deprecated and will be deleted in future versions.""" result[JvmAnalysisFlags.jvmDefaultMode] = it } ?: collector.report( CompilerMessageSeverity.ERROR, - "Unknown -Xjvm-default mode: $jvmDefault, supported modes: ${ - JvmDefaultMode.values().mapNotNull { mode -> - mode.description.takeIf { JvmDefaultMode.fromStringOrNull(it) != null } - } - }" + "Unknown -Xjvm-default mode: $jvmDefault, supported modes: ${JvmDefaultMode.values().map(JvmDefaultMode::description)}" ) result[JvmAnalysisFlags.inheritMultifileParts] = inheritMultifileParts result[JvmAnalysisFlags.sanitizeParentheses] = sanitizeParentheses @@ -869,7 +865,7 @@ This option is deprecated and will be deleted in future versions.""" if (enhanceTypeParameterTypesToDefNotNull) { result[LanguageFeature.ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated] = LanguageFeature.State.ENABLED } - if (JvmDefaultMode.fromStringOrNull(jvmDefault)?.forAllMethodsWithBody == true) { + if (JvmDefaultMode.fromStringOrNull(jvmDefault)?.isEnabled == true) { result[LanguageFeature.ForbidSuperDelegationToAbstractFakeOverride] = LanguageFeature.State.ENABLED result[LanguageFeature.AbstractClassMemberNotImplementedWithIntermediateAbstractClass] = LanguageFeature.State.ENABLED } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index d4f5e5853be..4e981930a79 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -75,16 +75,8 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu } } - val jvmDefaultMode = languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode) val jvmTarget = get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT - if (jvmDefaultMode == JvmDefaultMode.ENABLE || jvmDefaultMode == JvmDefaultMode.ENABLE_WITH_DEFAULT_IMPLS) { - messageCollector.report( - WARNING, - "'-Xjvm-default=${jvmDefaultMode.description}' is deprecated, please use '-Xjvm-default=all|all-compatibility'" - ) - } - val stringConcat = arguments.stringConcat if (stringConcat != null) { val runtimeStringConcat = JvmStringConcat.fromString(stringConcat) diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt index 05cc1a6b3c0..fbb466b5629 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJvmAnnotationHelper.kt @@ -24,7 +24,7 @@ fun FirBasedSymbol.isCompiledToJvmDefault( if (getAnnotationByClassId(JvmStandardClassIds.Annotations.JvmDefault, session) != null) return true val container = getContainingClassSymbol(session) - if (container !is FirRegularClassSymbol || container.origin.fromSource) return jvmDefaultMode.forAllMethodsWithBody + if (container !is FirRegularClassSymbol || container.origin.fromSource) return jvmDefaultMode.isEnabled // Opt-in is fine here because this flag is only possible for deserialized declarations, and it's set during deserialization. @OptIn(SymbolInternals::class) diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmDefaultChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmDefaultChecker.kt index 0920f696a78..deec2e3182e 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmDefaultChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmDefaultChecker.kt @@ -36,7 +36,7 @@ object FirJvmDefaultChecker : FirBasicDeclarationChecker(MppCheckerKind.Common) if (annotationWithCompatibility != null) { val source = annotationWithCompatibility.source when { - jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE -> { + jvmDefaultMode != JvmDefaultMode.ALL -> { reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION, context) return } diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt index ce333cf38a8..4459cb09c0c 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt @@ -27,7 +27,10 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.providers.getRegularClassSymbolByClassId import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol -import org.jetbrains.kotlin.fir.serialization.* +import org.jetbrains.kotlin.fir.serialization.FirAdditionalMetadataProvider +import org.jetbrains.kotlin.fir.serialization.FirElementAwareStringTable +import org.jetbrains.kotlin.fir.serialization.FirElementSerializer +import org.jetbrains.kotlin.fir.serialization.FirSerializerExtension import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.ir.declarations.MetadataSource @@ -100,14 +103,14 @@ class FirJvmSerializerExtension( writeLocalProperties(proto, JvmProtoBuf.classLocalVariable) writeVersionRequirementForJvmDefaultIfNeeded(klass, proto, versionRequirementTable) - if (jvmDefaultMode.forAllMethodsWithBody && klass is FirRegularClass && klass.classKind == ClassKind.INTERFACE) { + if (jvmDefaultMode.isEnabled && klass is FirRegularClass && klass.classKind == ClassKind.INTERFACE) { proto.setExtension( JvmProtoBuf.jvmClassFlags, JvmFlags.getClassFlags( - jvmDefaultMode.forAllMethodsWithBody, + true, (JvmDefaultMode.ALL_COMPATIBILITY == jvmDefaultMode && !klass.hasAnnotation(JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID, session)) || - (JvmDefaultMode.ALL_INCOMPATIBLE == jvmDefaultMode && + (JvmDefaultMode.ALL == jvmDefaultMode && klass.hasAnnotation(JVM_DEFAULT_WITH_COMPATIBILITY_CLASS_ID, session)) ) ) @@ -135,7 +138,7 @@ class FirJvmSerializerExtension( versionRequirementTable: MutableVersionRequirementTable ) { if (klass is FirRegularClass && klass.classKind == ClassKind.INTERFACE) { - if (jvmDefaultMode == JvmDefaultMode.ALL_INCOMPATIBLE) { + if (jvmDefaultMode == JvmDefaultMode.ALL) { builder.addVersionRequirement( DescriptorSerializer.writeVersionRequirement( 1, diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotations/jvmAnnotationUtil.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotations/jvmAnnotationUtil.kt index 02899fa36dc..546109a7d36 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotations/jvmAnnotationUtil.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotations/jvmAnnotationUtil.kt @@ -6,7 +6,10 @@ package org.jetbrains.kotlin.resolve.jvm.annotations import org.jetbrains.kotlin.config.JvmDefaultMode -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME @@ -68,7 +71,7 @@ fun CallableMemberDescriptor.isCompiledToJvmDefault(jvmDefault: JvmDefaultMode): // } if (directMember.annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)) return true - if (clazz !is DeserializedClassDescriptor) return jvmDefault.forAllMethodsWithBody + if (clazz !is DeserializedClassDescriptor) return jvmDefault.isEnabled return JvmProtoBufUtil.isNewPlaceForBodyGeneration(clazz.classProto) } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt index 74ddaaea39d..495b3de6442 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.jvm.checkers import com.intellij.openapi.project.Project import org.jetbrains.kotlin.config.JvmAnalysisFlags import org.jetbrains.kotlin.config.JvmDefaultMode +import org.jetbrains.kotlin.config.JvmDefaultMode.ALL_COMPATIBILITY import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor @@ -44,9 +45,10 @@ class JvmDefaultChecker(private val jvmTarget: JvmTarget, project: Project) : De // report error because absent of it's can affect library ABI // 2. If it's mixed hierarchy with implicit override in base class and override one in inherited derived interface report error. // Otherwise the implicit class override would be used for dispatching method calls (but not more specialized) - val performSpecializationCheck = jvmDefaultMode.isCompatibility && !descriptor.hasJvmDefaultNoCompatibilityAnnotation() && - //TODO: maybe remove this check for JVM compatibility - !(descriptor.modality !== Modality.OPEN && descriptor.modality !== Modality.ABSTRACT || descriptor.isEffectivelyPrivateApi) + val performSpecializationCheck = + jvmDefaultMode == JvmDefaultMode.ALL_COMPATIBILITY && !descriptor.hasJvmDefaultNoCompatibilityAnnotation() && + //TODO: maybe remove this check for JVM compatibility + !(descriptor.modality !== Modality.OPEN && descriptor.modality !== Modality.ABSTRACT || descriptor.isEffectivelyPrivateApi) //Should we check clash with implicit class member (that comes from old compilation scheme) and specialization for compatibility mode // If specialization check is reported clash one shouldn't be reported @@ -71,7 +73,7 @@ class JvmDefaultChecker(private val jvmTarget: JvmTarget, project: Project) : De } else if (actualImplementation is PropertyDescriptor && inheritedMember is PropertyDescriptor) { val getterImpl = actualImplementation.getter val getterInherited = inheritedMember.getter - if (getterImpl == null || getterInherited == null || !jvmDefaultMode.isCompatibility || + if (getterImpl == null || getterInherited == null || jvmDefaultMode != ALL_COMPATIBILITY || checkSpecializationInCompatibilityMode( getterInherited, getterImpl, @@ -117,7 +119,7 @@ class JvmDefaultChecker(private val jvmTarget: JvmTarget, project: Project) : De descriptor.annotations.findAnnotation(JVM_DEFAULT_WITH_COMPATIBILITY_FQ_NAME)?.let { annotationDescriptor -> val reportOn = DescriptorToSourceUtils.getSourceFromAnnotation(annotationDescriptor) ?: declaration - if (jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE) { + if (jvmDefaultMode != JvmDefaultMode.ALL) { context.trace.report(ErrorsJvm.JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION.on(reportOn)) return true } else if (!isInterface(descriptor)) { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index 48f0ccdc230..d42ec8e2074 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -19,7 +19,10 @@ import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.expressions.IrReturn -import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.util.functions @@ -65,8 +68,8 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran private fun handleInterface(irClass: IrClass) { val jvmDefaultMode = context.config.jvmDefaultMode val isCompatibilityMode = - (jvmDefaultMode.isCompatibility && !irClass.hasJvmDefaultNoCompatibilityAnnotation()) || - (jvmDefaultMode == JvmDefaultMode.ALL_INCOMPATIBLE && irClass.hasJvmDefaultWithCompatibilityAnnotation()) + (jvmDefaultMode == JvmDefaultMode.ALL_COMPATIBILITY && !irClass.hasJvmDefaultNoCompatibilityAnnotation()) || + (jvmDefaultMode == JvmDefaultMode.ALL && irClass.hasJvmDefaultWithCompatibilityAnnotation()) // There are 6 cases for functions on interfaces: for (function in irClass.functions) { when { @@ -130,8 +133,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran || function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER || function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS)) || (function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS && - (isCompatibilityMode || jvmDefaultMode == JvmDefaultMode.ENABLE) && - function.isCompiledToJvmDefault(jvmDefaultMode)) -> { + isCompatibilityMode && function.isCompiledToJvmDefault(jvmDefaultMode)) -> { if (function.origin == JvmLoweredDeclarationOrigin.INLINE_LAMBDA) { //move as is val defaultImplsClass = context.cachedDeclarations.getDefaultImplsClass(irClass) @@ -177,7 +179,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran // Move $$delegatedProperties array and $assertionsDisabled field for (field in irClass.declarations.filterIsInstance()) { - if ((jvmDefaultMode.forAllMethodsWithBody || field.origin != JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE) && + if ((jvmDefaultMode.isEnabled || field.origin != JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE) && field.origin != JvmLoweredDeclarationOrigin.GENERATED_ASSERTION_ENABLED_FIELD ) continue diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index d919b8a1a79..79a3d1faad1 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -218,7 +218,8 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle isFinal = true isStatic = true visibility = - if (irClass.isInterface && context.config.jvmDefaultMode.forAllMethodsWithBody) DescriptorVisibilities.PUBLIC else JavaDescriptorVisibilities.PACKAGE_VISIBILITY + if (irClass.isInterface && context.config.jvmDefaultMode.isEnabled) DescriptorVisibilities.PUBLIC + else JavaDescriptorVisibilities.PACKAGE_VISIBILITY } val localProperties = mutableListOf() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt index b5e9e9db8d1..833530a7c15 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/ir/JvmIrUtils.kt @@ -98,7 +98,7 @@ fun IrSimpleFunction.isCompiledToJvmDefault(jvmDefaultMode: JvmDefaultMode): Boo } is IrMaybeDeserializedClass -> return klass.isNewPlaceForBodyGeneration } - return jvmDefaultMode.forAllMethodsWithBody + return jvmDefaultMode.isEnabled } fun IrFunction.hasJvmDefault(): Boolean = propertyIfAccessor.hasAnnotation(JVM_DEFAULT_FQ_NAME) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/metadata/DescriptorMetadataSerializer.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/metadata/DescriptorMetadataSerializer.kt index 7d257b29306..9ad89160d74 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/metadata/DescriptorMetadataSerializer.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/metadata/DescriptorMetadataSerializer.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.createFreeFakeLambdaDescriptor import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension -import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin @@ -59,10 +58,8 @@ class DescriptorMetadataSerializer( context.state.bindingTrace.record( CodegenBinding.DELEGATED_PROPERTIES_WITH_METADATA, // key for local delegated properties metadata in interfaces depends on jvmDefaultMode - if (irClass.isInterface && !context.config.jvmDefaultMode.forAllMethodsWithBody) context.defaultTypeMapper.mapClass( - context.cachedDeclarations.getDefaultImplsClass( - irClass - ) + if (irClass.isInterface && !context.config.jvmDefaultMode.isEnabled) context.defaultTypeMapper.mapClass( + context.cachedDeclarations.getDefaultImplsClass(irClass) ) else type, localDelegatedProperties.mapNotNull { (it.owner.metadata as? DescriptorMetadataSource.LocalDelegatedProperty)?.descriptor } ) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassImpl.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassImpl.kt index dd3e3c28dee..3001ba26b67 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassImpl.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassImpl.kt @@ -171,7 +171,7 @@ abstract class KtLightClassImpl( .filter { it.name != null } .mapNotNullTo(result, KtClassOrObject::toLightClass) - if (classOrObject.hasInterfaceDefaultImpls && jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE) { + if (classOrObject.hasInterfaceDefaultImpls && jvmDefaultMode != JvmDefaultMode.ALL) { result.add(createClassForInterfaceDefaultImpls()) } diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt index 791bf456d89..f4e26cdb555 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/JvmVersionRequirementTest.kt @@ -66,7 +66,7 @@ class JvmVersionRequirementTest : AbstractVersionRequirementTest() { fun testAllJvmDefault() { doTest( VersionRequirement.Version(1, 4, 0), DeprecationLevel.ERROR, null, COMPILER_VERSION, null, - analysisFlags = mapOf(JvmAnalysisFlags.jvmDefaultMode to JvmDefaultMode.ALL_INCOMPATIBLE), + analysisFlags = mapOf(JvmAnalysisFlags.jvmDefaultMode to JvmDefaultMode.ALL), fqNamesWithRequirements = listOf( "test.Base", "test.Derived", diff --git a/compiler/util/src/org/jetbrains/kotlin/config/JvmDefaultMode.kt b/compiler/util/src/org/jetbrains/kotlin/config/JvmDefaultMode.kt index 323a949172b..744eff3fb9b 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/JvmDefaultMode.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/JvmDefaultMode.kt @@ -7,29 +7,18 @@ package org.jetbrains.kotlin.config enum class JvmDefaultMode(val description: String) { DISABLE("disable"), - ENABLE("enable"), - ENABLE_WITH_DEFAULT_IMPLS("compatibility"), ALL_COMPATIBILITY("all-compatibility"), - ALL_INCOMPATIBLE("all"); + ALL("all"); val isEnabled: Boolean get() = this != DISABLE - val isCompatibility: Boolean - get() = this == ENABLE_WITH_DEFAULT_IMPLS || this == ALL_COMPATIBILITY - - val forAllMethodsWithBody: Boolean - get() = this == ALL_COMPATIBILITY || this == ALL_INCOMPATIBLE - companion object { - @JvmField - val DEFAULT = DISABLE - @JvmStatic fun fromStringOrNull(string: String?): JvmDefaultMode? = when (string) { DISABLE.description -> DISABLE ALL_COMPATIBILITY.description -> ALL_COMPATIBILITY - ALL_INCOMPATIBLE.description -> ALL_INCOMPATIBLE + ALL.description -> ALL else -> null } } diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt index 62fb117a963..55015b44a89 100644 --- a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt +++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/KotlinJpsBuildTest.kt @@ -896,7 +896,7 @@ open class KotlinJpsBuildTest : KotlinJpsBuildTestBase() { val facet = KotlinFacetSettings() facet.useProjectSettings = false facet.compilerArguments = K2JVMCompilerArguments() - (facet.compilerArguments as K2JVMCompilerArguments).jvmDefault = JvmDefaultMode.DEFAULT.description + (facet.compilerArguments as K2JVMCompilerArguments).jvmDefault = JvmDefaultMode.DISABLE.description it.container.setChild( JpsKotlinFacetModuleExtension.KIND, diff --git a/plugins/kapt4/test/org/jetbrains/kotlin/kapt4/Kapt4EnvironmentConfigurator.kt b/plugins/kapt4/test/org/jetbrains/kotlin/kapt4/Kapt4EnvironmentConfigurator.kt index 32365aab7be..ce560f88731 100644 --- a/plugins/kapt4/test/org/jetbrains/kotlin/kapt4/Kapt4EnvironmentConfigurator.kt +++ b/plugins/kapt4/test/org/jetbrains/kotlin/kapt4/Kapt4EnvironmentConfigurator.kt @@ -20,7 +20,7 @@ class Kapt4EnvironmentConfigurator(testServices: TestServices) : EnvironmentConf languageVersion: LanguageVersion, ): Map, Any?> = mapOf( JvmAnalysisFlags.generatePropertyAnnotationsMethods to true, - JvmAnalysisFlags.jvmDefaultMode to JvmDefaultMode.ALL_INCOMPATIBLE + JvmAnalysisFlags.jvmDefaultMode to JvmDefaultMode.ALL ) override val directiveContainers: List = listOf(Kapt4TestDirectives)