JvmDefault: remove diagnostics related to @JvmDefault
#KT-54746
This commit is contained in:
committed by
Space Team
parent
3120a35a88
commit
e0b5ae7781
-18
@@ -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,
|
||||
|
||||
-12
@@ -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
|
||||
}
|
||||
|
||||
-15
@@ -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,
|
||||
|
||||
-3
@@ -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") {
|
||||
|
||||
-3
@@ -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)
|
||||
|
||||
-9
@@ -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")
|
||||
|
||||
+38
-113
@@ -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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-35
@@ -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)
|
||||
|
||||
-3
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user