JvmDefault: remove diagnostics related to @JvmDefault

#KT-54746
This commit is contained in:
Alexander Udalov
2023-04-22 00:13:14 +02:00
committed by Space Team
parent 3120a35a88
commit e0b5ae7781
11 changed files with 42 additions and 216 deletions
@@ -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,
@@ -3216,19 +3216,11 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = IllegalJavaLangRecordSupertype::class
}
abstract class JvmDefaultNotInInterface : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = JvmDefaultNotInInterface::class
}
abstract class JvmDefaultInJvm6Target : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = JvmDefaultInJvm6Target::class
abstract val annotation: String
}
abstract class JvmDefaultRequiredForOverride : KtFirDiagnostic<KtDeclaration>() {
override val diagnosticClass get() = JvmDefaultRequiredForOverride::class
}
abstract class JvmDefaultInDeclaration : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = JvmDefaultInDeclaration::class
abstract val annotation: String
@@ -3242,10 +3234,6 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = JvmDefaultWithCompatibilityNotOnInterface::class
}
abstract class NonJvmDefaultOverridesJavaDefault : KtFirDiagnostic<KtDeclaration>() {
override val diagnosticClass get() = NonJvmDefaultOverridesJavaDefault::class
}
abstract class ExternalDeclarationCannotBeAbstract : KtFirDiagnostic<KtDeclaration>() {
override val diagnosticClass get() = ExternalDeclarationCannotBeAbstract::class
}
@@ -3887,22 +3887,12 @@ internal class IllegalJavaLangRecordSupertypeImpl(
override val token: KtLifetimeToken,
) : KtFirDiagnostic.IllegalJavaLangRecordSupertype(), KtAbstractFirDiagnostic<PsiElement>
internal class JvmDefaultNotInInterfaceImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.JvmDefaultNotInInterface(), KtAbstractFirDiagnostic<PsiElement>
internal class JvmDefaultInJvm6TargetImpl(
override val annotation: String,
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.JvmDefaultInJvm6Target(), KtAbstractFirDiagnostic<PsiElement>
internal class JvmDefaultRequiredForOverrideImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.JvmDefaultRequiredForOverride(), KtAbstractFirDiagnostic<KtDeclaration>
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<KtElement>
internal class NonJvmDefaultOverridesJavaDefaultImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.NonJvmDefaultOverridesJavaDefault(), KtAbstractFirDiagnostic<KtDeclaration>
internal class ExternalDeclarationCannotBeAbstractImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
@@ -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<PsiElement>()
val JVM_DEFAULT_IN_JVM6_TARGET by error<PsiElement> {
parameter<String>("annotation")
}
val JVM_DEFAULT_REQUIRED_FOR_OVERRIDE by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val JVM_DEFAULT_IN_DECLARATION by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<String>("annotation")
}
val JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION by error<KtElement>()
val JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE by error<KtElement>()
val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
}
val EXTERNAL_DECLARATION by object : DiagnosticGroup("External Declaration") {
@@ -90,13 +90,10 @@ object FirJvmErrors {
val ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE by error0<PsiElement>()
// JVM Default
val JVM_DEFAULT_NOT_IN_INTERFACE by error0<PsiElement>()
val JVM_DEFAULT_IN_JVM6_TARGET by error1<PsiElement, String>()
val JVM_DEFAULT_REQUIRED_FOR_OVERRIDE by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val JVM_DEFAULT_IN_DECLARATION by error1<KtElement, String>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION by error0<KtElement>()
val JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE by error0<KtElement>()
val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
// External Declaration
val EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT by error0<KtDeclaration>(SourceElementPositioningStrategies.ABSTRACT_MODIFIER)
@@ -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")
@@ -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<FirClassLikeDeclaration>()
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<FirClassLikeDeclaration>()
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<FirCallableSymbol<*>> {
return if (this is FirIntersectionCallableSymbol) {
ArrayList(this.intersections)
} else {
ArrayList<FirCallableSymbol<*>>(1).also { it.add(this) }
}
}
}
@@ -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)
@@ -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);
@@ -130,9 +130,7 @@ public interface ErrorsJvm {
DiagnosticFactory0<KtExpression> ASSIGNMENT_TO_ARRAY_LOOP_VARIABLE = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> JVM_DEFAULT_NOT_IN_INTERFACE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, String> JVM_DEFAULT_IN_JVM6_TARGET = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<KtDeclaration> JVM_DEFAULT_REQUIRED_FOR_OVERRIDE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory1<KtElement, String> JVM_DEFAULT_IN_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtElement> JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtElement> JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE = DiagnosticFactory0.create(ERROR);
@@ -152,8 +150,6 @@ public interface ErrorsJvm {
DiagnosticFactory0<PsiElement> ILLEGAL_JAVA_LANG_RECORD_SUPERTYPE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> JVM_RECORDS_ILLEGAL_BYTECODE_TARGET = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtDeclaration> NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtAnnotationEntry> EXPLICIT_METADATA_IS_DISALLOWED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory2<KtElement, KotlinType, KotlinType> NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
@@ -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
}