FIR: support JVM_DEFAULT_WITH_COMPATIBILITY_* diagnostics (FE 1.0 sync)
This commit is contained in:
committed by
TeamCityServer
parent
178290eac3
commit
533e802c8d
+12
@@ -4110,6 +4110,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION) { firDiagnostic ->
|
||||||
|
JvmDefaultWithCompatibilityInDeclarationImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirJvmErrors.JVM_DEFAULT_WITH_COMPATIBILITY_NOT_ON_INTERFACE) { firDiagnostic ->
|
||||||
|
JvmDefaultWithCompatibilityNotOnInterfaceImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirJvmErrors.USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL) { firDiagnostic ->
|
add(FirJvmErrors.USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL) { firDiagnostic ->
|
||||||
UsageOfJvmDefaultThroughSuperCallImpl(
|
UsageOfJvmDefaultThroughSuperCallImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+8
@@ -2859,6 +2859,14 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val annotation: String
|
abstract val annotation: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class JvmDefaultWithCompatibilityInDeclaration : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = JvmDefaultWithCompatibilityInDeclaration::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class JvmDefaultWithCompatibilityNotOnInterface : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = JvmDefaultWithCompatibilityNotOnInterface::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class UsageOfJvmDefaultThroughSuperCall : KtFirDiagnostic<PsiElement>() {
|
abstract class UsageOfJvmDefaultThroughSuperCall : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = UsageOfJvmDefaultThroughSuperCall::class
|
override val diagnosticClass get() = UsageOfJvmDefaultThroughSuperCall::class
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -3456,6 +3456,16 @@ internal class JvmDefaultInDeclarationImpl(
|
|||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.JvmDefaultInDeclaration(), KtAbstractFirDiagnostic<KtElement>
|
) : KtFirDiagnostic.JvmDefaultInDeclaration(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class JvmDefaultWithCompatibilityInDeclarationImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.JvmDefaultWithCompatibilityInDeclaration(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class JvmDefaultWithCompatibilityNotOnInterfaceImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.JvmDefaultWithCompatibilityNotOnInterface(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
internal class UsageOfJvmDefaultThroughSuperCallImpl(
|
internal class UsageOfJvmDefaultThroughSuperCallImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
+2
@@ -112,6 +112,8 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
|
|||||||
val JVM_DEFAULT_IN_DECLARATION by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
val JVM_DEFAULT_IN_DECLARATION by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
parameter<String>("annotation")
|
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 USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL by error<PsiElement>()
|
||||||
val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
|
val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -93,6 +93,8 @@ object FirJvmErrors {
|
|||||||
val JVM_DEFAULT_IN_JVM6_TARGET by error1<PsiElement, String>()
|
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_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_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 USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL by error0<PsiElement>()
|
||||||
val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
val NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
|
|
||||||
|
|||||||
+10
@@ -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_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_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_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_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_CANNOT_BE_EMPTY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.JVM_PACKAGE_NAME_MUST_BE_VALID_NAME
|
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_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_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(
|
map.put(
|
||||||
USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL,
|
USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL,
|
||||||
"Super calls of '@JvmDefault' members are only allowed with -Xjvm-default option"
|
"Super calls of '@JvmDefault' members are only allowed with -Xjvm-default option"
|
||||||
|
|||||||
+60
-27
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol
|
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_CLASS_ID
|
||||||
import org.jetbrains.kotlin.name.JvmNames.JVM_DEFAULT_NO_COMPATIBILITY_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() {
|
object FirJvmDefaultChecker : FirBasicDeclarationChecker() {
|
||||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
@@ -36,35 +37,67 @@ object FirJvmDefaultChecker : FirBasicDeclarationChecker() {
|
|||||||
|
|
||||||
if (defaultAnnotation != null) {
|
if (defaultAnnotation != null) {
|
||||||
val containingDeclaration = context.findClosest<FirClassLikeDeclaration>()
|
val containingDeclaration = context.findClosest<FirClassLikeDeclaration>()
|
||||||
if (containingDeclaration !is FirClass || !containingDeclaration.isInterface) {
|
val source = defaultAnnotation.source
|
||||||
reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE, context)
|
when {
|
||||||
return
|
containingDeclaration !is FirClass || !containingDeclaration.isInterface -> {
|
||||||
} else if (context.isJvm6()) {
|
reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_NOT_IN_INTERFACE, context)
|
||||||
reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, "JvmDefault", context)
|
return
|
||||||
return
|
}
|
||||||
} else if (!jvmDefaultMode.isEnabled) {
|
context.isJvm6() -> {
|
||||||
reporter.reportOn(defaultAnnotation.source, FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, "JvmDefault", context)
|
reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET, "JvmDefault", context)
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
!jvmDefaultMode.isEnabled -> {
|
||||||
|
reporter.reportOn(source, FirJvmErrors.JVM_DEFAULT_IN_DECLARATION, "JvmDefault", context)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val annotation = declaration.getAnnotationByClassId(JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID)
|
val annotationNoCompatibility = declaration.getAnnotationByClassId(JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID)
|
||||||
if (annotation != null) {
|
if (annotationNoCompatibility != null) {
|
||||||
if (context.isJvm6()) {
|
val source = annotationNoCompatibility.source
|
||||||
reporter.reportOn(
|
when {
|
||||||
annotation.source,
|
context.isJvm6() -> {
|
||||||
FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET,
|
reporter.reportOn(
|
||||||
"JvmDefaultWithoutCompatibility",
|
source,
|
||||||
context
|
FirJvmErrors.JVM_DEFAULT_IN_JVM6_TARGET,
|
||||||
)
|
"JvmDefaultWithoutCompatibility",
|
||||||
return
|
context
|
||||||
} else if (!jvmDefaultMode.isEnabled) {
|
)
|
||||||
reporter.reportOn(
|
return
|
||||||
annotation.source,
|
}
|
||||||
FirJvmErrors.JVM_DEFAULT_IN_DECLARATION,
|
!jvmDefaultMode.isEnabled -> {
|
||||||
"JvmDefaultWithoutCompatibility",
|
reporter.reportOn(
|
||||||
context
|
source,
|
||||||
)
|
FirJvmErrors.JVM_DEFAULT_IN_DECLARATION,
|
||||||
return
|
"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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
// !JVM_TARGET: 1.6
|
|
||||||
|
|
||||||
@JvmDefaultWithCompatibility
|
|
||||||
interface A {}
|
|
||||||
|
|
||||||
@JvmDefaultWithCompatibility
|
|
||||||
class B : A {}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !JVM_TARGET: 1.6
|
// !JVM_TARGET: 1.6
|
||||||
|
|
||||||
<!JVM_DEFAULT_IN_JVM6_TARGET!>@JvmDefaultWithCompatibility<!>
|
<!JVM_DEFAULT_IN_JVM6_TARGET!>@JvmDefaultWithCompatibility<!>
|
||||||
|
|||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
// !JVM_TARGET: 1.8
|
|
||||||
// !JVM_DEFAULT_MODE: all
|
|
||||||
|
|
||||||
@JvmDefaultWithCompatibility
|
|
||||||
interface A<T> {
|
|
||||||
fun test(p: T) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmDefaultWithCompatibility
|
|
||||||
class B : A<String> {}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !JVM_TARGET: 1.8
|
// !JVM_TARGET: 1.8
|
||||||
// !JVM_DEFAULT_MODE: all
|
// !JVM_DEFAULT_MODE: all
|
||||||
|
|
||||||
|
|||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
// !JVM_TARGET: 1.8
|
|
||||||
|
|
||||||
@JvmDefaultWithCompatibility
|
|
||||||
interface A<T> {
|
|
||||||
fun test(p: T) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmDefaultWithCompatibility
|
|
||||||
class B : A<String> {}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !JVM_TARGET: 1.8
|
// !JVM_TARGET: 1.8
|
||||||
|
|
||||||
<!JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION!>@JvmDefaultWithCompatibility<!>
|
<!JVM_DEFAULT_WITH_COMPATIBILITY_IN_DECLARATION!>@JvmDefaultWithCompatibility<!>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ object JvmNames {
|
|||||||
val JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME = FqName("kotlin.jvm.JvmDefaultWithoutCompatibility")
|
val JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME = FqName("kotlin.jvm.JvmDefaultWithoutCompatibility")
|
||||||
val JVM_DEFAULT_WITH_COMPATIBILITY_FQ_NAME = FqName("kotlin.jvm.JvmDefaultWithCompatibility")
|
val JVM_DEFAULT_WITH_COMPATIBILITY_FQ_NAME = FqName("kotlin.jvm.JvmDefaultWithCompatibility")
|
||||||
val JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID = ClassId.topLevel(JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME)
|
val JVM_DEFAULT_NO_COMPATIBILITY_CLASS_ID = ClassId.topLevel(JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME)
|
||||||
|
val JVM_DEFAULT_WITH_COMPATIBILITY_CLASS_ID = ClassId.topLevel(JVM_DEFAULT_WITH_COMPATIBILITY_FQ_NAME)
|
||||||
val JVM_OVERLOADS_FQ_NAME = FqName("kotlin.jvm.JvmOverloads")
|
val JVM_OVERLOADS_FQ_NAME = FqName("kotlin.jvm.JvmOverloads")
|
||||||
val JVM_OVERLOADS_CLASS_ID = ClassId.topLevel(JVM_OVERLOADS_FQ_NAME)
|
val JVM_OVERLOADS_CLASS_ID = ClassId.topLevel(JVM_OVERLOADS_FQ_NAME)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user