From e0b5ae778129a5431ee9e74c1c7e7553430343bf Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Sat, 22 Apr 2023 00:13:14 +0200 Subject: [PATCH] JvmDefault: remove diagnostics related to `@JvmDefault` #KT-54746 --- .../diagnostics/KtFirDataClassConverters.kt | 18 --- .../api/fir/diagnostics/KtFirDiagnostics.kt | 12 -- .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 15 -- .../diagnostics/FirJvmDiagnosticsList.kt | 3 - .../analysis/diagnostics/jvm/FirJvmErrors.kt | 3 - .../jvm/FirJvmErrorsDefaultMessages.kt | 9 -- .../declaration/FirJvmDefaultChecker.kt | 151 +++++------------- .../resolve/jvm/checkers/JvmDefaultChecker.kt | 38 +---- .../diagnostics/DefaultErrorMessagesJvm.java | 3 - .../resolve/jvm/diagnostics/ErrorsJvm.java | 4 - .../stdlib/jvm/src/kotlin/reflect/TypesJVM.kt | 2 +- 11 files changed, 42 insertions(+), 216 deletions(-) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index f2541ff86b4..fbbb5fe91a0 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -4620,12 +4620,6 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } - add(FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE) { firDiagnostic -> - JvmDefaultNotInInterfaceImpl( - firDiagnostic as KtPsiDiagnostic, - token, - ) - } add(FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET) { firDiagnostic -> JvmDefaultInJvm6TargetImpl( firDiagnostic.a, @@ -4633,12 +4627,6 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } - add(FirJvmErrors.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE) { firDiagnostic -> - JvmDefaultRequiredForOverrideImpl( - firDiagnostic as KtPsiDiagnostic, - token, - ) - } add(FirJvmErrors.JVM_DEFAULT_IN_DECLARATION) { firDiagnostic -> JvmDefaultInDeclarationImpl( firDiagnostic.a, @@ -4658,12 +4646,6 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } - add(FirJvmErrors.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT) { firDiagnostic -> - NonJvmDefaultOverridesJavaDefaultImpl( - firDiagnostic as KtPsiDiagnostic, - token, - ) - } add(FirJvmErrors.EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT) { firDiagnostic -> ExternalDeclarationCannotBeAbstractImpl( firDiagnostic as KtPsiDiagnostic, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 06619ade4ad..0b8b8cac205 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -3216,19 +3216,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = IllegalJavaLangRecordSupertype::class } - abstract class JvmDefaultNotInInterface : KtFirDiagnostic() { - override val diagnosticClass get() = JvmDefaultNotInInterface::class - } - abstract class JvmDefaultInJvm6Target : KtFirDiagnostic() { override val diagnosticClass get() = JvmDefaultInJvm6Target::class abstract val annotation: String } - abstract class JvmDefaultRequiredForOverride : KtFirDiagnostic() { - override val diagnosticClass get() = JvmDefaultRequiredForOverride::class - } - abstract class JvmDefaultInDeclaration : KtFirDiagnostic() { override val diagnosticClass get() = JvmDefaultInDeclaration::class abstract val annotation: String @@ -3242,10 +3234,6 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = JvmDefaultWithCompatibilityNotOnInterface::class } - abstract class NonJvmDefaultOverridesJavaDefault : KtFirDiagnostic() { - override val diagnosticClass get() = NonJvmDefaultOverridesJavaDefault::class - } - abstract class ExternalDeclarationCannotBeAbstract : KtFirDiagnostic() { override val diagnosticClass get() = ExternalDeclarationCannotBeAbstract::class } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 9b8e3f57bde..4bbae14432c 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -3887,22 +3887,12 @@ internal class IllegalJavaLangRecordSupertypeImpl( override val token: KtLifetimeToken, ) : KtFirDiagnostic.IllegalJavaLangRecordSupertype(), KtAbstractFirDiagnostic -internal class JvmDefaultNotInInterfaceImpl( - override val firDiagnostic: KtPsiDiagnostic, - override val token: KtLifetimeToken, -) : KtFirDiagnostic.JvmDefaultNotInInterface(), KtAbstractFirDiagnostic - internal class JvmDefaultInJvm6TargetImpl( override val annotation: String, override val firDiagnostic: KtPsiDiagnostic, override val token: KtLifetimeToken, ) : KtFirDiagnostic.JvmDefaultInJvm6Target(), KtAbstractFirDiagnostic -internal class JvmDefaultRequiredForOverrideImpl( - override val firDiagnostic: KtPsiDiagnostic, - override val token: KtLifetimeToken, -) : KtFirDiagnostic.JvmDefaultRequiredForOverride(), KtAbstractFirDiagnostic - internal class JvmDefaultInDeclarationImpl( override val annotation: String, override val firDiagnostic: KtPsiDiagnostic, @@ -3919,11 +3909,6 @@ internal class JvmDefaultWithCompatibilityNotOnInterfaceImpl( override val token: KtLifetimeToken, ) : KtFirDiagnostic.JvmDefaultWithCompatibilityNotOnInterface(), KtAbstractFirDiagnostic -internal class NonJvmDefaultOverridesJavaDefaultImpl( - override val firDiagnostic: KtPsiDiagnostic, - override val token: KtLifetimeToken, -) : KtFirDiagnostic.NonJvmDefaultOverridesJavaDefault(), KtAbstractFirDiagnostic - internal class ExternalDeclarationCannotBeAbstractImpl( override val firDiagnostic: KtPsiDiagnostic, override val token: KtLifetimeToken, diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt index 9bfc069509b..e36fb97ad7c 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt @@ -108,17 +108,14 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { } val JVM_DEFAULT by object : DiagnosticGroup("JVM Default") { - val JVM_DEFAULT_NOT_IN_INTERFACE by error() val JVM_DEFAULT_IN_JVM6_TARGET by error { parameter("annotation") } - val JVM_DEFAULT_REQUIRED_FOR_OVERRIDE by error(PositioningStrategy.DECLARATION_SIGNATURE) val JVM_DEFAULT_IN_DECLARATION by error(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) { parameter("annotation") } val JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION by error() val JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE by error() - val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning(PositioningStrategy.DECLARATION_SIGNATURE) } val EXTERNAL_DECLARATION by object : DiagnosticGroup("External Declaration") { diff --git a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt index 36e08fd190d..19815b595b2 100644 --- a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt +++ b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt @@ -90,13 +90,10 @@ object FirJvmErrors { val ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE by error0() // JVM Default - val JVM_DEFAULT_NOT_IN_INTERFACE by error0() val JVM_DEFAULT_IN_JVM6_TARGET by error1() - val JVM_DEFAULT_REQUIRED_FOR_OVERRIDE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val JVM_DEFAULT_IN_DECLARATION by error1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) val JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION by error0() val JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE by error0() - val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) // External Declaration val EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT by error0(SourceElementPositioningStrategies.ABSTRACT_MODIFIER) diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt index cd61bd46229..daf249b48c4 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt @@ -35,8 +35,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_SAM_I import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JAVA_TYPE_MISMATCH import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_IN_DECLARATION import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET -import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE -import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_INLINE_WITHOUT_VALUE_CLASS @@ -56,7 +54,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_SYNTHE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.LOCAL_JVM_RECORD import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.NON_DATA_CLASS_JVM_RECORD import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.NON_FINAL_JVM_RECORD -import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.NON_SOURCE_REPEATED_ANNOTATION import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_ABSTRACT import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR @@ -169,13 +166,11 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put(VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION, "Value classes without @JvmInline annotation are not supported yet") map.put(JVM_INLINE_WITHOUT_VALUE_CLASS, "@JvmInline annotation is only applicable to value classes") - map.put(JVM_DEFAULT_NOT_IN_INTERFACE, "'@JvmDefault' is only supported on interface members") map.put( JVM_DEFAULT_IN_JVM6_TARGET, "''@{0}'' is only supported since JVM target 1.8. Recompile with ''-jvm-target 1.8''", STRING ) - map.put(JVM_DEFAULT_REQUIRED_FOR_OVERRIDE, "'@JvmDefault' is required for an override of a '@JvmDefault' member") map.put(JVM_DEFAULT_IN_DECLARATION, "Usage of ''@{0}'' is only allowed with -Xjvm-default option", STRING) map.put( JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION, @@ -185,10 +180,6 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() { JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE, "'@JvmDefaultWithCompatibility' annotation is only allowed on interfaces" ) - map.put( - NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, - "Non-@JvmDefault interface method cannot override default Java method. Please annotate this method with @JvmDefault or enable `-Xjvm-default=all|all-compatibility`" - ) map.put(EXTERNAL_DECLARATION_IN_INTERFACE, "Members of interfaces can not be external") map.put(EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT, "External declaration can not be abstract") 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 6aa52a3bc35..e5748f8f709 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 @@ -6,26 +6,17 @@ package org.jetbrains.kotlin.fir.analysis.jvm.checkers.declaration import org.jetbrains.kotlin.config.JvmDefaultMode -import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker -import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.analysis.jvm.checkers.isJvm6 -import org.jetbrains.kotlin.fir.containingClassLookupTag -import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId import org.jetbrains.kotlin.fir.declarations.utils.isInterface -import org.jetbrains.kotlin.fir.declarations.utils.modality -import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.java.jvmDefaultModeState -import org.jetbrains.kotlin.fir.resolve.toSymbol -import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol -import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_CLASS_ID import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_WITH_COMPATIBILITY_CLASS_ID @@ -33,118 +24,52 @@ object FirJvmDefaultChecker : FirBasicDeclarationChecker() { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { val jvmDefaultMode = context.session.jvmDefaultModeState val session = context.session - val defaultAnnotation = declaration.getAnnotationByClassId(JVM_DEFAULT_CLASS_ID, session) - - if (defaultAnnotation != null) { - val containingDeclaration = context.findClosest() - val source = defaultAnnotation.source + val annotationNoCompatibility = declaration.getAnnotationByClassId(JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID, session) + if (annotationNoCompatibility != null) { + val source = annotationNoCompatibility.source when { - containingDeclaration !is FirClass || !containingDeclaration.isInterface -> { - reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE, context) - return - } context.isJvm6() -> { - reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, "JvmDefault", context) + reporter.reportOn( + source, + FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, + "JvmDefaultWithoutCompatibility", + context + ) return } jvmDefaultMode?.isEnabled != true -> { - reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, "JvmDefault", context) + reporter.reportOn( + source, + FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, + "JvmDefaultWithoutCompatibility", + context + ) return } } - } else { - val annotationNoCompatibility = declaration.getAnnotationByClassId(JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID, session) - if (annotationNoCompatibility != null) { - val source = annotationNoCompatibility.source - when { - context.isJvm6() -> { - reporter.reportOn( - source, - FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, - "JvmDefaultWithoutCompatibility", - context - ) - return - } - jvmDefaultMode?.isEnabled != true -> { - reporter.reportOn( - source, - FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, - "JvmDefaultWithoutCompatibility", - context - ) - return - } - } - } - val annotationWithCompatibility = declaration.getAnnotationByClassId(JVM_DEFAULT_WITH_COMPATIBILITY_CLASS_ID, session) - if (annotationWithCompatibility != null) { - val source = annotationWithCompatibility.source - when { - context.isJvm6() -> { - reporter.reportOn( - source, - FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, - "JvmDefaultWithCompatibility", - context - ) - return - } - jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE -> { - reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION, context) - return - } - declaration !is FirRegularClass || !declaration.isInterface -> { - reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE, context) - return - } - } - } } - - checkNonJvmDefaultOverridesJavaDefault(defaultAnnotation, jvmDefaultMode, declaration, context, reporter) - } - - private fun checkNonJvmDefaultOverridesJavaDefault( - defaultAnnotation: FirAnnotation?, - jvmDefaultMode: JvmDefaultMode?, - declaration: FirDeclaration, - context: CheckerContext, - reporter: DiagnosticReporter - ) { - if (defaultAnnotation != null || jvmDefaultMode?.forAllMethodsWithBody == true) return - val member = declaration as? FirSimpleFunction ?: return - - val containingDeclaration = context.findClosest() - if (containingDeclaration is FirClass && containingDeclaration.isInterface) { - val unsubstitutedScope = containingDeclaration.unsubstitutedScope(context) - unsubstitutedScope.processFunctionsByName(member.name) {} - val overriddenFunctions = unsubstitutedScope.getDirectOverriddenFunctions(member.symbol) - - if (overriddenFunctions.any { it.getAnnotationByClassId(JVM_DEFAULT_CLASS_ID, context.session) != null }) { - reporter.reportOn(declaration.source, FirJvmErrors.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE, context) - } else if (jvmDefaultMode?.isEnabled != false) { - for (overriddenFunction in overriddenFunctions) { - val overriddenDeclarations = overriddenFunction.getOverriddenDeclarations() - for (overriddenDeclaration in overriddenDeclarations) { - val containingClassSymbol = overriddenDeclaration.containingClassLookupTag()?.toSymbol(context.session) - if (containingClassSymbol?.origin is FirDeclarationOrigin.Java && - overriddenDeclaration.modality != Modality.ABSTRACT - ) { - reporter.reportOn(declaration.source, FirJvmErrors.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, context) - return - } - } + val annotationWithCompatibility = declaration.getAnnotationByClassId(JVM_DEFAULT_WITH_COMPATIBILITY_CLASS_ID, session) + if (annotationWithCompatibility != null) { + val source = annotationWithCompatibility.source + when { + context.isJvm6() -> { + reporter.reportOn( + source, + FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, + "JvmDefaultWithCompatibility", + context + ) + return + } + jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE -> { + reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION, context) + return + } + declaration !is FirRegularClass || !declaration.isInterface -> { + reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE, context) + return } } } } - - private fun FirCallableSymbol<*>.getOverriddenDeclarations(): List> { - return if (this is FirIntersectionCallableSymbol) { - ArrayList(this.intersections) - } else { - ArrayList>(1).also { it.add(this) } - } - } } 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 19a043f013e..5c421056d98 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 @@ -13,19 +13,19 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor -import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_FQ_NAME import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.* import org.jetbrains.kotlin.resolve.LanguageVersionSettingsProvider -import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPrivateApi import org.jetbrains.kotlin.resolve.descriptorUtil.module -import org.jetbrains.kotlin.resolve.jvm.annotations.* +import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_WITH_COMPATIBILITY_FQ_NAME +import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultNoCompatibilityAnnotation +import org.jetbrains.kotlin.resolve.jvm.annotations.isCompiledToJvmDefault import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.util.getNonPrivateTraitMembersForDelegation @@ -36,40 +36,8 @@ class JvmDefaultChecker(private val jvmTarget: JvmTarget, project: Project) : De override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { val jvmDefaultMode = context.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode) - val jvmDefaultAnnotation = descriptor.annotations.findAnnotation(JVM_DEFAULT_FQ_NAME) - jvmDefaultAnnotation?.let { annotationDescriptor -> - val reportOn = DescriptorToSourceUtils.getSourceFromAnnotation(annotationDescriptor) ?: declaration - if (!isInterface(descriptor.containingDeclaration)) { - context.trace.report(ErrorsJvm.JVM_DEFAULT_NOT_IN_INTERFACE.on(reportOn)) - return@check - } else if (jvmTarget == JvmTarget.JVM_1_6) { - context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_JVM6_TARGET.on(reportOn, "JvmDefault")) - return@check - } else if (!jvmDefaultMode.isEnabled) { - context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_DECLARATION.on(declaration, "JvmDefault")) - return@check - } - } - if (checkJvmCompatibilityAnnotations(descriptor, declaration, context, jvmDefaultMode)) return - if (jvmDefaultAnnotation == null && !jvmDefaultMode.forAllMethodsWithBody && isInterface(descriptor.containingDeclaration)) { - val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return - if (descriptor is PropertyAccessorDescriptor) return - - if (memberDescriptor.overriddenDescriptors.any { it.annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME) }) { - context.trace.report(ErrorsJvm.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE.on(declaration)) - } else if (jvmDefaultMode.isEnabled) { - descriptor.overriddenDescriptors.flatMap { OverridingUtil.getOverriddenDeclarations(it) }.toSet().let { - for (realDescriptor in OverridingUtil.filterOutOverridden(it)) { - if (realDescriptor is JavaMethodDescriptor && realDescriptor.modality != Modality.ABSTRACT) { - return context.trace.report(ErrorsJvm.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT.on(declaration)) - } - } - } - } - } - if (!jvmDefaultMode.isEnabled || descriptor !is ClassDescriptor || isInterface(descriptor) || isAnnotationClass(descriptor)) return // JvmDefaults members checks across class hierarchy: // 1. If in old scheme class have implicit override with different signature than overridden method (e.g. generic specialization) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java index 2e198d3c6d7..278abe78820 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java @@ -168,13 +168,10 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(ASSIGNMENT_TO_ARRAY_LOOP_VARIABLE, "Assignment to a for-in-array loop range variable. Behavior may change in Kotlin 1.3. " + "See https://youtrack.jetbrains.com/issue/KT-21354 for more details"); - MAP.put(JVM_DEFAULT_NOT_IN_INTERFACE,"'@JvmDefault' is only supported on interface members"); MAP.put(JVM_DEFAULT_IN_JVM6_TARGET,"''@{0}'' is only supported since JVM target 1.8. Recompile with ''-jvm-target 1.8''", STRING); - MAP.put(JVM_DEFAULT_REQUIRED_FOR_OVERRIDE, "'@JvmDefault' is required for an override of a '@JvmDefault' member"); MAP.put(JVM_DEFAULT_IN_DECLARATION, "Usage of ''@{0}'' is only allowed with -Xjvm-default option", STRING); MAP.put(JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION, "Usage of '@JvmDefaultWithCompatibility' is only allowed with '-Xjvm-default=all' option"); MAP.put(JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE, "'@JvmDefaultWithCompatibility' annotation is only allowed on interfaces"); - MAP.put(NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, "Non-@JvmDefault interface method cannot override default Java method. Please annotate this method with @JvmDefault or enable `-Xjvm-default=all|all-compatibility`"); MAP.put(EXPLICIT_METADATA_IS_DISALLOWED, "Explicit @Metadata is disallowed"); MAP.put(SUSPENSION_POINT_INSIDE_MONITOR, "A suspension point at {0} is inside a critical section", STRING); MAP.put(SUSPENSION_POINT_INSIDE_CRITICAL_SECTION, "The ''{0}'' suspension point is inside a critical section", NAME); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java index e0440bbc28f..60ada841fa7 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java @@ -130,9 +130,7 @@ public interface ErrorsJvm { DiagnosticFactory0 ASSIGNMENT_TO_ARRAY_LOOP_VARIABLE = DiagnosticFactory0.create(WARNING); - DiagnosticFactory0 JVM_DEFAULT_NOT_IN_INTERFACE = DiagnosticFactory0.create(ERROR); DiagnosticFactory1 JVM_DEFAULT_IN_JVM6_TARGET = DiagnosticFactory1.create(ERROR); - DiagnosticFactory0 JVM_DEFAULT_REQUIRED_FOR_OVERRIDE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory1 JVM_DEFAULT_IN_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory0 JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE = DiagnosticFactory0.create(ERROR); @@ -152,8 +150,6 @@ public interface ErrorsJvm { DiagnosticFactory0 ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 JVM_RECORDS_ILLEGAL_BYTECODE_TARGET = DiagnosticFactory0.create(ERROR); - DiagnosticFactory0 NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE); - DiagnosticFactory0 EXPLICIT_METADATA_IS_DISALLOWED = DiagnosticFactory0.create(ERROR); DiagnosticFactory2 NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS diff --git a/libraries/stdlib/jvm/src/kotlin/reflect/TypesJVM.kt b/libraries/stdlib/jvm/src/kotlin/reflect/TypesJVM.kt index daa8f860f76..a0257450c02 100644 --- a/libraries/stdlib/jvm/src/kotlin/reflect/TypesJVM.kt +++ b/libraries/stdlib/jvm/src/kotlin/reflect/TypesJVM.kt @@ -98,7 +98,7 @@ private val KTypeProjection.javaType: Type private interface TypeImpl : Type { // This is a copy of [Type.getTypeName] which is present on JDK 8+. @Suppress( - "VIRTUAL_MEMBER_HIDDEN", "NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT" + "VIRTUAL_MEMBER_HIDDEN" ) // This is needed for cases when environment variable JDK_1_6 points to JDK 8+. fun getTypeName(): String }