FIR: support JVM_DEFAULT_WITH_COMPATIBILITY_* diagnostics (FE 1.0 sync)

This commit is contained in:
Mikhail Glukhikh
2021-12-08 17:44:08 +03:00
committed by TeamCityServer
parent 178290eac3
commit 533e802c8d
14 changed files with 108 additions and 53 deletions
@@ -112,6 +112,8 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
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 USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL by error<PsiElement>()
val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
}
@@ -93,6 +93,8 @@ object FirJvmErrors {
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 USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL by error0<PsiElement>()
val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
@@ -36,6 +36,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_DEFAUL
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
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_CANNOT_BE_EMPTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_MUST_BE_VALID_NAME
@@ -176,6 +178,14 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
)
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(
USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL,
"Super calls of '@JvmDefault' members are only allowed with -Xjvm-default option"
@@ -28,6 +28,7 @@ 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
object FirJvmDefaultChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -36,35 +37,67 @@ object FirJvmDefaultChecker : FirBasicDeclarationChecker() {
if (defaultAnnotation != null) {
val containingDeclaration = context.findClosest<FirClassLikeDeclaration>()
if (containingDeclaration !is FirClass || !containingDeclaration.isInterface) {
reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE, context)
return
} else if (context.isJvm6()) {
reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, "JvmDefault", context)
return
} else if (!jvmDefaultMode.isEnabled) {
reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, "JvmDefault", context)
return
val source = defaultAnnotation.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)
return
}
!jvmDefaultMode.isEnabled -> {
reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, "JvmDefault", context)
return
}
}
} else {
val annotation = declaration.getAnnotationByClassId(JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID)
if (annotation != null) {
if (context.isJvm6()) {
reporter.reportOn(
annotation.source,
FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET,
"JvmDefaultWithoutCompatibility",
context
)
return
} else if (!jvmDefaultMode.isEnabled) {
reporter.reportOn(
annotation.source,
FirJvmErrors.JVM_DEFAULT_IN_DECLARATION,
"JvmDefaultWithoutCompatibility",
context
)
return
val annotationNoCompatibility = declaration.getAnnotationByClassId(JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID)
if (annotationNoCompatibility != null) {
val source = annotationNoCompatibility.source
when {
context.isJvm6() -> {
reporter.reportOn(
source,
FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET,
"JvmDefaultWithoutCompatibility",
context
)
return
}
!jvmDefaultMode.isEnabled -> {
reporter.reportOn(
source,
FirJvmErrors.JVM_DEFAULT_IN_DECLARATION,
"JvmDefaultWithoutCompatibility",
context
)
return
}
}
}
val annotationWithCompatibility = declaration.getAnnotationByClassId(JVM_DEFAULT_WITH_COMPATIBILITY_CLASS_ID)
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
}
}
}
}