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 289a74b0815..b179dea2604 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 @@ -26,6 +26,7 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { val JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION by error(PositioningStrategy.DECLARATION_SIGNATURE) val JVM_STATIC_ON_NON_PUBLIC_MEMBER by error(PositioningStrategy.DECLARATION_SIGNATURE) val JVM_STATIC_ON_CONST_OR_JVM_FIELD by error(PositioningStrategy.DECLARATION_SIGNATURE) + val JVM_STATIC_ON_EXTERNAL_IN_INTERFACE by error(PositioningStrategy.DECLARATION_SIGNATURE) val INAPPLICABLE_JVM_NAME by error() val ILLEGAL_JVM_NAME by error() 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 3c448a77617..5b8adf05e45 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 @@ -27,6 +27,7 @@ object FirJvmErrors { val JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val JVM_STATIC_ON_NON_PUBLIC_MEMBER by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val JVM_STATIC_ON_CONST_OR_JVM_FIELD by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + val JVM_STATIC_ON_EXTERNAL_IN_INTERFACE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val INAPPLICABLE_JVM_NAME by error0() val ILLEGAL_JVM_NAME by error0() diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmStaticChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmStaticChecker.kt index 349c5206cae..63ca577a1c6 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmStaticChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmStaticChecker.kt @@ -17,10 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.isCompanion -import org.jetbrains.kotlin.fir.declarations.utils.isConst -import org.jetbrains.kotlin.fir.declarations.utils.isOverride -import org.jetbrains.kotlin.fir.declarations.utils.visibility +import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference @@ -51,7 +48,7 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() { checkOverrideCannotBeStatic(declaration, context, reporter, annotatedParts) checkStaticNotInProperObject(context, reporter, annotatedParts) - checkStaticNonPublic(declaration, context, reporter, annotatedParts) + checkStaticNonPublicOrExternal(declaration, context, reporter, annotatedParts) checkStaticOnConstOrJvmField(context, reporter, annotatedParts) } @@ -70,7 +67,7 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() { } } - private fun checkStaticNonPublic( + private fun checkStaticNonPublicOrExternal( declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter, @@ -93,12 +90,14 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() { val minVisibility = declaration.getMinimumVisibility() - if (minVisibility == Visibilities.Public) { - return - } - - annotatedParts.forEach { - reporter.reportOn(it.source, FirJvmErrors.JVM_STATIC_ON_NON_PUBLIC_MEMBER, context) + if (minVisibility != Visibilities.Public) { + annotatedParts.forEach { + reporter.reportOn(it.source, FirJvmErrors.JVM_STATIC_ON_NON_PUBLIC_MEMBER, context) + } + } else if (declaration.isExternal) { + annotatedParts.forEach { + reporter.reportOn(it.source, FirJvmErrors.JVM_STATIC_ON_EXTERNAL_IN_INTERFACE, context) + } } } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt index 1ed27b0f235..d4e55ccd272 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/diagnostics/FirJvmDefaultErrorMessages.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_RECORD import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_STATIC_ON_CONST_OR_JVM_FIELD +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_STATIC_ON_EXTERNAL_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_STATIC_ON_NON_PUBLIC_MEMBER 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 @@ -118,6 +119,10 @@ object FirJvmDefaultErrorMessages { JVM_STATIC_ON_CONST_OR_JVM_FIELD, "'@JvmStatic' annotation is useless for const or '@JvmField' properties", ) + map.put( + JVM_STATIC_ON_EXTERNAL_IN_INTERFACE, + "'@JvmStatic' annotation cannot be used on 'external' members of interface companions" + ) map.put(INAPPLICABLE_JVM_NAME, "'@JvmName' annotation is not applicable to this declaration") map.put(ILLEGAL_JVM_NAME, "Illegal JVM name") diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL12.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL12.fir.kt index 1c4193a01e6..4f66bc393b4 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL12.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL12.fir.kt @@ -18,7 +18,7 @@ interface B { } - @JvmStatic external fun a5() + @JvmStatic external fun a5() @JvmStatic var foo = 1 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL13_16.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL13_16.fir.kt index 640f0bad7eb..a9f224f8a56 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL13_16.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL13_16.fir.kt @@ -20,7 +20,7 @@ interface B { } - @JvmStatic external fun a5() + @JvmStatic external fun a5() @JvmStatic var foo = 1 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL13_18.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL13_18.fir.kt index 2e40383872a..ca96f7f72f6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL13_18.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/interfaceCompanion_LL13_18.fir.kt @@ -19,7 +19,7 @@ interface B { } - @JvmStatic external fun a5() + @JvmStatic external fun a5() @JvmStatic var foo = 1 diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index e9da3bfa61d..9eb392df8af 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -3694,6 +3694,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJvmErrors.JVM_STATIC_ON_EXTERNAL_IN_INTERFACE) { firDiagnostic -> + JvmStaticOnExternalInInterfaceImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirJvmErrors.INAPPLICABLE_JVM_NAME) { firDiagnostic -> InapplicableJvmNameImpl( firDiagnostic as FirPsiDiagnostic, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index dc1318e3d79..fd59cf4dad5 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2570,6 +2570,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = JvmStaticOnConstOrJvmField::class } + abstract class JvmStaticOnExternalInInterface : KtFirDiagnostic() { + override val diagnosticClass get() = JvmStaticOnExternalInInterface::class + } + abstract class InapplicableJvmName : KtFirDiagnostic() { override val diagnosticClass get() = InapplicableJvmName::class } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 561cee683b6..6b4b2e2c9c4 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -4173,6 +4173,13 @@ internal class JvmStaticOnConstOrJvmFieldImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class JvmStaticOnExternalInInterfaceImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.JvmStaticOnExternalInInterface(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + internal class InapplicableJvmNameImpl( firDiagnostic: FirPsiDiagnostic, override val token: ValidityToken,