[FIR] Add support for JVM_STATIC_ON_EXTERNAL_IN_INTERFACE diagnostic

This commit is contained in:
Nikolay Lunyak
2021-08-02 15:40:15 +03:00
parent 7006426304
commit 2a2c92d8b3
10 changed files with 38 additions and 15 deletions
@@ -26,6 +26,7 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
val JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE) val JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE)
val JVM_STATIC_ON_NON_PUBLIC_MEMBER by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE) val JVM_STATIC_ON_NON_PUBLIC_MEMBER by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE)
val JVM_STATIC_ON_CONST_OR_JVM_FIELD by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE) val JVM_STATIC_ON_CONST_OR_JVM_FIELD by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE)
val JVM_STATIC_ON_EXTERNAL_IN_INTERFACE by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE)
val INAPPLICABLE_JVM_NAME by error<PsiElement>() val INAPPLICABLE_JVM_NAME by error<PsiElement>()
val ILLEGAL_JVM_NAME by error<PsiElement>() val ILLEGAL_JVM_NAME by error<PsiElement>()
@@ -27,6 +27,7 @@ object FirJvmErrors {
val JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION by error0<PsiElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val JVM_STATIC_NOT_IN_OBJECT_OR_COMPANION by error0<PsiElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val JVM_STATIC_ON_NON_PUBLIC_MEMBER by error0<PsiElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val JVM_STATIC_ON_NON_PUBLIC_MEMBER by error0<PsiElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val JVM_STATIC_ON_CONST_OR_JVM_FIELD by error0<PsiElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val JVM_STATIC_ON_CONST_OR_JVM_FIELD by error0<PsiElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val JVM_STATIC_ON_EXTERNAL_IN_INTERFACE by error0<PsiElement>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val INAPPLICABLE_JVM_NAME by error0<PsiElement>() val INAPPLICABLE_JVM_NAME by error0<PsiElement>()
val ILLEGAL_JVM_NAME by error0<PsiElement>() val ILLEGAL_JVM_NAME by error0<PsiElement>()
@@ -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.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion import org.jetbrains.kotlin.fir.declarations.utils.*
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.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
@@ -51,7 +48,7 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() {
checkOverrideCannotBeStatic(declaration, context, reporter, annotatedParts) checkOverrideCannotBeStatic(declaration, context, reporter, annotatedParts)
checkStaticNotInProperObject(context, reporter, annotatedParts) checkStaticNotInProperObject(context, reporter, annotatedParts)
checkStaticNonPublic(declaration, context, reporter, annotatedParts) checkStaticNonPublicOrExternal(declaration, context, reporter, annotatedParts)
checkStaticOnConstOrJvmField(context, reporter, annotatedParts) checkStaticOnConstOrJvmField(context, reporter, annotatedParts)
} }
@@ -70,7 +67,7 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() {
} }
} }
private fun checkStaticNonPublic( private fun checkStaticNonPublicOrExternal(
declaration: FirMemberDeclaration, declaration: FirMemberDeclaration,
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
@@ -93,12 +90,14 @@ object FirJvmStaticChecker : FirBasicDeclarationChecker() {
val minVisibility = declaration.getMinimumVisibility() val minVisibility = declaration.getMinimumVisibility()
if (minVisibility == Visibilities.Public) { if (minVisibility != Visibilities.Public) {
return annotatedParts.forEach {
} reporter.reportOn(it.source, FirJvmErrors.JVM_STATIC_ON_NON_PUBLIC_MEMBER, context)
}
annotatedParts.forEach { } else if (declaration.isExternal) {
reporter.reportOn(it.source, FirJvmErrors.JVM_STATIC_ON_NON_PUBLIC_MEMBER, context) annotatedParts.forEach {
reporter.reportOn(it.source, FirJvmErrors.JVM_STATIC_ON_EXTERNAL_IN_INTERFACE, context)
}
} }
} }
@@ -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_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_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_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.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.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_DATA_CLASS_JVM_RECORD
@@ -118,6 +119,10 @@ object FirJvmDefaultErrorMessages {
JVM_STATIC_ON_CONST_OR_JVM_FIELD, JVM_STATIC_ON_CONST_OR_JVM_FIELD,
"'@JvmStatic' annotation is useless for const or '@JvmField' properties", "'@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(INAPPLICABLE_JVM_NAME, "'@JvmName' annotation is not applicable to this declaration")
map.put(ILLEGAL_JVM_NAME, "Illegal JVM name") map.put(ILLEGAL_JVM_NAME, "Illegal JVM name")
@@ -18,7 +18,7 @@ interface B {
} }
<!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION!>@JvmStatic external fun a5()<!> <!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION, JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic external fun a5()<!>
<!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION!>@JvmStatic <!JVM_STATIC_NOT_IN_OBJECT_OR_CLASS_COMPANION!>@JvmStatic
var foo<!> = 1 var foo<!> = 1
@@ -20,7 +20,7 @@ interface B {
} }
@JvmStatic external fun a5() <!JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic external fun a5()<!>
@JvmStatic @JvmStatic
var foo = 1 var foo = 1
@@ -19,7 +19,7 @@ interface B {
} }
@JvmStatic external fun a5() <!JVM_STATIC_ON_EXTERNAL_IN_INTERFACE!>@JvmStatic external fun a5()<!>
@JvmStatic @JvmStatic
var foo = 1 var foo = 1
@@ -3694,6 +3694,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirJvmErrors.JVM_STATIC_ON_EXTERNAL_IN_INTERFACE) { firDiagnostic ->
JvmStaticOnExternalInInterfaceImpl(
firDiagnostic as FirPsiDiagnostic,
token,
)
}
add(FirJvmErrors.INAPPLICABLE_JVM_NAME) { firDiagnostic -> add(FirJvmErrors.INAPPLICABLE_JVM_NAME) { firDiagnostic ->
InapplicableJvmNameImpl( InapplicableJvmNameImpl(
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
@@ -2570,6 +2570,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = JvmStaticOnConstOrJvmField::class override val diagnosticClass get() = JvmStaticOnConstOrJvmField::class
} }
abstract class JvmStaticOnExternalInInterface : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = JvmStaticOnExternalInInterface::class
}
abstract class InapplicableJvmName : KtFirDiagnostic<PsiElement>() { abstract class InapplicableJvmName : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = InapplicableJvmName::class override val diagnosticClass get() = InapplicableJvmName::class
} }
@@ -4173,6 +4173,13 @@ internal class JvmStaticOnConstOrJvmFieldImpl(
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
} }
internal class JvmStaticOnExternalInInterfaceImpl(
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.JvmStaticOnExternalInInterface(), KtAbstractFirDiagnostic<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class InapplicableJvmNameImpl( internal class InapplicableJvmNameImpl(
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,